Version 1.0.2.0

svn merge -r 30576:30767 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@30779 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/dart.gyp b/dart.gyp
index 9bfc1d3..0b4e11e 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -15,7 +15,6 @@
         'packages',
         'runtime',
         'samples',
-        'upload_sdk',
       ],
     },
     {
@@ -41,8 +40,6 @@
       ],
     },
     {
-      # Build the SDK. This target is separate from upload_sdk as the
-      # editor needs to build the SDK without uploading it.
       'target_name': 'create_sdk',
       'type': 'none',
       'dependencies': [
@@ -79,35 +76,6 @@
       ],
     },
     {
-      # Upload the SDK. This target is separate from create_sdk as the
-      # editor needs to build the SDK without uploading it.
-      'target_name': 'upload_sdk',
-      'type': 'none',
-      'dependencies': [
-        'create_sdk',
-      ],
-      'inputs': [
-        '<(PRODUCT_DIR)/dart-sdk/README',
-      ],
-      'actions': [
-        {
-          'action_name': 'upload_sdk_py',
-          'inputs': [
-            '<(PRODUCT_DIR)/dart-sdk/README',
-            'tools/upload_sdk.py',
-          ],
-          'outputs': [
-            '<(PRODUCT_DIR)/dart-sdk/upload.stamp',
-          ],
-          'action': [
-            'python',
-            'tools/upload_sdk.py',
-            '<(PRODUCT_DIR)/dart-sdk'
-          ],
-        },
-      ],
-    },
-    {
       'target_name': 'dart2js',
       'type': 'none',
       'dependencies': [
diff --git a/pkg/analyzer/bin/formatter.dart b/pkg/analyzer/bin/formatter.dart
index 5693e9c..b49aff3 100755
--- a/pkg/analyzer/bin/formatter.dart
+++ b/pkg/analyzer/bin/formatter.dart
@@ -20,6 +20,7 @@
 
 var formatterSettings;
 
+CodeKind kind;
 bool machineFormat;
 bool overwriteFileContents;
 Selection selection;
@@ -36,13 +37,14 @@
   _readOptions(options);
 
   if (options.rest.isEmpty) {
-    _formatStdin(options);
+    _formatStdin(kind);
   } else {
     _formatPaths(options.rest);
   }
 }
 
 _readOptions(options) {
+  kind = _parseKind(options['kind']);
   machineFormat = options['machine'];
   overwriteFileContents = options['write'];
   selection = _parseSelection(options['selection']);
@@ -50,6 +52,15 @@
       new FormatterOptions(codeTransforms: options['transform']);
 }
 
+CodeKind _parseKind(kindOption) {
+  switch(kindOption) {
+    case 'stmt' :
+      return CodeKind.STATEMENT;
+    default:
+      return CodeKind.COMPILATION_UNIT;
+  }
+}
+
 Selection _parseSelection(selectionOption) {
   if (selectionOption != null) {
     var units = selectionOption.split(',');
@@ -93,7 +104,7 @@
     try {
       var buffer = new StringBuffer();
       var rawSource = file.readAsStringSync();
-      var formatted = _formatCU(rawSource);
+      var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT);
       if (overwriteFileContents) {
         file.writeAsStringSync(formatted);
       } else {
@@ -107,12 +118,12 @@
 
 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path));
 
-_formatStdin(options) {
+_formatStdin(kind) {
   var input = new StringBuffer();
   stdin.transform(new Utf8Decoder())
       .listen((data) => input.write(data),
         onError: (error) => _log('Error reading from stdin'),
-        onDone: () => print(_formatCU(input.toString())));
+        onDone: () => print(_format(input.toString(), kind)));
 }
 
 /// Initialize the arg parser instance.
@@ -122,6 +133,9 @@
   parser.addFlag('write', abbr: 'w', negatable: false,
       help: 'Write reformatted sources to files (overwriting contents).  '
             'Do not print reformatted sources to standard output.');
+  parser.addOption('kind', abbr: 'k', defaultsTo: 'cu',
+      help: 'Specify source snippet kind ("stmt" or "cu")'
+            ' --- [PROVISIONAL API].');
   parser.addFlag('machine', abbr: 'm', negatable: false,
       help: 'Produce output in a format suitable for parsing.');
   parser.addOption('selection', abbr: 's',
@@ -153,10 +167,10 @@
   _log(buffer.toString());
 }
 
-/// Format the given [src] as a compilation unit.
-String _formatCU(src) {
+/// Format this [src], treating it as the given snippet [kind].
+String _format(src, kind) {
   var formatResult = new CodeFormatter(formatterSettings).format(
-      CodeKind.COMPILATION_UNIT, src, selection: selection);
+      kind, src, selection: selection);
   if (machineFormat) {
     if (formatResult.selection == null) {
       formatResult.selection = defaultSelection;
diff --git a/pkg/args/lib/args.dart b/pkg/args/lib/args.dart
index 7f524df..a76e726 100644
--- a/pkg/args/lib/args.dart
+++ b/pkg/args/lib/args.dart
@@ -321,9 +321,9 @@
    * * There is already an option using abbreviation [abbr].
    */
   void addFlag(String name, {String abbr, String help, bool defaultsTo: false,
-      bool negatable: true, void callback(bool value)}) {
+      bool negatable: true, void callback(bool value), bool hide: false}) {
     _addOption(name, abbr, help, null, null, defaultsTo, callback,
-        isFlag: true, negatable: negatable);
+        isFlag: true, negatable: negatable, hide: hide);
   }
 
   /**
diff --git a/pkg/args/pubspec.yaml b/pkg/args/pubspec.yaml
index 0ff36a8..06e201f 100644
--- a/pkg/args/pubspec.yaml
+++ b/pkg/args/pubspec.yaml
@@ -1,5 +1,5 @@
 name: args
-version: 0.9.0
+version: 0.10.0
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/args
@@ -12,4 +12,4 @@
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/args/test/args_test.dart b/pkg/args/test/args_test.dart
index cf31cc2..075a3e8 100644
--- a/pkg/args/test/args_test.dart
+++ b/pkg/args/test/args_test.dart
@@ -6,8 +6,9 @@
 
 import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
+import 'utils.dart';
 
-main() {
+void main() {
   group('ArgParser.addFlag()', () {
     test('throws ArgumentError if the flag already exists', () {
       var parser = new ArgParser();
@@ -182,45 +183,42 @@
     });
   });
 
-  group('ArgResults.options', () {
-    test('returns the provided options', () {
-      var parser = new ArgParser();
-      parser.addFlag('woof');
-      parser.addOption('meow');
-      var args = parser.parse(['--woof', '--meow', 'kitty']);
-      expect(args.options, hasLength(2));
-      expect(args.options.any((o) => o == 'woof'), isTrue);
-      expect(args.options.any((o) => o == 'meow'), isTrue);
+  group('ArgResults', () {
+    group('options', () {
+      test('returns the provided options', () {
+        var parser = new ArgParser();
+        parser.addFlag('woof');
+        parser.addOption('meow');
+        var args = parser.parse(['--woof', '--meow', 'kitty']);
+        expect(args.options, hasLength(2));
+        expect(args.options, contains('woof'));
+        expect(args.options, contains('meow'));
+      });
+
+      test('includes defaulted options', () {
+        var parser = new ArgParser();
+        parser.addFlag('woof', defaultsTo: false);
+        parser.addOption('meow', defaultsTo: 'kitty');
+        var args = parser.parse([]);
+        expect(args.options, hasLength(2));
+        expect(args.options, contains('woof'));
+        expect(args.options, contains('meow'));
+      });
     });
 
-    test('includes defaulted options', () {
-      var parser = new ArgParser();
-      parser.addFlag('woof', defaultsTo: false);
-      parser.addOption('meow', defaultsTo: 'kitty');
-      var args = parser.parse([]);
-      expect(args.options, hasLength(2));
-      expect(args.options.any((o) => o == 'woof'), isTrue);
-      expect(args.options.any((o) => o == 'meow'), isTrue);
-    });
-  });
-
-  group('ArgResults[]', () {
-    test('throws if the name is not an option', () {
+    test('[] throws if the name is not an option', () {
       var parser = new ArgParser();
       var results = parser.parse([]);
       throwsIllegalArg(() => results['unknown']);
     });
+
+    test('rest cannot be modified', () {
+      var results = new ArgResults({}, '', null, []);
+      expect(() => results.rest.add('oops'), throwsUnsupportedError);
+    });
   });
 }
 
-throwsIllegalArg(function, {String reason: null}) {
-  expect(function, throwsArgumentError, reason: reason);
-}
-
-throwsFormat(ArgParser parser, List<String> args) {
-  expect(() => parser.parse(args), throwsFormatException);
-}
-
 const _INVALID_OPTIONS = const [
  ' ', '', '-', '--', '--foo',
  ' with space',
diff --git a/pkg/args/test/command_test.dart b/pkg/args/test/command_test.dart
index 6115ab1..1380e16 100644
--- a/pkg/args/test/command_test.dart
+++ b/pkg/args/test/command_test.dart
@@ -6,8 +6,9 @@
 
 import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
+import 'utils.dart';
 
-main() {
+void main() {
   group('ArgParser.addCommand()', () {
     test('creates a new ArgParser if none is given', () {
       var parser = new ArgParser();
@@ -204,11 +205,3 @@
     });
   });
 }
-
-throwsIllegalArg(function) {
-  expect(function, throwsArgumentError);
-}
-
-throwsFormat(ArgParser parser, List<String> args) {
-  expect(() => parser.parse(args), throwsFormatException);
-}
diff --git a/pkg/args/test/parse_all_test.dart b/pkg/args/test/parse_all_test.dart
index 8498ae6..d404c2f 100644
--- a/pkg/args/test/parse_all_test.dart
+++ b/pkg/args/test/parse_all_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
 
-main() {
+void main() {
   group('ArgParser.parse(allowTrailingOptions: true) '
         'starting with a non-option', () {
     test('followed by flag', () {
@@ -57,7 +57,8 @@
     });
   });
 }
-expectThrows(ArgParser parser, List<String> args) =>
+
+void expectThrows(ArgParser parser, List<String> args) =>
   expect(() => parser.parse(args, allowTrailingOptions: true),
       throwsFormatException,
       reason: "with allowTrailingOptions: true");
diff --git a/pkg/args/test/parse_test.dart b/pkg/args/test/parse_test.dart
index 715c226..659c08e 100644
--- a/pkg/args/test/parse_test.dart
+++ b/pkg/args/test/parse_test.dart
@@ -6,8 +6,9 @@
 
 import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
+import 'utils.dart';
 
-main() {
+void main() {
   group('ArgParser.parse()', () {
     test('does not destructively modify the argument list', () {
       var parser = new ArgParser();
@@ -421,11 +422,3 @@
     });
   });
 }
-
-throwsIllegalArg(function) {
-  expect(function, throwsArgumentError);
-}
-
-throwsFormat(ArgParser parser, List<String> args) {
-  expect(() => parser.parse(args), throwsFormatException);
-}
diff --git a/pkg/args/test/usage_test.dart b/pkg/args/test/usage_test.dart
index 27b0389..ddd223c 100644
--- a/pkg/args/test/usage_test.dart
+++ b/pkg/args/test/usage_test.dart
@@ -7,7 +7,7 @@
 import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
 
-main() {
+void main() {
   group('ArgParser.getUsage()', () {
     test('negatable flags show "no-" in title', () {
       var parser = new ArgParser();
@@ -168,7 +168,7 @@
           ''');
     });
 
-    test("hidden flags don't appear in the help", () {
+    test("hidden options don't appear in the help", () {
       var parser = new ArgParser();
       parser.addOption('first', help: 'The first option');
       parser.addOption('second', hide: true);
@@ -181,14 +181,24 @@
           --third     The third option
           ''');
     });
+
+    test("hidden flags don't appear in the help", () {
+      var parser = new ArgParser();
+      parser.addFlag('first', help: 'The first flag');
+      parser.addFlag('second', hide: true);
+      parser.addFlag('third', help: 'The third flag');
+
+
+      validateUsage(parser,
+          '''
+          --[no-]first     The first flag
+          --[no-]third     The third flag
+          ''');
+    });
   });
 }
 
-throwsIllegalArg(function) {
-  expect(function, throwsArgumentError);
-}
-
-validateUsage(ArgParser parser, String expected) {
+void validateUsage(ArgParser parser, String expected) {
   expected = unindentString(expected);
   expect(parser.getUsage(), equals(expected));
 }
diff --git a/pkg/args/test/utils.dart b/pkg/args/test/utils.dart
new file mode 100644
index 0000000..4586f57
--- /dev/null
+++ b/pkg/args/test/utils.dart
@@ -0,0 +1,16 @@
+// 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 utils;
+
+import 'package:unittest/unittest.dart';
+import 'package:args/args.dart';
+
+void throwsIllegalArg(function, {String reason: null}) {
+  expect(function, throwsArgumentError, reason: reason);
+}
+
+void throwsFormat(ArgParser parser, List<String> args) {
+  expect(() => parser.parse(args), throwsFormatException);
+}
diff --git a/pkg/barback/lib/src/cancelable_future.dart b/pkg/barback/lib/src/cancelable_future.dart
index 284df41..4454f5c 100644
--- a/pkg/barback/lib/src/cancelable_future.dart
+++ b/pkg/barback/lib/src/cancelable_future.dart
@@ -32,7 +32,8 @@
   Future then(onValue(T value), {Function onError}) =>
     _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);
   /// Cancels this future.
   void cancel() {
     _canceled = true;
diff --git a/pkg/barback/lib/src/pool.dart b/pkg/barback/lib/src/pool.dart
index 23b878f..7f89c12 100644
--- a/pkg/barback/lib/src/pool.dart
+++ b/pkg/barback/lib/src/pool.dart
@@ -106,7 +106,7 @@
   /// emit exceptions.
   void _onTimeout() {
     for (var completer in _requestedResources) {
-      completer.completeException("Pool deadlock: all resources have been "
+      completer.completeError("Pool deadlock: all resources have been "
           "allocated for too long.", new Trace.current().vmTrace);
     }
     _requestedResources.clear();
diff --git a/pkg/barback/pubspec.yaml b/pkg/barback/pubspec.yaml
index 93604ed..54e3a1a 100644
--- a/pkg/barback/pubspec.yaml
+++ b/pkg/barback/pubspec.yaml
@@ -1,5 +1,5 @@
 name: barback
-version: 0.9.0
+version: 0.9.0 # Replaced by publish_barback.py. Do not edit.
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/docgen/bin/dartdoc.py b/pkg/docgen/bin/dartdoc.py
index c822cba..4971e36 100644
--- a/pkg/docgen/bin/dartdoc.py
+++ b/pkg/docgen/bin/dartdoc.py
@@ -15,7 +15,6 @@
 import sys
 sys.path.append(abspath(join(dirname(__file__), '../../../tools')))
 import utils
-from upload_sdk import ExecuteCommand
 
 DIRECTORY = abspath(dirname(__file__))
 DART_DIR = dirname(dirname(dirname(DIRECTORY)))
@@ -134,15 +133,15 @@
       docgen = [DART_EXECUTABLE, '--checked',
           '--package-root=' + PACKAGE_ROOT, join(DIRECTORY, 'docgen.dart')]
       docgen.extend(options.options.split())
-      ExecuteCommand(docgen)
+      utils.ExecuteCommand(docgen)
   if generate_all_docs:
     GenerateAllDocs(docgen_options)
   if not options.just_docs:
     cwd = os.getcwd()
     try:
-      ExecuteCommand(['git', 'clone', '-b', 'master',
+      utils.ExecuteCommand(['git', 'clone', '-b', 'master',
        'git://github.com/dart-lang/dartdoc-viewer.git'])
-      ExecuteCommand(['mv', 'docs', 'dartdoc-viewer/client/local'])
+      utils.ExecuteCommand(['mv', 'docs', 'dartdoc-viewer/client/local'])
       os.chdir('dartdoc-viewer/client/')
       subprocess.call([PUB, 'install'])
       subprocess.call([DART_EXECUTABLE, 'deploy.dart'])
diff --git a/pkg/docgen/bin/upload_docgen.py b/pkg/docgen/bin/upload_docgen.py
index b598394..c376dad 100644
--- a/pkg/docgen/bin/upload_docgen.py
+++ b/pkg/docgen/bin/upload_docgen.py
@@ -16,7 +16,6 @@
 import sys
 sys.path.append(abspath(join(dirname(__file__), '../../../tools')))
 import utils
-from upload_sdk import ExecuteCommand
 
 
 DART = abspath(join(dirname(__file__), '../../../%s/%s/dart-sdk/bin/dart'
@@ -63,7 +62,7 @@
 def Upload(source, target):
   """ Upload files to Google Storage. """
   cmd = [GSUTIL, '-m', 'cp', '-q', '-a', 'public-read', '-r', source, target]
-  (status, output) = ExecuteCommand(cmd)
+  (status, output) = utils.ExecuteCommand(cmd)
   return status
 
 
@@ -73,7 +72,7 @@
   SetGsutil()
 
   # Execute Docgen.dart on the SDK.
-  ExecuteCommand(['python', 'dartdoc.py', '-d'])
+  utils.ExecuteCommand(['python', 'dartdoc.py', '-d'])
 
   # Use SVN Revision to get the revision number.
   revision = None
@@ -109,8 +108,8 @@
   Upload('./VERSION', GS_SITE + '/' + revision + '/' + 'VERSION')
 
   # Clean up the files it creates.
-  ExecuteCommand(['rm', '-rf', './docs'])
-  ExecuteCommand(['rm', '-f', './VERSION'])
+  utils.ExecuteCommand(['rm', '-rf', './docs'])
+  utils.ExecuteCommand(['rm', '-f', './VERSION'])
 
 
 if __name__ == '__main__':
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 0482da1..d21d235 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -128,7 +128,7 @@
       _coreLibrary = _sdkLibraries.singleWhere((lib) =>
           lib.uri.toString().startsWith('dart:core'));
       var availableLibrariesByPath = new Map.fromIterables(
-          availableLibraries.map((each) => each.uri.toFilePath()),
+          availableLibraries.map((each) => each.uri),
           availableLibraries);
       var librariesToDocument = requestedLibraries.map(
           (each) => availableLibrariesByPath.putIfAbsent(each,
@@ -189,14 +189,14 @@
   return contents;
 }
 
-List<String> _listLibraries(List<String> args) {
-  var libraries = new List<String>();
+List<Uri> _listLibraries(List<String> args) {
+  var libraries = new List<Uri>();
   for (var arg in args) {
     var type = FileSystemEntity.typeSync(arg);
 
     if (type == FileSystemEntityType.FILE) {
       if (arg.endsWith('.dart')) {
-        libraries.add(path.absolute(arg));
+        libraries.add(new Uri.file(path.absolute(arg)));
         logger.info('Added to libraries: ${libraries.last}');
       }
     } else {
@@ -206,7 +206,7 @@
   return libraries;
 }
 
-List<String> _listDartFromDir(String args) {
+List<Uri> _listDartFromDir(String args) {
   var libraries = [];
   // To avoid anaylzing package files twice, only files with paths not
   // containing '/packages' will be added. The only exception is if the file to
@@ -223,12 +223,12 @@
       var contents = new File(f).readAsStringSync();
       if (!(contents.contains(new RegExp('\npart of ')) ||
           contents.startsWith(new RegExp('part of ')))) {
-        libraries.add(f);
+        libraries.add(new Uri.file(path.normalize(path.absolute(f))));
         logger.info('Added to libraries: $f');
       }
     }
   });
-  return libraries.map(path.absolute).map(path.normalize).toList();
+  return libraries;
 }
 
 String _findPackageRoot(String directory) {
@@ -251,11 +251,11 @@
   return spec["name"];
 }
 
-List<String> _listSdk() {
-  var sdk = new List<String>();
+List<Uri> _listSdk() {
+  var sdk = new List<Uri>();
   LIBRARIES.forEach((String name, LibraryInfo info) {
     if (info.documented) {
-      sdk.add('dart:$name');
+      sdk.add(Uri.parse('dart:$name'));
       logger.info('Add to SDK: ${sdk.last}');
     }
   });
@@ -264,7 +264,7 @@
 
 /// Analyzes set of libraries by getting a mirror system and triggers the
 /// documentation of the libraries.
-Future<MirrorSystem> getMirrorSystem(List<String> libraries,
+Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
     {String packageRoot, bool parseSdk: false}) {
   if (libraries.isEmpty) throw new StateError('No Libraries.');
   // Finds the root of SDK library based off the location of docgen.
@@ -286,7 +286,7 @@
 
 /// Analyzes set of libraries and provides a mirror system which can be used
 /// for static inspection of the source code.
-Future<MirrorSystem> _analyzeLibraries(List<String> libraries,
+Future<MirrorSystem> _analyzeLibraries(List<Uri> libraries,
       String libraryRoot, {String packageRoot}) {
   SourceFileProvider provider = new CompilerSourceFileProvider();
   api.DiagnosticHandler diagnosticHandler =
@@ -294,16 +294,12 @@
         ..showHints = false
         ..showWarnings = false)
           .diagnosticHandler;
-  Uri libraryUri = new Uri(scheme: 'file', path: appendSlash(libraryRoot));
+  Uri libraryUri = new Uri.file(appendSlash(libraryRoot));
   Uri packageUri = null;
   if (packageRoot != null) {
-    packageUri = new Uri(scheme: 'file', path: appendSlash(packageRoot));
+    packageUri = new Uri.file(appendSlash(packageRoot));
   }
-  List<Uri> librariesUri = <Uri>[];
-  libraries.forEach((library) {
-    librariesUri.add(currentDirectory.resolve(library));
-  });
-  return dart2js.analyze(librariesUri, libraryUri, packageUri,
+  return dart2js.analyze(libraries, libraryUri, packageUri,
       provider.readStringFromUri, diagnosticHandler,
       ['--preserve-comments', '--categories=Client,Server'])
       ..catchError((error) {
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index d2c94a7..12cd6b6 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -46,7 +46,7 @@
       var fileName = path.join(temporaryDir.path, 'temp.dart');
       var file = new File(fileName);
       file.writeAsStringSync(DART_LIBRARY);
-      getMirrorSystem([fileName])
+      getMirrorSystem([new Uri.file(fileName)])
         .then(expectAsync1((mirrorSystem) {
           var testLibraryUri = new Uri(scheme: 'file',
               path: path.absolute(fileName));
diff --git a/pkg/http/test/safe_http_server.dart b/pkg/http/test/safe_http_server.dart
index 5d709f9..9c3622d 100644
--- a/pkg/http/test/safe_http_server.dart
+++ b/pkg/http/test/safe_http_server.dart
@@ -30,8 +30,9 @@
       : super(server),
         _inner = server;
 
-  Future close() => _inner.close();
+  Future close({bool force: false}) => _inner.close(force: force);
 
+  InternetAddress get address => _inner.address;
   int get port => _inner.port;
 
   set sessionTimeout(int timeout) {
@@ -138,6 +139,7 @@
   Future<HttpResponse> addStream(Stream<List<int>> stream) =>
     _inner.addStream(stream);
   Future close() => _inner.close();
+  Future flush() => _inner.flush();
   void write(Object obj) => _inner.write(obj);
   void writeAll(Iterable objects, [String separator = ""]) =>
     _inner.writeAll(objects, separator);
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index 757bb6b..5d39090 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -144,7 +144,7 @@
   // At least in most cases. In some cases, we can't even do that. e.g.
   // the skeleton WEEKDAY can't be reconstructed at all, and YEAR_MONTH
   // formats don't give us enough information to construct a valid date.
-  var badSkeletons = [
+  var badSkeletons = const [
       DateFormat.ABBR_WEEKDAY,
       DateFormat.WEEKDAY,
       DateFormat.QUARTER,
@@ -156,6 +156,9 @@
       DateFormat.MONTH_WEEKDAY_DAY,
       DateFormat.NUM_MONTH_WEEKDAY_DAY,
       DateFormat.ABBR_MONTH_WEEKDAY_DAY];
+  var originalTime = new DateTime.now();
+  var originalTimeZoneOffset = date.timeZoneOffset;
+  var originalTimeZoneName = date.timeZoneName;
   for(int i = 0; i < formatsToTest.length; i++) {
     var skeleton = formatsToTest[i];
     if (!badSkeletons.any((x) => x == skeleton)) {
@@ -163,6 +166,25 @@
       var actualResult = format.format(date);
       var parsed = format.parse(actualResult);
       var thenPrintAgain = format.format(parsed);
+      // We've seen a case where this failed in a way that seemed like a time
+      // zone shifting or some other strange behaviour that caused an off by
+      // one error in the date. Check for this and print out as much information
+      // as possible if it occurs again.
+      if (thenPrintAgain != actualResult) {
+        print("Date mismatch!");
+        print("  Expected $actualResult");
+        print("  Got $thenPrintAgain");
+        print("  Original date = $date");
+        print("  Original ms = ${date.millisecondsSinceEpoch}");
+        print("  Parsed back to $parsed");
+        print("  Parsed ms = ${parsed.millisecondsSinceEpoch}");
+        print("  Original tz = $originalTimeZoneOffset");
+        print("  Current tz name = $originalTimeZoneName");
+        print("  Current tz = ${parsed.timeZoneOffset}");
+        print("  Current tz name = ${parsed.timeZoneName}");
+        print("  Start time = $originalTime");
+        print("  Current time ${new DateTime.now()}");
+      }
       expect(thenPrintAgain, equals(actualResult));
     }
   }
diff --git a/pkg/logging/lib/logging.dart b/pkg/logging/lib/logging.dart
index 37ac67d..8bff36b 100644
--- a/pkg/logging/lib/logging.dart
+++ b/pkg/logging/lib/logging.dart
@@ -311,6 +311,9 @@
   /** Key for extra debugging loudness ([value] = 1200). */
   static const Level SHOUT = const Level('SHOUT', 1200);
 
+  static const List<Level> LEVELS = const
+      [ALL, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, SHOUT, OFF];
+
   bool operator ==(Object other) => other is Level && value == other.value;
   bool operator <(Level other) => value < other.value;
   bool operator <=(Level other) => value <= other.value;
diff --git a/pkg/logging/pubspec.yaml b/pkg/logging/pubspec.yaml
index d298608..334113f 100644
--- a/pkg/logging/pubspec.yaml
+++ b/pkg/logging/pubspec.yaml
@@ -1,12 +1,12 @@
 name: logging
-version: 0.9.0
+version: 0.9.1-dev
 author: Dart Team <misc@dartlang.org>
 description: Provides APIs for debugging and error logging. This library introduces abstractions similar to those used in other languages, such as the Closure JS Logger and java.util.logging.Logger.
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/logging
-dependencies:
-  collection_helpers: ">=0.9.0 <0.10.0"
-dev_dependencies:
-  unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: '>=0.8.10+6 <2.0.0'
+dependencies:
+  collection_helpers: '>=0.9.1 <0.10.0'
+dev_dependencies:
+  unittest: '>=0.9.0 <0.10.0'
diff --git a/pkg/logging/test/logging_test.dart b/pkg/logging/test/logging_test.dart
index a188bb5..82ef3e1 100644
--- a/pkg/logging/test/logging_test.dart
+++ b/pkg/logging/test/logging_test.dart
@@ -29,10 +29,7 @@
   });
 
   test('default levels are in order', () {
-    final levels = const [
-        Level.ALL, Level.FINEST, Level.FINER, Level.FINE, Level.CONFIG,
-        Level.INFO, Level.WARNING, Level.SEVERE, Level.SHOUT, Level.OFF
-      ];
+    final levels = Level.LEVELS;
 
     for (int i = 0; i < levels.length; i++) {
       for (int j = i + 1; j < levels.length; j++) {
@@ -46,13 +43,12 @@
         Level.INFO, Level.CONFIG, Level.FINE, Level.SHOUT, Level.OFF,
         Level.FINER, Level.ALL, Level.WARNING, Level.FINEST,  Level.SEVERE,
       ];
-    final sorted = const [
-        Level.ALL, Level.FINEST, Level.FINER, Level.FINE, Level.CONFIG,
-        Level.INFO, Level.WARNING, Level.SEVERE, Level.SHOUT, Level.OFF
-      ];
+
+    final sorted = Level.LEVELS;
+
     expect(unsorted, isNot(orderedEquals(sorted)));
 
-    unsorted.sort((a, b) => a.compareTo(b));
+    unsorted.sort();
     expect(unsorted, orderedEquals(sorted));
   });
 
@@ -65,7 +61,7 @@
   });
 
   test('logger name cannot start with a "." ', () {
-    expect(() => new Logger('.c'), throws);
+    expect(() => new Logger('.c'), throwsArgumentError);
   });
 
   test('logger naming is hierarchical', () {
diff --git a/pkg/observe/AUTHORS b/pkg/observe/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/pkg/observe/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/observe/LICENSE b/pkg/observe/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/observe/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2013, 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/observe/PATENTS b/pkg/observe/PATENTS
new file mode 100644
index 0000000..6954196
--- /dev/null
+++ b/pkg/observe/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/observe/lib/src/observable.dart b/pkg/observe/lib/src/observable.dart
index f798f44..35e91c8 100644
--- a/pkg/observe/lib/src/observable.dart
+++ b/pkg/observe/lib/src/observable.dart
@@ -82,8 +82,11 @@
     // 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.variables.values) {
-        if (field.isFinal || field.isStatic || field.isPrivate) continue;
+      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) {
diff --git a/pkg/observe/lib/src/observable_list.dart b/pkg/observe/lib/src/observable_list.dart
index 76cf06b..be25afa 100644
--- a/pkg/observe/lib/src/observable_list.dart
+++ b/pkg/observe/lib/src/observable_list.dart
@@ -82,7 +82,7 @@
     if (len == value) return;
 
     // Produce notifications if needed
-    notifyPropertyChange(#length, len, value);
+    _notifyChangeLength(len, value);
     if (_hasListObservers) {
       if (value < len) {
         _recordChange(new ListChangeRecord(this, value,
@@ -106,6 +106,15 @@
     _list[index] = value;
   }
 
+  // Forwarders so we can reflect on the properties.
+  @reflectable bool get isEmpty => super.isEmpty;
+  @reflectable bool get isNotEmpty => super.isNotEmpty;
+
+  // TODO(jmesserly): should we support first/last/single? They're kind of
+  // dangerous to use in a path because they throw exceptions. Also we'd need
+  // to produce property change notifications which seems to conflict with our
+  // existing list notifications.
+
   // The following methods are here so that we can provide nice change events.
 
   void setAll(int index, Iterable<E> iterable) {
@@ -122,7 +131,7 @@
 
   void add(E value) {
     int len = _list.length;
-    notifyPropertyChange(#length, len, len + 1);
+    _notifyChangeLength(len, len + 1);
     if (_hasListObservers) {
       _recordChange(new ListChangeRecord(this, len, addedCount: 1));
     }
@@ -134,7 +143,7 @@
     int len = _list.length;
     _list.addAll(iterable);
 
-    notifyPropertyChange(#length, len, _list.length);
+    _notifyChangeLength(len, _list.length);
 
     int added = _list.length - len;
     if (_hasListObservers && added > 0) {
@@ -157,7 +166,7 @@
     int rangeLength = end - start;
     int len = _list.length;
 
-    notifyPropertyChange(#length, len, len - rangeLength);
+    _notifyChangeLength(len, len - rangeLength);
     if (_hasListObservers && rangeLength > 0) {
       _recordChange(new ListChangeRecord(this, start,
           removed: _list.getRange(start, end).toList()));
@@ -184,7 +193,7 @@
     _list.setRange(index + insertionLength, this.length, this, index);
     _list.setAll(index, iterable);
 
-    notifyPropertyChange(#length, len, _list.length);
+    _notifyChangeLength(len, _list.length);
 
     if (_hasListObservers && insertionLength > 0) {
       _recordChange(new ListChangeRecord(this, index,
@@ -207,7 +216,7 @@
     _list.length++;
     _list.setRange(index + 1, length, this, index);
 
-    notifyPropertyChange(#length, _list.length - 1, _list.length);
+    _notifyChangeLength(_list.length - 1, _list.length);
     if (_hasListObservers) {
       _recordChange(new ListChangeRecord(this, index, addedCount: 1));
     }
@@ -240,6 +249,12 @@
     _listRecords.add(record);
   }
 
+  void _notifyChangeLength(int oldValue, int newValue) {
+    notifyPropertyChange(#length, oldValue, newValue);
+    notifyPropertyChange(#isEmpty, oldValue == 0, newValue == 0);
+    notifyPropertyChange(#isNotEmpty, oldValue != 0, newValue != 0);
+  }
+
   bool deliverListChanges() {
     if (_listRecords == null) return false;
     var records = projectListSplices(this, _listRecords);
diff --git a/pkg/observe/pubspec.yaml b/pkg/observe/pubspec.yaml
index 7938f6e..75dd77a 100644
--- a/pkg/observe/pubspec.yaml
+++ b/pkg/observe/pubspec.yaml
@@ -1,5 +1,5 @@
 name: observe
-version: 0.9.1-dev
+version: 0.9.1+1
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 description: >
   Observable properties and objects for use in Model-Driven-Views (MDV).
@@ -10,11 +10,11 @@
 homepage: https://www.dartlang.org/polymer-dart/
 dependencies:
   analyzer: ">=0.10.1 <0.11.0"
-  barback: ">=0.9.0 <0.10.0"
+  barback: ">=0.9.0 <0.11.0"
   logging: ">=0.9.0 <0.10.0"
   path: ">=0.9.0 <0.10.0"
   source_maps: ">=0.9.0 <0.10.0"
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/observe/test/observable_list_test.dart b/pkg/observe/test/observable_list_test.dart
index 0b4575d..66a03d3 100644
--- a/pkg/observe/test/observable_list_test.dart
+++ b/pkg/observe/test/observable_list_test.dart
@@ -253,7 +253,11 @@
       expect(list, []);
 
       performMicrotaskCheckpoint();
-      expectChanges(propRecords, [_lengthChange(6, 0)]);
+      expectChanges(propRecords, [
+          _lengthChange(6, 0),
+          new PropertyChangeRecord(list, #isEmpty, false, true),
+          new PropertyChangeRecord(list, #isNotEmpty, true, false),
+      ]);
       expectChanges(listRecords, [_change(0, removed: [1, 2, 3, 1, 3, 4])]);
     });
   });
diff --git a/pkg/observe/test/path_observer_test.dart b/pkg/observe/test/path_observer_test.dart
index 91d68a1..10378fa 100644
--- a/pkg/observe/test/path_observer_test.dart
+++ b/pkg/observe/test/path_observer_test.dart
@@ -152,6 +152,34 @@
     model.add(123);
   });
 
+  group('ObservableList', () {
+    observeTest('isNotEmpty', () {
+      var model = new ObservableList();
+      var path = observePath(model, 'isNotEmpty');
+      expect(path.value, false);
+
+      var future = path.changes.first.then((_) {
+        expect(path.value, true);
+      });
+      model.add(123);
+
+      return future;
+    });
+
+    observeTest('isEmpty', () {
+      var model = new ObservableList();
+      var path = observePath(model, 'isEmpty');
+      expect(path.value, true);
+
+      var future = path.changes.first.then((_) {
+        expect(path.value, false);
+      });
+      model.add(123);
+
+      return future;
+    });
+  });
+
   for (var createModel in [() => new TestModel(), () => new WatcherModel()]) {
     observeTest('Path Observation - ${createModel().runtimeType}', () {
       var model = createModel()..a =
diff --git a/pkg/path/pubspec.yaml b/pkg/path/pubspec.yaml
index a391d96..491c3bc 100644
--- a/pkg/path/pubspec.yaml
+++ b/pkg/path/pubspec.yaml
@@ -10,4 +10,4 @@
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=1.0.0+3.r30188 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 41fd2a5..d9c7d08 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -40,6 +40,7 @@
 [ $runtime == d8 || $runtime == jsshell ]
 unittest/test/unittest_nested_groups_setup_teardown_test: Pass, RuntimeError # http://dartbug.com/10109
 stack_trace/test/vm_test: RuntimeError, OK # VM-specific traces
+stack_trace/test/chain_test: Fail # Issues 15171 and 15105
 sequence_zip/test/stream_test: RuntimeError, OK # Timers are not supported.
 unittest/test/missing_tick_test: Fail # Timer interface not supported: dartbug.com/7728.
 
@@ -169,6 +170,7 @@
 
 [ $compiler == dart2js && $browser ]
 stack_trace/test/vm_test: Fail, OK # VM-specific traces
+stack_trace/test/chain_test: Fail # Issues 15171 and 15105
 crypto/test/sha256_test: Slow, Pass
 crypto/test/sha1_test: Slow, Pass
 polymer/example/component: Fail # Issue 13198
diff --git a/pkg/polymer/AUTHORS b/pkg/polymer/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/pkg/polymer/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/polymer/LICENSE b/pkg/polymer/LICENSE
new file mode 100644
index 0000000..92d60b0
--- /dev/null
+++ b/pkg/polymer/LICENSE
@@ -0,0 +1,27 @@
+// Copyright (c) 2012 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/polymer/PATENTS b/pkg/polymer/PATENTS
new file mode 100644
index 0000000..e120963
--- /dev/null
+++ b/pkg/polymer/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/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index ab6bad8..ba87001 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: polymer
-version: 0.9.1-dev
+version: 0.9.1+1
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 description: >
   Polymer.dart is a new type of library for the web, built on top of Web
@@ -9,17 +9,17 @@
 dependencies:
   analyzer: ">=0.10.1 <0.11.0"
   args: ">=0.9.0 <0.10.0"
-  barback: ">=0.9.0 <0.10.0"
+  barback: ">=0.9.0 <0.11.0"
   browser: ">=0.9.0 <0.10.0"
   csslib: ">=0.9.0 <0.10.0"
   custom_element: ">=0.9.0 <0.10.0"
-  html5lib: ">=0.9.1-dev <0.10.0"
+  html5lib: ">=0.9.1 <0.10.0"
   html_import: ">=0.9.0 <0.10.0"
   logging: ">=0.9.0 <0.10.0"
-  observe: ">=0.9.1-dev <0.10.0"
+  observe: ">=0.9.1 <0.10.0"
   path: ">=0.9.0 <0.10.0"
-  polymer_expressions: ">=0.9.0 <0.10.0"
-  shadow_dom: ">=0.9.0 <0.10.0"
+  polymer_expressions: ">=0.9.1 <0.10.0"
+  shadow_dom: ">=0.9.1 <0.10.0"
   source_maps: ">=0.9.0 <0.10.0"
   template_binding: ">=0.9.0 <0.10.0"
   yaml: ">=0.9.0 <0.10.0"
@@ -29,4 +29,4 @@
 dev_dependencies:
   unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/polymer_expressions/AUTHORS b/pkg/polymer_expressions/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/pkg/polymer_expressions/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/polymer_expressions/LICENSE b/pkg/polymer_expressions/LICENSE
new file mode 100644
index 0000000..ee99930
--- /dev/null
+++ b/pkg/polymer_expressions/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2013, 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/polymer_expressions/PATENTS b/pkg/polymer_expressions/PATENTS
new file mode 100644
index 0000000..6954196
--- /dev/null
+++ b/pkg/polymer_expressions/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/polymer_expressions/pubspec.yaml b/pkg/polymer_expressions/pubspec.yaml
index 92db8e4..5b80ae9 100644
--- a/pkg/polymer_expressions/pubspec.yaml
+++ b/pkg/polymer_expressions/pubspec.yaml
@@ -1,5 +1,5 @@
 name: polymer_expressions
-version: 0.9.0
+version: 0.9.1
 author: Web UI Authors <html-dev@dartlang.org>
 description: An expressive custom binding syntax for MDV templates
 homepage: http://www.dartlang.org/polymer-dart/
@@ -11,4 +11,4 @@
   unittest: ">=0.9.0 <0.10.0"
   benchmark_harness: ">=1.0.0 <2.0.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
index 9e1eeb2..4c9abe7 100644
--- a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
@@ -32,6 +32,7 @@
 
   Future close({bool force: false}) => _inner.close(force: force);
 
+  InternetAddress get address => _inner.address;
   int get port => _inner.port;
 
   set sessionTimeout(int timeout) {
@@ -138,6 +139,7 @@
   Future<HttpResponse> addStream(Stream<List<int>> stream) =>
     _inner.addStream(stream);
   Future close() => _inner.close();
+  Future flush() => _inner.flush();
   void write(Object obj) => _inner.write(obj);
   void writeAll(Iterable objects, [String separator = ""]) =>
     _inner.writeAll(objects, separator);
diff --git a/pkg/scheduled_test/lib/src/substitute_future.dart b/pkg/scheduled_test/lib/src/substitute_future.dart
index c4b9ffb..d30c936 100644
--- a/pkg/scheduled_test/lib/src/substitute_future.dart
+++ b/pkg/scheduled_test/lib/src/substitute_future.dart
@@ -29,6 +29,8 @@
   Future then(onValue(T value), {Function onError}) =>
     _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);
 
   /// Substitutes [newFuture] for the currently wrapped [Future], which is
   /// returned.
diff --git a/pkg/scheduled_test/lib/src/value_future.dart b/pkg/scheduled_test/lib/src/value_future.dart
index a7d6517..3821feb 100644
--- a/pkg/scheduled_test/lib/src/value_future.dart
+++ b/pkg/scheduled_test/lib/src/value_future.dart
@@ -35,4 +35,6 @@
   Future then(onValue(T value), {Function onError}) =>
     _future.then(onValue, onError: onError);
   Future<T> whenComplete(action()) => _future.whenComplete(action);
+  Future timeout(Duration timeLimit, [void onTimeout()]) =>
+    _future.timeout(timeLimit, onTimeout);
 }
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index 49e42ae..38fafca 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -410,13 +410,17 @@
     if (name.contains(":")) {
       var uri = Uri.parse(name);
       var libMirror = currentMirrorSystem().libraries[uri];
-      return libMirror.classes[new Symbol(type)];
+      var candidate = libMirror.declarations[new Symbol(type)];
+      return candidate is ClassMirror ? candidate : null;
     } else {
       var symbol = new Symbol(name);
       var typeSymbol = new Symbol(type);
-      var libMirror = currentMirrorSystem().libraries.values.firstWhere(
-        (lib) => lib.simpleName == symbol && lib.classes[typeSymbol] != null);
-      return libMirror.classes[typeSymbol];
+      for (var libMirror in currentMirrorSystem().libraries.values) {
+        if (libMirror.simpleName != symbol) continue;
+        var candidate = libMirror.declarations[typeSymbol];
+        if (candidate != null && candidate is ClassMirror) return candidate;
+      }
+      return null;
     }
   }
 }
diff --git a/pkg/shadow_dom/AUTHORS b/pkg/shadow_dom/AUTHORS
new file mode 100644
index 0000000..0617765
--- /dev/null
+++ b/pkg/shadow_dom/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/shadow_dom/LICENSE b/pkg/shadow_dom/LICENSE
new file mode 100644
index 0000000..92d60b0
--- /dev/null
+++ b/pkg/shadow_dom/LICENSE
@@ -0,0 +1,27 @@
+// Copyright (c) 2012 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/shadow_dom/PATENTS b/pkg/shadow_dom/PATENTS
new file mode 100644
index 0000000..e120963
--- /dev/null
+++ b/pkg/shadow_dom/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/shadow_dom/lib/shadow_dom.debug.js b/pkg/shadow_dom/lib/shadow_dom.debug.js
index 477e03b..f86df70 100644
--- a/pkg/shadow_dom/lib/shadow_dom.debug.js
+++ b/pkg/shadow_dom/lib/shadow_dom.debug.js
@@ -904,36 +904,35 @@
   // 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(object, name, descriptor) {
+  PathObserver.defineProperty = function(target, name, object, path) {
     // TODO(rafaelw): Validate errors
-    var obj = descriptor.object;
-    var path = getPath(descriptor.path);
-    var notify = notifyFunction(object, name);
+    path = getPath(path);
+    var notify = notifyFunction(target, name);
 
-    var observer = new PathObserver(obj, descriptor.path,
+    var observer = new PathObserver(object, path,
         function(newValue, oldValue) {
           if (notify)
             notify(PROP_UPDATE_TYPE, oldValue);
         }
     );
 
-    Object.defineProperty(object, name, {
+    Object.defineProperty(target, name, {
       get: function() {
-        return path.getValueFrom(obj);
+        return path.getValueFrom(object);
       },
       set: function(newValue) {
-        path.setValueFrom(obj, newValue);
+        path.setValueFrom(object, newValue);
       },
       configurable: true
     });
 
     return {
       close: function() {
-        var oldValue = path.getValueFrom(obj);
+        var oldValue = path.getValueFrom(object);
         if (notify)
           observer.deliver();
         observer.close();
-        Object.defineProperty(object, name, {
+        Object.defineProperty(target, name, {
           value: oldValue,
           writable: true,
           configurable: true
@@ -1419,7 +1418,7 @@
     'delete': PROP_DELETE_TYPE,
     splice: ARRAY_SPLICE_TYPE
   };
-})(typeof global !== 'undefined' && global ? global : this);
+})(typeof global !== 'undefined' && global ? global : this || window);
 
 /*
  * Copyright 2012 The Polymer Authors. All rights reserved.
@@ -1490,16 +1489,19 @@
       throw new Error('Assertion failed');
   };
 
+  var defineProperty = Object.defineProperty;
+  var getOwnPropertyNames = Object.getOwnPropertyNames;
+  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+
   function mixin(to, from) {
-    Object.getOwnPropertyNames(from).forEach(function(name) {
-      Object.defineProperty(to, name,
-                            Object.getOwnPropertyDescriptor(from, name));
+    getOwnPropertyNames(from).forEach(function(name) {
+      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
     });
     return to;
   };
 
   function mixinStatics(to, from) {
-    Object.getOwnPropertyNames(from).forEach(function(name) {
+    getOwnPropertyNames(from).forEach(function(name) {
       switch (name) {
         case 'arguments':
         case 'caller':
@@ -1509,8 +1511,7 @@
         case 'toString':
           return;
       }
-      Object.defineProperty(to, name,
-                            Object.getOwnPropertyDescriptor(from, name));
+      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
     });
     return to;
   };
@@ -1525,7 +1526,7 @@
   // Mozilla's old DOM bindings are bretty busted:
   // https://bugzilla.mozilla.org/show_bug.cgi?id=855844
   // Make sure they are create before we start modifying things.
-  Object.getOwnPropertyNames(window);
+  getOwnPropertyNames(window);
 
   function getWrapperConstructor(node) {
     var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
@@ -1587,28 +1588,39 @@
         function() { return this.impl[name].apply(this.impl, arguments); };
   }
 
-  function installProperty(source, target, allowMethod) {
-    Object.getOwnPropertyNames(source).forEach(function(name) {
+  function getDescriptor(source, name) {
+    try {
+      return Object.getOwnPropertyDescriptor(source, name);
+    } catch (ex) {
+      // JSC and V8 both use data properties instead of accessors which can
+      // cause getting the property desciptor to throw an exception.
+      // https://bugs.webkit.org/show_bug.cgi?id=49739
+      return dummyDescriptor;
+    }
+  }
+
+  function installProperty(source, target, allowMethod, opt_blacklist) {
+    var names = getOwnPropertyNames(source);
+    for (var i = 0; i < names.length; i++) {
+      var name = names[i];
+      if (name === 'polymerBlackList_')
+        continue;
+
       if (name in target)
-        return;
+        continue;
+
+      if (source.polymerBlackList_ && source.polymerBlackList_[name])
+        continue;
 
       if (isFirefox) {
         // Tickle Firefox's old bindings.
         source.__lookupGetter__(name);
       }
-      var descriptor;
-      try {
-        descriptor = Object.getOwnPropertyDescriptor(source, name);
-      } catch (ex) {
-        // JSC and V8 both use data properties instead of accessors which can
-        // cause getting the property desciptor to throw an exception.
-        // https://bugs.webkit.org/show_bug.cgi?id=49739
-        descriptor = dummyDescriptor;
-      }
+      var descriptor = getDescriptor(source, name);
       var getter, setter;
       if (allowMethod && typeof descriptor.value === 'function') {
         target[name] = getMethod(name);
-        return;
+        continue;
       }
 
       var isEvent = isEventHandlerName(name);
@@ -1624,13 +1636,13 @@
           setter = getSetter(name);
       }
 
-      Object.defineProperty(target, name, {
+      defineProperty(target, name, {
         get: getter,
         set: setter,
         configurable: descriptor.configurable,
         enumerable: descriptor.enumerable
       });
-    });
+    }
   }
 
   /**
@@ -1655,6 +1667,12 @@
     addForwardingProperties(nativePrototype, wrapperPrototype);
     if (opt_instance)
       registerInstanceProperties(wrapperPrototype, opt_instance);
+    defineProperty(wrapperPrototype, 'constructor', {
+      value: wrapperConstructor,
+      configurable: true,
+      enumerable: false,
+      writable: true
+    });
   }
 
   function isWrapperFor(wrapperConstructor, nativeConstructor) {
@@ -1665,11 +1683,7 @@
   /**
    * Creates a generic wrapper constructor based on |object| and its
    * constructor.
-   * Sometimes the constructor does not have an associated instance
-   * (CharacterData for example). In that case you can pass the constructor that
-   * you want to map the object to using |opt_nativeConstructor|.
    * @param {Node} object
-   * @param {Function=} opt_nativeConstructor
    * @return {Function} The generated constructor.
    */
   function registerObject(object) {
@@ -1782,7 +1796,7 @@
   }
 
   function defineGetter(constructor, name, getter) {
-    Object.defineProperty(constructor.prototype, name, {
+    defineProperty(constructor.prototype, name, {
       get: getter,
       configurable: true,
       enumerable: true
@@ -2437,17 +2451,6 @@
     return false;
   }
 
-  var mutationEventsAreSilenced = 0;
-
-  function muteMutationEvents() {
-    mutationEventsAreSilenced++;
-  }
-
-  function unmuteMutationEvents() {
-    mutationEventsAreSilenced--;
-  }
-
-  var OriginalMutationEvent = window.MutationEvent;
 
   function dispatchOriginalEvent(originalEvent) {
     // Make sure this event is only dispatched once.
@@ -2455,15 +2458,9 @@
       return;
     handledEventsTable.set(originalEvent, true);
 
-    // Don't do rendering if this is a mutation event since rendering might
-    // mutate the DOM which would fire more events and we would most likely
-    // just iloop.
-    if (originalEvent instanceof OriginalMutationEvent) {
-      if (mutationEventsAreSilenced)
-        return;
-    } else {
-      scope.renderAllPending();
-    }
+    // Render before dispatching the event to ensure that the event path is
+    // correct.
+    scope.renderAllPending();
 
     var target = wrap(originalEvent.target);
     var event = wrap(originalEvent);
@@ -2633,6 +2630,7 @@
   };
 
   var OriginalEvent = window.Event;
+  OriginalEvent.prototype.polymerBlackList_ = {returnValue: true};
 
   /**
    * Creates a new Event wrapper or wraps an existin native Event object.
@@ -2748,13 +2746,6 @@
   var MouseEvent = registerGenericEvent('MouseEvent', UIEvent, mouseEventProto);
   var FocusEvent = registerGenericEvent('FocusEvent', UIEvent, focusEventProto);
 
-  var MutationEvent = registerGenericEvent('MutationEvent', Event, {
-    initMutationEvent: getInitFunction('initMutationEvent', 3),
-    get relatedNode() {
-      return wrap(this.impl.relatedNode);
-    },
-  });
-
   // In case the browser does not support event constructors we polyfill that
   // by calling `createEvent('Foo')` and `initFooEvent` where the arguments to
   // `initFooEvent` are derived from the registered default event init dict.
@@ -2821,12 +2812,41 @@
     configureEventConstructor('FocusEvent', {relatedTarget: null}, 'UIEvent');
   }
 
+  function BeforeUnloadEvent(impl) {
+    Event.call(this);
+  }
+  BeforeUnloadEvent.prototype = Object.create(Event.prototype);
+  mixin(BeforeUnloadEvent.prototype, {
+    get returnValue() {
+      return this.impl.returnValue;
+    },
+    set returnValue(v) {
+      this.impl.returnValue = v;
+    }
+  });
+
   function isValidListener(fun) {
     if (typeof fun === 'function')
       return true;
     return fun && fun.handleEvent;
   }
 
+  function isMutationEvent(type) {
+    switch (type) {
+      case 'DOMAttrModified':
+      case 'DOMAttributeNameChanged':
+      case 'DOMCharacterDataModified':
+      case 'DOMElementNameChanged':
+      case 'DOMNodeInserted':
+      case 'DOMNodeInsertedIntoDocument':
+      case 'DOMNodeRemoved':
+      case 'DOMNodeRemovedFromDocument':
+      case 'DOMSubtreeModified':
+        return true;
+    }
+    return false;
+  }
+
   var OriginalEventTarget = window.EventTarget;
 
   /**
@@ -2861,7 +2881,7 @@
 
   EventTarget.prototype = {
     addEventListener: function(type, fun, capture) {
-      if (!isValidListener(fun))
+      if (!isValidListener(fun) || isMutationEvent(type))
         return;
 
       var listener = new Listener(type, fun, capture);
@@ -2991,15 +3011,13 @@
   scope.elementFromPoint = elementFromPoint;
   scope.getEventHandlerGetter = getEventHandlerGetter;
   scope.getEventHandlerSetter = getEventHandlerSetter;
-  scope.muteMutationEvents = muteMutationEvents;
-  scope.unmuteMutationEvents = unmuteMutationEvents;
   scope.wrapEventTargetMethods = wrapEventTargetMethods;
+  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
   scope.wrappers.CustomEvent = CustomEvent;
   scope.wrappers.Event = Event;
   scope.wrappers.EventTarget = EventTarget;
   scope.wrappers.FocusEvent = FocusEvent;
   scope.wrappers.MouseEvent = MouseEvent;
-  scope.wrappers.MutationEvent = MutationEvent;
   scope.wrappers.UIEvent = UIEvent;
 
 })(window.ShadowDOMPolyfill);
@@ -4365,10 +4383,8 @@
   var HTMLElement = scope.wrappers.HTMLElement;
   var getInnerHTML = scope.getInnerHTML;
   var mixin = scope.mixin;
-  var muteMutationEvents = scope.muteMutationEvents;
   var registerWrapper = scope.registerWrapper;
   var setInnerHTML = scope.setInnerHTML;
-  var unmuteMutationEvents = scope.unmuteMutationEvents;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
 
@@ -4397,11 +4413,9 @@
     var doc = getTemplateContentsOwner(templateElement.ownerDocument);
     var df = unwrap(doc.createDocumentFragment());
     var child;
-    muteMutationEvents();
     while (child = templateElement.firstChild) {
       df.appendChild(child);
     }
-    unmuteMutationEvents();
     return df;
   }
 
@@ -4894,9 +4908,7 @@
   var ShadowRoot = scope.wrappers.ShadowRoot;
   var assert = scope.assert;
   var mixin = scope.mixin;
-  var muteMutationEvents = scope.muteMutationEvents;
   var oneOf = scope.oneOf;
-  var unmuteMutationEvents = scope.unmuteMutationEvents;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
 
@@ -5240,11 +5252,8 @@
         this.renderNode(shadowRoot, renderNode, node, false);
       }
 
-      if (topMostRenderer) {
-        //muteMutationEvents();
+      if (topMostRenderer)
         renderNode.sync();
-        //unmuteMutationEvents();
-      }
 
       this.dirty = false;
     },
@@ -5679,6 +5688,8 @@
       doc.adoptNode(oldShadowRoot);
   }
 
+  var originalImportNode = document.importNode;
+
   mixin(Document.prototype, {
     adoptNode: function(node) {
       if (node.parentNode)
@@ -5688,6 +5699,17 @@
     },
     elementFromPoint: function(x, y) {
       return elementFromPoint(this, this, x, y);
+    },
+    importNode: function(node, deep) {
+      // We need to manually walk the tree to ensure we do not include rendered
+      // shadow trees.
+      var clone = wrap(originalImportNode.call(this.impl, unwrap(node), false));
+      if (deep) {
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          clone.appendChild(this.importNode(child, true));
+        }
+      }
+      return clone;
     }
   });
 
@@ -5806,6 +5828,7 @@
     window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument
   ], [
     'adoptNode',
+    'importNode',
     'contains',
     'createComment',
     'createDocumentFragment',
@@ -6529,11 +6552,16 @@
     return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) {
       p1 = polyfillHostNoCombinator;
       if (p2) {
-        if (p2.match(polyfillHost)) {
-          return p1 + p2.replace(polyfillHost, '') + p3;
-        } else {
-          return p1 + p2 + p3 + ', ' + p2 + ' ' + p1 + p3;
+        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);
+          }
         }
+        return r.join(',');
       } else {
         return p1 + p3;
       }
@@ -6555,7 +6583,7 @@
         cssText += this.propertiesFromRule(rule) + '\n}\n\n';
       } else if (rule.media) {
         cssText += '@media ' + rule.media.mediaText + ' {\n';
-        cssText += this.scopeRules(rule.cssRules, name);
+        cssText += this.scopeRules(rule.cssRules, name, typeExtension);
         cssText += '\n}\n\n';
       } else if (rule.cssText) {
         cssText += rule.cssText + '\n\n';
@@ -6568,8 +6596,9 @@
     parts.forEach(function(p) {
       p = p.trim();
       if (this.selectorNeedsScoping(p, name, typeExtension)) {
-        p = strict ? this.applyStrictSelectorScope(p, name) :
-          this.applySimpleSelectorScope(p, name, typeExtension);
+        p = (strict && !p.match(polyfillHostNoCombinator)) ? 
+            this.applyStrictSelectorScope(p, name) :
+            this.applySimpleSelectorScope(p, name, typeExtension);
       }
       r.push(p);
     }, this);
@@ -6617,14 +6646,7 @@
         polyfillHost);
   },
   propertiesFromRule: function(rule) {
-    var properties = rule.style.cssText;
-    // TODO(sorvell): Chrome cssom incorrectly removes quotes from the content
-    // property. (https://code.google.com/p/chromium/issues/detail?id=247231)
-    if (rule.style.content && !rule.style.content.match(/['"]+/)) {
-      properties = 'content: \'' + rule.style.content + '\';\n' + 
-        rule.style.cssText.replace(/content:[^;]*;/g, '');
-    }
-    return properties;
+    return rule.style.cssText;
   }
 };
 
@@ -6638,15 +6660,18 @@
     cssPolyfillUnscopedRuleCommentRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
     cssPseudoRe = /::(x-[^\s{,(]*)/gim,
     cssPartRe = /::part\(([^)]*)\)/gim,
-    // note: :host pre-processed to -host.
-    cssColonHostRe = /(-host)(?:\(([^)]*)\))?([^,{]*)/gim,
+    // note: :host pre-processed to -shadowcsshost.
+    polyfillHost = '-shadowcsshost',
+    cssColonHostRe = new RegExp('(' + polyfillHost +
+        ')(?:\\((' +
+        '(?:\\([^)(]*\\)|[^)(]*)+?' +
+        ')\\))?([^,{]*)', 'gim'),
     selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
     hostRe = /@host/gim,
     colonHostRe = /\:host/gim,
-    polyfillHost = '-host',
     /* host name without combinator */
-    polyfillHostNoCombinator = '-host-no-combinator',
-    polyfillHostRe = /-host/gim;
+    polyfillHostNoCombinator = polyfillHost + '-no-combinator',
+    polyfillHostRe = new RegExp(polyfillHost, 'gim');
 
 function stylesToCssText(styles, preserveComments) {
   var cssText = '';
diff --git a/pkg/shadow_dom/lib/shadow_dom.min.js b/pkg/shadow_dom/lib/shadow_dom.min.js
index 1080a13..a0ff506 100644
--- a/pkg/shadow_dom/lib/shadow_dom.min.js
+++ b/pkg/shadow_dom/lib/shadow_dom.min.js
@@ -1,3 +1,3 @@
-if(!HTMLElement.prototype.createShadowRoot||window.__forceShadowDomPolyfill){!function(){Element.prototype.webkitCreateShadowRoot&&(Element.prototype.webkitCreateShadowRoot=function(){return window.ShadowDOMPolyfill.wrapIfNeeded(this).createShadowRoot()})}(),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={};if(Object.observe(c,a),c.id=1,c.id=2,delete c.id,Object.deliverChangeRecords(a),3!==b.length)return!1;if("new"==b[0].type&&"updated"==b[1].type&&"deleted"==b[2].type)F="new",G="updated",H="reconfigured",I="deleted";else if("add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type)return console.error("Unexpected change record names for Object.observe. Using dirty-checking instead"),!1;return Object.unobserve(c,a),c=[0],Array.observe(c,a),c[1]=1,c.length=0,Object.deliverChangeRecords(a),2!=b.length?!1:b[0].type!=J||b[1].type!=J?!1:(Array.unobserve(c,a),!0)}function c(){if(a.document&&"securityPolicy"in a.document&&!a.document.securityPolicy.allowsEval)return!1;try{var b=new Function("","return true;");return b()}catch(c){return!1}}function d(a){return+a===a>>>0}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:M(a)&&M(b)?!0:a!==a&&b!==b}function h(a){return"string"!=typeof a?!1:(a=a.trim(),""==a?!0:"."==a[0]?!1:U.test(a))}function i(a,b){if(b!==V)throw Error("Use Path.get to retrieve path objects");return""==a.trim()?this:d(a)?(this.push(a),this):(a.split(/\s*\.\s*/).filter(function(a){return a}).forEach(function(a){this.push(a)},this),L&&!K&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn()),void 0)}function j(a){if(a instanceof i)return a;null==a&&(a=""),"string"!=typeof a&&(a=String(a));var b=W[a];if(b)return b;if(!h(a))return X;var b=new i(a,V);return W[a]=b,b}function k(b){for(var c=0;Y>c&&b.check();)b.report(),c++;a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=c)}function l(a){for(var b in a)return!1;return!0}function m(a){return l(a.added)&&l(a.removed)&&l(a.changed)}function n(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function o(a,b){var c=b||(Array.isArray(a)?[]:{});for(var d in a)c[d]=a[d];return Array.isArray(a)&&(c.length=a.length),c}function p(a,b,c,d){if(this.closed=!1,this.object=a,this.callback=b,this.target=c,this.token=d,this.reporting=!0,K){var e=this;this.boundInternalCallback=function(a){e.internalCallback(a)}}q(this)}function q(a){$&&(Z.push(a),p._allObserversCount++)}function r(a,b,c,d){p.call(this,a,b,c,d),this.connect(),this.sync(!0)}function s(a,b,c,d){if(!Array.isArray(a))throw Error("Provided object is not an Array");r.call(this,a,b,c,d)}function t(a){this.arr=[],this.callback=a,this.isObserved=!0}function u(a,b,c,d,e,g,h){var b=b instanceof i?b:j(b);return b&&b.length&&f(a)?(p.call(this,a,c,d,e),this.valueFn=g,this.setValueFn=h,this.path=b,this.connect(),this.sync(!0),void 0):(this.value_=b?b.getValueFrom(a):void 0,this.value=g?g(this.value_):this.value_,this.closed=!0,void 0)}function v(a,b,c,d){p.call(this,void 0,a,b,c),this.valueFn=d,this.observed=[],this.values=[],this.value=void 0,this.oldValue=void 0,this.oldValues=void 0,this.changeFlags=void 0,this.started=!1}function w(a,b){if("function"==typeof Object.observe){var c=Object.getNotifier(a);return function(d,e){var f={object:a,type:d,name:b};2===arguments.length&&(f.oldValue=e),c.notify(f)}}}function x(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];db[g.type]?(g.name in c||(c[g.name]=g.oldValue),g.type!=G&&(g.type!=F?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function y(a,b,c){return{index:a,removed:b,addedCount:c}}function z(){}function A(a,b,c,d,e,f){return ib.calcSplices(a,b,c,d,e,f)}function B(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function C(a,b,c,d){for(var e=y(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=B(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function D(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case J:C(c,g.index,g.removed.slice(),g.addedCount);break;case F:case G:case I:if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;C(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function E(a,b){var c=[];return D(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?(b.removed[0]!==a[b.index]&&c.push(b),void 0):(c=c.concat(A(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)),void 0)}),c}var F="add",G="update",H="reconfigure",I="delete",J="splice",K=b(),L=c(),M=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},N="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},O="[$_a-zA-Z]",P="[$_a-zA-Z0-9]",Q=O+"+"+P+"*",R="(?:[0-9]|[1-9]+[0-9]+)",S="(?:"+Q+"|"+R+")",T="(?:"+S+")(?:\\s*\\.\\s*"+S+")*",U=new RegExp("^"+T+"$"),V={},W={};i.get=j,i.prototype=N({__proto__:[],valid:!0,toString:function(){return this.join(".")},getValueFrom:function(a,b){for(var c=0;c<this.length;c++){if(null==a)return;b&&b.observe(a),a=a[this[c]]}return a},compiledGetValueFromFn:function(){var a=this.map(function(a){return d(a)?'["'+a+'"]':"."+a}),b="",c="obj";b+="if (obj != null";for(var e=0;e<this.length-1;e++)this[e],c+=a[e],b+=" &&\n     "+c+" != null";return b+=")\n",c+=a[e],b+="  return "+c+";\nelse\n  return undefined;",new Function("obj",b)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var X=new i("",V);X.valid=!1,X.getValueFrom=X.setValueFrom=function(){};var Y=1e3;p.prototype={internalCallback:function(a){this.closed||this.reporting&&this.check(a)&&(this.report(),this.testingResults&&(this.testingResults.anyChanged=!0))},close:function(){this.closed||(this.object&&"function"==typeof this.object.close&&this.object.close(),this.disconnect(),this.object=void 0,this.closed=!0)},deliver:function(a){this.closed||(K?(this.testingResults=a,Object.deliverChangeRecords(this.boundInternalCallback),this.testingResults=void 0):k(this))},report:function(){this.reporting&&(this.sync(!1),this.callback&&(this.reportArgs.push(this.token),this.invokeCallback(this.reportArgs)),this.reportArgs=void 0)},invokeCallback:function(a){try{this.callback.apply(this.target,a)}catch(b){p._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},reset:function(){this.closed||(K&&(this.reporting=!1,Object.deliverChangeRecords(this.boundInternalCallback),this.reporting=!0),this.sync(!0))}};var Z,$=!K||a.forceCollectObservers;p._allObserversCount=0,$&&(Z=[]);var _=!1,ab="function"==typeof Object.deliverAllChangeRecords;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!_){if(ab)return Object.deliverAllChangeRecords(),void 0;if($){_=!0;var b=0,c={};do{b++;var d=Z;Z=[],c.anyChanged=!1;for(var e=0;e<d.length;e++){var f=d[e];f.closed||(K?f.deliver(c):f.check()&&(c.anyChanged=!0,f.report()),Z.push(f))}}while(Y>b&&c.anyChanged);a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=b),p._allObserversCount=Z.length,_=!1}}},$&&(a.Platform.clearObservers=function(){Z=[]}),r.prototype=N({__proto__:p.prototype,connect:function(){K&&Object.observe(this.object,this.boundInternalCallback)},sync:function(){K||(this.oldObject=o(this.object))},check:function(a){var b,c;if(K){if(!a)return!1;c={},b=x(this.object,a,c)}else c=this.oldObject,b=n(this.object,this.oldObject);return m(b)?!1:(this.reportArgs=[b.added||{},b.removed||{},b.changed||{}],this.reportArgs.push(function(a){return c[a]}),!0)},disconnect:function(){K?this.object&&Object.unobserve(this.object,this.boundInternalCallback):this.oldObject=void 0}}),s.prototype=N({__proto__:r.prototype,connect:function(){K&&Array.observe(this.object,this.boundInternalCallback)},sync:function(){K||(this.oldObject=this.object.slice())},check:function(a){var b;if(K){if(!a)return!1;b=E(this.object,a)}else b=A(this.object,0,this.object.length,this.oldObject,0,this.oldObject.length);return b&&b.length?(this.reportArgs=[b],!0):!1}}),s.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})};var bb=Object.getPrototypeOf({}),cb=Object.getPrototypeOf([]);t.prototype={reset:function(){this.isObserved=!this.isObserved},observe:function(a){if(f(a)&&a!==bb&&a!==cb){var b=this.arr.indexOf(a);b>=0&&this.arr[b+1]===this.isObserved||(0>b&&(b=this.arr.length,this.arr[b]=a,Object.observe(a,this.callback)),this.arr[b+1]=this.isObserved,this.observe(Object.getPrototypeOf(a)))}},cleanup:function(){for(var a=0,b=0,c=this.isObserved;b<this.arr.length;){var d=this.arr[b];this.arr[b+1]==c?(b>a&&(this.arr[a]=d,this.arr[a+1]=c),a+=2):Object.unobserve(d,this.callback),b+=2}this.arr.length=a}},u.prototype=N({__proto__:p.prototype,connect:function(){K&&(this.observedSet=new t(this.boundInternalCallback))},disconnect:function(){this.value=void 0,this.value_=void 0,this.observedSet&&(this.observedSet.reset(),this.observedSet.cleanup(),this.observedSet=void 0)},check:function(){return this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.observedSet&&this.observedSet.cleanup(),g(this.value_,this.oldValue_)?!1:(this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.reportArgs=[this.value,this.oldValue],!0)},sync:function(a){a&&(this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.observedSet&&this.observedSet.cleanup()),this.oldValue_=this.value_,this.oldValue=this.value},setValue:function(a){this.path&&("function"==typeof this.setValueFn&&(a=this.setValueFn(a)),this.path.setValueFrom(this.object,a))}}),v.prototype=N({__proto__:u.prototype,addPath:function(a,b){if(this.started)throw Error("Cannot add more paths once started.");var b=b instanceof i?b:j(b),c=b?b.getValueFrom(a):void 0;this.observed.push(a,b),this.values.push(c)},start:function(){this.started=!0,this.connect(),this.sync(!0)},getValues:function(){this.observedSet&&this.observedSet.reset();for(var a=!1,b=0;b<this.observed.length;b+=2){var c=this.observed[b+1];if(c){var d=this.observed[b],e=c.getValueFrom(d,this.observedSet),f=this.values[b/2];if(!g(e,f)){if(!a&&!this.valueFn){this.oldValues=this.oldValues||[],this.changeFlags=this.changeFlags||[];for(var h=0;h<this.values.length;h++)this.oldValues[h]=this.values[h],this.changeFlags[h]=!1}this.valueFn||(this.changeFlags[b/2]=!0),this.values[b/2]=e,a=!0}}}return this.observedSet&&this.observedSet.cleanup(),a},check:function(){if(this.getValues()){if(this.valueFn){if(this.value=this.valueFn(this.values),g(this.value,this.oldValue))return!1;this.reportArgs=[this.value,this.oldValue]}else this.reportArgs=[this.values,this.oldValues,this.changeFlags,this.observed];return!0}},sync:function(a){a&&(this.getValues(),this.valueFn&&(this.value=this.valueFn(this.values))),this.valueFn&&(this.oldValue=this.value)},close:function(){if(this.observed){for(var a=0;a<this.observed.length;a+=2){var b=this.observed[a];b&&"function"==typeof b.close&&b.close()}this.observed=void 0,this.values=void 0}p.prototype.close.call(this)}});var db={};db[F]=!0,db[G]=!0,db[I]=!0,u.defineProperty=function(a,b,c){var d=c.object,e=j(c.path),f=w(a,b),g=new u(d,c.path,function(a,b){f&&f(G,b)});return Object.defineProperty(a,b,{get:function(){return e.getValueFrom(d)},set:function(a){e.setValueFrom(d,a)},configurable:!0}),{close:function(){var c=e.getValueFrom(d);f&&g.deliver(),g.close(),Object.defineProperty(a,b,{value:c,writable:!0,configurable:!0})}}};var eb=0,fb=1,gb=2,hb=3;z.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(eb):(e.push(fb),d=g),b--,c--):f==h?(e.push(hb),b--,d=h):(e.push(gb),c--,d=i)}else e.push(hb),b--;else e.push(gb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,0==c-b&&0==f-e)return[];if(b==c){for(var j=y(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[y(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case eb:j&&(l.push(j),j=void 0),m++,n++;break;case fb:j||(j=y(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case gb:j||(j=y(m,[],0)),j.addedCount++,m++;break;case hb:j||(j=y(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var ib=new z;a.Observer=p,a.Observer.hasObjectObserve=K,a.ArrayObserver=s,a.ArrayObserver.calculateSplices=function(a,b){return ib.calculateSplices(a,b)},a.ArraySplice=z,a.ObjectObserver=r,a.PathObserver=u,a.CompoundPathObserver=v,a.Path=i,a.Observer.changeRecordTypes={add:F,update:G,reconfigure:H,"delete":I,splice:J}}("undefined"!=typeof global&&global?global:this),"undefined"==typeof WeakMap&&!function(){var a=Object.defineProperty,b=Date.now()%1e9,c=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")};c.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}},window.WeakMap=c}(),window.ShadowDOMPolyfill={},function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a,b){return Object.getOwnPropertyNames(b).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))}),a}function d(a,b){return Object.getOwnPropertyNames(b).forEach(function(c){switch(c){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":return}Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))}),a}function e(a,b){for(var c=0;c<b.length;c++)if(b[c]in a)return b[c]}function f(a){var b=a.__proto__||Object.getPrototypeOf(a),c=D.get(b);if(c)return c;var d=f(b),e=s(d);return p(b,e,a),e}function g(a,b){n(a,b,!0)}function h(a,b){n(b,a,!1)}function i(a){return/^on[a-z]+$/.test(a)}function j(a){return/^\w[a-zA-Z_0-9]*$/.test(a)}function k(a){return G&&j(a)?new Function("return this.impl."+a):function(){return this.impl[a]}}function l(a){return G&&j(a)?new Function("v","this.impl."+a+" = v"):function(b){this.impl[a]=b}}function m(a){return G&&j(a)?new Function("return this.impl."+a+".apply(this.impl, arguments)"):function(){return this.impl[a].apply(this.impl,arguments)}}function n(b,c,d){Object.getOwnPropertyNames(b).forEach(function(e){if(!(e in c)){J&&b.__lookupGetter__(e);var f;try{f=Object.getOwnPropertyDescriptor(b,e)}catch(g){f=K}var h,j;if(d&&"function"==typeof f.value)return c[e]=m(e),void 0;var n=i(e);h=n?a.getEventHandlerGetter(e):k(e),(f.writable||f.set)&&(j=n?a.getEventHandlerSetter(e):l(e)),Object.defineProperty(c,e,{get:h,set:j,configurable:f.configurable,enumerable:f.enumerable})}})}function o(a,b,c){var e=a.prototype;p(e,b,c),d(b,a)}function p(a,c,d){var e=c.prototype;b(void 0===D.get(a)),D.set(a,c),E.set(e,a),g(a,e),d&&h(e,d)}function q(a,b){return D.get(b.prototype)===a}function r(a){var b=Object.getPrototypeOf(a),c=f(b),d=s(c);return p(b,d,a),d}function s(a){function b(b){a.call(this,b)}return b.prototype=Object.create(a.prototype),b.prototype.constructor=b,b}function t(a){return a instanceof F.EventTarget||a instanceof F.Event||a instanceof F.Range||a instanceof F.DOMImplementation||a instanceof F.CanvasRenderingContext2D||F.WebGLRenderingContext&&a instanceof F.WebGLRenderingContext}function u(a){return a instanceof N||a instanceof M||a instanceof O||a instanceof P||a instanceof L||a instanceof Q||R&&a instanceof R}function v(a){return null===a?null:(b(u(a)),a.polymerWrapper_||(a.polymerWrapper_=new(f(a))(a)))}function w(a){return null===a?null:(b(t(a)),a.impl)}function x(a){return a&&t(a)?w(a):a}function y(a){return a&&!t(a)?v(a):a}function z(a,c){null!==c&&(b(u(a)),b(void 0===c||t(c)),a.polymerWrapper_=c)}function A(a,b,c){Object.defineProperty(a.prototype,b,{get:c,configurable:!0,enumerable:!0})}function B(a,b){A(a,b,function(){return v(this.impl[b])})}function C(a,b){a.forEach(function(a){b.forEach(function(b){a.prototype[b]=function(){var a=y(this);return a[b].apply(a,arguments)}})})}var D=new WeakMap,E=new WeakMap,F=Object.create(null),G=!("securityPolicy"in document)||document.securityPolicy.allowsEval;if(G)try{var H=new Function("","return true;");G=H()}catch(I){G=!1}Object.getOwnPropertyNames(window);var J=/Firefox/.test(navigator.userAgent),K={get:function(){},set:function(){},configurable:!0,enumerable:!0},L=window.DOMImplementation,M=window.Event,N=window.Node,O=window.Window,P=window.Range,Q=window.CanvasRenderingContext2D,R=window.WebGLRenderingContext;a.assert=b,a.constructorTable=D,a.defineGetter=A,a.defineWrapGetter=B,a.forwardMethodsToWrapper=C,a.isWrapperFor=q,a.mixin=c,a.nativePrototypeTable=E,a.oneOf=e,a.registerObject=r,a.registerWrapper=o,a.rewrap=z,a.unwrap=w,a.unwrapIfNeeded=x,a.wrap=v,a.wrapIfNeeded=y,a.wrappers=F}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){g=!1;var a=f.slice(0);f=[];for(var b=0;b<a.length;b++)a[b]()}function c(a){f.push(a),g||(g=!0,d(b,0))}var d,e=window.MutationObserver,f=[],g=!1;if(e){var h=1,i=new e(b),j=document.createTextNode(h);i.observe(j,{characterData:!0}),d=function(){h=(h+1)%2,j.data=h}}else d=window.setImmediate||window.setTimeout;a.setEndOfMicrotask=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){p||(k(c),p=!0)}function c(){p=!1;do for(var a=o.slice(),b=!1,c=0;c<a.length;c++){var d=a[c],e=d.takeRecords();f(d),e.length&&(d.callback_(e,d),b=!0)}while(b)}function d(a,b){this.type=a,this.target=b,this.addedNodes=new m.NodeList,this.removedNodes=new m.NodeList,this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function e(a,b){for(;a;a=a.parentNode){var c=n.get(a);if(c)for(var d=0;d<c.length;d++){var e=c[d];e.options.subtree&&e.addTransientObserver(b)}}}function f(a){for(var b=0;b<a.nodes_.length;b++){var c=a.nodes_[b],d=n.get(c);if(!d)return;for(var e=0;e<d.length;e++){var f=d[e];f.observer===a&&f.removeTransientObservers()}}}function g(a,c,e){for(var f=Object.create(null),g=Object.create(null),h=a;h;h=h.parentNode){var i=n.get(h);if(i)for(var j=0;j<i.length;j++){var k=i[j],l=k.options;if(!(h!==a&&!l.subtree||"attributes"===c&&!l.attributes||"attributes"===c&&l.attributeFilter&&(null!==e.namespace||-1===l.attributeFilter.indexOf(e.name))||"characterData"===c&&!l.characterData||"childList"===c&&!l.childList)){var m=k.observer;f[m.uid_]=m,("attributes"===c&&l.attributeOldValue||"characterData"===c&&l.characterDataOldValue)&&(g[m.uid_]=e.oldValue)}}}var o=!1;for(var p in f){var m=f[p],q=new d(c,a);"name"in e&&"namespace"in e&&(q.attributeName=e.name,q.attributeNamespace=e.namespace),e.addedNodes&&(q.addedNodes=e.addedNodes),e.removedNodes&&(q.removedNodes=e.removedNodes),e.previousSibling&&(q.previousSibling=e.previousSibling),e.nextSibling&&(q.nextSibling=e.nextSibling),void 0!==g[p]&&(q.oldValue=g[p]),m.records_.push(q),o=!0}o&&b()}function h(a){if(this.childList=!!a.childList,this.subtree=!!a.subtree,this.attributes="attributes"in a||!("attributeOldValue"in a||"attributeFilter"in a)?!!a.attributes:!0,this.characterData="characterDataOldValue"in a&&!("characterData"in a)?!0:!!a.characterData,!this.attributes&&(a.attributeOldValue||"attributeFilter"in a)||!this.characterData&&a.characterDataOldValue)throw new TypeError;if(this.characterData=!!a.characterData,this.attributeOldValue=!!a.attributeOldValue,this.characterDataOldValue=!!a.characterDataOldValue,"attributeFilter"in a){if(null==a.attributeFilter||"object"!=typeof a.attributeFilter)throw new TypeError;this.attributeFilter=q.call(a.attributeFilter)}else this.attributeFilter=null}function i(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++r,o.push(this)}function j(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var k=a.setEndOfMicrotask,l=a.wrapIfNeeded,m=a.wrappers,n=new WeakMap,o=[],p=!1,q=Array.prototype.slice,r=0;i.prototype={observe:function(a,b){a=l(a);var c,d=new h(b),e=n.get(a);e||n.set(a,e=[]);for(var f=0;f<e.length;f++)e[f].observer===this&&(c=e[f],c.removeTransientObservers(),c.options=d);c||(c=new j(this,a,d),e.push(c),this.nodes_.push(a))},disconnect:function(){this.nodes_.forEach(function(a){for(var b=n.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}},j.prototype={addTransientObserver:function(a){if(a!==this.target){this.transientObservedNodes.push(a);var b=n.get(a);b||n.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[];for(var b=0;b<a.length;b++)for(var c=a[b],d=n.get(c),e=0;e<d.length;e++)if(d[e]===this){d.splice(e,1);break}}},a.enqueueMutation=g,a.registerTransientObservers=e,a.wrappers.MutationObserver=i,a.wrappers.MutationRecord=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a instanceof O.ShadowRoot}function c(a){var b=a.localName;return"content"===b||"shadow"===b}function d(a){return!!a.shadowRoot}function e(a){var b;return a.parentNode||(b=a.defaultView)&&N(b)||null}function f(f,g,h){if(h.length)return h.shift();if(b(f))return j(f)||f.host;var i=a.eventParentsTable.get(f);if(i){for(var k=1;k<i.length;k++)h[k-1]=i[k];return i[0]}if(g&&c(f)){var l=f.parentNode;if(l&&d(l))for(var m=a.getShadowTrees(l),n=j(g),k=0;k<m.length;k++)if(m[k].contains(n))return n}return e(f)}function g(a){for(var d=[],e=a,g=[],i=[];e;){var j=null;if(c(e)){j=h(d);var k=d[d.length-1]||e;d.push(k)}else d.length||d.push(e);var l=d[d.length-1];g.push({target:l,currentTarget:e}),b(e)&&d.pop(),e=f(e,j,i)}return g}function h(a){for(var b=a.length-1;b>=0;b--)if(!c(a[b]))return a[b];return null}function i(a,d){for(var e=[];a;){for(var g=[],i=d,j=void 0;i;){var l=null;if(g.length){if(c(i)&&(l=h(g),k(j))){var n=g[g.length-1];g.push(n)}}else g.push(i);if(m(i,a))return g[g.length-1];b(i)&&g.pop(),j=i,i=f(i,l,e)}a=b(a)?a.host:a.parentNode}}function j(b){return a.insertionParentTable.get(b)}function k(a){return j(a)}function l(a){for(var b;b=a.parentNode;)a=b;return a}function m(a,b){return l(a)===l(b)}function n(a,b){return a===b?!0:a instanceof O.ShadowRoot?n(l(a.host),b):!1}function o(){Z++}function p(){Z--}function q(b){if(!Q.get(b)){if(Q.set(b,!0),b instanceof $){if(Z)return}else a.renderAllPending();var c=N(b.target),d=N(b);return r(d,c)}}function r(a,b){var c=g(b);return"load"===a.type&&2===c.length&&c[0].target instanceof O.Document&&c.shift(),Y.set(a,c),s(a,c)&&t(a,c)&&u(a,c),U.set(a,x.NONE),S.set(a,null),a.defaultPrevented}function s(a,b){for(var c,d=b.length-1;d>0;d--){var e=b[d].target,f=b[d].currentTarget;if(e!==f&&(c=x.CAPTURING_PHASE,!v(b[d],a,c)))return!1}return!0}function t(a,b){var c=x.AT_TARGET;return v(b[0],a,c)}function u(a,b){for(var c,d=a.bubbles,e=1;e<b.length;e++){var f=b[e].target,g=b[e].currentTarget;if(f===g)c=x.AT_TARGET;else{if(!d||W.get(a))continue;c=x.BUBBLING_PHASE}if(!v(b[e],a,c))return}}function v(a,b,c){var d=a.target,e=a.currentTarget,f=P.get(e);if(!f)return!0;if("relatedTarget"in b){var g=M(b);if(g.relatedTarget){var h=N(g.relatedTarget),j=i(e,h);if(j===d)return!0;T.set(b,j)}}U.set(b,c);var k=b.type,l=!1;R.set(b,d),S.set(b,e);for(var m=0;m<f.length;m++){var n=f[m];if(n.removed)l=!0;else if(!(n.type!==k||!n.capture&&c===x.CAPTURING_PHASE||n.capture&&c===x.BUBBLING_PHASE))try{if("function"==typeof n.handler?n.handler.call(e,b):n.handler.handleEvent(b),W.get(b))return!1}catch(o){window.onerror?window.onerror(o.message):console.error(o,o.stack)}}if(l){var p=f.slice();f.length=0;for(var m=0;m<p.length;m++)p[m].removed||f.push(p[m])}return!V.get(b)}function w(a,b,c){this.type=a,this.handler=b,this.capture=Boolean(c)}function x(a,b){return a instanceof _?(this.impl=a,void 0):N(B(_,"Event",a,b))}function y(a){return a&&a.relatedTarget?Object.create(a,{relatedTarget:{value:M(a.relatedTarget)}}):a}function z(a,b,c){var d=window[a],e=function(b,c){return b instanceof d?(this.impl=b,void 0):N(B(d,a,b,c))};return e.prototype=Object.create(b.prototype),c&&K(e.prototype,c),d&&(d.prototype["init"+a]?L(d,e,document.createEvent(a)):L(d,e,new d("temp"))),e}function A(a,b){return function(){arguments[b]=M(arguments[b]);var c=M(this);c[a].apply(c,arguments)}}function B(a,b,c,d){if(jb)return new a(c,y(d));var e=M(document.createEvent(b)),f=ib[b],g=[c];return Object.keys(f).forEach(function(a){var b=null!=d&&a in d?d[a]:f[a];"relatedTarget"===a&&(b=M(b)),g.push(b)}),e["init"+b].apply(e,g),e}function C(a){return"function"==typeof a?!0:a&&a.handleEvent}function D(a){this.impl=a}function E(a){return a instanceof O.ShadowRoot&&(a=a.host),M(a)}function F(a){J(a,mb)}function G(b,c,d,e){a.renderAllPending();for(var f=N(nb.call(c.impl,d,e)),h=g(f,this),i=0;i<h.length;i++){var j=h[i];if(j.currentTarget===b)return j.target}return null}function H(a){return function(){var b=X.get(this);return b&&b[a]&&b[a].value||null}}function I(a){var b=a.slice(2);return function(c){var d=X.get(this);d||(d=Object.create(null),X.set(this,d));var e=d[a];if(e&&this.removeEventListener(b,e.wrapped,!1),"function"==typeof c){var f=function(b){var d=c.call(this,b);d===!1?b.preventDefault():"onbeforeunload"===a&&"string"==typeof d&&(b.returnValue=d)};this.addEventListener(b,f,!1),d[a]={value:c,wrapped:f}}}}var J=a.forwardMethodsToWrapper,K=a.mixin,L=a.registerWrapper,M=a.unwrap,N=a.wrap,O=a.wrappers;new WeakMap;var P=new WeakMap,Q=new WeakMap,R=new WeakMap,S=new WeakMap,T=new WeakMap,U=new WeakMap,V=new WeakMap,W=new WeakMap,X=new WeakMap,Y=new WeakMap,Z=0,$=window.MutationEvent;w.prototype={equals:function(a){return this.handler===a.handler&&this.type===a.type&&this.capture===a.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var _=window.Event;x.prototype={get target(){return R.get(this)},get currentTarget(){return S.get(this)},get eventPhase(){return U.get(this)},get path(){var a=new O.NodeList,b=Y.get(this);if(b){for(var c=0,d=b.length-1,e=l(S.get(this)),f=0;d>=f;f++){var g=b[f].currentTarget,h=l(g);n(e,h)&&(f!==d||g instanceof O.Node)&&(a[c++]=g)}a.length=c}return a},stopPropagation:function(){V.set(this,!0)},stopImmediatePropagation:function(){V.set(this,!0),W.set(this,!0)}},L(_,x,document.createEvent("Event"));var ab=z("UIEvent",x),bb=z("CustomEvent",x),cb={get relatedTarget(){return T.get(this)||N(M(this).relatedTarget)}},db=K({initMouseEvent:A("initMouseEvent",14)},cb),eb=K({initFocusEvent:A("initFocusEvent",5)},cb),fb=z("MouseEvent",ab,db),gb=z("FocusEvent",ab,eb),hb=z("MutationEvent",x,{initMutationEvent:A("initMutationEvent",3),get relatedNode(){return N(this.impl.relatedNode)}}),ib=Object.create(null),jb=function(){try{new window.MouseEvent("click")}catch(a){return!1}return!0}();if(!jb){var kb=function(a,b,c){if(c){var d=ib[c];b=K(K({},d),b)}ib[a]=b};kb("Event",{bubbles:!1,cancelable:!1}),kb("CustomEvent",{detail:null},"Event"),kb("UIEvent",{view:null,detail:0},"Event"),kb("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),kb("FocusEvent",{relatedTarget:null},"UIEvent")}var lb=window.EventTarget,mb=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(a){var b=a.prototype;mb.forEach(function(a){Object.defineProperty(b,a+"_",{value:b[a]})})}),D.prototype={addEventListener:function(a,b,c){if(C(b)){var d=new w(a,b,c),e=P.get(this);if(e){for(var f=0;f<e.length;f++)if(d.equals(e[f]))return}else e=[],P.set(this,e);e.push(d);var g=E(this);g.addEventListener_(a,q,!0)}},removeEventListener:function(a,b,c){c=Boolean(c);var d=P.get(this);if(d){for(var e=0,f=!1,g=0;g<d.length;g++)d[g].type===a&&d[g].capture===c&&(e++,d[g].handler===b&&(f=!0,d[g].remove()));if(f&&1===e){var h=E(this);h.removeEventListener_(a,q,!0)}}},dispatchEvent:function(a){var b=E(this),c=M(a);return Q.set(c,!1),b.dispatchEvent_(c)}},lb&&L(lb,D);var nb=document.elementFromPoint;a.adjustRelatedTarget=i,a.elementFromPoint=G,a.getEventHandlerGetter=H,a.getEventHandlerSetter=I,a.muteMutationEvents=o,a.unmuteMutationEvents=p,a.wrapEventTargetMethods=F,a.wrappers.CustomEvent=bb,a.wrappers.Event=x,a.wrappers.EventTarget=D,a.wrappers.FocusEvent=gb,a.wrappers.MouseEvent=fb,a.wrappers.MutationEvent=hb,a.wrappers.UIEvent=ab}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){Object.defineProperty(a,b,{enumerable:!1})}function c(){this.length=0,b(this,"length")}function d(a){if(null==a)return a;for(var b=new c,d=0,e=a.length;e>d;d++)b[d]=f(a[d]);return b.length=e,b}function e(a,b){a.prototype[b]=function(){return d(this.impl[b].apply(this.impl,arguments))}}var f=a.wrap;c.prototype={item:function(a){return this[a]}},b(c.prototype,"item"),a.wrappers.NodeList=c,a.addWrapNodeListMethod=e,a.wrapNodeList=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){v(a instanceof s)}function c(a){var b=new u;return b[0]=a,b.length=1,b}function d(a,b,c){x(b,"childList",{removedNodes:c,previousSibling:a.previousSibling,nextSibling:a.nextSibling})}function e(a,b){x(a,"childList",{removedNodes:b})}function f(a,b,d,e){if(a instanceof DocumentFragment){var f=h(a);E=!0;for(var g=f.length-1;g>=0;g--)a.removeChild(f[g]),f[g].parentNode_=b;E=!1;for(var g=0;g<f.length;g++)f[g].previousSibling_=f[g-1]||d,f[g].nextSibling_=f[g+1]||e;return d&&(d.nextSibling_=f[0]),e&&(e.previousSibling_=f[f.length-1]),f}var f=c(a),i=a.parentNode;return i&&i.removeChild(a),a.parentNode_=b,a.previousSibling_=d,a.nextSibling_=e,d&&(d.nextSibling_=a),e&&(e.previousSibling_=a),f}function g(a){if(a instanceof DocumentFragment)return h(a);var b=c(a),e=a.parentNode;return e&&d(a,e,b),b}function h(a){for(var b=new u,c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;
-return b.length=c,e(a,b),b}function i(a){return a}function j(a){a.nodeIsInserted_()}function k(a){for(var b=0;b<a.length;b++)j(a[b])}function l(){}function m(){}function n(a,b){var c=a.nodeType===s.DOCUMENT_NODE?a:a.ownerDocument;c!==b.ownerDocument&&c.adoptNode(b)}function o(b,c){if(c.length){var d=b.ownerDocument;if(d!==c[0].ownerDocument)for(var e=0;e<c.length;e++)a.adoptNodeNoRemove(c[e],d)}}function p(a,b){o(a,b);var c=b.length;if(1===c)return B(b[0]);for(var d=B(a.ownerDocument.createDocumentFragment()),e=0;c>e;e++)d.appendChild(B(b[e]));return d}function q(a){if(a.invalidateShadowRenderer()){for(var b=a.firstChild;b;){v(b.parentNode===a);var c=b.nextSibling,d=B(b),e=d.parentNode;e&&J.call(e,d),b.previousSibling_=b.nextSibling_=b.parentNode_=null,b=c}a.firstChild_=a.lastChild_=null}else for(var c,f=B(a),g=f.firstChild;g;)c=g.nextSibling,J.call(f,g),g=c}function r(a){var b=a.parentNode;return b&&b.invalidateShadowRenderer()}function s(a){v(a instanceof F),t.call(this,a),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0}var t=a.wrappers.EventTarget,u=a.wrappers.NodeList,v=a.assert,w=a.defineWrapGetter,x=a.enqueueMutation,y=a.mixin,z=a.registerTransientObservers,A=a.registerWrapper,B=a.unwrap,C=a.wrap,D=a.wrapIfNeeded,E=!1,F=window.Node,G=window.DocumentFragment;F.prototype.appendChild;var H=F.prototype.compareDocumentPosition,I=F.prototype.insertBefore,J=F.prototype.removeChild,K=F.prototype.replaceChild,L=/Trident/.test(navigator.userAgent),M=L?function(a,b){try{J.call(a,b)}catch(c){if(!(a instanceof G))throw c}}:function(a,b){J.call(a,b)};s.prototype=Object.create(t.prototype),y(s.prototype,{appendChild:function(a){return this.insertBefore(a,null)},insertBefore:function(a,c){b(a),c=c||null,c&&b(c),c&&v(c.parentNode===this);var d,e=c?c.previousSibling:this.lastChild,h=!this.invalidateShadowRenderer()&&!r(a);if(d=h?g(a):f(a,this,e,c),h)n(this,a),I.call(this.impl,B(a),B(c));else{e||(this.firstChild_=d[0]),c||(this.lastChild_=d[d.length-1]);var i=B(c),j=i?i.parentNode:this.impl;j?I.call(j,p(this,d),i):o(this,d)}return x(this,"childList",{addedNodes:d,nextSibling:c,previousSibling:e}),k(d),a},removeChild:function(a){if(b(a),a.parentNode!==this){var d=!1;this.childNodes;for(var e=this.firstChild;e;e=e.nextSibling)if(e===a){d=!0;break}if(!d)throw new Error("NotFoundError")}var f=B(a),g=a.nextSibling,h=a.previousSibling;if(this.invalidateShadowRenderer()){var i=this.firstChild,j=this.lastChild,k=f.parentNode;k&&M(k,f),i===a&&(this.firstChild_=g),j===a&&(this.lastChild_=h),h&&(h.nextSibling_=g),g&&(g.previousSibling_=h),a.previousSibling_=a.nextSibling_=a.parentNode_=void 0}else M(this.impl,f);return E||x(this,"childList",{removedNodes:c(a),nextSibling:g,previousSibling:h}),z(this,a),a},replaceChild:function(a,d){if(b(a),b(d),d.parentNode!==this)throw new Error("NotFoundError");var e,h=B(d),i=d.nextSibling,j=d.previousSibling,m=!this.invalidateShadowRenderer()&&!r(a);return m?e=g(a):(i===a&&(i=a.nextSibling),e=f(a,this,j,i)),m?(n(this,a),K.call(this.impl,B(a),h)):(this.firstChild===d&&(this.firstChild_=e[0]),this.lastChild===d&&(this.lastChild_=e[e.length-1]),d.previousSibling_=d.nextSibling_=d.parentNode_=void 0,h.parentNode&&K.call(h.parentNode,p(this,e),h)),x(this,"childList",{addedNodes:e,removedNodes:c(d),nextSibling:i,previousSibling:j}),l(d),k(e),d},nodeIsInserted_:function(){for(var a=this.firstChild;a;a=a.nextSibling)a.nodeIsInserted_()},hasChildNodes:function(){return null!==this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:C(this.impl.parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:C(this.impl.firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:C(this.impl.lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:C(this.impl.nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:C(this.impl.previousSibling)},get parentElement(){for(var a=this.parentNode;a&&a.nodeType!==s.ELEMENT_NODE;)a=a.parentNode;return a},get textContent(){for(var a="",b=this.firstChild;b;b=b.nextSibling)a+=b.textContent;return a},set textContent(a){var b=i(this.childNodes);if(this.invalidateShadowRenderer()){if(q(this),""!==a){var c=this.impl.ownerDocument.createTextNode(a);this.appendChild(c)}}else this.impl.textContent=a;var d=i(this.childNodes);x(this,"childList",{addedNodes:d,removedNodes:b}),m(b),k(d)},get childNodes(){for(var a=new u,b=0,c=this.firstChild;c;c=c.nextSibling)a[b++]=c;return a.length=b,a},cloneNode:function(a){var b=C(this.impl.cloneNode(!1));if(a)for(var c=this.firstChild;c;c=c.nextSibling)b.appendChild(c.cloneNode(!0));return b},contains:function(a){if(!a)return!1;if(a=D(a),a===this)return!0;var b=a.parentNode;return b?this.contains(b):!1},compareDocumentPosition:function(a){return H.call(this.impl,B(a))}}),w(s,"ownerDocument"),A(F,s,document.createDocumentFragment()),delete s.prototype.querySelector,delete s.prototype.querySelectorAll,s.prototype=y(Object.create(t.prototype),s.prototype),a.nodeWasAdded=j,a.nodeWasRemoved=l,a.nodesWereAdded=k,a.nodesWereRemoved=m,a.snapshotNodeList=i,a.wrappers.Node=s}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,c){for(var d,e=a.firstElementChild;e;){if(e.matches(c))return e;if(d=b(e,c))return d;e=e.nextElementSibling}return null}function c(a,b,d){for(var e=a.firstElementChild;e;)e.matches(b)&&(d[d.length++]=e),c(e,b,d),e=e.nextElementSibling;return d}var d={querySelector:function(a){return b(this,a)},querySelectorAll:function(a){return c(this,a,new NodeList)}},e={getElementsByTagName:function(a){return this.querySelectorAll(a)},getElementsByClassName:function(a){return this.querySelectorAll("."+a)},getElementsByTagNameNS:function(a,b){if("*"===a)return this.getElementsByTagName(b);for(var c=new NodeList,d=this.getElementsByTagName(b),e=0,f=0;e<d.length;e++)d[e].namespaceURI===a&&(c[f++]=d[e]);return c.length=f,c}};a.GetElementsByInterface=e,a.SelectorsInterface=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}function c(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}var d=a.wrappers.NodeList,e={get firstElementChild(){return b(this.firstChild)},get lastElementChild(){return c(this.lastChild)},get childElementCount(){for(var a=0,b=this.firstElementChild;b;b=b.nextElementSibling)a++;return a},get children(){for(var a=new d,b=0,c=this.firstElementChild;c;c=c.nextElementSibling)a[b++]=c;return a.length=b,a}},f={get nextElementSibling(){return b(this.nextSibling)},get previousElementSibling(){return c(this.previousSibling)}};a.ChildNodeInterface=f,a.ParentNodeInterface=e}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}var c=a.ChildNodeInterface,d=a.wrappers.Node,e=a.enqueueMutation,f=a.mixin,g=a.registerWrapper,h=window.CharacterData;b.prototype=Object.create(d.prototype),f(b.prototype,{get textContent(){return this.data},set textContent(a){this.data=a},get data(){return this.impl.data},set data(a){var b=this.impl.data;e(this,"characterData",{oldValue:b}),this.impl.data=a}}),f(b.prototype,c),g(h,b,document.createTextNode("")),a.wrappers.CharacterData=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b,c){var d=b.parentNode;if(d&&d.shadowRoot){var e=a.getRendererForHost(d);e.dependsOnAttribute(c)&&e.invalidate()}}function c(a,b,c){k(a,"attributes",{name:b,namespace:null,oldValue:c})}function d(a){h.call(this,a)}function e(a,c,d){var e=d||c;Object.defineProperty(a,c,{get:function(){return this.impl[c]},set:function(a){this.impl[c]=a,b(this,e)},configurable:!0,enumerable:!0})}var f=a.ChildNodeInterface,g=a.GetElementsByInterface,h=a.wrappers.Node,i=a.ParentNodeInterface,j=a.SelectorsInterface;a.addWrapNodeListMethod;var k=a.enqueueMutation,l=a.mixin,m=a.oneOf,n=a.registerWrapper,o=a.wrappers,p=window.Element,q=m(p.prototype,["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"]),r=p.prototype[q];d.prototype=Object.create(h.prototype),l(d.prototype,{createShadowRoot:function(){var b=new o.ShadowRoot(this);this.impl.polymerShadowRoot_=b;var c=a.getRendererForHost(this);return c.invalidate(),b},get shadowRoot(){return this.impl.polymerShadowRoot_||null},setAttribute:function(a,d){var e=this.impl.getAttribute(a);this.impl.setAttribute(a,d),c(this,a,e),b(this,a)},removeAttribute:function(a){var d=this.impl.getAttribute(a);this.impl.removeAttribute(a),c(this,a,d),b(this,a)},matches:function(a){return r.call(this.impl,a)}}),d.prototype[q]=function(a){return this.matches(a)},p.prototype.webkitCreateShadowRoot&&(d.prototype.webkitCreateShadowRoot=d.prototype.createShadowRoot),e(d.prototype,"id"),e(d.prototype,"className","class"),l(d.prototype,f),l(d.prototype,g),l(d.prototype,i),l(d.prototype,j),n(p,d),a.matchesName=q,a.wrappers.Element=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a){case"&":return"&amp;";case"<":return"&lt;";case'"':return"&quot;"}}function c(a){return a.replace(v,b)}function d(a){switch(a.nodeType){case Node.ELEMENT_NODE:for(var b,d=a.tagName.toLowerCase(),f="<"+d,g=a.attributes,h=0;b=g[h];h++)f+=" "+b.name+'="'+c(b.value)+'"';return f+=">",w[d]?f:f+e(a)+"</"+d+">";case Node.TEXT_NODE:return c(a.nodeValue);case Node.COMMENT_NODE:return"<!--"+c(a.nodeValue)+"-->";default:throw console.error(a),new Error("not implemented")}}function e(a){for(var b="",c=a.firstChild;c;c=c.nextSibling)b+=d(c);return b}function f(a,b,c){var d=c||"div";a.textContent="";var e=t(a.ownerDocument.createElement(d));e.innerHTML=b;for(var f;f=e.firstChild;)a.appendChild(u(f))}function g(a){l.call(this,a)}function h(b){return function(){return a.renderAllPending(),this.impl[b]}}function i(a){m(g,a,h(a))}function j(b){Object.defineProperty(g.prototype,b,{get:h(b),set:function(c){a.renderAllPending(),this.impl[b]=c},configurable:!0,enumerable:!0})}function k(b){Object.defineProperty(g.prototype,b,{value:function(){return a.renderAllPending(),this.impl[b].apply(this.impl,arguments)},configurable:!0,enumerable:!0})}var l=a.wrappers.Element,m=a.defineGetter,n=a.enqueueMutation,o=a.mixin,p=a.nodesWereAdded,q=a.nodesWereRemoved,r=a.registerWrapper,s=a.snapshotNodeList,t=a.unwrap,u=a.wrap,v=/&|<|"/g,w={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},x=window.HTMLElement;g.prototype=Object.create(l.prototype),o(g.prototype,{get innerHTML(){return e(this)},set innerHTML(a){var b=s(this.childNodes);this.invalidateShadowRenderer()?f(this,a,this.tagName):this.impl.innerHTML=a;var c=s(this.childNodes);n(this,"childList",{addedNodes:c,removedNodes:b}),q(b),p(c)},get outerHTML(){return d(this)},set outerHTML(a){var b=this.parentNode;b&&(b.invalidateShadowRenderer(),this.impl.outerHTML=a)}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(i),["scrollLeft","scrollTop"].forEach(j),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(k),r(x,g,document.createElement("b")),a.wrappers.HTMLElement=g,a.getInnerHTML=e,a.setInnerHTML=f}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrap,g=window.HTMLCanvasElement;b.prototype=Object.create(c.prototype),d(b.prototype,{getContext:function(){var a=this.impl.getContext.apply(this.impl,arguments);return a&&f(a)}}),e(g,b,document.createElement("canvas")),a.wrappers.HTMLCanvasElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLContentElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get select(){return this.getAttribute("select")},set select(a){this.setAttribute("select",a)},setAttribute:function(a,b){c.prototype.setAttribute.call(this,a,b),"select"===String(a).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),f&&e(f,b),a.wrappers.HTMLContentElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a,b){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var e=f(document.createElement("img"));d.call(this,e),g(e,this),void 0!==a&&(e.width=a),void 0!==b&&(e.height=b)}var d=a.wrappers.HTMLElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLImageElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("img")),c.prototype=b.prototype,a.wrappers.HTMLImageElement=b,a.wrappers.Image=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLShadowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{}),f&&e(f,b),a.wrappers.HTMLShadowElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){if(!a.defaultView)return a;var b=o.get(a);if(!b){for(b=a.implementation.createHTMLDocument("");b.lastChild;)b.removeChild(b.lastChild);o.set(a,b)}return b}function c(a){var c,d=b(a.ownerDocument),e=l(d.createDocumentFragment());for(h();c=a.firstChild;)e.appendChild(c);return k(),e}function d(a){if(e.call(this,a),!p){var b=c(a);n.set(this,m(b))}}var e=a.wrappers.HTMLElement,f=a.getInnerHTML,g=a.mixin,h=a.muteMutationEvents,i=a.registerWrapper,j=a.setInnerHTML,k=a.unmuteMutationEvents,l=a.unwrap,m=a.wrap,n=new WeakMap,o=new WeakMap,p=window.HTMLTemplateElement;d.prototype=Object.create(e.prototype),g(d.prototype,{get content(){return p?m(this.impl.content):n.get(this)},get innerHTML(){return f(this.content)},set innerHTML(a){j(this.content,a)}}),p&&i(p,d),a.wrappers.HTMLTemplateElement=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.registerWrapper,e=window.HTMLMediaElement;b.prototype=Object.create(c.prototype),d(e,b,document.createElement("audio")),a.wrappers.HTMLMediaElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var b=f(document.createElement("audio"));d.call(this,b),g(b,this),b.setAttribute("preload","auto"),void 0!==a&&b.setAttribute("src",a)}var d=a.wrappers.HTMLMediaElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLAudioElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("audio")),c.prototype=b.prototype,a.wrappers.HTMLAudioElement=b,a.wrappers.Audio=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a.replace(/\s+/g," ").trim()}function c(a){e.call(this,a)}function d(a,b,c,f){if(!(this instanceof d))throw new TypeError("DOM object constructor cannot be called as a function.");var g=i(document.createElement("option"));e.call(this,g),h(g,this),void 0!==a&&(g.text=a),void 0!==b&&g.setAttribute("value",b),c===!0&&g.setAttribute("selected",""),g.selected=f===!0}var e=a.wrappers.HTMLElement,f=a.mixin,g=a.registerWrapper,h=a.rewrap,i=a.unwrap,j=a.wrap,k=window.HTMLOptionElement;c.prototype=Object.create(e.prototype),f(c.prototype,{get text(){return b(this.textContent)},set text(a){this.textContent=b(String(a))},get form(){return j(i(this).form)}}),g(k,c,document.createElement("option")),d.prototype=c.prototype,a.wrappers.HTMLOptionElement=c,a.wrappers.Option=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a.localName){case"content":return new c(a);case"shadow":return new e(a);case"template":return new f(a)}d.call(this,a)}var c=a.wrappers.HTMLContentElement,d=a.wrappers.HTMLElement,e=a.wrappers.HTMLShadowElement,f=a.wrappers.HTMLTemplateElement;a.mixin;var g=a.registerWrapper,h=window.HTMLUnknownElement;b.prototype=Object.create(d.prototype),g(h,b),a.wrappers.HTMLUnknownElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrap,f=a.unwrapIfNeeded,g=a.wrap,h=window.CanvasRenderingContext2D;c(b.prototype,{get canvas(){return g(this.impl.canvas)},drawImage:function(){arguments[0]=f(arguments[0]),this.impl.drawImage.apply(this.impl,arguments)},createPattern:function(){return arguments[0]=e(arguments[0]),this.impl.createPattern.apply(this.impl,arguments)}}),d(h,b,document.createElement("canvas").getContext("2d")),a.wrappers.CanvasRenderingContext2D=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrapIfNeeded,f=a.wrap,g=window.WebGLRenderingContext;if(g){c(b.prototype,{get canvas(){return f(this.impl.canvas)},texImage2D:function(){arguments[5]=e(arguments[5]),this.impl.texImage2D.apply(this.impl,arguments)},texSubImage2D:function(){arguments[6]=e(arguments[6]),this.impl.texSubImage2D.apply(this.impl,arguments)}});var h=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};d(g,b,h),a.wrappers.WebGLRenderingContext=b}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap,g=window.Range;b.prototype={get startContainer(){return f(this.impl.startContainer)},get endContainer(){return f(this.impl.endContainer)},get commonAncestorContainer(){return f(this.impl.commonAncestorContainer)},setStart:function(a,b){this.impl.setStart(e(a),b)},setEnd:function(a,b){this.impl.setEnd(e(a),b)},setStartBefore:function(a){this.impl.setStartBefore(e(a))},setStartAfter:function(a){this.impl.setStartAfter(e(a))},setEndBefore:function(a){this.impl.setEndBefore(e(a))},setEndAfter:function(a){this.impl.setEndAfter(e(a))},selectNode:function(a){this.impl.selectNode(e(a))},selectNodeContents:function(a){this.impl.selectNodeContents(e(a))},compareBoundaryPoints:function(a,b){return this.impl.compareBoundaryPoints(a,d(b))},extractContents:function(){return f(this.impl.extractContents())},cloneContents:function(){return f(this.impl.cloneContents())},insertNode:function(a){this.impl.insertNode(e(a))},surroundContents:function(a){this.impl.surroundContents(e(a))},cloneRange:function(){return f(this.impl.cloneRange())},isPointInRange:function(a,b){return this.impl.isPointInRange(e(a),b)},comparePoint:function(a,b){return this.impl.comparePoint(e(a),b)},intersectsNode:function(a){return this.impl.intersectsNode(e(a))}},g.prototype.createContextualFragment&&(b.prototype.createContextualFragment=function(a){return f(this.impl.createContextualFragment(a))}),c(window.Range,b,document.createRange()),a.wrappers.Range=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.GetElementsByInterface,c=a.ParentNodeInterface,d=a.SelectorsInterface,e=a.mixin,f=a.registerObject,g=f(document.createDocumentFragment());e(g.prototype,c),e(g.prototype,d),e(g.prototype,b);var h=f(document.createTextNode("")),i=f(document.createComment(""));a.wrappers.Comment=i,a.wrappers.DocumentFragment=g,a.wrappers.Text=h}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=i(a.impl.ownerDocument.createDocumentFragment());c.call(this,b),g(b,this);var d=a.shadowRoot;k.set(this,d),j.set(this,a)}var c=a.wrappers.DocumentFragment,d=a.elementFromPoint,e=a.getInnerHTML,f=a.mixin,g=a.rewrap,h=a.setInnerHTML,i=a.unwrap,j=new WeakMap,k=new WeakMap;b.prototype=Object.create(c.prototype),f(b.prototype,{get innerHTML(){return e(this)},set innerHTML(a){h(this,a),this.invalidateShadowRenderer()},get olderShadowRoot(){return k.get(this)||null},get host(){return j.get(this)||null},invalidateShadowRenderer:function(){return j.get(this).invalidateShadowRenderer()},elementFromPoint:function(a,b){return d(this,this.ownerDocument,a,b)},getElementById:function(a){return this.querySelector("#"+a)}}),a.wrappers.ShadowRoot=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){a.previousSibling_=a.previousSibling,a.nextSibling_=a.nextSibling,a.parentNode_=a.parentNode}function c(a,c,e){var f=F(a),g=F(c),h=e?F(e):null;if(d(c),b(c),e)a.firstChild===e&&(a.firstChild_=e),e.previousSibling_=e.previousSibling;else{a.lastChild_=a.lastChild,a.lastChild===a.firstChild&&(a.firstChild_=a.firstChild);var i=G(f.lastChild);i&&(i.nextSibling_=i.nextSibling)}f.insertBefore(g,h)}function d(a){var c=F(a),d=c.parentNode;if(d){var e=G(d);b(a),a.previousSibling&&(a.previousSibling.nextSibling_=a),a.nextSibling&&(a.nextSibling.previousSibling_=a),e.lastChild===a&&(e.lastChild_=a),e.firstChild===a&&(e.firstChild_=a),d.removeChild(c)}}function e(a,b){g(b).push(a),x(a,b);var c=I.get(a);c||I.set(a,c=[]),c.push(b)}function f(a){H.set(a,[])}function g(a){return H.get(a)}function h(a){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}function i(a,b,c){for(var d=a.firstChild;d;d=d.nextSibling)if(b(d)){if(c(d)===!1)return}else i(d,b,c)}function j(a,b){var c=b.getAttribute("select");if(!c)return!0;if(c=c.trim(),!c)return!0;if(!(a instanceof y))return!1;if(!L.test(c))return!1;if(":"===c[0]&&!M.test(c))return!1;try{return a.matches(c)}catch(d){return!1}}function k(){for(var a=0;a<O.length;a++)O[a].render();O=[]}function l(){E=null,k()}function m(a){var b=K.get(a);return b||(b=new q(a),K.set(a,b)),b}function n(a){for(;a;a=a.parentNode)if(a instanceof C)return a;return null}function o(a){return m(a.host)}function p(a){this.skip=!1,this.node=a,this.childNodes=[]}function q(a){this.host=a,this.dirty=!1,this.invalidateAttributes(),this.associateNode(a)}function r(a){return a instanceof z}function s(a){return a instanceof z}function t(a){return a instanceof A}function u(a){return a instanceof A}function v(a){return a.shadowRoot}function w(a){for(var b=[],c=a.shadowRoot;c;c=c.olderShadowRoot)b.push(c);return b}function x(a,b){J.set(a,b)}var y=a.wrappers.Element,z=a.wrappers.HTMLContentElement,A=a.wrappers.HTMLShadowElement,B=a.wrappers.Node,C=a.wrappers.ShadowRoot;a.assert,a.mixin,a.muteMutationEvents;var D=a.oneOf;a.unmuteMutationEvents;var E,F=a.unwrap,G=a.wrap,H=new WeakMap,I=new WeakMap,J=new WeakMap,K=new WeakMap,L=/^[*.:#[a-zA-Z_|]/,M=new RegExp("^:("+["link","visited","target","enabled","disabled","checked","indeterminate","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-of-type"].join("|")+")"),N=D(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),O=[],P=new ArraySplice;P.equals=function(a,b){return F(a.node)===b},p.prototype={append:function(a){var b=new p(a);return this.childNodes.push(b),b},sync:function(a){if(!this.skip){for(var b=this.node,e=this.childNodes,f=h(F(b)),g=a||new WeakMap,i=P.calculateSplices(e,f),j=0,k=0,l=0,m=0;m<i.length;m++){for(var n=i[m];l<n.index;l++)k++,e[j++].sync(g);for(var o=n.removed.length,p=0;o>p;p++){var q=G(f[k++]);g.get(q)||d(q)}for(var r=n.addedCount,s=f[k]&&G(f[k]),p=0;r>p;p++){var t=e[j++],u=t.node;c(b,u,s),g.set(u,!0),t.sync(g)}l+=r}for(var m=l;m<e.length;m++)e[m].sync(g)}}},q.prototype={render:function(a){if(this.dirty){this.invalidateAttributes(),this.treeComposition();var b=this.host,c=b.shadowRoot;this.associateNode(b);for(var d=!e,e=a||new p(b),f=c.firstChild;f;f=f.nextSibling)this.renderNode(c,e,f,!1);d&&e.sync(),this.dirty=!1}},invalidate:function(){if(!this.dirty){if(this.dirty=!0,O.push(this),E)return;E=window[N](l,0)}},renderNode:function(a,b,c,d){if(v(c)){b=b.append(c);var e=m(c);e.dirty=!0,e.render(b)}else r(c)?this.renderInsertionPoint(a,b,c,d):t(c)?this.renderShadowInsertionPoint(a,b,c):this.renderAsAnyDomTree(a,b,c,d)},renderAsAnyDomTree:function(a,b,c,d){if(b=b.append(c),v(c)){var e=m(c);b.skip=!e.dirty,e.render(b)}else for(var f=c.firstChild;f;f=f.nextSibling)this.renderNode(a,b,f,d)},renderInsertionPoint:function(a,b,c,d){var e=g(c);if(e.length){this.associateNode(c);for(var f=0;f<e.length;f++){var h=e[f];r(h)&&d?this.renderInsertionPoint(a,b,h,d):this.renderAsAnyDomTree(a,b,h,d)}}else this.renderFallbackContent(a,b,c);this.associateNode(c.parentNode)},renderShadowInsertionPoint:function(a,b,c){var d=a.olderShadowRoot;if(d){x(d,c),this.associateNode(c.parentNode);for(var e=d.firstChild;e;e=e.nextSibling)this.renderNode(d,b,e,!0)}else this.renderFallbackContent(a,b,c)},renderFallbackContent:function(a,b,c){this.associateNode(c),this.associateNode(c.parentNode);for(var d=c.firstChild;d;d=d.nextSibling)this.renderAsAnyDomTree(a,b,d,!1)},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(a){if(a){var b=this.attributes;/\.\w+/.test(a)&&(b["class"]=!0),/#\w+/.test(a)&&(b.id=!0),a.replace(/\[\s*([^\s=\|~\]]+)/g,function(a,c){b[c]=!0})}},dependsOnAttribute:function(a){return this.attributes[a]},distribute:function(a,b){var c=this;i(a,s,function(a){f(a),c.updateDependentAttributes(a.getAttribute("select"));for(var d=0;d<b.length;d++){var g=b[d];void 0!==g&&j(g,a)&&(e(g,a),b[d]=void 0)}})},treeComposition:function(){for(var a=this.host,b=a.shadowRoot,c=[],d=a.firstChild;d;d=d.nextSibling)if(r(d)){var e=g(d);e&&e.length||(e=h(d)),c.push.apply(c,e)}else c.push(d);for(var f,j;b;){if(f=void 0,i(b,u,function(a){return f=a,!1}),j=f,this.distribute(b,c),j){var k=b.olderShadowRoot;if(k){b=k,x(b,j);continue}break}break}},associateNode:function(a){a.impl.polymerShadowRenderer_=this}},B.prototype.invalidateShadowRenderer=function(){var a=this.impl.polymerShadowRenderer_;return a?(a.invalidate(),!0):!1},z.prototype.getDistributedNodes=function(){return k(),g(this)},A.prototype.nodeIsInserted_=z.prototype.nodeIsInserted_=function(){this.invalidateShadowRenderer();var a,b=n(this);b&&(a=o(b)),this.impl.polymerShadowRenderer_=a,a&&a.invalidate()},a.eventParentsTable=I,a.getRendererForHost=m,a.getShadowTrees=w,a.insertionParentTable=J,a.renderAllPending=k,a.visual={insertBefore:c,remove:d}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b){if(window[b]){d(!a.wrappers[b]);var i=function(a){c.call(this,a)};i.prototype=Object.create(c.prototype),e(i.prototype,{get form(){return h(g(this).form)}}),f(window[b],i,document.createElement(b.slice(4,-7))),a.wrappers[b]=i}}var c=a.wrappers.HTMLElement,d=a.assert,e=a.mixin,f=a.registerWrapper,g=a.unwrap,h=a.wrap,i=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOutputElement","HTMLSelectElement","HTMLTextAreaElement"];i.forEach(b)}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){k.call(this,a)}function c(a){var c=document[a];b.prototype[a]=function(){return v(c.apply(this.impl,arguments))}}function d(a,b){y.call(b.impl,u(a)),e(a,b)}function e(a,b){a.shadowRoot&&b.adoptNode(a.shadowRoot),a instanceof n&&f(a,b);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}function f(a,b){var c=a.olderShadowRoot;c&&b.adoptNode(c)}function g(a){this.impl=a}function h(a,b){var c=document.implementation[b];a.prototype[b]=function(){return v(c.apply(this.impl,arguments))}}function i(a,b){var c=document.implementation[b];a.prototype[b]=function(){return c.apply(this.impl,arguments)}}var j=a.GetElementsByInterface,k=a.wrappers.Node,l=a.ParentNodeInterface,m=a.SelectorsInterface,n=a.wrappers.ShadowRoot,o=a.defineWrapGetter,p=a.elementFromPoint,q=a.forwardMethodsToWrapper,r=a.matchesName,s=a.mixin,t=a.registerWrapper,u=a.unwrap,v=a.wrap,w=a.wrapEventTargetMethods;a.wrapNodeList;var x=new WeakMap;b.prototype=Object.create(k.prototype),o(b,"documentElement"),o(b,"body"),o(b,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","getElementById"].forEach(c);var y=document.adoptNode;if(s(b.prototype,{adoptNode:function(a){return a.parentNode&&a.parentNode.removeChild(a),d(a,this),a},elementFromPoint:function(a,b){return p(this,this,a,b)}}),document.register){var z=document.register;b.prototype.register=function(b,c){function d(a){return a?(this.impl=a,void 0):c.extends?document.createElement(c.extends,b):document.createElement(b)}var e=c.prototype;if(a.nativePrototypeTable.get(e))throw new Error("NotSupportedError");for(var f,g=Object.getPrototypeOf(e),h=[];g&&!(f=a.nativePrototypeTable.get(g));)h.push(g),g=Object.getPrototypeOf(g);if(!f)throw new Error("NotSupportedError");for(var i=Object.create(f),j=h.length-1;j>=0;j--)i=Object.create(i);["createdCallback","enteredViewCallback","leftViewCallback","attributeChangedCallback"].forEach(function(a){var b=e[a];b&&(i[a]=function(){b.apply(v(this),arguments)})});var k={prototype:i};return c.extends&&(k.extends=c.extends),z.call(u(this),b,k),d.prototype=e,d.prototype.constructor=d,a.constructorTable.set(i,d),a.nativePrototypeTable.set(e,i),d},q([window.HTMLDocument||window.Document],["register"])}q([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild",r]),q([window.HTMLDocument||window.Document],["adoptNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById"]),s(b.prototype,j),s(b.prototype,l),s(b.prototype,m),s(b.prototype,{get implementation(){var a=x.get(this);return a?a:(a=new g(u(this).implementation),x.set(this,a),a)}}),t(window.Document,b,document.implementation.createHTMLDocument("")),window.HTMLDocument&&t(window.HTMLDocument,b),w([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),h(g,"createDocumentType"),h(g,"createDocument"),h(g,"createHTMLDocument"),i(g,"hasFeature"),t(window.DOMImplementation,g),q([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),a.adoptNodeNoRemove=d,a.wrappers.DOMImplementation=g,a.wrappers.Document=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.unwrapIfNeeded,h=a.wrap,i=a.renderAllPending,j=window.Window;b.prototype=Object.create(c.prototype);var k=window.getComputedStyle;j.prototype.getComputedStyle=function(a,b){return i(),k.call(this||window,g(a),b)},["addEventListener","removeEventListener","dispatchEvent"].forEach(function(a){j.prototype[a]=function(){var b=h(this||window);return b[a].apply(b,arguments)}}),d(b.prototype,{getComputedStyle:function(a,b){return k.call(f(this),g(a),b)}}),e(j,b),a.wrappers.Window=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=c[a],d=window[b];if(d){var e=document.createElement(a),f=e.constructor;window[b]=f}}a.isWrapperFor;var c={a:"HTMLAnchorElement",applet:"HTMLAppletElement",area:"HTMLAreaElement",br:"HTMLBRElement",base:"HTMLBaseElement",body:"HTMLBodyElement",button:"HTMLButtonElement",dl:"HTMLDListElement",datalist:"HTMLDataListElement",data:"HTMLDataElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",hr:"HTMLHRElement",head:"HTMLHeadElement",h1:"HTMLHeadingElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",input:"HTMLInputElement",li:"HTMLLIElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",del:"HTMLModElement",ol:"HTMLOListElement",object:"HTMLObjectElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",time:"HTMLTimeElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",table:"HTMLTableElement",tr:"HTMLTableRowElement",thead:"HTMLTableSectionElement",tbody:"HTMLTableSectionElement",textarea:"HTMLTextAreaElement",track:"HTMLTrackElement",title:"HTMLTitleElement",ul:"HTMLUListElement",video:"HTMLVideoElement"};
-Object.keys(c).forEach(b),Object.getOwnPropertyNames(a.wrappers).forEach(function(b){window[b]=a.wrappers[b]}),a.knownElements=c}(window.ShadowDOMPolyfill),function(){var a=window.ShadowDOMPolyfill;a.wrap,Object.defineProperties(HTMLElement.prototype,{webkitShadowRoot:{get:function(){return this.shadowRoot}}}),HTMLElement.prototype.webkitCreateShadowRoot=HTMLElement.prototype.createShadowRoot,window.dartExperimentalFixupGetTag=function(b){function c(a){if(a instanceof d)return"NodeList";if(a instanceof e)return"ShadowRoot";if(window.MutationRecord&&a instanceof MutationRecord)return"MutationRecord";if(window.MutationObserver&&a instanceof MutationObserver)return"MutationObserver";if(a instanceof HTMLTemplateElement)return"HTMLTemplateElement";var c=f(a);if(a!==c){var g=a.constructor;if(g===c.constructor){var h=g._ShadowDOMPolyfill$cacheTag_;return h||(h=Object.prototype.toString.call(c),h=h.substring(8,h.length-1),g._ShadowDOMPolyfill$cacheTag_=h),h}a=c}return b(a)}var d=a.wrappers.NodeList,e=a.wrappers.ShadowRoot,f=a.unwrapIfNeeded;return c}}();var Platform={};!function(a){function b(a,b){var c="";return Array.prototype.forEach.call(a,function(a){c+=a.textContent+"\n\n"}),b||(c=c.replace(n,"")),c}function c(a){var b=document.createElement("style");return b.textContent=a,b}function d(a){var b=c(a);document.head.appendChild(b);var d=b.sheet.cssRules;return b.parentNode.removeChild(b),d}function e(a){for(var b=0,c=[];b<a.length;b++)c.push(a[b].cssText);return c.join("\n\n")}function f(a){a&&g().appendChild(document.createTextNode(a))}function g(){return h||(h=document.createElement("style"),h.setAttribute("ShadowCSSShim","")),h}var h,i={strictStyling:!1,registry:{},shimStyling:function(a,b,d){var e=this.isTypeExtension(d),g=this.registerDefinition(a,b,d);this.strictStyling&&this.applyScopeToContent(a,b),this.insertPolyfillDirectives(g.rootStyles),this.insertPolyfillRules(g.rootStyles);var h=this.stylesToShimmedCssText(g.scopeStyles,b,e);h+=this.extractPolyfillUnscopedRules(g.rootStyles),g.shimmedStyle=c(h),a&&(a.shimmedStyle=g.shimmedStyle);for(var i,j=0,k=g.rootStyles.length;k>j&&(i=g.rootStyles[j]);j++)i.parentNode.removeChild(i);f(h)},registerDefinition:function(a,b,c){var d=this.registry[b]={root:a,name:b,extendsName:c},e=a?a.querySelectorAll("style"):[];e=e?Array.prototype.slice.call(e,0):[],d.rootStyles=e,d.scopeStyles=d.rootStyles;var f=this.registry[d.extendsName];return!f||a&&!a.querySelector("shadow")||(d.scopeStyles=f.scopeStyles.concat(d.scopeStyles)),d},isTypeExtension:function(a){return a&&a.indexOf("-")<0},applyScopeToContent:function(a,b){a&&(Array.prototype.forEach.call(a.querySelectorAll("*"),function(a){a.setAttribute(b,"")}),Array.prototype.forEach.call(a.querySelectorAll("template"),function(a){this.applyScopeToContent(a.content,b)},this))},insertPolyfillDirectives:function(a){a&&Array.prototype.forEach.call(a,function(a){a.textContent=this.insertPolyfillDirectivesInCssText(a.textContent)},this)},insertPolyfillDirectivesInCssText:function(a){return a.replace(o,function(a,b){return b.slice(0,-2)+"{"})},insertPolyfillRules:function(a){a&&Array.prototype.forEach.call(a,function(a){a.textContent=this.insertPolyfillRulesInCssText(a.textContent)},this)},insertPolyfillRulesInCssText:function(a){return a.replace(p,function(a,b){return b.slice(0,-1)})},extractPolyfillUnscopedRules:function(a){var b="";return a&&Array.prototype.forEach.call(a,function(a){b+=this.extractPolyfillUnscopedRulesFromCssText(a.textContent)+"\n\n"},this),b},extractPolyfillUnscopedRulesFromCssText:function(a){for(var b,c="";b=q.exec(a);)c+=b[1].slice(0,-1)+"\n\n";return c},stylesToShimmedCssText:function(a,b,c){return this.shimAtHost(a,b,c)+this.shimScoping(a,b,c)},shimAtHost:function(a,b,c){return a?this.convertAtHostStyles(a,b,c):void 0},convertAtHostStyles:function(a,c,f){var g=b(a),h=this;return g=g.replace(j,function(a,b){return h.scopeHostCss(b,c,f)}),g=e(this.findAtHostRules(d(g),this.makeScopeMatcher(c,f)))},scopeHostCss:function(a,b,c){var d=this;return a.replace(k,function(a,e,f){return d.scopeHostSelector(e,b,c)+" "+f+"\n	"})},scopeHostSelector:function(a,b,c){var d=[],e=a.split(","),f="[is="+b+"]";return e.forEach(function(a){a=a.trim(),a.match(l)?a=a.replace(l,c?f+"$1$3":b+"$1$3"):a.match(m)&&(a=c?f+a:b+a),d.push(a)},this),d.join(", ")},findAtHostRules:function(a,b){return Array.prototype.filter.call(a,this.isHostRule.bind(this,b))},isHostRule:function(a,b){return b.selectorText&&b.selectorText.match(a)||b.cssRules&&this.findAtHostRules(b.cssRules,a).length||b.type==CSSRule.WEBKIT_KEYFRAMES_RULE},shimScoping:function(a,b,c){return a?this.convertScopedStyles(a,b,c):void 0},convertScopedStyles:function(a,c,e){var f=b(a).replace(j,"");f=this.insertPolyfillHostInCssText(f),f=this.convertColonHost(f),f=this.convertPseudos(f),f=this.convertParts(f),f=this.convertCombinators(f);var g=d(f);return f=this.scopeRules(g,c,e)},convertPseudos:function(a){return a.replace(r," [pseudo=$1]")},convertParts:function(a){return a.replace(s," [part=$1]")},convertColonHost:function(a){return a.replace(t,function(a,b,c,d){return b=y,c?c.match(x)?b+c.replace(x,"")+d:b+c+d+", "+c+" "+b+d:b+d})},convertCombinators:function(a){return a.replace(/\^\^/g," ").replace(/\^/g," ")},scopeRules:function(a,b,c){var d="";return Array.prototype.forEach.call(a,function(a){a.selectorText&&a.style&&a.style.cssText?(d+=this.scopeSelector(a.selectorText,b,c,this.strictStyling)+" {\n	",d+=this.propertiesFromRule(a)+"\n}\n\n"):a.media?(d+="@media "+a.media.mediaText+" {\n",d+=this.scopeRules(a.cssRules,b),d+="\n}\n\n"):a.cssText&&(d+=a.cssText+"\n\n")},this),d},scopeSelector:function(a,b,c,d){var e=[],f=a.split(",");return f.forEach(function(a){a=a.trim(),this.selectorNeedsScoping(a,b,c)&&(a=d?this.applyStrictSelectorScope(a,b):this.applySimpleSelectorScope(a,b,c)),e.push(a)},this),e.join(", ")},selectorNeedsScoping:function(a,b,c){var d=this.makeScopeMatcher(b,c);return!a.match(d)},makeScopeMatcher:function(a,b){var c=b?"\\[is=['\"]?"+a+"['\"]?\\]":a;return new RegExp("^("+c+")"+u,"m")},applySimpleSelectorScope:function(a,b,c){var d=c?"[is="+b+"]":b;return a.match(z)?(a=a.replace(y,d),a.replace(z,d+" ")):d+" "+a},applyStrictSelectorScope:function(a,b){var c=[" ",">","+","~"],d=a,e="["+b+"]";return c.forEach(function(a){var b=d.split(a);d=b.map(function(a){var b=a.trim().replace(z,"");return b&&c.indexOf(b)<0&&b.indexOf(e)<0&&(a=b.replace(/([^:]*)(:*)(.*)/,"$1"+e+"$2$3")),a}).join(a)}),d},insertPolyfillHostInCssText:function(a){return a.replace(v,x).replace(w,x)},propertiesFromRule:function(a){var b=a.style.cssText;return a.style.content&&!a.style.content.match(/['"]+/)&&(b="content: '"+a.style.content+"';\n"+a.style.cssText.replace(/content:[^;]*;/g,"")),b}},j=/@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,k=/([^{]*)({[\s\S]*?})/gim,l=/(.*)((?:\*)|(?:\:scope))(.*)/,m=/^[.\[:]/,n=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,o=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,p=/\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,q=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,r=/::(x-[^\s{,(]*)/gim,s=/::part\(([^)]*)\)/gim,t=/(-host)(?:\(([^)]*)\))?([^,{]*)/gim,u="([>\\s~+[.,{:][\\s\\S]*)?$",v=/@host/gim,w=/\:host/gim,x="-host",y="-host-no-combinator",z=/-host/gim;if(window.ShadowDOMPolyfill){f("style { display: none !important; }\n");var A=document.querySelector("head");A.insertBefore(g(),A.childNodes[0])}a.ShadowCSS=i}(window.Platform)}
\ No newline at end of file
+if(!HTMLElement.prototype.createShadowRoot||window.__forceShadowDomPolyfill){!function(){Element.prototype.webkitCreateShadowRoot&&(Element.prototype.webkitCreateShadowRoot=function(){return window.ShadowDOMPolyfill.wrapIfNeeded(this).createShadowRoot()})}(),function(a){"use strict";function b(){function a(a){b=a}if("function"!=typeof Object.observe||"function"!=typeof Array.observe)return!1;var b=[],c={};if(Object.observe(c,a),c.id=1,c.id=2,delete c.id,Object.deliverChangeRecords(a),3!==b.length)return!1;if("new"==b[0].type&&"updated"==b[1].type&&"deleted"==b[2].type)F="new",G="updated",H="reconfigured",I="deleted";else if("add"!=b[0].type||"update"!=b[1].type||"delete"!=b[2].type)return console.error("Unexpected change record names for Object.observe. Using dirty-checking instead"),!1;return Object.unobserve(c,a),c=[0],Array.observe(c,a),c[1]=1,c.length=0,Object.deliverChangeRecords(a),2!=b.length?!1:b[0].type!=J||b[1].type!=J?!1:(Array.unobserve(c,a),!0)}function c(){if(a.document&&"securityPolicy"in a.document&&!a.document.securityPolicy.allowsEval)return!1;try{var b=new Function("","return true;");return b()}catch(c){return!1}}function d(a){return+a===a>>>0}function e(a){return+a}function f(a){return a===Object(a)}function g(a,b){return a===b?0!==a||1/a===1/b:M(a)&&M(b)?!0:a!==a&&b!==b}function h(a){return"string"!=typeof a?!1:(a=a.trim(),""==a?!0:"."==a[0]?!1:U.test(a))}function i(a,b){if(b!==V)throw Error("Use Path.get to retrieve path objects");return""==a.trim()?this:d(a)?(this.push(a),this):(a.split(/\s*\.\s*/).filter(function(a){return a}).forEach(function(a){this.push(a)},this),L&&!K&&this.length&&(this.getValueFrom=this.compiledGetValueFromFn()),void 0)}function j(a){if(a instanceof i)return a;null==a&&(a=""),"string"!=typeof a&&(a=String(a));var b=W[a];if(b)return b;if(!h(a))return X;var b=new i(a,V);return W[a]=b,b}function k(b){for(var c=0;Y>c&&b.check();)b.report(),c++;a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=c)}function l(a){for(var b in a)return!1;return!0}function m(a){return l(a.added)&&l(a.removed)&&l(a.changed)}function n(a,b){var c={},d={},e={};for(var f in b){var g=a[f];(void 0===g||g!==b[f])&&(f in a?g!==b[f]&&(e[f]=g):d[f]=void 0)}for(var f in a)f in b||(c[f]=a[f]);return Array.isArray(a)&&a.length!==b.length&&(e.length=a.length),{added:c,removed:d,changed:e}}function o(a,b){var c=b||(Array.isArray(a)?[]:{});for(var d in a)c[d]=a[d];return Array.isArray(a)&&(c.length=a.length),c}function p(a,b,c,d){if(this.closed=!1,this.object=a,this.callback=b,this.target=c,this.token=d,this.reporting=!0,K){var e=this;this.boundInternalCallback=function(a){e.internalCallback(a)}}q(this)}function q(a){$&&(Z.push(a),p._allObserversCount++)}function r(a,b,c,d){p.call(this,a,b,c,d),this.connect(),this.sync(!0)}function s(a,b,c,d){if(!Array.isArray(a))throw Error("Provided object is not an Array");r.call(this,a,b,c,d)}function t(a){this.arr=[],this.callback=a,this.isObserved=!0}function u(a,b,c,d,e,g,h){var b=b instanceof i?b:j(b);return b&&b.length&&f(a)?(p.call(this,a,c,d,e),this.valueFn=g,this.setValueFn=h,this.path=b,this.connect(),this.sync(!0),void 0):(this.value_=b?b.getValueFrom(a):void 0,this.value=g?g(this.value_):this.value_,this.closed=!0,void 0)}function v(a,b,c,d){p.call(this,void 0,a,b,c),this.valueFn=d,this.observed=[],this.values=[],this.value=void 0,this.oldValue=void 0,this.oldValues=void 0,this.changeFlags=void 0,this.started=!1}function w(a,b){if("function"==typeof Object.observe){var c=Object.getNotifier(a);return function(d,e){var f={object:a,type:d,name:b};2===arguments.length&&(f.oldValue=e),c.notify(f)}}}function x(a,b,c){for(var d={},e={},f=0;f<b.length;f++){var g=b[f];db[g.type]?(g.name in c||(c[g.name]=g.oldValue),g.type!=G&&(g.type!=F?g.name in d?(delete d[g.name],delete c[g.name]):e[g.name]=!0:g.name in e?delete e[g.name]:d[g.name]=!0)):(console.error("Unknown changeRecord type: "+g.type),console.error(g))}for(var h in d)d[h]=a[h];for(var h in e)e[h]=void 0;var i={};for(var h in c)if(!(h in d||h in e)){var j=a[h];c[h]!==j&&(i[h]=j)}return{added:d,removed:e,changed:i}}function y(a,b,c){return{index:a,removed:b,addedCount:c}}function z(){}function A(a,b,c,d,e,f){return ib.calcSplices(a,b,c,d,e,f)}function B(a,b,c,d){return c>b||a>d?-1:b==c||d==a?0:c>a?d>b?b-c:d-c:b>d?d-a:b-a}function C(a,b,c,d){for(var e=y(b,c,d),f=!1,g=0,h=0;h<a.length;h++){var i=a[h];if(i.index+=g,!f){var j=B(e.index,e.index+e.removed.length,i.index,i.index+i.addedCount);if(j>=0){a.splice(h,1),h--,g-=i.addedCount-i.removed.length,e.addedCount+=i.addedCount-j;var k=e.removed.length+i.removed.length-j;if(e.addedCount||k){var c=i.removed;if(e.index<i.index){var l=e.removed.slice(0,i.index-e.index);Array.prototype.push.apply(l,c),c=l}if(e.index+e.removed.length>i.index+i.addedCount){var m=e.removed.slice(i.index+i.addedCount-e.index);Array.prototype.push.apply(c,m)}e.removed=c,i.index<e.index&&(e.index=i.index)}else f=!0}else if(e.index<i.index){f=!0,a.splice(h,0,e),h++;var n=e.addedCount-e.removed.length;i.index+=n,g+=n}}}f||a.push(e)}function D(a,b){for(var c=[],f=0;f<b.length;f++){var g=b[f];switch(g.type){case J:C(c,g.index,g.removed.slice(),g.addedCount);break;case F:case G:case I:if(!d(g.name))continue;var h=e(g.name);if(0>h)continue;C(c,h,[g.oldValue],1);break;default:console.error("Unexpected record type: "+JSON.stringify(g))}}return c}function E(a,b){var c=[];return D(a,b).forEach(function(b){return 1==b.addedCount&&1==b.removed.length?(b.removed[0]!==a[b.index]&&c.push(b),void 0):(c=c.concat(A(a,b.index,b.index+b.addedCount,b.removed,0,b.removed.length)),void 0)}),c}var F="add",G="update",H="reconfigure",I="delete",J="splice",K=b(),L=c(),M=a.Number.isNaN||function(b){return"number"==typeof b&&a.isNaN(b)},N="__proto__"in{}?function(a){return a}:function(a){var b=a.__proto__;if(!b)return a;var c=Object.create(b);return Object.getOwnPropertyNames(a).forEach(function(b){Object.defineProperty(c,b,Object.getOwnPropertyDescriptor(a,b))}),c},O="[$_a-zA-Z]",P="[$_a-zA-Z0-9]",Q=O+"+"+P+"*",R="(?:[0-9]|[1-9]+[0-9]+)",S="(?:"+Q+"|"+R+")",T="(?:"+S+")(?:\\s*\\.\\s*"+S+")*",U=new RegExp("^"+T+"$"),V={},W={};i.get=j,i.prototype=N({__proto__:[],valid:!0,toString:function(){return this.join(".")},getValueFrom:function(a,b){for(var c=0;c<this.length;c++){if(null==a)return;b&&b.observe(a),a=a[this[c]]}return a},compiledGetValueFromFn:function(){var a=this.map(function(a){return d(a)?'["'+a+'"]':"."+a}),b="",c="obj";b+="if (obj != null";for(var e=0;e<this.length-1;e++){{this[e]}c+=a[e],b+=" &&\n     "+c+" != null"}return b+=")\n",c+=a[e],b+="  return "+c+";\nelse\n  return undefined;",new Function("obj",b)},setValueFrom:function(a,b){if(!this.length)return!1;for(var c=0;c<this.length-1;c++){if(!f(a))return!1;a=a[this[c]]}return f(a)?(a[this[c]]=b,!0):!1}});var X=new i("",V);X.valid=!1,X.getValueFrom=X.setValueFrom=function(){};var Y=1e3;p.prototype={internalCallback:function(a){this.closed||this.reporting&&this.check(a)&&(this.report(),this.testingResults&&(this.testingResults.anyChanged=!0))},close:function(){this.closed||(this.object&&"function"==typeof this.object.close&&this.object.close(),this.disconnect(),this.object=void 0,this.closed=!0)},deliver:function(a){this.closed||(K?(this.testingResults=a,Object.deliverChangeRecords(this.boundInternalCallback),this.testingResults=void 0):k(this))},report:function(){this.reporting&&(this.sync(!1),this.callback&&(this.reportArgs.push(this.token),this.invokeCallback(this.reportArgs)),this.reportArgs=void 0)},invokeCallback:function(a){try{this.callback.apply(this.target,a)}catch(b){p._errorThrownDuringCallback=!0,console.error("Exception caught during observer callback: "+(b.stack||b))}},reset:function(){this.closed||(K&&(this.reporting=!1,Object.deliverChangeRecords(this.boundInternalCallback),this.reporting=!0),this.sync(!0))}};var Z,$=!K||a.forceCollectObservers;p._allObserversCount=0,$&&(Z=[]);var _=!1,ab="function"==typeof Object.deliverAllChangeRecords;a.Platform=a.Platform||{},a.Platform.performMicrotaskCheckpoint=function(){if(!_){if(ab)return Object.deliverAllChangeRecords(),void 0;if($){_=!0;var b=0,c={};do{b++;var d=Z;Z=[],c.anyChanged=!1;for(var e=0;e<d.length;e++){var f=d[e];f.closed||(K?f.deliver(c):f.check()&&(c.anyChanged=!0,f.report()),Z.push(f))}}while(Y>b&&c.anyChanged);a.testingExposeCycleCount&&(a.dirtyCheckCycleCount=b),p._allObserversCount=Z.length,_=!1}}},$&&(a.Platform.clearObservers=function(){Z=[]}),r.prototype=N({__proto__:p.prototype,connect:function(){K&&Object.observe(this.object,this.boundInternalCallback)},sync:function(){K||(this.oldObject=o(this.object))},check:function(a){var b,c;if(K){if(!a)return!1;c={},b=x(this.object,a,c)}else c=this.oldObject,b=n(this.object,this.oldObject);return m(b)?!1:(this.reportArgs=[b.added||{},b.removed||{},b.changed||{}],this.reportArgs.push(function(a){return c[a]}),!0)},disconnect:function(){K?this.object&&Object.unobserve(this.object,this.boundInternalCallback):this.oldObject=void 0}}),s.prototype=N({__proto__:r.prototype,connect:function(){K&&Array.observe(this.object,this.boundInternalCallback)},sync:function(){K||(this.oldObject=this.object.slice())},check:function(a){var b;if(K){if(!a)return!1;b=E(this.object,a)}else b=A(this.object,0,this.object.length,this.oldObject,0,this.oldObject.length);return b&&b.length?(this.reportArgs=[b],!0):!1}}),s.applySplices=function(a,b,c){c.forEach(function(c){for(var d=[c.index,c.removed.length],e=c.index;e<c.index+c.addedCount;)d.push(b[e]),e++;Array.prototype.splice.apply(a,d)})};var bb=Object.getPrototypeOf({}),cb=Object.getPrototypeOf([]);t.prototype={reset:function(){this.isObserved=!this.isObserved},observe:function(a){if(f(a)&&a!==bb&&a!==cb){var b=this.arr.indexOf(a);b>=0&&this.arr[b+1]===this.isObserved||(0>b&&(b=this.arr.length,this.arr[b]=a,Object.observe(a,this.callback)),this.arr[b+1]=this.isObserved,this.observe(Object.getPrototypeOf(a)))}},cleanup:function(){for(var a=0,b=0,c=this.isObserved;b<this.arr.length;){var d=this.arr[b];this.arr[b+1]==c?(b>a&&(this.arr[a]=d,this.arr[a+1]=c),a+=2):Object.unobserve(d,this.callback),b+=2}this.arr.length=a}},u.prototype=N({__proto__:p.prototype,connect:function(){K&&(this.observedSet=new t(this.boundInternalCallback))},disconnect:function(){this.value=void 0,this.value_=void 0,this.observedSet&&(this.observedSet.reset(),this.observedSet.cleanup(),this.observedSet=void 0)},check:function(){return this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.observedSet&&this.observedSet.cleanup(),g(this.value_,this.oldValue_)?!1:(this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.reportArgs=[this.value,this.oldValue],!0)},sync:function(a){a&&(this.observedSet&&this.observedSet.reset(),this.value_=this.path.getValueFrom(this.object,this.observedSet),this.value=this.valueFn?this.valueFn(this.value_):this.value_,this.observedSet&&this.observedSet.cleanup()),this.oldValue_=this.value_,this.oldValue=this.value},setValue:function(a){this.path&&("function"==typeof this.setValueFn&&(a=this.setValueFn(a)),this.path.setValueFrom(this.object,a))}}),v.prototype=N({__proto__:u.prototype,addPath:function(a,b){if(this.started)throw Error("Cannot add more paths once started.");var b=b instanceof i?b:j(b),c=b?b.getValueFrom(a):void 0;this.observed.push(a,b),this.values.push(c)},start:function(){this.started=!0,this.connect(),this.sync(!0)},getValues:function(){this.observedSet&&this.observedSet.reset();for(var a=!1,b=0;b<this.observed.length;b+=2){var c=this.observed[b+1];if(c){var d=this.observed[b],e=c.getValueFrom(d,this.observedSet),f=this.values[b/2];if(!g(e,f)){if(!a&&!this.valueFn){this.oldValues=this.oldValues||[],this.changeFlags=this.changeFlags||[];for(var h=0;h<this.values.length;h++)this.oldValues[h]=this.values[h],this.changeFlags[h]=!1}this.valueFn||(this.changeFlags[b/2]=!0),this.values[b/2]=e,a=!0}}}return this.observedSet&&this.observedSet.cleanup(),a},check:function(){if(this.getValues()){if(this.valueFn){if(this.value=this.valueFn(this.values),g(this.value,this.oldValue))return!1;this.reportArgs=[this.value,this.oldValue]}else this.reportArgs=[this.values,this.oldValues,this.changeFlags,this.observed];return!0}},sync:function(a){a&&(this.getValues(),this.valueFn&&(this.value=this.valueFn(this.values))),this.valueFn&&(this.oldValue=this.value)},close:function(){if(this.observed){for(var a=0;a<this.observed.length;a+=2){var b=this.observed[a];b&&"function"==typeof b.close&&b.close()}this.observed=void 0,this.values=void 0}p.prototype.close.call(this)}});var db={};db[F]=!0,db[G]=!0,db[I]=!0,u.defineProperty=function(a,b,c,d){d=j(d);var e=w(a,b),f=new u(c,d,function(a,b){e&&e(G,b)});return Object.defineProperty(a,b,{get:function(){return d.getValueFrom(c)},set:function(a){d.setValueFrom(c,a)},configurable:!0}),{close:function(){var g=d.getValueFrom(c);e&&f.deliver(),f.close(),Object.defineProperty(a,b,{value:g,writable:!0,configurable:!0})}}};var eb=0,fb=1,gb=2,hb=3;z.prototype={calcEditDistances:function(a,b,c,d,e,f){for(var g=f-e+1,h=c-b+1,i=new Array(g),j=0;g>j;j++)i[j]=new Array(h),i[j][0]=j;for(var k=0;h>k;k++)i[0][k]=k;for(var j=1;g>j;j++)for(var k=1;h>k;k++)if(this.equals(a[b+k-1],d[e+j-1]))i[j][k]=i[j-1][k-1];else{var l=i[j-1][k]+1,m=i[j][k-1]+1;i[j][k]=m>l?l:m}return i},spliceOperationsFromEditDistances:function(a){for(var b=a.length-1,c=a[0].length-1,d=a[b][c],e=[];b>0||c>0;)if(0!=b)if(0!=c){var f,g=a[b-1][c-1],h=a[b-1][c],i=a[b][c-1];f=i>h?g>h?h:g:g>i?i:g,f==g?(g==d?e.push(eb):(e.push(fb),d=g),b--,c--):f==h?(e.push(hb),b--,d=h):(e.push(gb),c--,d=i)}else e.push(hb),b--;else e.push(gb),c--;return e.reverse(),e},calcSplices:function(a,b,c,d,e,f){var g=0,h=0,i=Math.min(c-b,f-e);if(0==b&&0==e&&(g=this.sharedPrefix(a,d,i)),c==a.length&&f==d.length&&(h=this.sharedSuffix(a,d,i-g)),b+=g,e+=g,c-=h,f-=h,c-b==0&&f-e==0)return[];if(b==c){for(var j=y(b,[],0);f>e;)j.removed.push(d[e++]);return[j]}if(e==f)return[y(b,[],c-b)];for(var k=this.spliceOperationsFromEditDistances(this.calcEditDistances(a,b,c,d,e,f)),j=void 0,l=[],m=b,n=e,o=0;o<k.length;o++)switch(k[o]){case eb:j&&(l.push(j),j=void 0),m++,n++;break;case fb:j||(j=y(m,[],0)),j.addedCount++,m++,j.removed.push(d[n]),n++;break;case gb:j||(j=y(m,[],0)),j.addedCount++,m++;break;case hb:j||(j=y(m,[],0)),j.removed.push(d[n]),n++}return j&&l.push(j),l},sharedPrefix:function(a,b,c){for(var d=0;c>d;d++)if(!this.equals(a[d],b[d]))return d;return c},sharedSuffix:function(a,b,c){for(var d=a.length,e=b.length,f=0;c>f&&this.equals(a[--d],b[--e]);)f++;return f},calculateSplices:function(a,b){return this.calcSplices(a,0,a.length,b,0,b.length)},equals:function(a,b){return a===b}};var ib=new z;a.Observer=p,a.Observer.hasObjectObserve=K,a.ArrayObserver=s,a.ArrayObserver.calculateSplices=function(a,b){return ib.calculateSplices(a,b)},a.ArraySplice=z,a.ObjectObserver=r,a.PathObserver=u,a.CompoundPathObserver=v,a.Path=i,a.Observer.changeRecordTypes={add:F,update:G,reconfigure:H,"delete":I,splice:J}}("undefined"!=typeof global&&global?global:this||window),"undefined"==typeof WeakMap&&!function(){var a=Object.defineProperty,b=Date.now()%1e9,c=function(){this.name="__st"+(1e9*Math.random()>>>0)+(b++ +"__")};c.prototype={set:function(b,c){var d=b[this.name];d&&d[0]===b?d[1]=c:a(b,this.name,{value:[b,c],writable:!0})},get:function(a){var b;return(b=a[this.name])&&b[0]===a?b[1]:void 0},"delete":function(a){this.set(a,void 0)}},window.WeakMap=c}(),window.ShadowDOMPolyfill={},function(a){"use strict";function b(a){if(!a)throw new Error("Assertion failed")}function c(a,b){return L(b).forEach(function(c){K(a,c,M(b,c))}),a}function d(a,b){return L(b).forEach(function(c){switch(c){case"arguments":case"caller":case"length":case"name":case"prototype":case"toString":return}K(a,c,M(b,c))}),a}function e(a,b){for(var c=0;c<b.length;c++)if(b[c]in a)return b[c]}function f(a){var b=a.__proto__||Object.getPrototypeOf(a),c=E.get(b);if(c)return c;var d=f(b),e=t(d);return q(b,e,a),e}function g(a,b){o(a,b,!0)}function h(a,b){o(b,a,!1)}function i(a){return/^on[a-z]+$/.test(a)}function j(a){return/^\w[a-zA-Z_0-9]*$/.test(a)}function k(a){return H&&j(a)?new Function("return this.impl."+a):function(){return this.impl[a]}}function l(a){return H&&j(a)?new Function("v","this.impl."+a+" = v"):function(b){this.impl[a]=b}}function m(a){return H&&j(a)?new Function("return this.impl."+a+".apply(this.impl, arguments)"):function(){return this.impl[a].apply(this.impl,arguments)}}function n(a,b){try{return Object.getOwnPropertyDescriptor(a,b)}catch(c){return O}}function o(b,c,d){for(var e=L(b),f=0;f<e.length;f++){var g=e[f];if("polymerBlackList_"!==g&&!(g in c||b.polymerBlackList_&&b.polymerBlackList_[g])){N&&b.__lookupGetter__(g);var h,j,o=n(b,g);if(d&&"function"==typeof o.value)c[g]=m(g);else{var p=i(g);h=p?a.getEventHandlerGetter(g):k(g),(o.writable||o.set)&&(j=p?a.getEventHandlerSetter(g):l(g)),K(c,g,{get:h,set:j,configurable:o.configurable,enumerable:o.enumerable})}}}}function p(a,b,c){var e=a.prototype;q(e,b,c),d(b,a)}function q(a,c,d){var e=c.prototype;b(void 0===E.get(a)),E.set(a,c),F.set(e,a),g(a,e),d&&h(e,d),K(e,"constructor",{value:c,configurable:!0,enumerable:!1,writable:!0})}function r(a,b){return E.get(b.prototype)===a}function s(a){var b=Object.getPrototypeOf(a),c=f(b),d=t(c);return q(b,d,a),d}function t(a){function b(b){a.call(this,b)}return b.prototype=Object.create(a.prototype),b.prototype.constructor=b,b}function u(a){return a instanceof G.EventTarget||a instanceof G.Event||a instanceof G.Range||a instanceof G.DOMImplementation||a instanceof G.CanvasRenderingContext2D||G.WebGLRenderingContext&&a instanceof G.WebGLRenderingContext}function v(a){return a instanceof R||a instanceof Q||a instanceof S||a instanceof T||a instanceof P||a instanceof U||V&&a instanceof V}function w(a){return null===a?null:(b(v(a)),a.polymerWrapper_||(a.polymerWrapper_=new(f(a))(a)))}function x(a){return null===a?null:(b(u(a)),a.impl)}function y(a){return a&&u(a)?x(a):a}function z(a){return a&&!u(a)?w(a):a}function A(a,c){null!==c&&(b(v(a)),b(void 0===c||u(c)),a.polymerWrapper_=c)}function B(a,b,c){K(a.prototype,b,{get:c,configurable:!0,enumerable:!0})}function C(a,b){B(a,b,function(){return w(this.impl[b])})}function D(a,b){a.forEach(function(a){b.forEach(function(b){a.prototype[b]=function(){var a=z(this);return a[b].apply(a,arguments)}})})}var E=new WeakMap,F=new WeakMap,G=Object.create(null),H=!("securityPolicy"in document)||document.securityPolicy.allowsEval;if(H)try{var I=new Function("","return true;");H=I()}catch(J){H=!1}var K=Object.defineProperty,L=Object.getOwnPropertyNames,M=Object.getOwnPropertyDescriptor;L(window);var N=/Firefox/.test(navigator.userAgent),O={get:function(){},set:function(){},configurable:!0,enumerable:!0},P=window.DOMImplementation,Q=window.Event,R=window.Node,S=window.Window,T=window.Range,U=window.CanvasRenderingContext2D,V=window.WebGLRenderingContext;a.assert=b,a.constructorTable=E,a.defineGetter=B,a.defineWrapGetter=C,a.forwardMethodsToWrapper=D,a.isWrapperFor=r,a.mixin=c,a.nativePrototypeTable=F,a.oneOf=e,a.registerObject=s,a.registerWrapper=p,a.rewrap=A,a.unwrap=x,a.unwrapIfNeeded=y,a.wrap=w,a.wrapIfNeeded=z,a.wrappers=G}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){g=!1;var a=f.slice(0);f=[];for(var b=0;b<a.length;b++)a[b]()}function c(a){f.push(a),g||(g=!0,d(b,0))}var d,e=window.MutationObserver,f=[],g=!1;if(e){var h=1,i=new e(b),j=document.createTextNode(h);i.observe(j,{characterData:!0}),d=function(){h=(h+1)%2,j.data=h}}else d=window.setImmediate||window.setTimeout;a.setEndOfMicrotask=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(){p||(k(c),p=!0)}function c(){p=!1;do for(var a=o.slice(),b=!1,c=0;c<a.length;c++){var d=a[c],e=d.takeRecords();f(d),e.length&&(d.callback_(e,d),b=!0)}while(b)}function d(a,b){this.type=a,this.target=b,this.addedNodes=new m.NodeList,this.removedNodes=new m.NodeList,this.previousSibling=null,this.nextSibling=null,this.attributeName=null,this.attributeNamespace=null,this.oldValue=null}function e(a,b){for(;a;a=a.parentNode){var c=n.get(a);if(c)for(var d=0;d<c.length;d++){var e=c[d];e.options.subtree&&e.addTransientObserver(b)}}}function f(a){for(var b=0;b<a.nodes_.length;b++){var c=a.nodes_[b],d=n.get(c);if(!d)return;for(var e=0;e<d.length;e++){var f=d[e];f.observer===a&&f.removeTransientObservers()}}}function g(a,c,e){for(var f=Object.create(null),g=Object.create(null),h=a;h;h=h.parentNode){var i=n.get(h);if(i)for(var j=0;j<i.length;j++){var k=i[j],l=k.options;if((h===a||l.subtree)&&!("attributes"===c&&!l.attributes||"attributes"===c&&l.attributeFilter&&(null!==e.namespace||-1===l.attributeFilter.indexOf(e.name))||"characterData"===c&&!l.characterData||"childList"===c&&!l.childList)){var m=k.observer;f[m.uid_]=m,("attributes"===c&&l.attributeOldValue||"characterData"===c&&l.characterDataOldValue)&&(g[m.uid_]=e.oldValue)}}}var o=!1;for(var p in f){var m=f[p],q=new d(c,a);"name"in e&&"namespace"in e&&(q.attributeName=e.name,q.attributeNamespace=e.namespace),e.addedNodes&&(q.addedNodes=e.addedNodes),e.removedNodes&&(q.removedNodes=e.removedNodes),e.previousSibling&&(q.previousSibling=e.previousSibling),e.nextSibling&&(q.nextSibling=e.nextSibling),void 0!==g[p]&&(q.oldValue=g[p]),m.records_.push(q),o=!0}o&&b()}function h(a){if(this.childList=!!a.childList,this.subtree=!!a.subtree,this.attributes="attributes"in a||!("attributeOldValue"in a||"attributeFilter"in a)?!!a.attributes:!0,this.characterData="characterDataOldValue"in a&&!("characterData"in a)?!0:!!a.characterData,!this.attributes&&(a.attributeOldValue||"attributeFilter"in a)||!this.characterData&&a.characterDataOldValue)throw new TypeError;if(this.characterData=!!a.characterData,this.attributeOldValue=!!a.attributeOldValue,this.characterDataOldValue=!!a.characterDataOldValue,"attributeFilter"in a){if(null==a.attributeFilter||"object"!=typeof a.attributeFilter)throw new TypeError;this.attributeFilter=q.call(a.attributeFilter)}else this.attributeFilter=null}function i(a){this.callback_=a,this.nodes_=[],this.records_=[],this.uid_=++r,o.push(this)}function j(a,b,c){this.observer=a,this.target=b,this.options=c,this.transientObservedNodes=[]}var k=a.setEndOfMicrotask,l=a.wrapIfNeeded,m=a.wrappers,n=new WeakMap,o=[],p=!1,q=Array.prototype.slice,r=0;i.prototype={observe:function(a,b){a=l(a);var c,d=new h(b),e=n.get(a);e||n.set(a,e=[]);for(var f=0;f<e.length;f++)e[f].observer===this&&(c=e[f],c.removeTransientObservers(),c.options=d);c||(c=new j(this,a,d),e.push(c),this.nodes_.push(a))},disconnect:function(){this.nodes_.forEach(function(a){for(var b=n.get(a),c=0;c<b.length;c++){var d=b[c];if(d.observer===this){b.splice(c,1);break}}},this),this.records_=[]},takeRecords:function(){var a=this.records_;return this.records_=[],a}},j.prototype={addTransientObserver:function(a){if(a!==this.target){this.transientObservedNodes.push(a);var b=n.get(a);b||n.set(a,b=[]),b.push(this)}},removeTransientObservers:function(){var a=this.transientObservedNodes;this.transientObservedNodes=[];for(var b=0;b<a.length;b++)for(var c=a[b],d=n.get(c),e=0;e<d.length;e++)if(d[e]===this){d.splice(e,1);break}}},a.enqueueMutation=g,a.registerTransientObservers=e,a.wrappers.MutationObserver=i,a.wrappers.MutationRecord=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a instanceof O.ShadowRoot}function c(a){var b=a.localName;return"content"===b||"shadow"===b}function d(a){return!!a.shadowRoot}function e(a){var b;return a.parentNode||(b=a.defaultView)&&N(b)||null}function f(f,g,h){if(h.length)return h.shift();if(b(f))return j(f)||f.host;var i=a.eventParentsTable.get(f);if(i){for(var k=1;k<i.length;k++)h[k-1]=i[k];return i[0]}if(g&&c(f)){var l=f.parentNode;if(l&&d(l))for(var m=a.getShadowTrees(l),n=j(g),k=0;k<m.length;k++)if(m[k].contains(n))return n}return e(f)}function g(a){for(var d=[],e=a,g=[],i=[];e;){var j=null;if(c(e)){j=h(d);var k=d[d.length-1]||e;d.push(k)}else d.length||d.push(e);var l=d[d.length-1];g.push({target:l,currentTarget:e}),b(e)&&d.pop(),e=f(e,j,i)}return g}function h(a){for(var b=a.length-1;b>=0;b--)if(!c(a[b]))return a[b];return null}function i(a,d){for(var e=[];a;){for(var g=[],i=d,j=void 0;i;){var l=null;if(g.length){if(c(i)&&(l=h(g),k(j))){var n=g[g.length-1];g.push(n)}}else g.push(i);if(m(i,a))return g[g.length-1];b(i)&&g.pop(),j=i,i=f(i,l,e)}a=b(a)?a.host:a.parentNode}}function j(b){return a.insertionParentTable.get(b)}function k(a){return j(a)}function l(a){for(var b;b=a.parentNode;)a=b;return a}function m(a,b){return l(a)===l(b)}function n(a,b){return a===b?!0:a instanceof O.ShadowRoot?n(l(a.host),b):!1}function o(b){if(!Q.get(b)){Q.set(b,!0),a.renderAllPending();var c=N(b.target),d=N(b);return p(d,c)}}function p(a,b){var c=g(b);return"load"===a.type&&2===c.length&&c[0].target instanceof O.Document&&c.shift(),Y.set(a,c),q(a,c)&&r(a,c)&&s(a,c),U.set(a,v.NONE),S.set(a,null),a.defaultPrevented}function q(a,b){for(var c,d=b.length-1;d>0;d--){var e=b[d].target,f=b[d].currentTarget;if(e!==f&&(c=v.CAPTURING_PHASE,!t(b[d],a,c)))return!1}return!0}function r(a,b){var c=v.AT_TARGET;return t(b[0],a,c)}function s(a,b){for(var c,d=a.bubbles,e=1;e<b.length;e++){var f=b[e].target,g=b[e].currentTarget;if(f===g)c=v.AT_TARGET;else{if(!d||W.get(a))continue;c=v.BUBBLING_PHASE}if(!t(b[e],a,c))return}}function t(a,b,c){var d=a.target,e=a.currentTarget,f=P.get(e);if(!f)return!0;if("relatedTarget"in b){var g=M(b);if(g.relatedTarget){var h=N(g.relatedTarget),j=i(e,h);if(j===d)return!0;T.set(b,j)}}U.set(b,c);var k=b.type,l=!1;R.set(b,d),S.set(b,e);for(var m=0;m<f.length;m++){var n=f[m];if(n.removed)l=!0;else if(!(n.type!==k||!n.capture&&c===v.CAPTURING_PHASE||n.capture&&c===v.BUBBLING_PHASE))try{if("function"==typeof n.handler?n.handler.call(e,b):n.handler.handleEvent(b),W.get(b))return!1}catch(o){window.onerror?window.onerror(o.message):console.error(o,o.stack)}}if(l){var p=f.slice();f.length=0;for(var m=0;m<p.length;m++)p[m].removed||f.push(p[m])}return!V.get(b)}function u(a,b,c){this.type=a,this.handler=b,this.capture=Boolean(c)}function v(a,b){return a instanceof Z?(this.impl=a,void 0):N(z(Z,"Event",a,b))}function w(a){return a&&a.relatedTarget?Object.create(a,{relatedTarget:{value:M(a.relatedTarget)}}):a}function x(a,b,c){var d=window[a],e=function(b,c){return b instanceof d?(this.impl=b,void 0):N(z(d,a,b,c))};return e.prototype=Object.create(b.prototype),c&&K(e.prototype,c),d&&(d.prototype["init"+a]?L(d,e,document.createEvent(a)):L(d,e,new d("temp"))),e}function y(a,b){return function(){arguments[b]=M(arguments[b]);var c=M(this);c[a].apply(c,arguments)}}function z(a,b,c,d){if(gb)return new a(c,w(d));var e=M(document.createEvent(b)),f=fb[b],g=[c];return Object.keys(f).forEach(function(a){var b=null!=d&&a in d?d[a]:f[a];"relatedTarget"===a&&(b=M(b)),g.push(b)}),e["init"+b].apply(e,g),e}function A(){v.call(this)}function B(a){return"function"==typeof a?!0:a&&a.handleEvent}function C(a){switch(a){case"DOMAttrModified":case"DOMAttributeNameChanged":case"DOMCharacterDataModified":case"DOMElementNameChanged":case"DOMNodeInserted":case"DOMNodeInsertedIntoDocument":case"DOMNodeRemoved":case"DOMNodeRemovedFromDocument":case"DOMSubtreeModified":return!0}return!1}function D(a){this.impl=a}function E(a){return a instanceof O.ShadowRoot&&(a=a.host),M(a)}function F(a){J(a,jb)}function G(b,c,d,e){a.renderAllPending();for(var f=N(kb.call(c.impl,d,e)),h=g(f,this),i=0;i<h.length;i++){var j=h[i];if(j.currentTarget===b)return j.target}return null}function H(a){return function(){var b=X.get(this);return b&&b[a]&&b[a].value||null}}function I(a){var b=a.slice(2);return function(c){var d=X.get(this);d||(d=Object.create(null),X.set(this,d));var e=d[a];if(e&&this.removeEventListener(b,e.wrapped,!1),"function"==typeof c){var f=function(b){var d=c.call(this,b);d===!1?b.preventDefault():"onbeforeunload"===a&&"string"==typeof d&&(b.returnValue=d)};this.addEventListener(b,f,!1),d[a]={value:c,wrapped:f}}}}var J=a.forwardMethodsToWrapper,K=a.mixin,L=a.registerWrapper,M=a.unwrap,N=a.wrap,O=a.wrappers,P=(new WeakMap,new WeakMap),Q=new WeakMap,R=new WeakMap,S=new WeakMap,T=new WeakMap,U=new WeakMap,V=new WeakMap,W=new WeakMap,X=new WeakMap,Y=new WeakMap;u.prototype={equals:function(a){return this.handler===a.handler&&this.type===a.type&&this.capture===a.capture},get removed(){return null===this.handler},remove:function(){this.handler=null}};var Z=window.Event;Z.prototype.polymerBlackList_={returnValue:!0},v.prototype={get target(){return R.get(this)},get currentTarget(){return S.get(this)},get eventPhase(){return U.get(this)},get path(){var a=new O.NodeList,b=Y.get(this);if(b){for(var c=0,d=b.length-1,e=l(S.get(this)),f=0;d>=f;f++){var g=b[f].currentTarget,h=l(g);n(e,h)&&(f!==d||g instanceof O.Node)&&(a[c++]=g)}a.length=c}return a},stopPropagation:function(){V.set(this,!0)},stopImmediatePropagation:function(){V.set(this,!0),W.set(this,!0)}},L(Z,v,document.createEvent("Event"));var $=x("UIEvent",v),_=x("CustomEvent",v),ab={get relatedTarget(){return T.get(this)||N(M(this).relatedTarget)}},bb=K({initMouseEvent:y("initMouseEvent",14)},ab),cb=K({initFocusEvent:y("initFocusEvent",5)},ab),db=x("MouseEvent",$,bb),eb=x("FocusEvent",$,cb),fb=Object.create(null),gb=function(){try{new window.MouseEvent("click")}catch(a){return!1}return!0}();if(!gb){var hb=function(a,b,c){if(c){var d=fb[c];b=K(K({},d),b)}fb[a]=b};hb("Event",{bubbles:!1,cancelable:!1}),hb("CustomEvent",{detail:null},"Event"),hb("UIEvent",{view:null,detail:0},"Event"),hb("MouseEvent",{screenX:0,screenY:0,clientX:0,clientY:0,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:null},"UIEvent"),hb("FocusEvent",{relatedTarget:null},"UIEvent")}A.prototype=Object.create(v.prototype),K(A.prototype,{get returnValue(){return this.impl.returnValue},set returnValue(a){this.impl.returnValue=a}});var ib=window.EventTarget,jb=["addEventListener","removeEventListener","dispatchEvent"];[Node,Window].forEach(function(a){var b=a.prototype;jb.forEach(function(a){Object.defineProperty(b,a+"_",{value:b[a]})})}),D.prototype={addEventListener:function(a,b,c){if(B(b)&&!C(a)){var d=new u(a,b,c),e=P.get(this);if(e){for(var f=0;f<e.length;f++)if(d.equals(e[f]))return}else e=[],P.set(this,e);e.push(d);var g=E(this);g.addEventListener_(a,o,!0)}},removeEventListener:function(a,b,c){c=Boolean(c);var d=P.get(this);if(d){for(var e=0,f=!1,g=0;g<d.length;g++)d[g].type===a&&d[g].capture===c&&(e++,d[g].handler===b&&(f=!0,d[g].remove()));if(f&&1===e){var h=E(this);h.removeEventListener_(a,o,!0)}}},dispatchEvent:function(a){var b=E(this),c=M(a);return Q.set(c,!1),b.dispatchEvent_(c)}},ib&&L(ib,D);var kb=document.elementFromPoint;a.adjustRelatedTarget=i,a.elementFromPoint=G,a.getEventHandlerGetter=H,a.getEventHandlerSetter=I,a.wrapEventTargetMethods=F,a.wrappers.BeforeUnloadEvent=A,a.wrappers.CustomEvent=_,a.wrappers.Event=v,a.wrappers.EventTarget=D,a.wrappers.FocusEvent=eb,a.wrappers.MouseEvent=db,a.wrappers.UIEvent=$}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,b){Object.defineProperty(a,b,{enumerable:!1})}function c(){this.length=0,b(this,"length")}function d(a){if(null==a)return a;for(var b=new c,d=0,e=a.length;e>d;d++)b[d]=f(a[d]);return b.length=e,b}function e(a,b){a.prototype[b]=function(){return d(this.impl[b].apply(this.impl,arguments))}}var f=a.wrap;c.prototype={item:function(a){return this[a]}},b(c.prototype,"item"),a.wrappers.NodeList=c,a.addWrapNodeListMethod=e,a.wrapNodeList=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){v(a instanceof s)}function c(a){var b=new u;return b[0]=a,b.length=1,b}function d(a,b,c){x(b,"childList",{removedNodes:c,previousSibling:a.previousSibling,nextSibling:a.nextSibling})}function e(a,b){x(a,"childList",{removedNodes:b})}function f(a,b,d,e){if(a instanceof DocumentFragment){var f=h(a);E=!0;for(var g=f.length-1;g>=0;g--)a.removeChild(f[g]),f[g].parentNode_=b;E=!1;for(var g=0;g<f.length;g++)f[g].previousSibling_=f[g-1]||d,f[g].nextSibling_=f[g+1]||e;return d&&(d.nextSibling_=f[0]),e&&(e.previousSibling_=f[f.length-1]),f
+}var f=c(a),i=a.parentNode;return i&&i.removeChild(a),a.parentNode_=b,a.previousSibling_=d,a.nextSibling_=e,d&&(d.nextSibling_=a),e&&(e.previousSibling_=a),f}function g(a){if(a instanceof DocumentFragment)return h(a);var b=c(a),e=a.parentNode;return e&&d(a,e,b),b}function h(a){for(var b=new u,c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b.length=c,e(a,b),b}function i(a){return a}function j(a){a.nodeIsInserted_()}function k(a){for(var b=0;b<a.length;b++)j(a[b])}function l(){}function m(){}function n(a,b){var c=a.nodeType===s.DOCUMENT_NODE?a:a.ownerDocument;c!==b.ownerDocument&&c.adoptNode(b)}function o(b,c){if(c.length){var d=b.ownerDocument;if(d!==c[0].ownerDocument)for(var e=0;e<c.length;e++)a.adoptNodeNoRemove(c[e],d)}}function p(a,b){o(a,b);var c=b.length;if(1===c)return B(b[0]);for(var d=B(a.ownerDocument.createDocumentFragment()),e=0;c>e;e++)d.appendChild(B(b[e]));return d}function q(a){if(a.invalidateShadowRenderer()){for(var b=a.firstChild;b;){v(b.parentNode===a);var c=b.nextSibling,d=B(b),e=d.parentNode;e&&J.call(e,d),b.previousSibling_=b.nextSibling_=b.parentNode_=null,b=c}a.firstChild_=a.lastChild_=null}else for(var c,f=B(a),g=f.firstChild;g;)c=g.nextSibling,J.call(f,g),g=c}function r(a){var b=a.parentNode;return b&&b.invalidateShadowRenderer()}function s(a){v(a instanceof F),t.call(this,a),this.parentNode_=void 0,this.firstChild_=void 0,this.lastChild_=void 0,this.nextSibling_=void 0,this.previousSibling_=void 0}var t=a.wrappers.EventTarget,u=a.wrappers.NodeList,v=a.assert,w=a.defineWrapGetter,x=a.enqueueMutation,y=a.mixin,z=a.registerTransientObservers,A=a.registerWrapper,B=a.unwrap,C=a.wrap,D=a.wrapIfNeeded,E=!1,F=window.Node,G=window.DocumentFragment,H=(F.prototype.appendChild,F.prototype.compareDocumentPosition),I=F.prototype.insertBefore,J=F.prototype.removeChild,K=F.prototype.replaceChild,L=/Trident/.test(navigator.userAgent),M=L?function(a,b){try{J.call(a,b)}catch(c){if(!(a instanceof G))throw c}}:function(a,b){J.call(a,b)};s.prototype=Object.create(t.prototype),y(s.prototype,{appendChild:function(a){return this.insertBefore(a,null)},insertBefore:function(a,c){b(a),c=c||null,c&&b(c),c&&v(c.parentNode===this);var d,e=c?c.previousSibling:this.lastChild,h=!this.invalidateShadowRenderer()&&!r(a);if(d=h?g(a):f(a,this,e,c),h)n(this,a),I.call(this.impl,B(a),B(c));else{e||(this.firstChild_=d[0]),c||(this.lastChild_=d[d.length-1]);var i=B(c),j=i?i.parentNode:this.impl;j?I.call(j,p(this,d),i):o(this,d)}return x(this,"childList",{addedNodes:d,nextSibling:c,previousSibling:e}),k(d),a},removeChild:function(a){if(b(a),a.parentNode!==this){for(var d=!1,e=(this.childNodes,this.firstChild);e;e=e.nextSibling)if(e===a){d=!0;break}if(!d)throw new Error("NotFoundError")}var f=B(a),g=a.nextSibling,h=a.previousSibling;if(this.invalidateShadowRenderer()){var i=this.firstChild,j=this.lastChild,k=f.parentNode;k&&M(k,f),i===a&&(this.firstChild_=g),j===a&&(this.lastChild_=h),h&&(h.nextSibling_=g),g&&(g.previousSibling_=h),a.previousSibling_=a.nextSibling_=a.parentNode_=void 0}else M(this.impl,f);return E||x(this,"childList",{removedNodes:c(a),nextSibling:g,previousSibling:h}),z(this,a),a},replaceChild:function(a,d){if(b(a),b(d),d.parentNode!==this)throw new Error("NotFoundError");var e,h=B(d),i=d.nextSibling,j=d.previousSibling,m=!this.invalidateShadowRenderer()&&!r(a);return m?e=g(a):(i===a&&(i=a.nextSibling),e=f(a,this,j,i)),m?(n(this,a),K.call(this.impl,B(a),h)):(this.firstChild===d&&(this.firstChild_=e[0]),this.lastChild===d&&(this.lastChild_=e[e.length-1]),d.previousSibling_=d.nextSibling_=d.parentNode_=void 0,h.parentNode&&K.call(h.parentNode,p(this,e),h)),x(this,"childList",{addedNodes:e,removedNodes:c(d),nextSibling:i,previousSibling:j}),l(d),k(e),d},nodeIsInserted_:function(){for(var a=this.firstChild;a;a=a.nextSibling)a.nodeIsInserted_()},hasChildNodes:function(){return null!==this.firstChild},get parentNode(){return void 0!==this.parentNode_?this.parentNode_:C(this.impl.parentNode)},get firstChild(){return void 0!==this.firstChild_?this.firstChild_:C(this.impl.firstChild)},get lastChild(){return void 0!==this.lastChild_?this.lastChild_:C(this.impl.lastChild)},get nextSibling(){return void 0!==this.nextSibling_?this.nextSibling_:C(this.impl.nextSibling)},get previousSibling(){return void 0!==this.previousSibling_?this.previousSibling_:C(this.impl.previousSibling)},get parentElement(){for(var a=this.parentNode;a&&a.nodeType!==s.ELEMENT_NODE;)a=a.parentNode;return a},get textContent(){for(var a="",b=this.firstChild;b;b=b.nextSibling)a+=b.textContent;return a},set textContent(a){var b=i(this.childNodes);if(this.invalidateShadowRenderer()){if(q(this),""!==a){var c=this.impl.ownerDocument.createTextNode(a);this.appendChild(c)}}else this.impl.textContent=a;var d=i(this.childNodes);x(this,"childList",{addedNodes:d,removedNodes:b}),m(b),k(d)},get childNodes(){for(var a=new u,b=0,c=this.firstChild;c;c=c.nextSibling)a[b++]=c;return a.length=b,a},cloneNode:function(a){var b=C(this.impl.cloneNode(!1));if(a)for(var c=this.firstChild;c;c=c.nextSibling)b.appendChild(c.cloneNode(!0));return b},contains:function(a){if(!a)return!1;if(a=D(a),a===this)return!0;var b=a.parentNode;return b?this.contains(b):!1},compareDocumentPosition:function(a){return H.call(this.impl,B(a))}}),w(s,"ownerDocument"),A(F,s,document.createDocumentFragment()),delete s.prototype.querySelector,delete s.prototype.querySelectorAll,s.prototype=y(Object.create(t.prototype),s.prototype),a.nodeWasAdded=j,a.nodeWasRemoved=l,a.nodesWereAdded=k,a.nodesWereRemoved=m,a.snapshotNodeList=i,a.wrappers.Node=s}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a,c){for(var d,e=a.firstElementChild;e;){if(e.matches(c))return e;if(d=b(e,c))return d;e=e.nextElementSibling}return null}function c(a,b,d){for(var e=a.firstElementChild;e;)e.matches(b)&&(d[d.length++]=e),c(e,b,d),e=e.nextElementSibling;return d}var d={querySelector:function(a){return b(this,a)},querySelectorAll:function(a){return c(this,a,new NodeList)}},e={getElementsByTagName:function(a){return this.querySelectorAll(a)},getElementsByClassName:function(a){return this.querySelectorAll("."+a)},getElementsByTagNameNS:function(a,b){if("*"===a)return this.getElementsByTagName(b);for(var c=new NodeList,d=this.getElementsByTagName(b),e=0,f=0;e<d.length;e++)d[e].namespaceURI===a&&(c[f++]=d[e]);return c.length=f,c}};a.GetElementsByInterface=e,a.SelectorsInterface=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}function c(a){for(;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}var d=a.wrappers.NodeList,e={get firstElementChild(){return b(this.firstChild)},get lastElementChild(){return c(this.lastChild)},get childElementCount(){for(var a=0,b=this.firstElementChild;b;b=b.nextElementSibling)a++;return a},get children(){for(var a=new d,b=0,c=this.firstElementChild;c;c=c.nextElementSibling)a[b++]=c;return a.length=b,a}},f={get nextElementSibling(){return b(this.nextSibling)},get previousElementSibling(){return c(this.previousSibling)}};a.ChildNodeInterface=f,a.ParentNodeInterface=e}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}var c=a.ChildNodeInterface,d=a.wrappers.Node,e=a.enqueueMutation,f=a.mixin,g=a.registerWrapper,h=window.CharacterData;b.prototype=Object.create(d.prototype),f(b.prototype,{get textContent(){return this.data},set textContent(a){this.data=a},get data(){return this.impl.data},set data(a){var b=this.impl.data;e(this,"characterData",{oldValue:b}),this.impl.data=a}}),f(b.prototype,c),g(h,b,document.createTextNode("")),a.wrappers.CharacterData=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b,c){var d=b.parentNode;if(d&&d.shadowRoot){var e=a.getRendererForHost(d);e.dependsOnAttribute(c)&&e.invalidate()}}function c(a,b,c){k(a,"attributes",{name:b,namespace:null,oldValue:c})}function d(a){h.call(this,a)}function e(a,c,d){var e=d||c;Object.defineProperty(a,c,{get:function(){return this.impl[c]},set:function(a){this.impl[c]=a,b(this,e)},configurable:!0,enumerable:!0})}var f=a.ChildNodeInterface,g=a.GetElementsByInterface,h=a.wrappers.Node,i=a.ParentNodeInterface,j=a.SelectorsInterface,k=(a.addWrapNodeListMethod,a.enqueueMutation),l=a.mixin,m=a.oneOf,n=a.registerWrapper,o=a.wrappers,p=window.Element,q=m(p.prototype,["matches","mozMatchesSelector","msMatchesSelector","webkitMatchesSelector"]),r=p.prototype[q];d.prototype=Object.create(h.prototype),l(d.prototype,{createShadowRoot:function(){var b=new o.ShadowRoot(this);this.impl.polymerShadowRoot_=b;var c=a.getRendererForHost(this);return c.invalidate(),b},get shadowRoot(){return this.impl.polymerShadowRoot_||null},setAttribute:function(a,d){var e=this.impl.getAttribute(a);this.impl.setAttribute(a,d),c(this,a,e),b(this,a)},removeAttribute:function(a){var d=this.impl.getAttribute(a);this.impl.removeAttribute(a),c(this,a,d),b(this,a)},matches:function(a){return r.call(this.impl,a)}}),d.prototype[q]=function(a){return this.matches(a)},p.prototype.webkitCreateShadowRoot&&(d.prototype.webkitCreateShadowRoot=d.prototype.createShadowRoot),e(d.prototype,"id"),e(d.prototype,"className","class"),l(d.prototype,f),l(d.prototype,g),l(d.prototype,i),l(d.prototype,j),n(p,d),a.matchesName=q,a.wrappers.Element=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a){case"&":return"&amp;";case"<":return"&lt;";case'"':return"&quot;"}}function c(a){return a.replace(v,b)}function d(a){switch(a.nodeType){case Node.ELEMENT_NODE:for(var b,d=a.tagName.toLowerCase(),f="<"+d,g=a.attributes,h=0;b=g[h];h++)f+=" "+b.name+'="'+c(b.value)+'"';return f+=">",w[d]?f:f+e(a)+"</"+d+">";case Node.TEXT_NODE:return c(a.nodeValue);case Node.COMMENT_NODE:return"<!--"+c(a.nodeValue)+"-->";default:throw console.error(a),new Error("not implemented")}}function e(a){for(var b="",c=a.firstChild;c;c=c.nextSibling)b+=d(c);return b}function f(a,b,c){var d=c||"div";a.textContent="";var e=t(a.ownerDocument.createElement(d));e.innerHTML=b;for(var f;f=e.firstChild;)a.appendChild(u(f))}function g(a){l.call(this,a)}function h(b){return function(){return a.renderAllPending(),this.impl[b]}}function i(a){m(g,a,h(a))}function j(b){Object.defineProperty(g.prototype,b,{get:h(b),set:function(c){a.renderAllPending(),this.impl[b]=c},configurable:!0,enumerable:!0})}function k(b){Object.defineProperty(g.prototype,b,{value:function(){return a.renderAllPending(),this.impl[b].apply(this.impl,arguments)},configurable:!0,enumerable:!0})}var l=a.wrappers.Element,m=a.defineGetter,n=a.enqueueMutation,o=a.mixin,p=a.nodesWereAdded,q=a.nodesWereRemoved,r=a.registerWrapper,s=a.snapshotNodeList,t=a.unwrap,u=a.wrap,v=/&|<|"/g,w={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},x=window.HTMLElement;g.prototype=Object.create(l.prototype),o(g.prototype,{get innerHTML(){return e(this)},set innerHTML(a){var b=s(this.childNodes);this.invalidateShadowRenderer()?f(this,a,this.tagName):this.impl.innerHTML=a;var c=s(this.childNodes);n(this,"childList",{addedNodes:c,removedNodes:b}),q(b),p(c)},get outerHTML(){return d(this)},set outerHTML(a){var b=this.parentNode;b&&(b.invalidateShadowRenderer(),this.impl.outerHTML=a)}}),["clientHeight","clientLeft","clientTop","clientWidth","offsetHeight","offsetLeft","offsetTop","offsetWidth","scrollHeight","scrollWidth"].forEach(i),["scrollLeft","scrollTop"].forEach(j),["getBoundingClientRect","getClientRects","scrollIntoView"].forEach(k),r(x,g,document.createElement("b")),a.wrappers.HTMLElement=g,a.getInnerHTML=e,a.setInnerHTML=f}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=a.wrap,g=window.HTMLCanvasElement;b.prototype=Object.create(c.prototype),d(b.prototype,{getContext:function(){var a=this.impl.getContext.apply(this.impl,arguments);return a&&f(a)}}),e(g,b,document.createElement("canvas")),a.wrappers.HTMLCanvasElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLContentElement;b.prototype=Object.create(c.prototype),d(b.prototype,{get select(){return this.getAttribute("select")},set select(a){this.setAttribute("select",a)},setAttribute:function(a,b){c.prototype.setAttribute.call(this,a,b),"select"===String(a).toLowerCase()&&this.invalidateShadowRenderer(!0)}}),f&&e(f,b),a.wrappers.HTMLContentElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a,b){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var e=f(document.createElement("img"));d.call(this,e),g(e,this),void 0!==a&&(e.width=a),void 0!==b&&(e.height=b)}var d=a.wrappers.HTMLElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLImageElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("img")),c.prototype=b.prototype,a.wrappers.HTMLImageElement=b,a.wrappers.Image=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.mixin,e=a.registerWrapper,f=window.HTMLShadowElement;b.prototype=Object.create(c.prototype),d(b.prototype,{}),f&&e(f,b),a.wrappers.HTMLShadowElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){if(!a.defaultView)return a;var b=m.get(a);if(!b){for(b=a.implementation.createHTMLDocument("");b.lastChild;)b.removeChild(b.lastChild);m.set(a,b)}return b}function c(a){for(var c,d=b(a.ownerDocument),e=j(d.createDocumentFragment());c=a.firstChild;)e.appendChild(c);return e}function d(a){if(e.call(this,a),!n){var b=c(a);l.set(this,k(b))}}var e=a.wrappers.HTMLElement,f=a.getInnerHTML,g=a.mixin,h=a.registerWrapper,i=a.setInnerHTML,j=a.unwrap,k=a.wrap,l=new WeakMap,m=new WeakMap,n=window.HTMLTemplateElement;d.prototype=Object.create(e.prototype),g(d.prototype,{get content(){return n?k(this.impl.content):l.get(this)},get innerHTML(){return f(this.content)},set innerHTML(a){i(this.content,a)}}),n&&h(n,d),a.wrappers.HTMLTemplateElement=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.HTMLElement,d=a.registerWrapper,e=window.HTMLMediaElement;b.prototype=Object.create(c.prototype),d(e,b,document.createElement("audio")),a.wrappers.HTMLMediaElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){d.call(this,a)}function c(a){if(!(this instanceof c))throw new TypeError("DOM object constructor cannot be called as a function.");var b=f(document.createElement("audio"));d.call(this,b),g(b,this),b.setAttribute("preload","auto"),void 0!==a&&b.setAttribute("src",a)}var d=a.wrappers.HTMLMediaElement,e=a.registerWrapper,f=a.unwrap,g=a.rewrap,h=window.HTMLAudioElement;b.prototype=Object.create(d.prototype),e(h,b,document.createElement("audio")),c.prototype=b.prototype,a.wrappers.HTMLAudioElement=b,a.wrappers.Audio=c}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){return a.replace(/\s+/g," ").trim()}function c(a){e.call(this,a)}function d(a,b,c,f){if(!(this instanceof d))throw new TypeError("DOM object constructor cannot be called as a function.");var g=i(document.createElement("option"));e.call(this,g),h(g,this),void 0!==a&&(g.text=a),void 0!==b&&g.setAttribute("value",b),c===!0&&g.setAttribute("selected",""),g.selected=f===!0}var e=a.wrappers.HTMLElement,f=a.mixin,g=a.registerWrapper,h=a.rewrap,i=a.unwrap,j=a.wrap,k=window.HTMLOptionElement;c.prototype=Object.create(e.prototype),f(c.prototype,{get text(){return b(this.textContent)},set text(a){this.textContent=b(String(a))},get form(){return j(i(this).form)}}),g(k,c,document.createElement("option")),d.prototype=c.prototype,a.wrappers.HTMLOptionElement=c,a.wrappers.Option=d}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){switch(a.localName){case"content":return new c(a);case"shadow":return new e(a);case"template":return new f(a)}d.call(this,a)}var c=a.wrappers.HTMLContentElement,d=a.wrappers.HTMLElement,e=a.wrappers.HTMLShadowElement,f=a.wrappers.HTMLTemplateElement,g=(a.mixin,a.registerWrapper),h=window.HTMLUnknownElement;b.prototype=Object.create(d.prototype),g(h,b),a.wrappers.HTMLUnknownElement=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrap,f=a.unwrapIfNeeded,g=a.wrap,h=window.CanvasRenderingContext2D;c(b.prototype,{get canvas(){return g(this.impl.canvas)},drawImage:function(){arguments[0]=f(arguments[0]),this.impl.drawImage.apply(this.impl,arguments)},createPattern:function(){return arguments[0]=e(arguments[0]),this.impl.createPattern.apply(this.impl,arguments)}}),d(h,b,document.createElement("canvas").getContext("2d")),a.wrappers.CanvasRenderingContext2D=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.mixin,d=a.registerWrapper,e=a.unwrapIfNeeded,f=a.wrap,g=window.WebGLRenderingContext;if(g){c(b.prototype,{get canvas(){return f(this.impl.canvas)},texImage2D:function(){arguments[5]=e(arguments[5]),this.impl.texImage2D.apply(this.impl,arguments)},texSubImage2D:function(){arguments[6]=e(arguments[6]),this.impl.texSubImage2D.apply(this.impl,arguments)}});var h=/WebKit/.test(navigator.userAgent)?{drawingBufferHeight:null,drawingBufferWidth:null}:{};d(g,b,h),a.wrappers.WebGLRenderingContext=b}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){this.impl=a}var c=a.registerWrapper,d=a.unwrap,e=a.unwrapIfNeeded,f=a.wrap,g=window.Range;b.prototype={get startContainer(){return f(this.impl.startContainer)},get endContainer(){return f(this.impl.endContainer)},get commonAncestorContainer(){return f(this.impl.commonAncestorContainer)},setStart:function(a,b){this.impl.setStart(e(a),b)},setEnd:function(a,b){this.impl.setEnd(e(a),b)},setStartBefore:function(a){this.impl.setStartBefore(e(a))},setStartAfter:function(a){this.impl.setStartAfter(e(a))},setEndBefore:function(a){this.impl.setEndBefore(e(a))},setEndAfter:function(a){this.impl.setEndAfter(e(a))},selectNode:function(a){this.impl.selectNode(e(a))},selectNodeContents:function(a){this.impl.selectNodeContents(e(a))},compareBoundaryPoints:function(a,b){return this.impl.compareBoundaryPoints(a,d(b))},extractContents:function(){return f(this.impl.extractContents())},cloneContents:function(){return f(this.impl.cloneContents())},insertNode:function(a){this.impl.insertNode(e(a))},surroundContents:function(a){this.impl.surroundContents(e(a))},cloneRange:function(){return f(this.impl.cloneRange())},isPointInRange:function(a,b){return this.impl.isPointInRange(e(a),b)},comparePoint:function(a,b){return this.impl.comparePoint(e(a),b)},intersectsNode:function(a){return this.impl.intersectsNode(e(a))}},g.prototype.createContextualFragment&&(b.prototype.createContextualFragment=function(a){return f(this.impl.createContextualFragment(a))}),c(window.Range,b,document.createRange()),a.wrappers.Range=b}(window.ShadowDOMPolyfill),function(a){"use strict";var b=a.GetElementsByInterface,c=a.ParentNodeInterface,d=a.SelectorsInterface,e=a.mixin,f=a.registerObject,g=f(document.createDocumentFragment());e(g.prototype,c),e(g.prototype,d),e(g.prototype,b);var h=f(document.createTextNode("")),i=f(document.createComment(""));a.wrappers.Comment=i,a.wrappers.DocumentFragment=g,a.wrappers.Text=h}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=i(a.impl.ownerDocument.createDocumentFragment());c.call(this,b),g(b,this);var d=a.shadowRoot;k.set(this,d),j.set(this,a)}var c=a.wrappers.DocumentFragment,d=a.elementFromPoint,e=a.getInnerHTML,f=a.mixin,g=a.rewrap,h=a.setInnerHTML,i=a.unwrap,j=new WeakMap,k=new WeakMap;b.prototype=Object.create(c.prototype),f(b.prototype,{get innerHTML(){return e(this)},set innerHTML(a){h(this,a),this.invalidateShadowRenderer()},get olderShadowRoot(){return k.get(this)||null},get host(){return j.get(this)||null},invalidateShadowRenderer:function(){return j.get(this).invalidateShadowRenderer()},elementFromPoint:function(a,b){return d(this,this.ownerDocument,a,b)},getElementById:function(a){return this.querySelector("#"+a)}}),a.wrappers.ShadowRoot=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){a.previousSibling_=a.previousSibling,a.nextSibling_=a.nextSibling,a.parentNode_=a.parentNode}function c(a,c,e){var f=F(a),g=F(c),h=e?F(e):null;if(d(c),b(c),e)a.firstChild===e&&(a.firstChild_=e),e.previousSibling_=e.previousSibling;else{a.lastChild_=a.lastChild,a.lastChild===a.firstChild&&(a.firstChild_=a.firstChild);var i=G(f.lastChild);i&&(i.nextSibling_=i.nextSibling)}f.insertBefore(g,h)}function d(a){var c=F(a),d=c.parentNode;if(d){var e=G(d);b(a),a.previousSibling&&(a.previousSibling.nextSibling_=a),a.nextSibling&&(a.nextSibling.previousSibling_=a),e.lastChild===a&&(e.lastChild_=a),e.firstChild===a&&(e.firstChild_=a),d.removeChild(c)}}function e(a,b){g(b).push(a),x(a,b);var c=I.get(a);c||I.set(a,c=[]),c.push(b)}function f(a){H.set(a,[])}function g(a){return H.get(a)}function h(a){for(var b=[],c=0,d=a.firstChild;d;d=d.nextSibling)b[c++]=d;return b}function i(a,b,c){for(var d=a.firstChild;d;d=d.nextSibling)if(b(d)){if(c(d)===!1)return}else i(d,b,c)}function j(a,b){var c=b.getAttribute("select");if(!c)return!0;if(c=c.trim(),!c)return!0;if(!(a instanceof z))return!1;if(!L.test(c))return!1;if(":"===c[0]&&!M.test(c))return!1;try{return a.matches(c)}catch(d){return!1}}function k(){for(var a=0;a<O.length;a++)O[a].render();O=[]}function l(){y=null,k()}function m(a){var b=K.get(a);return b||(b=new q(a),K.set(a,b)),b}function n(a){for(;a;a=a.parentNode)if(a instanceof D)return a;return null}function o(a){return m(a.host)}function p(a){this.skip=!1,this.node=a,this.childNodes=[]}function q(a){this.host=a,this.dirty=!1,this.invalidateAttributes(),this.associateNode(a)}function r(a){return a instanceof A}function s(a){return a instanceof A}function t(a){return a instanceof B}function u(a){return a instanceof B}function v(a){return a.shadowRoot}function w(a){for(var b=[],c=a.shadowRoot;c;c=c.olderShadowRoot)b.push(c);return b}function x(a,b){J.set(a,b)}var y,z=a.wrappers.Element,A=a.wrappers.HTMLContentElement,B=a.wrappers.HTMLShadowElement,C=a.wrappers.Node,D=a.wrappers.ShadowRoot,E=(a.assert,a.mixin,a.oneOf),F=a.unwrap,G=a.wrap,H=new WeakMap,I=new WeakMap,J=new WeakMap,K=new WeakMap,L=/^[*.:#[a-zA-Z_|]/,M=new RegExp("^:("+["link","visited","target","enabled","disabled","checked","indeterminate","nth-child","nth-last-child","nth-of-type","nth-last-of-type","first-child","last-child","first-of-type","last-of-type","only-of-type"].join("|")+")"),N=E(window,["requestAnimationFrame","mozRequestAnimationFrame","webkitRequestAnimationFrame","setTimeout"]),O=[],P=new ArraySplice;P.equals=function(a,b){return F(a.node)===b},p.prototype={append:function(a){var b=new p(a);return this.childNodes.push(b),b},sync:function(a){if(!this.skip){for(var b=this.node,e=this.childNodes,f=h(F(b)),g=a||new WeakMap,i=P.calculateSplices(e,f),j=0,k=0,l=0,m=0;m<i.length;m++){for(var n=i[m];l<n.index;l++)k++,e[j++].sync(g);for(var o=n.removed.length,p=0;o>p;p++){var q=G(f[k++]);g.get(q)||d(q)}for(var r=n.addedCount,s=f[k]&&G(f[k]),p=0;r>p;p++){var t=e[j++],u=t.node;c(b,u,s),g.set(u,!0),t.sync(g)}l+=r}for(var m=l;m<e.length;m++)e[m].sync(g)}}},q.prototype={render:function(a){if(this.dirty){this.invalidateAttributes(),this.treeComposition();var b=this.host,c=b.shadowRoot;this.associateNode(b);for(var d=!e,e=a||new p(b),f=c.firstChild;f;f=f.nextSibling)this.renderNode(c,e,f,!1);d&&e.sync(),this.dirty=!1}},invalidate:function(){if(!this.dirty){if(this.dirty=!0,O.push(this),y)return;y=window[N](l,0)}},renderNode:function(a,b,c,d){if(v(c)){b=b.append(c);var e=m(c);e.dirty=!0,e.render(b)}else r(c)?this.renderInsertionPoint(a,b,c,d):t(c)?this.renderShadowInsertionPoint(a,b,c):this.renderAsAnyDomTree(a,b,c,d)},renderAsAnyDomTree:function(a,b,c,d){if(b=b.append(c),v(c)){var e=m(c);b.skip=!e.dirty,e.render(b)}else for(var f=c.firstChild;f;f=f.nextSibling)this.renderNode(a,b,f,d)},renderInsertionPoint:function(a,b,c,d){var e=g(c);if(e.length){this.associateNode(c);for(var f=0;f<e.length;f++){var h=e[f];r(h)&&d?this.renderInsertionPoint(a,b,h,d):this.renderAsAnyDomTree(a,b,h,d)}}else this.renderFallbackContent(a,b,c);this.associateNode(c.parentNode)},renderShadowInsertionPoint:function(a,b,c){var d=a.olderShadowRoot;if(d){x(d,c),this.associateNode(c.parentNode);for(var e=d.firstChild;e;e=e.nextSibling)this.renderNode(d,b,e,!0)}else this.renderFallbackContent(a,b,c)},renderFallbackContent:function(a,b,c){this.associateNode(c),this.associateNode(c.parentNode);for(var d=c.firstChild;d;d=d.nextSibling)this.renderAsAnyDomTree(a,b,d,!1)},invalidateAttributes:function(){this.attributes=Object.create(null)},updateDependentAttributes:function(a){if(a){var b=this.attributes;/\.\w+/.test(a)&&(b["class"]=!0),/#\w+/.test(a)&&(b.id=!0),a.replace(/\[\s*([^\s=\|~\]]+)/g,function(a,c){b[c]=!0})}},dependsOnAttribute:function(a){return this.attributes[a]},distribute:function(a,b){var c=this;i(a,s,function(a){f(a),c.updateDependentAttributes(a.getAttribute("select"));for(var d=0;d<b.length;d++){var g=b[d];void 0!==g&&j(g,a)&&(e(g,a),b[d]=void 0)}})},treeComposition:function(){for(var a=this.host,b=a.shadowRoot,c=[],d=a.firstChild;d;d=d.nextSibling)if(r(d)){var e=g(d);e&&e.length||(e=h(d)),c.push.apply(c,e)}else c.push(d);for(var f,j;b;){if(f=void 0,i(b,u,function(a){return f=a,!1}),j=f,this.distribute(b,c),j){var k=b.olderShadowRoot;if(k){b=k,x(b,j);continue}break}break}},associateNode:function(a){a.impl.polymerShadowRenderer_=this}},C.prototype.invalidateShadowRenderer=function(){var a=this.impl.polymerShadowRenderer_;return a?(a.invalidate(),!0):!1},A.prototype.getDistributedNodes=function(){return k(),g(this)},B.prototype.nodeIsInserted_=A.prototype.nodeIsInserted_=function(){this.invalidateShadowRenderer();var a,b=n(this);b&&(a=o(b)),this.impl.polymerShadowRenderer_=a,a&&a.invalidate()},a.eventParentsTable=I,a.getRendererForHost=m,a.getShadowTrees=w,a.insertionParentTable=J,a.renderAllPending=k,a.visual={insertBefore:c,remove:d}}(window.ShadowDOMPolyfill),function(a){"use strict";function b(b){if(window[b]){d(!a.wrappers[b]);var i=function(a){c.call(this,a)};i.prototype=Object.create(c.prototype),e(i.prototype,{get form(){return h(g(this).form)}}),f(window[b],i,document.createElement(b.slice(4,-7))),a.wrappers[b]=i}}var c=a.wrappers.HTMLElement,d=a.assert,e=a.mixin,f=a.registerWrapper,g=a.unwrap,h=a.wrap,i=["HTMLButtonElement","HTMLFieldSetElement","HTMLInputElement","HTMLKeygenElement","HTMLLabelElement","HTMLLegendElement","HTMLObjectElement","HTMLOutputElement","HTMLSelectElement","HTMLTextAreaElement"];i.forEach(b)}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){k.call(this,a)}function c(a){var c=document[a];b.prototype[a]=function(){return v(c.apply(this.impl,arguments))}}function d(a,b){y.call(b.impl,u(a)),e(a,b)}function e(a,b){a.shadowRoot&&b.adoptNode(a.shadowRoot),a instanceof n&&f(a,b);for(var c=a.firstChild;c;c=c.nextSibling)e(c,b)}function f(a,b){var c=a.olderShadowRoot;c&&b.adoptNode(c)}function g(a){this.impl=a}function h(a,b){var c=document.implementation[b];a.prototype[b]=function(){return v(c.apply(this.impl,arguments))}}function i(a,b){var c=document.implementation[b];a.prototype[b]=function(){return c.apply(this.impl,arguments)}}var j=a.GetElementsByInterface,k=a.wrappers.Node,l=a.ParentNodeInterface,m=a.SelectorsInterface,n=a.wrappers.ShadowRoot,o=a.defineWrapGetter,p=a.elementFromPoint,q=a.forwardMethodsToWrapper,r=a.matchesName,s=a.mixin,t=a.registerWrapper,u=a.unwrap,v=a.wrap,w=a.wrapEventTargetMethods,x=(a.wrapNodeList,new WeakMap);b.prototype=Object.create(k.prototype),o(b,"documentElement"),o(b,"body"),o(b,"head"),["createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","getElementById"].forEach(c);var y=document.adoptNode,z=document.importNode;if(s(b.prototype,{adoptNode:function(a){return a.parentNode&&a.parentNode.removeChild(a),d(a,this),a},elementFromPoint:function(a,b){return p(this,this,a,b)},importNode:function(a,b){var c=v(z.call(this.impl,u(a),!1));if(b)for(var d=a.firstChild;d;d=d.nextSibling)c.appendChild(this.importNode(d,!0));return c}}),document.register){var A=document.register;b.prototype.register=function(b,c){function d(a){return a?(this.impl=a,void 0):c.extends?document.createElement(c.extends,b):document.createElement(b)}var e=c.prototype;if(a.nativePrototypeTable.get(e))throw new Error("NotSupportedError");for(var f,g=Object.getPrototypeOf(e),h=[];g&&!(f=a.nativePrototypeTable.get(g));)h.push(g),g=Object.getPrototypeOf(g);if(!f)throw new Error("NotSupportedError");for(var i=Object.create(f),j=h.length-1;j>=0;j--)i=Object.create(i);["createdCallback","enteredViewCallback","leftViewCallback","attributeChangedCallback"].forEach(function(a){var b=e[a];b&&(i[a]=function(){b.apply(v(this),arguments)})});var k={prototype:i};c.extends&&(k.extends=c.extends);A.call(u(this),b,k);return d.prototype=e,d.prototype.constructor=d,a.constructorTable.set(i,d),a.nativePrototypeTable.set(e,i),d},q([window.HTMLDocument||window.Document],["register"])}q([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement,window.HTMLHtmlElement],["appendChild","compareDocumentPosition","contains","getElementsByClassName","getElementsByTagName","getElementsByTagNameNS","insertBefore","querySelector","querySelectorAll","removeChild","replaceChild",r]),q([window.HTMLDocument||window.Document],["adoptNode","importNode","contains","createComment","createDocumentFragment","createElement","createElementNS","createEvent","createEventNS","createRange","createTextNode","elementFromPoint","getElementById"]),s(b.prototype,j),s(b.prototype,l),s(b.prototype,m),s(b.prototype,{get implementation(){var a=x.get(this);return a?a:(a=new g(u(this).implementation),x.set(this,a),a)}}),t(window.Document,b,document.implementation.createHTMLDocument("")),window.HTMLDocument&&t(window.HTMLDocument,b),w([window.HTMLBodyElement,window.HTMLDocument||window.Document,window.HTMLHeadElement]),h(g,"createDocumentType"),h(g,"createDocument"),h(g,"createHTMLDocument"),i(g,"hasFeature"),t(window.DOMImplementation,g),q([window.DOMImplementation],["createDocumentType","createDocument","createHTMLDocument","hasFeature"]),a.adoptNodeNoRemove=d,a.wrappers.DOMImplementation=g,a.wrappers.Document=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){c.call(this,a)}var c=a.wrappers.EventTarget,d=a.mixin,e=a.registerWrapper,f=a.unwrap,g=a.unwrapIfNeeded,h=a.wrap,i=a.renderAllPending,j=window.Window;b.prototype=Object.create(c.prototype);var k=window.getComputedStyle;j.prototype.getComputedStyle=function(a,b){return i(),k.call(this||window,g(a),b)},["addEventListener","removeEventListener","dispatchEvent"].forEach(function(a){j.prototype[a]=function(){var b=h(this||window);return b[a].apply(b,arguments)}}),d(b.prototype,{getComputedStyle:function(a,b){return k.call(f(this),g(a),b)}}),e(j,b),a.wrappers.Window=b}(window.ShadowDOMPolyfill),function(a){"use strict";function b(a){var b=c[a],d=window[b];if(d){var e=document.createElement(a),f=e.constructor;window[b]=f}}var c=(a.isWrapperFor,{a:"HTMLAnchorElement",applet:"HTMLAppletElement",area:"HTMLAreaElement",br:"HTMLBRElement",base:"HTMLBaseElement",body:"HTMLBodyElement",button:"HTMLButtonElement",dl:"HTMLDListElement",datalist:"HTMLDataListElement",data:"HTMLDataElement",dir:"HTMLDirectoryElement",div:"HTMLDivElement",embed:"HTMLEmbedElement",fieldset:"HTMLFieldSetElement",font:"HTMLFontElement",form:"HTMLFormElement",frame:"HTMLFrameElement",frameset:"HTMLFrameSetElement",hr:"HTMLHRElement",head:"HTMLHeadElement",h1:"HTMLHeadingElement",html:"HTMLHtmlElement",iframe:"HTMLIFrameElement",input:"HTMLInputElement",li:"HTMLLIElement",label:"HTMLLabelElement",legend:"HTMLLegendElement",link:"HTMLLinkElement",map:"HTMLMapElement",marquee:"HTMLMarqueeElement",menu:"HTMLMenuElement",menuitem:"HTMLMenuItemElement",meta:"HTMLMetaElement",meter:"HTMLMeterElement",del:"HTMLModElement",ol:"HTMLOListElement",object:"HTMLObjectElement",optgroup:"HTMLOptGroupElement",option:"HTMLOptionElement",output:"HTMLOutputElement",p:"HTMLParagraphElement",param:"HTMLParamElement",pre:"HTMLPreElement",progress:"HTMLProgressElement",q:"HTMLQuoteElement",script:"HTMLScriptElement",select:"HTMLSelectElement",source:"HTMLSourceElement",span:"HTMLSpanElement",style:"HTMLStyleElement",time:"HTMLTimeElement",caption:"HTMLTableCaptionElement",col:"HTMLTableColElement",table:"HTMLTableElement",tr:"HTMLTableRowElement",thead:"HTMLTableSectionElement",tbody:"HTMLTableSectionElement",textarea:"HTMLTextAreaElement",track:"HTMLTrackElement",title:"HTMLTitleElement",ul:"HTMLUListElement",video:"HTMLVideoElement"});
+Object.keys(c).forEach(b),Object.getOwnPropertyNames(a.wrappers).forEach(function(b){window[b]=a.wrappers[b]}),a.knownElements=c}(window.ShadowDOMPolyfill),function(){{var a=window.ShadowDOMPolyfill;a.wrap}Object.defineProperties(HTMLElement.prototype,{webkitShadowRoot:{get:function(){return this.shadowRoot}}}),HTMLElement.prototype.webkitCreateShadowRoot=HTMLElement.prototype.createShadowRoot,window.dartExperimentalFixupGetTag=function(b){function c(a){if(a instanceof d)return"NodeList";if(a instanceof e)return"ShadowRoot";if(window.MutationRecord&&a instanceof MutationRecord)return"MutationRecord";if(window.MutationObserver&&a instanceof MutationObserver)return"MutationObserver";if(a instanceof HTMLTemplateElement)return"HTMLTemplateElement";var c=f(a);if(a!==c){var g=a.constructor;if(g===c.constructor){var h=g._ShadowDOMPolyfill$cacheTag_;return h||(h=Object.prototype.toString.call(c),h=h.substring(8,h.length-1),g._ShadowDOMPolyfill$cacheTag_=h),h}a=c}return b(a)}var d=a.wrappers.NodeList,e=a.wrappers.ShadowRoot,f=a.unwrapIfNeeded;return c}}();var Platform={};!function(a){function b(a,b){var c="";return Array.prototype.forEach.call(a,function(a){c+=a.textContent+"\n\n"}),b||(c=c.replace(n,"")),c}function c(a){var b=document.createElement("style");return b.textContent=a,b}function d(a){var b=c(a);document.head.appendChild(b);var d=b.sheet.cssRules;return b.parentNode.removeChild(b),d}function e(a){for(var b=0,c=[];b<a.length;b++)c.push(a[b].cssText);return c.join("\n\n")}function f(a){a&&g().appendChild(document.createTextNode(a))}function g(){return h||(h=document.createElement("style"),h.setAttribute("ShadowCSSShim","")),h}var h,i={strictStyling:!1,registry:{},shimStyling:function(a,b,d){var e=this.isTypeExtension(d),g=this.registerDefinition(a,b,d);this.strictStyling&&this.applyScopeToContent(a,b),this.insertPolyfillDirectives(g.rootStyles),this.insertPolyfillRules(g.rootStyles);var h=this.stylesToShimmedCssText(g.scopeStyles,b,e);h+=this.extractPolyfillUnscopedRules(g.rootStyles),g.shimmedStyle=c(h),a&&(a.shimmedStyle=g.shimmedStyle);for(var i,j=0,k=g.rootStyles.length;k>j&&(i=g.rootStyles[j]);j++)i.parentNode.removeChild(i);f(h)},registerDefinition:function(a,b,c){var d=this.registry[b]={root:a,name:b,extendsName:c},e=a?a.querySelectorAll("style"):[];e=e?Array.prototype.slice.call(e,0):[],d.rootStyles=e,d.scopeStyles=d.rootStyles;var f=this.registry[d.extendsName];return!f||a&&!a.querySelector("shadow")||(d.scopeStyles=f.scopeStyles.concat(d.scopeStyles)),d},isTypeExtension:function(a){return a&&a.indexOf("-")<0},applyScopeToContent:function(a,b){a&&(Array.prototype.forEach.call(a.querySelectorAll("*"),function(a){a.setAttribute(b,"")}),Array.prototype.forEach.call(a.querySelectorAll("template"),function(a){this.applyScopeToContent(a.content,b)},this))},insertPolyfillDirectives:function(a){a&&Array.prototype.forEach.call(a,function(a){a.textContent=this.insertPolyfillDirectivesInCssText(a.textContent)},this)},insertPolyfillDirectivesInCssText:function(a){return a.replace(o,function(a,b){return b.slice(0,-2)+"{"})},insertPolyfillRules:function(a){a&&Array.prototype.forEach.call(a,function(a){a.textContent=this.insertPolyfillRulesInCssText(a.textContent)},this)},insertPolyfillRulesInCssText:function(a){return a.replace(p,function(a,b){return b.slice(0,-1)})},extractPolyfillUnscopedRules:function(a){var b="";return a&&Array.prototype.forEach.call(a,function(a){b+=this.extractPolyfillUnscopedRulesFromCssText(a.textContent)+"\n\n"},this),b},extractPolyfillUnscopedRulesFromCssText:function(a){for(var b,c="";b=q.exec(a);)c+=b[1].slice(0,-1)+"\n\n";return c},stylesToShimmedCssText:function(a,b,c){return this.shimAtHost(a,b,c)+this.shimScoping(a,b,c)},shimAtHost:function(a,b,c){return a?this.convertAtHostStyles(a,b,c):void 0},convertAtHostStyles:function(a,c,f){var g=b(a),h=this;return g=g.replace(j,function(a,b){return h.scopeHostCss(b,c,f)}),g=e(this.findAtHostRules(d(g),this.makeScopeMatcher(c,f)))},scopeHostCss:function(a,b,c){var d=this;return a.replace(k,function(a,e,f){return d.scopeHostSelector(e,b,c)+" "+f+"\n	"})},scopeHostSelector:function(a,b,c){var d=[],e=a.split(","),f="[is="+b+"]";return e.forEach(function(a){a=a.trim(),a.match(l)?a=a.replace(l,c?f+"$1$3":b+"$1$3"):a.match(m)&&(a=c?f+a:b+a),d.push(a)},this),d.join(", ")},findAtHostRules:function(a,b){return Array.prototype.filter.call(a,this.isHostRule.bind(this,b))},isHostRule:function(a,b){return b.selectorText&&b.selectorText.match(a)||b.cssRules&&this.findAtHostRules(b.cssRules,a).length||b.type==CSSRule.WEBKIT_KEYFRAMES_RULE},shimScoping:function(a,b,c){return a?this.convertScopedStyles(a,b,c):void 0},convertScopedStyles:function(a,c,e){var f=b(a).replace(j,"");f=this.insertPolyfillHostInCssText(f),f=this.convertColonHost(f),f=this.convertPseudos(f),f=this.convertParts(f),f=this.convertCombinators(f);var g=d(f);return f=this.scopeRules(g,c,e)},convertPseudos:function(a){return a.replace(r," [pseudo=$1]")},convertParts:function(a){return a.replace(s," [part=$1]")},convertColonHost:function(a){return a.replace(u,function(a,b,c,d){if(b=y,c){for(var e,f=c.split(","),g=[],h=0,i=f.length;i>h&&(e=f[h]);h++)e=e.trim(),e.match(t)?g.push(b+e.replace(t,"")+d):g.push(b+e+d+", "+e+" "+b+d);return g.join(",")}return b+d})},convertCombinators:function(a){return a.replace(/\^\^/g," ").replace(/\^/g," ")},scopeRules:function(a,b,c){var d="";return Array.prototype.forEach.call(a,function(a){a.selectorText&&a.style&&a.style.cssText?(d+=this.scopeSelector(a.selectorText,b,c,this.strictStyling)+" {\n	",d+=this.propertiesFromRule(a)+"\n}\n\n"):a.media?(d+="@media "+a.media.mediaText+" {\n",d+=this.scopeRules(a.cssRules,b,c),d+="\n}\n\n"):a.cssText&&(d+=a.cssText+"\n\n")},this),d},scopeSelector:function(a,b,c,d){var e=[],f=a.split(",");return f.forEach(function(a){a=a.trim(),this.selectorNeedsScoping(a,b,c)&&(a=d&&!a.match(y)?this.applyStrictSelectorScope(a,b):this.applySimpleSelectorScope(a,b,c)),e.push(a)},this),e.join(", ")},selectorNeedsScoping:function(a,b,c){var d=this.makeScopeMatcher(b,c);return!a.match(d)},makeScopeMatcher:function(a,b){var c=b?"\\[is=['\"]?"+a+"['\"]?\\]":a;return new RegExp("^("+c+")"+v,"m")},applySimpleSelectorScope:function(a,b,c){var d=c?"[is="+b+"]":b;return a.match(z)?(a=a.replace(y,d),a.replace(z,d+" ")):d+" "+a},applyStrictSelectorScope:function(a,b){var c=[" ",">","+","~"],d=a,e="["+b+"]";return c.forEach(function(a){var b=d.split(a);d=b.map(function(a){var b=a.trim().replace(z,"");return b&&c.indexOf(b)<0&&b.indexOf(e)<0&&(a=b.replace(/([^:]*)(:*)(.*)/,"$1"+e+"$2$3")),a}).join(a)}),d},insertPolyfillHostInCssText:function(a){return a.replace(w,t).replace(x,t)},propertiesFromRule:function(a){return a.style.cssText}},j=/@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,k=/([^{]*)({[\s\S]*?})/gim,l=/(.*)((?:\*)|(?:\:scope))(.*)/,m=/^[.\[:]/,n=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,o=/\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,p=/\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,q=/\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,r=/::(x-[^\s{,(]*)/gim,s=/::part\(([^)]*)\)/gim,t="-shadowcsshost",u=new RegExp("("+t+")(?:\\(((?:\\([^)(]*\\)|[^)(]*)+?)\\))?([^,{]*)","gim"),v="([>\\s~+[.,{:][\\s\\S]*)?$",w=/@host/gim,x=/\:host/gim,y=t+"-no-combinator",z=new RegExp(t,"gim");if(window.ShadowDOMPolyfill){f("style { display: none !important; }\n");var A=document.querySelector("head");A.insertBefore(g(),A.childNodes[0])}a.ShadowCSS=i}(window.Platform)}
\ No newline at end of file
diff --git a/pkg/shadow_dom/pubspec.yaml b/pkg/shadow_dom/pubspec.yaml
index 358945b..0c3bb3e 100644
--- a/pkg/shadow_dom/pubspec.yaml
+++ b/pkg/shadow_dom/pubspec.yaml
@@ -1,5 +1,5 @@
 name: shadow_dom
-version: 0.9.1-dev
+version: 0.9.1
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 homepage: https://www.dartlang.org/polymer-dart/
 description: >
@@ -9,4 +9,4 @@
   within a document, thus enabling better functional encapsulation within the
   DOM.
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/shadow_dom/tool/build.json b/pkg/shadow_dom/tool/build.json
index 8c2b7be..76e4ec4 100644
--- a/pkg/shadow_dom/tool/build.json
+++ b/pkg/shadow_dom/tool/build.json
@@ -4,6 +4,6 @@
   "../../../third_party/polymer/ShadowDOM/build.json",
   "../lib/src/platform/patches-shadowdom-polyfill.js",
   "../lib/src/platform/platform-init.js",
-  "../../../third_party/polymer/platform/src/ShadowCSS.js",
+  "../../../third_party/polymer/platform-dev/src/ShadowCSS.js",
   "build/end-if.js"
 ]
diff --git a/pkg/shadow_dom/tool/build.sh b/pkg/shadow_dom/tool/build.sh
index 10cd859..f10e8c2 100755
--- a/pkg/shadow_dom/tool/build.sh
+++ b/pkg/shadow_dom/tool/build.sh
@@ -18,7 +18,7 @@
 
 NEWLINE=$'\n'
 REVISIONS=""
-for NAME in ShadowDOM observe-js WeakMap platform; do
+for NAME in ShadowDOM observe-js WeakMap platform-dev; do
   GIT_REMOTE="$POLYMER_REMOTE/$NAME.git"
   GIT_DIR="$POLYMER_DIR/$NAME"
   echo "*** Syncing $GIT_DIR from $GIT_REMOTE"
diff --git a/pkg/stack_trace/lib/src/chain.dart b/pkg/stack_trace/lib/src/chain.dart
new file mode 100644
index 0000000..f6e2f3f
--- /dev/null
+++ b/pkg/stack_trace/lib/src/chain.dart
@@ -0,0 +1,173 @@
+// 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 stack_trace.chain;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'stack_zone_specification.dart';
+import 'trace.dart';
+import 'utils.dart';
+
+/// A function that handles errors in the zone wrapped by [Chain.capture].
+typedef void ChainHandler(error, Chain chain);
+
+/// A chain of stack traces.
+///
+/// A stack chain is a collection of one or more stack traces that collectively
+/// represent the path from [main] through nested function calls to a particular
+/// code location, usually where an error was thrown. Multiple stack traces are
+/// necessary when using asynchronous functions, since the program's stack is
+/// reset before each asynchronous callback is run.
+///
+/// Stack chains can be automatically tracked using [Chain.capture]. This sets
+/// up a new [Zone] in which the current stack chain is tracked and can be
+/// accessed using [new Chain.current]. Any errors that would be top-leveled in
+/// the zone can be handled, along with their associated chains, with the
+/// `onError` callback.
+///
+/// For the most part [Chain.capture] will notice when an error is thrown and
+/// associate the correct stack chain with it; the chain can be accessed using
+/// [new Chain.forTrace]. However, there are some cases where exceptions won't
+/// be automatically detected: any [Future] constructor,
+/// [Completer.completeError], [Stream.addError], and libraries that use these.
+/// For these, all you need to do is wrap the Future or Stream in a call to
+/// [Chain.track] and the errors will be tracked correctly.
+class Chain implements StackTrace {
+  /// The line used in the string representation of stack chains to represent
+  /// the gap between traces.
+  static const _GAP = '===== asynchronous gap ===========================\n';
+
+  /// The stack traces that make up this chain.
+  ///
+  /// Like the frames in a stack trace, the traces are ordered from most local
+  /// to least local. The first one is the trace where the actual exception was
+  /// raised, the second one is where that callback was scheduled, and so on.
+  final List<Trace> traces;
+
+  /// The [StackZoneSpecification] for the current zone.
+  static StackZoneSpecification get _currentSpec =>
+    Zone.current[#stack_trace.stack_zone.spec];
+
+  /// Runs [callback] in a [Zone] in which the current stack chain is tracked
+  /// and automatically associated with (most) errors.
+  ///
+  /// If [onError] is passed, any error in the zone that would otherwise go
+  /// unhandled is passed to it, along with the [Chain] associated with that
+  /// error. Note that if [callback] produces multiple unhandled errors,
+  /// [onError] may be called more than once. If [onError] isn't passed, the
+  /// parent Zone's `unhandledErrorHandler` will be called with the error and
+  /// its chain.
+  ///
+  /// For the most part an error thrown in the zone will have the correct stack
+  /// chain associated with it. However, there are some cases where exceptions
+  /// won't be automatically detected: any [Future] constructor,
+  /// [Completer.completeError], [Stream.addError], and libraries that use
+  /// these. For these, all you need to do is wrap the Future or Stream in a
+  /// call to [Chain.track] and the errors will be tracked correctly.
+  ///
+  /// Note that even if [onError] isn't passed, this zone will still be an error
+  /// zone. This means that any errors that would cross the zone boundary are
+  /// considered unhandled.
+  ///
+  /// If [callback] returns a value, it will be returned by [capture] as well.
+  ///
+  /// Currently, capturing stack chains doesn't work when using dart2js due to
+  /// issues [15171] and [15105]. Stack chains reported on dart2js will contain
+  /// only one trace.
+  ///
+  /// [15171]: https://code.google.com/p/dart/issues/detail?id=15171
+  /// [15105]: https://code.google.com/p/dart/issues/detail?id=15105
+  static capture(callback(), {ChainHandler onError}) {
+    var spec = new StackZoneSpecification(onError);
+    return runZoned(callback, zoneSpecification: spec.toSpec(), zoneValues: {
+      #stack_trace.stack_zone.spec: spec
+    });
+  }
+
+  /// Ensures that any errors emitted by [futureOrStream] have the correct stack
+  /// chain information associated with them.
+  ///
+  /// For the most part an error thrown within a [capture] zone will have the
+  /// correct stack chain automatically associated with it. However, there are
+  /// some cases where exceptions won't be automatically detected: any [Future]
+  /// constructor, [Completer.completeError], [Stream.addError], and libraries
+  /// that use these.
+  ///
+  /// This returns a [Future] or [Stream] that will emit the same values and
+  /// errors as [futureOrStream]. The only exception is that if [futureOrStream]
+  /// emits an error without a stack trace, one will be added in the return
+  /// value.
+  ///
+  /// If this is called outside of a [capture] zone, it just returns
+  /// [futureOrStream] as-is.
+  ///
+  /// As the name suggests, [futureOrStream] may be either a [Future] or a
+  /// [Stream].
+  static track(futureOrStream) {
+    if (_currentSpec == null) return futureOrStream;
+    if (futureOrStream is Future) {
+      return _currentSpec.trackFuture(futureOrStream, 1);
+    } else {
+      return _currentSpec.trackStream(futureOrStream, 1);
+    }
+  }
+
+  /// Returns the current stack chain.
+  ///
+  /// By default, the first frame of the first trace will be the line where
+  /// [Chain.current] is called. If [level] is passed, the first trace will
+  /// start that many frames up instead.
+  ///
+  /// If this is called outside of a [capture] zone, it just returns a
+  /// single-trace chain.
+  factory Chain.current([int level=0]) {
+    if (_currentSpec != null) return _currentSpec.currentChain(level + 1);
+    return new Chain([new Trace.current(level + 1)]);
+  }
+
+  /// Returns the stack chain associated with [trace].
+  ///
+  /// The first stack trace in the returned chain will always be [trace]
+  /// (converted to a [Trace] if necessary). If there is no chain associated
+  /// with [trace] or if this is called outside of a [capture] zone, this just
+  /// returns a single-trace chain containing [trace].
+  ///
+  /// If [trace] is already a [Chain], it will be returned as-is.
+  factory Chain.forTrace(StackTrace trace) {
+    if (trace is Chain) return trace;
+    if (_currentSpec == null) return new Chain([new Trace.from(trace)]);
+    return _currentSpec.chainFor(trace);
+  }
+
+  /// Parses a string representation of a stack chain.
+  ///
+  /// Specifically, this parses the output of [Chain.toString].
+  factory Chain.parse(String chain) =>
+    new Chain(chain.split(_GAP).map((trace) => new Trace.parseFriendly(trace)));
+
+  /// Returns a new [Chain] comprised of [traces].
+  Chain(Iterable<Trace> traces)
+      : traces = new UnmodifiableListView<Trace>(traces.toList());
+
+  /// Returns a terser version of [this].
+  ///
+  /// This calls [Trace.terse] on every trace in [traces], and discards any
+  /// trace that contain only internal frames.
+  Chain get terse {
+    return new Chain(traces.map((trace) => trace.terse).where((trace) {
+      // Ignore traces that contain only internal processing.
+      return trace.frames.length > 1;
+    }));
+  }
+
+  /// Converts [this] to a [Trace].
+  ///
+  /// The trace version of a chain is just the concatenation of all the traces
+  /// in the chain.
+  Trace toTrace() => new Trace(flatten(traces.map((trace) => trace.frames)));
+
+  String toString() => traces.join(_GAP);
+}
diff --git a/pkg/stack_trace/lib/src/stack_zone_specification.dart b/pkg/stack_trace/lib/src/stack_zone_specification.dart
new file mode 100644
index 0000000..36e0717
--- /dev/null
+++ b/pkg/stack_trace/lib/src/stack_zone_specification.dart
@@ -0,0 +1,205 @@
+// 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 stack_trace.stack_zone_specification;
+
+import 'dart:async';
+
+import 'trace.dart';
+import 'chain.dart';
+
+/// A class encapsulating the zone specification for a [Chain.capture] zone.
+///
+/// Until they're materialized and exposed to the user, stack chains are tracked
+/// as linked lists of [Trace]s using the [_Node] class. These nodes are stored
+/// in three distinct ways:
+///
+/// * When a callback is registered, a node is created and stored as a captured
+///   local variable until the callback is run.
+///
+/// * When a callback is run, its captured node is set as the [_currentNode] so
+///   it can be available to [Chain.current] and to be linked into additional
+///   chains when more callbacks are scheduled.
+///
+/// * When a callback throws an error or a [Chain.track]ed Future or Stream
+///   emits an error, the current node is associated with that error's stack
+///   trace using the [_chains] expando.
+///
+/// Since [ZoneSpecification] can't be extended or even implemented, in order to
+/// get a real [ZoneSpecification] instance it's necessary to call [toSpec].
+class StackZoneSpecification {
+  /// The expando that associates stack chains with [StackTrace]s.
+  ///
+  /// The chains are associated with stack traces rather than errors themselves
+  /// because it's a common practice to throw strings as errors, which can't be
+  /// used with expandos.
+  ///
+  /// The chain associated with a given stack trace doesn't contain a node for
+  /// that stack trace.
+  final _chains = new Expando<_Node>("stack chains");
+
+  /// The error handler for the zone.
+  ///
+  /// If this is null, that indicates that any unhandled errors should be passed
+  /// to the parent zone.
+  final ChainHandler _onError;
+
+  /// The most recent node of the current stack chain.
+  _Node _currentNode;
+
+  StackZoneSpecification([this._onError]);
+
+  /// Converts [this] to a real [ZoneSpecification].
+  ZoneSpecification toSpec() {
+    return new ZoneSpecification(
+        handleUncaughtError: handleUncaughtError,
+        registerCallback: registerCallback,
+        registerUnaryCallback: registerUnaryCallback,
+        registerBinaryCallback: registerBinaryCallback);
+  }
+
+  /// Returns the current stack chain.
+  ///
+  /// By default, the first frame of the first trace will be the line where
+  /// [currentChain] is called. If [level] is passed, the first trace will start
+  /// that many frames up instead.
+  Chain currentChain([int level=0]) => _createNode(level + 1).toChain();
+
+  /// Returns the stack chain associated with [trace], if one exists.
+  ///
+  /// The first stack trace in the returned chain will always be [trace]
+  /// (converted to a [Trace] if necessary). If there is no chain associated
+  /// with [trace], this just returns a single-trace chain containing [trace].
+  Chain chainFor(StackTrace trace) {
+    if (trace is Chain) return trace;
+    var previous = trace == null ? null : _chains[trace];
+    return new _Node(trace, previous).toChain();
+  }
+
+  /// Ensures that an error emitted by [future] has the correct stack
+  /// information associated with it.
+  ///
+  /// By default, the first frame of the first trace will be the line where
+  /// [trackFuture] is called. If [level] is passed, the first trace will start
+  /// that many frames up instead.
+  Future trackFuture(Future future, [int level=0]) {
+    var completer = new Completer.sync();
+    var node = _createNode(level + 1);
+    future.then(completer.complete).catchError((e, stackTrace) {
+      if (stackTrace == null) stackTrace = new Trace.current();
+      if (_chains[stackTrace] == null) _chains[stackTrace] = node;
+      completer.completeError(e, stackTrace);
+    });
+    return completer.future;
+  }
+
+  /// Ensures that any errors emitted by [stream] have the correct stack
+  /// information associated with them.
+  ///
+  /// By default, the first frame of the first trace will be the line where
+  /// [trackStream] is called. If [level] is passed, the first trace will start
+  /// that many frames up instead.
+  Stream trackStream(Stream stream, [int level=0]) {
+    var node = _createNode(level + 1);
+    return stream.transform(new StreamTransformer.fromHandlers(
+        handleError: (error, stackTrace, sink) {
+      if (stackTrace == null) stackTrace = new Trace.current();
+      if (_chains[stackTrace] == null) _chains[stackTrace] = node;
+      sink.addError(error, stackTrace);
+    }));
+  }
+
+  /// Tracks the current stack chain so it can be set to [_currentChain] when
+  /// [f] is run.
+  ZoneCallback registerCallback(Zone self, ZoneDelegate parent, Zone zone,
+      Function f) {
+    if (f == null) return parent.registerCallback(zone, null);
+    var node = _createNode(1);
+    return parent.registerCallback(zone, () => _run(f, node));
+  }
+
+  /// Tracks the current stack chain so it can be set to [_currentChain] when
+  /// [f] is run.
+  ZoneUnaryCallback registerUnaryCallback(Zone self, ZoneDelegate parent,
+      Zone zone, Function f) {
+    if (f == null) return parent.registerUnaryCallback(zone, null);
+    var node = _createNode(1);
+    return parent.registerUnaryCallback(zone, (arg) {
+      return _run(() => f(arg), node);
+    });
+  }
+
+  /// Tracks the current stack chain so it can be set to [_currentChain] when
+  /// [f] is run.
+  ZoneBinaryCallback registerBinaryCallback(Zone self, ZoneDelegate parent,
+      Zone zone, Function f) {
+    if (f == null) return parent.registerBinaryCallback(zone, null);
+    var node = _createNode(1);
+    return parent.registerBinaryCallback(zone, (arg1, arg2) {
+      return _run(() => f(arg1, arg2), node);
+    });
+  }
+
+  /// Looks up the chain associated with [stackTrace] and passes it either to
+  /// [_onError] or [parent]'s error handler.
+  handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone, error,
+      StackTrace stackTrace) {
+    if (_onError == null) {
+      return parent.handleUncaughtError(zone, error, chainFor(stackTrace));
+    } else {
+      _onError(error, chainFor(stackTrace));
+    }
+  }
+
+  /// Creates a [_Node] with the current stack trace and linked to
+  /// [_currentNode].
+  ///
+  /// By default, the first frame of the first trace will be the line where
+  /// [_createNode] is called. If [level] is passed, the first trace will start
+  /// that many frames up instead.
+  _Node _createNode([int level=0]) =>
+    new _Node(new Trace.current(level + 1), _currentNode);
+
+  // TODO(nweiz): use a more robust way of detecting and tracking errors when
+  // issue 15105 is fixed.
+  /// Runs [f] with [_currentNode] set to [node].
+  ///
+  /// If [f] throws an error, this associates [node] with that error's stack
+  /// trace.
+  _run(Function f, _Node node) {
+    var previousNode = _currentNode;
+    _currentNode = node;
+    try {
+      return f();
+    } catch (e, stackTrace) {
+      _chains[stackTrace] = node;
+      rethrow;
+    } finally {
+      _currentNode = previousNode;
+    }
+  }
+}
+
+/// A linked list node representing a single entry in a stack chain.
+class _Node {
+  /// The stack trace for this link of the chain.
+  final Trace trace;
+
+  /// The previous node in the chain.
+  final _Node previous;
+
+  _Node(StackTrace trace, [this.previous])
+      : trace = trace == null ? new Trace.current() : new Trace.from(trace);
+
+  /// Converts this to a [Chain].
+  Chain toChain() {
+    var nodes = <Trace>[];
+    var node = this;
+    while (node != null) {
+      nodes.add(node.trace);
+      node = node.previous;
+    }
+    return new Chain(nodes);
+  }
+}
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index c3db43e..88b9275 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -7,6 +7,7 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'chain.dart';
 import 'frame.dart';
 import 'lazy_trace.dart';
 import 'utils.dart';
@@ -92,6 +93,7 @@
   /// a [Trace], it will be returned as-is.
   factory Trace.from(StackTrace trace) {
     if (trace is Trace) return trace;
+    if (trace is Chain) return trace.toTrace();
     return new LazyTrace(() => new Trace.parse(trace.toString()));
   }
 
@@ -172,9 +174,14 @@
           .where((line) => line != '[native code]')
           .map((line) => new Frame.parseFirefox(line)));
 
-  /// Parses this package's a string representation of a stack trace.
+  /// Parses this package's string representation of a stack trace.
+  ///
+  /// This also parses string representations of [Chain]s. They parse to the
+  /// same trace that [Chain.toTrace] would return.
   Trace.parseFriendly(String trace)
       : this(trace.trim().split("\n")
+          // Filter out asynchronous gaps from [Chain]s.
+          .where((line) => !line.startsWith('====='))
           .map((line) => new Frame.parseFriendly(line)));
 
   /// Returns a new [Trace] comprised of [frames].
@@ -191,10 +198,13 @@
   /// Returns a terser version of [this].
   ///
   /// This is accomplished by folding together multiple stack frames from the
-  /// core library, as in [foldFrames]. Remaining core library frames have their
-  /// libraries, "-patch" suffixes, and line numbers removed.
+  /// core library or from this package, as in [foldFrames]. Remaining core
+  /// library frames have their libraries, "-patch" suffixes, and line numbers
+  /// removed.
   Trace get terse {
-    return new Trace(foldFrames((frame) => frame.isCore).frames.map((frame) {
+    return new Trace(foldFrames((frame) {
+      return frame.isCore || frame.package == 'stack_trace';
+    }).frames.map((frame) {
       if (!frame.isCore) return frame;
       var library = frame.library.replaceAll(_terseRegExp, '');
       return new Frame(Uri.parse(library), null, null, frame.member);
diff --git a/pkg/stack_trace/lib/src/utils.dart b/pkg/stack_trace/lib/src/utils.dart
index 08b3b96..62a2820 100644
--- a/pkg/stack_trace/lib/src/utils.dart
+++ b/pkg/stack_trace/lib/src/utils.dart
@@ -18,3 +18,19 @@
   return result.toString();
 }
 
+/// Flattens nested lists inside an iterable into a single list containing only
+/// non-list elements.
+List flatten(Iterable nested) {
+  var result = [];
+  helper(list) {
+    for (var element in list) {
+      if (element is List) {
+        helper(element);
+      } else {
+        result.add(element);
+      }
+    }
+  }
+  helper(nested);
+  return result;
+}
diff --git a/pkg/stack_trace/lib/stack_trace.dart b/pkg/stack_trace/lib/stack_trace.dart
index dba95e9..ac875a9 100644
--- a/pkg/stack_trace/lib/stack_trace.dart
+++ b/pkg/stack_trace/lib/stack_trace.dart
@@ -25,3 +25,4 @@
 
 export 'src/trace.dart';
 export 'src/frame.dart';
+export 'src/chain.dart';
diff --git a/pkg/stack_trace/test/chain_test.dart b/pkg/stack_trace/test/chain_test.dart
new file mode 100644
index 0000000..4d31acb
--- /dev/null
+++ b/pkg/stack_trace/test/chain_test.dart
@@ -0,0 +1,620 @@
+// 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 chain_test;
+
+import 'dart:async';
+
+import 'package:path/path.dart' as p;
+import 'package:stack_trace/stack_trace.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+void main() {
+  group('capture() with onError catches exceptions', () {
+    test('thrown in a microtask', () {
+      return captureFuture(() => inMicrotask(() => throw 'error'))
+          .then((chain) {
+        // Since there was only one asynchronous operation, there should be only
+        // two traces in the chain.
+        expect(chain.traces, hasLength(2));
+
+        // The first frame of the first trace should be the line on which the
+        // actual error was thrown.
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+
+        // The second trace should describe the stack when the error callback
+        // was scheduled.
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('thrown in a one-shot timer', () {
+      return captureFuture(() => inOneShotTimer(() => throw 'error'))
+          .then((chain) {
+        expect(chain.traces, hasLength(2));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inOneShotTimer'))));
+      });
+    });
+
+    test('thrown in a periodic timer', () {
+      return captureFuture(() => inPeriodicTimer(() => throw 'error'))
+          .then((chain) {
+        expect(chain.traces, hasLength(2));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inPeriodicTimer'))));
+      });
+    });
+
+    test('thrown in a nested series of asynchronous operations', () {
+      return captureFuture(() {
+        inPeriodicTimer(() {
+          inOneShotTimer(() => inMicrotask(() => throw 'error'));
+        });
+      }).then((chain) {
+        expect(chain.traces, hasLength(4));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inOneShotTimer'))));
+        expect(chain.traces[3].frames,
+            contains(frameMember(startsWith('inPeriodicTimer'))));
+      });
+    });
+
+    test('thrown in a long future chain', () {
+      return captureFuture(() => inFutureChain(() => throw 'error'))
+          .then((chain) {
+        // Despite many asynchronous operations, there's only one level of
+        // nested calls, so there should be only two traces in the chain. This
+        // is important; programmers expect stack trace memory consumption to be
+        // O(depth of program), not O(length of program).
+        expect(chain.traces, hasLength(2));
+
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inFutureChain'))));
+      });
+    });
+
+    test('multiple times', () {
+      var completer = new Completer();
+      var first = true;
+
+      Chain.capture(() {
+        inMicrotask(() => throw 'first error');
+        inPeriodicTimer(() => throw 'second error');
+      }, onError: (error, chain) {
+        if (first) {
+          expect(error, equals('first error'));
+          expect(chain.traces[1].frames,
+              contains(frameMember(startsWith('inMicrotask'))));
+          first = false;
+        } else {
+          expect(error, equals('second error'));
+          expect(chain.traces[1].frames,
+              contains(frameMember(startsWith('inPeriodicTimer'))));
+          completer.complete();
+        }
+      });
+
+      return completer.future;
+    });
+  });
+
+  test('capture() without onError passes exceptions to parent zone', () {
+    var completer = new Completer();
+
+    runZoned(() {
+      Chain.capture(() => inMicrotask(() => throw 'error'));
+    }, onError: (error, chain) {
+      expect(error, equals('error'));
+      expect(chain, new isInstanceOf<Chain>());
+      expect(chain.traces[1].frames,
+          contains(frameMember(startsWith('inMicrotask'))));
+      completer.complete();
+    });
+
+    return completer.future;
+  });
+
+  group('current() within capture()', () {
+    test('called in a microtask', () {
+      var completer = new Completer();
+      Chain.capture(() {
+        inMicrotask(() => completer.complete(new Chain.current()));
+      });
+
+      return completer.future.then((chain) {
+        expect(chain.traces, hasLength(2));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('called in a one-shot timer', () {
+      var completer = new Completer();
+      Chain.capture(() {
+        inOneShotTimer(() => completer.complete(new Chain.current()));
+      });
+
+      return completer.future.then((chain) {
+        expect(chain.traces, hasLength(2));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inOneShotTimer'))));
+      });
+    });
+
+    test('called in a periodic timer', () {
+      var completer = new Completer();
+      Chain.capture(() {
+        inPeriodicTimer(() => completer.complete(new Chain.current()));
+      });
+
+      return completer.future.then((chain) {
+        expect(chain.traces, hasLength(2));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inPeriodicTimer'))));
+      });
+    });
+
+    test('called in a nested series of asynchronous operations', () {
+      var completer = new Completer();
+      Chain.capture(() {
+        inPeriodicTimer(() {
+          inOneShotTimer(() {
+            inMicrotask(() => completer.complete(new Chain.current()));
+          });
+        });
+      });
+
+      return completer.future.then((chain) {
+        expect(chain.traces, hasLength(4));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inOneShotTimer'))));
+        expect(chain.traces[3].frames,
+            contains(frameMember(startsWith('inPeriodicTimer'))));
+      });
+    });
+
+    test('called in a long future chain', () {
+      var completer = new Completer();
+      Chain.capture(() {
+        inFutureChain(() => completer.complete(new Chain.current()));
+      });
+
+      return completer.future.then((chain) {
+        expect(chain.traces, hasLength(2));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inFutureChain'))));
+      });
+    });
+  });
+
+  test('current() outside of capture() returns a chain wrapping the current '
+      'trace', () {
+    var completer = new Completer();
+    inMicrotask(() => completer.complete(new Chain.current()));
+
+    return completer.future.then((chain) {
+      // Since the chain wasn't loaded within [Chain.capture], the full stack
+      // chain isn't available and it just returns the current stack when
+      // called.
+      expect(chain.traces, hasLength(1));
+      expect(chain.traces.first.frames.first, frameMember(startsWith('main')));
+    });
+  });
+
+  group('forTrace() within capture()', () {
+    test('called for a stack trace from a microtask', () {
+      return Chain.capture(() {
+        return chainForTrace(inMicrotask, () => throw 'error');
+      }).then((chain) {
+        // Because [chainForTrace] has to set up a future chain to capture the
+        // stack trace while still showing it to the zone specification, it adds
+        // an additional level of async nesting and so an additional trace.
+        expect(chain.traces, hasLength(3));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('chainForTrace'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('called for a stack trace from a one-shot timer', () {
+      return Chain.capture(() {
+        return chainForTrace(inOneShotTimer, () => throw 'error');
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('chainForTrace'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inOneShotTimer'))));
+      });
+    });
+
+    test('called for a stack trace from a periodic timer', () {
+      return Chain.capture(() {
+        return chainForTrace(inPeriodicTimer, () => throw 'error');
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('chainForTrace'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inPeriodicTimer'))));
+      });
+    });
+
+    test('called for a stack trace from a nested series of asynchronous '
+        'operations', () {
+      return Chain.capture(() {
+        return chainForTrace((callback) {
+          inPeriodicTimer(() => inOneShotTimer(() => inMicrotask(callback)));
+        }, () => throw 'error');
+      }).then((chain) {
+        expect(chain.traces, hasLength(5));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('chainForTrace'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+        expect(chain.traces[3].frames,
+            contains(frameMember(startsWith('inOneShotTimer'))));
+        expect(chain.traces[4].frames,
+            contains(frameMember(startsWith('inPeriodicTimer'))));
+      });
+    });
+
+    test('called for a stack trace from a long future chain', () {
+      return Chain.capture(() {
+        return chainForTrace(inFutureChain, () => throw 'error');
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+        expect(chain.traces[0].frames.first, frameMember(startsWith('main')));
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('chainForTrace'))));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inFutureChain'))));
+      });
+    });
+
+    test('called for an unregistered stack trace returns a chain wrapping that '
+        'trace', () {
+      var trace;
+      var chain = Chain.capture(() {
+        try {
+          throw 'error';
+        } catch (_, stackTrace) {
+          trace = stackTrace;
+          return new Chain.forTrace(stackTrace);
+        }
+      });
+
+      expect(chain.traces, hasLength(1));
+      expect(chain.traces.first.toString(),
+          equals(new Trace.from(trace).toString()));
+    });
+  });
+
+  test('forTrace() outside of capture() returns a chain wrapping the given '
+      'trace', () {
+    var trace;
+    var chain = Chain.capture(() {
+      try {
+        throw 'error';
+      } catch (_, stackTrace) {
+        trace = stackTrace;
+        return new Chain.forTrace(stackTrace);
+      }
+    });
+
+    expect(chain.traces, hasLength(1));
+    expect(chain.traces.first.toString(),
+        equals(new Trace.from(trace).toString()));
+  });
+
+  test('Chain.parse() parses a real Chain', () {
+    return captureFuture(() => inMicrotask(() => throw 'error')).then((chain) {
+      expect(new Chain.parse(chain.toString()).toString(),
+          equals(chain.toString()));
+    });
+  });
+
+  var userSlashCode = p.join('user', 'code.dart');
+  group('Chain.terse', () {
+    test('makes each trace terse', () {
+      var chain = new Chain([
+        new Trace.parse(
+            'dart:core 10:11       Foo.bar\n'
+            'dart:core 10:11       Bar.baz\n'
+            'user/code.dart 10:11  Bang.qux\n'
+            'dart:core 10:11       Zip.zap\n'
+            'dart:core 10:11       Zop.zoop'),
+        new Trace.parse(
+            'user/code.dart 10:11                        Bang.qux\n'
+            'dart:core 10:11                             Foo.bar\n'
+            'package:stack_trace/stack_trace.dart 10:11  Bar.baz\n'
+            'dart:core 10:11                             Zip.zap\n'
+            'user/code.dart 10:11                        Zop.zoop')
+      ]);
+
+      expect(chain.terse.toString(), equals(
+          'dart:core             Bar.baz\n'
+          '$userSlashCode 10:11  Bang.qux\n'
+          'dart:core             Zop.zoop\n'
+          '===== asynchronous gap ===========================\n'
+          '$userSlashCode 10:11  Bang.qux\n'
+          'dart:core             Zip.zap\n'
+          '$userSlashCode 10:11  Zop.zoop\n'));
+    });
+
+    test('eliminates internal-only traces', () {
+      var chain = new Chain([
+        new Trace.parse(
+            'user/code.dart 10:11  Foo.bar\n'
+            'dart:core 10:11       Bar.baz'),
+        new Trace.parse(
+            'dart:core 10:11                             Foo.bar\n'
+            'package:stack_trace/stack_trace.dart 10:11  Bar.baz\n'
+            'dart:core 10:11                             Zip.zap'),
+        new Trace.parse(
+            'user/code.dart 10:11  Foo.bar\n'
+            'dart:core 10:11       Bar.baz')
+      ]);
+
+      expect(chain.terse.toString(), equals(
+          '$userSlashCode 10:11  Foo.bar\n'
+          'dart:core             Bar.baz\n'
+          '===== asynchronous gap ===========================\n'
+          '$userSlashCode 10:11  Foo.bar\n'
+          'dart:core             Bar.baz\n'));
+    });
+  });
+
+  test('Chain.toTrace eliminates asynchronous gaps', () {
+    var trace = new Chain([
+      new Trace.parse(
+          'user/code.dart 10:11  Foo.bar\n'
+          'dart:core 10:11       Bar.baz'),
+      new Trace.parse(
+          'user/code.dart 10:11  Foo.bar\n'
+          'dart:core 10:11       Bar.baz')
+    ]).toTrace();
+
+    expect(trace.toString(), equals(
+        '$userSlashCode 10:11  Foo.bar\n'
+        'dart:core 10:11       Bar.baz\n'
+        '$userSlashCode 10:11  Foo.bar\n'
+        'dart:core 10:11       Bar.baz\n'));
+  });
+
+  group('Chain.track(Future)', () {
+    test('associates the current chain with a manually-reported exception with '
+        'a stack trace', () {
+      var trace = new Trace.current();
+      return captureFuture(() {
+        inMicrotask(() => trackedErrorFuture(trace));
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+
+        // The first trace is the trace that was manually reported for the
+        // error.
+        expect(chain.traces.first.toString(), equals(trace.toString()));
+
+        // The second trace is the trace that was captured when [Chain.track]
+        // was called.
+        expect(chain.traces[1].frames.first,
+            frameMember(startsWith('trackedErrorFuture')));
+
+        // The third trace is the automatically-captured trace from when the
+        // microtask was scheduled.
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('associates the current chain with a manually-reported exception with '
+        'no stack trace', () {
+      return captureFuture(() {
+        inMicrotask(() => trackedErrorFuture());
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+
+        // The first trace is the one captured by
+        // [StackZoneSpecification.trackFuture], which should contain only
+        // stack_trace and dart: frames.
+        expect(chain.traces.first.frames,
+            everyElement(frameLibrary(isNot(contains('chain_test')))));
+
+        expect(chain.traces[1].frames.first,
+            frameMember(startsWith('trackedErrorFuture')));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('forwards the future value within Chain.capture()', () {
+      Chain.capture(() {
+        expect(Chain.track(new Future.value('value')),
+            completion(equals('value')));
+
+        var trace = new Trace.current();
+        expect(Chain.track(new Future.error('error', trace))
+            .catchError((e, stackTrace) {
+          expect(e, equals('error'));
+          expect(stackTrace.toString(), equals(trace.toString()));
+        }), completes);
+      });
+    });
+
+    test('forwards the future value outside of Chain.capture()', () {
+      expect(Chain.track(new Future.value('value')),
+          completion(equals('value')));
+
+      var trace = new Trace.current();
+      expect(Chain.track(new Future.error('error', trace))
+          .catchError((e, stackTrace) {
+        expect(e, equals('error'));
+        expect(stackTrace.toString(), equals(trace.toString()));
+      }), completes);
+    });
+  });
+
+  group('Chain.track(Stream)', () {
+    test('associates the current chain with a manually-reported exception with '
+        'a stack trace', () {
+      var trace = new Trace.current();
+      return captureFuture(() {
+        inMicrotask(() => trackedErrorStream(trace).listen(null));
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+        expect(chain.traces.first.toString(), equals(trace.toString()));
+        expect(chain.traces[1].frames.first,
+            frameMember(startsWith('trackedErrorStream')));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('associates the current chain with a manually-reported exception with '
+        'no stack trace', () {
+      return captureFuture(() {
+        inMicrotask(() => trackedErrorStream().listen(null));
+      }).then((chain) {
+        expect(chain.traces, hasLength(3));
+        expect(chain.traces.first.frames,
+            everyElement(frameLibrary(isNot(contains('chain_test')))));
+        expect(chain.traces[1].frames.first,
+            frameMember(startsWith('trackedErrorStream')));
+        expect(chain.traces[2].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+      });
+    });
+
+    test('forwards stream values within Chain.capture()', () {
+      Chain.capture(() {
+        var controller = new StreamController()
+            ..add(1)..add(2)..add(3)..close();
+        expect(Chain.track(controller.stream).toList(),
+            completion(equals([1, 2, 3])));
+
+        var trace = new Trace.current();
+        controller = new StreamController()..addError('error', trace);
+        expect(Chain.track(controller.stream).toList()
+            .catchError((e, stackTrace) {
+          expect(e, equals('error'));
+          expect(stackTrace.toString(), equals(trace.toString()));
+        }), completes);
+      });
+    });
+
+    test('forwards stream values outside of Chain.capture()', () {
+      Chain.capture(() {
+        var controller = new StreamController()
+            ..add(1)..add(2)..add(3)..close();
+        expect(Chain.track(controller.stream).toList(),
+            completion(equals([1, 2, 3])));
+
+        var trace = new Trace.current();
+        controller = new StreamController()..addError('error', trace);
+        expect(Chain.track(controller.stream).toList()
+            .catchError((e, stackTrace) {
+          expect(e, equals('error'));
+          expect(stackTrace.toString(), equals(trace.toString()));
+        }), completes);
+      });
+    });
+  });
+}
+
+/// Runs [callback] in a microtask callback.
+void inMicrotask(callback()) => scheduleMicrotask(callback);
+
+/// Runs [callback] in a one-shot timer callback.
+void inOneShotTimer(callback()) => Timer.run(callback);
+
+/// Runs [callback] once in a periodic timer callback.
+void inPeriodicTimer(callback()) {
+  var count = 0;
+  new Timer.periodic(new Duration(milliseconds: 1), (timer) {
+    count++;
+    if (count != 5) return;
+    timer.cancel();
+    callback();
+  });
+}
+
+/// Runs [callback] within a long asynchronous Future chain.
+void inFutureChain(callback()) {
+  new Future(() {})
+      .then((_) => new Future(() {}))
+      .then((_) => new Future(() {}))
+      .then((_) => new Future(() {}))
+      .then((_) => new Future(() {}))
+      .then((_) => callback())
+      .then((_) => new Future(() {}));
+}
+
+/// Returns a Future that completes to an error and is wrapped in [Chain.track].
+///
+/// If [trace] is passed, it's used as the stack trace for the error.
+Future trackedErrorFuture([StackTrace trace]) {
+  var completer = new Completer();
+  completer.completeError('error', trace);
+  return Chain.track(completer.future);
+}
+
+/// Returns a Stream that emits an error and is wrapped in [Chain.track].
+///
+/// If [trace] is passed, it's used as the stack trace for the error.
+Stream trackedErrorStream([StackTrace trace]) {
+  var controller = new StreamController();
+  controller.addError('error', trace);
+  return Chain.track(controller.stream);
+}
+
+/// Runs [callback] within [asyncFn], then converts any errors raised into a
+/// [Chain] with [Chain.forTrace].
+Future<Chain> chainForTrace(asyncFn(callback()), callback()) {
+  var completer = new Completer();
+  asyncFn(() {
+    // We use `new Future.value().then(...)` here as opposed to [new Future] or
+    // [new Future.sync] because those methods don't pass the exception through
+    // the zone specification before propagating it, so there's no chance to
+    // attach a chain to its stack trace. See issue 15105.
+    new Future.value().then((_) => callback())
+        .catchError(completer.completeError);
+  });
+  return completer.future
+      .catchError((_, stackTrace) => new Chain.forTrace(stackTrace));
+}
+
+/// Runs [callback] in a [Chain.capture] zone and returns a Future that
+/// completes to the stack chain for an error thrown by [callback].
+///
+/// [callback] is expected to throw the string `"error"`.
+Future<Chain> captureFuture(callback()) {
+  var completer = new Completer<Chain>();
+  Chain.capture(callback, onError: (error, chain) {
+    expect(error, equals('error'));
+    completer.complete(chain);
+  });
+  return completer.future;
+}
diff --git a/pkg/stack_trace/test/trace_test.dart b/pkg/stack_trace/test/trace_test.dart
index ad916f1..4c3278f 100644
--- a/pkg/stack_trace/test/trace_test.dart
+++ b/pkg/stack_trace/test/trace_test.dart
@@ -171,6 +171,24 @@
           equals(Uri.parse("http://dartlang.org/foo/baz.dart")));
     });
 
+    test('parses a package:stack_trace stack chain correctly', () {
+      var trace = new Trace.parse(
+          'http://dartlang.org/foo/bar.dart 10:11  Foo.<fn>.bar\n'
+          'http://dartlang.org/foo/baz.dart        Foo.<fn>.bar\n'
+          '===== asynchronous gap ===========================\n'
+          'http://dartlang.org/foo/bang.dart 10:11  Foo.<fn>.bar\n'
+          'http://dartlang.org/foo/quux.dart        Foo.<fn>.bar');
+
+      expect(trace.frames[0].uri,
+          equals(Uri.parse("http://dartlang.org/foo/bar.dart")));
+      expect(trace.frames[1].uri,
+          equals(Uri.parse("http://dartlang.org/foo/baz.dart")));
+      expect(trace.frames[2].uri,
+          equals(Uri.parse("http://dartlang.org/foo/bang.dart")));
+      expect(trace.frames[3].uri,
+          equals(Uri.parse("http://dartlang.org/foo/quux.dart")));
+    });
+
     test('parses a real package:stack_trace stack trace correctly', () {
       var traceString = new Trace.current().toString();
       expect(new Trace.parse(traceString).toString(), equals(traceString));
diff --git a/pkg/stack_trace/test/utils.dart b/pkg/stack_trace/test/utils.dart
new file mode 100644
index 0000000..ed75631
--- /dev/null
+++ b/pkg/stack_trace/test/utils.dart
@@ -0,0 +1,37 @@
+// 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 stack_trace.test.utils;
+
+import 'package:unittest/unittest.dart';
+
+/// Returns a matcher that runs [matcher] against a [Frame]'s `member` field.
+Matcher frameMember(matcher) =>
+  transform((frame) => frame.member, matcher, 'member');
+
+/// Returns a matcher that runs [matcher] against a [Frame]'s `library` field.
+Matcher frameLibrary(matcher) =>
+  transform((frame) => frame.library, matcher, 'library');
+
+/// Returns a matcher that runs [transformation] on its input, then matches
+/// the output against [matcher].
+///
+/// [description] should be a noun phrase that describes the relation of the
+/// output of [transformation] to its input.
+Matcher transform(transformation(value), matcher, String description) =>
+  new _TransformMatcher(transformation, wrapMatcher(matcher), description);
+
+class _TransformMatcher extends Matcher {
+  final Function _transformation;
+  final Matcher _matcher;
+  final String _description;
+
+  _TransformMatcher(this._transformation, this._matcher, this._description);
+
+  bool matches(item, Map matchState) =>
+    _matcher.matches(_transformation(item), matchState);
+
+  Description describe(Description description) =>
+    description.add(_description).add(' ').addDescriptionOf(_matcher);
+}
diff --git a/pkg/template_binding/test/template_binding_test.dart b/pkg/template_binding/test/template_binding_test.dart
index cc52811..7639d76 100644
--- a/pkg/template_binding/test/template_binding_test.dart
+++ b/pkg/template_binding/test/template_binding_test.dart
@@ -1177,27 +1177,38 @@
     });
 
     recursivelySetTemplateModel(div, m);
+
+    var completer = new Completer();
+
+    new MutationObserver((records, observer) {
+      var select = div.nodes[0].nextNode;
+      if (select == null || select.querySelector('option') == null) return;
+
+      observer.disconnect();
+      new Future(() {
+        expect(select.nodes.length, 2);
+
+        expect(select.selectedIndex, 1, reason: 'selected index should update '
+            'after template expands.');
+
+        expect(select.nodes[0].tagName, 'TEMPLATE');
+        expect((templateBind(templateBind(select.nodes[0]).ref)
+            .content.nodes[0] as Element).tagName, 'OPTGROUP');
+
+        var optgroup = select.nodes[1];
+        expect(optgroup.nodes[0].tagName, 'TEMPLATE');
+        expect(optgroup.nodes[1].tagName, 'OPTION');
+        expect(optgroup.nodes[1].text, '0');
+        expect(optgroup.nodes[2].tagName, 'OPTION');
+        expect(optgroup.nodes[2].text, '1');
+
+        completer.complete();
+      });
+    })..observe(div, childList: true, subtree: true);
+
     Observable.dirtyCheck();
 
-    // Use a timer so it's slower than mutation observers.
-    return new Future(() {
-      var select = div.nodes[0].nextNode;
-      expect(select.nodes.length, 2);
-
-      expect(select.selectedIndex, 1, reason: 'selected index should update by '
-          'animationFrame time');
-
-      expect(select.nodes[0].tagName, 'TEMPLATE');
-      expect((templateBind(templateBind(select.nodes[0]).ref)
-          .content.nodes[0] as Element).tagName, 'OPTGROUP');
-
-      var optgroup = select.nodes[1];
-      expect(optgroup.nodes[0].tagName, 'TEMPLATE');
-      expect(optgroup.nodes[1].tagName, 'OPTION');
-      expect(optgroup.nodes[1].text, '0');
-      expect(optgroup.nodes[2].tagName, 'OPTION');
-      expect(optgroup.nodes[2].text, '1');
-    });
+    return completer.future;
   });
 
   observeTest('NestedIterateTableMixedSemanticNative', () {
diff --git a/pkg/third_party/html5lib/pubspec.yaml b/pkg/third_party/html5lib/pubspec.yaml
index 0e54366..955132d 100644
--- a/pkg/third_party/html5lib/pubspec.yaml
+++ b/pkg/third_party/html5lib/pubspec.yaml
@@ -1,5 +1,5 @@
 name: html5lib
-version: 0.9.1-dev
+version: 0.9.1
 author: Dart Team <misc@dartlang.org>
 description: A library for working with HTML documents.
 homepage: http://pub.dartlang.org/packages/html5lib
@@ -11,4 +11,4 @@
   path: ">=0.9.0 <0.10.0"
   unittest: ">=0.9.0 <0.10.0"
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/watcher/lib/src/directory_watcher/linux.dart b/pkg/watcher/lib/src/directory_watcher/linux.dart
index 5196078..d62c6ef 100644
--- a/pkg/watcher/lib/src/directory_watcher/linux.dart
+++ b/pkg/watcher/lib/src/directory_watcher/linux.dart
@@ -166,7 +166,7 @@
         if (error is FileSystemException) return;
 
         _eventsController.addError(error, stackTrace);
-        _eventsController.close();
+        close();
       }, cancelOnError: true);
     });
   }
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 1c1277b..ed010db 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -65,19 +65,30 @@
 
 
 int64_t DartUtils::GetIntegerValue(Dart_Handle value_obj) {
-  ASSERT(Dart_IsInteger(value_obj));
   int64_t value = 0;
   Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
+  return value;
+}
+
+
+int64_t DartUtils::GetInt64ValueCheckRange(
+    Dart_Handle value_obj, int64_t lower, int64_t upper) {
+  int64_t value = DartUtils::GetIntegerValue(value_obj);
+  if (value < lower || upper < value) {
+    Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
+  }
   return value;
 }
 
 
 intptr_t DartUtils::GetIntptrValue(Dart_Handle value_obj) {
-  ASSERT(Dart_IsInteger(value_obj));
   int64_t value = 0;
   Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
+  if (value < kIntptrMin || kIntptrMax < value) {
+    Dart_PropagateError(Dart_NewApiError("Value outside intptr_t range"));
+  }
   return static_cast<intptr_t>(value);
 }
 
@@ -86,11 +97,11 @@
   bool valid = Dart_IsInteger(value_obj);
   if (valid) {
     Dart_Handle result = Dart_IntegerFitsIntoInt64(value_obj, &valid);
-    ASSERT(!Dart_IsError(result));
+    if (Dart_IsError(result)) Dart_PropagateError(result);
   }
   if (!valid) return false;
   Dart_Handle result = Dart_IntegerToInt64(value_obj, value);
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
   return true;
 }
 
@@ -98,7 +109,7 @@
 const char* DartUtils::GetStringValue(Dart_Handle str_obj) {
   const char* cstring = NULL;
   Dart_Handle result = Dart_StringToCString(str_obj, &cstring);
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
   return cstring;
 }
 
@@ -106,7 +117,7 @@
 bool DartUtils::GetBooleanValue(Dart_Handle bool_obj) {
   bool value = false;
   Dart_Handle result = Dart_BooleanValue(bool_obj, &value);
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
   return value;
 }
 
@@ -117,14 +128,14 @@
   Dart_Handle result = Dart_SetField(handle,
                                      NewString(name),
                                      Dart_NewInteger(val));
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
 }
 
 
 intptr_t DartUtils::GetIntegerField(Dart_Handle handle,
                                     const char* name) {
   Dart_Handle result = Dart_GetField(handle, NewString(name));
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
   intptr_t value = DartUtils::GetIntegerValue(result);
   return value;
 }
@@ -134,7 +145,7 @@
                                const char* name,
                                const char* val) {
   Dart_Handle result = Dart_SetField(handle, NewString(name), NewString(val));
-  ASSERT(!Dart_IsError(result));
+  if (Dart_IsError(result)) Dart_PropagateError(result);
 }
 
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 476d813..f6ae3ab 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -78,23 +78,30 @@
 
 class DartUtils {
  public:
-  // TODO(turnidge): Clean up the implementations of these so that
-  // they allow for proper error propagation.
-
-  // Assumes that the value object is known to be an integer object
-  // that fits in a signed 64-bit integer.
+  // Returns the integer value of a Dart object. If the object is not
+  // an integer value an API error is propagated.
   static int64_t GetIntegerValue(Dart_Handle value_obj);
-  // Assumes that the value object is known to be an intptr_t. This should
-  // only be known when the value has been put into Dart as a pointer encoded
-  // in a 64-bit integer. This is the case for file and directory operations.
+  // Returns the integer value of a Dart object. If the object is not
+  // an integer value or outside the requested range an API error is
+  // propagated.
+  static int64_t GetInt64ValueCheckRange(
+      Dart_Handle value_obj, int64_t lower, int64_t upper);
+  // Returns the intptr_t value of a Dart object. If the object is not
+  // an integer value or the value is outside the intptr_t range an
+  // API error is propagated.
   static intptr_t GetIntptrValue(Dart_Handle value_obj);
   // Checks that the value object is an integer object that fits in a
   // signed 64-bit integer. If it is, the value is returned in the
   // value out parameter and true is returned. Otherwise, false is
   // returned.
   static bool GetInt64Value(Dart_Handle value_obj, int64_t* value);
+  // Returns the string value of a Dart object. If the object is not
+  // a string value an API error is propagated.
   static const char* GetStringValue(Dart_Handle str_obj);
+  // Returns the boolean value of a Dart object. If the object is not
+  // a boolean value an API error is propagated.
   static bool GetBooleanValue(Dart_Handle bool_obj);
+
   static void SetIntegerField(Dart_Handle handle,
                               const char* name,
                               intptr_t val);
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index d4960ec..3b9d016 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -69,7 +69,7 @@
 // These are scanned to detect loops while doing a recursive directory listing.
 struct LinkList {
   dev_t dev;
-  ino_t ino;
+  ino64_t ino;
   LinkList* next;
 };
 
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index 6a339b3..fb8cc25 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -74,9 +74,6 @@
   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_,
@@ -341,10 +338,11 @@
     } 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 {
+      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);
@@ -400,9 +398,8 @@
       if (errno != EWOULDBLOCK) {
         perror("Poll failed");
       }
-    } else if (result == 0) {
-      handler->HandleTimeout();
     } else {
+      handler->HandleTimeout();
       handler->HandleEvents(events, result);
     }
   }
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index 67f5c46..6c7744f 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -78,11 +78,19 @@
   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, 0, 0, sd);
+        EV_SET(events + changes,
+               sd->fd(),
+               EVFILT_READ,
+               EV_ADD | EV_ONESHOT,
+               0,
+               0,
+               sd);
         ++changes;
         sd->set_read_tracked_by_kqueue(true);
       }
@@ -94,7 +102,13 @@
     // 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, 0, 0, sd);
+        EV_SET(events + changes,
+               sd->fd(),
+               EVFILT_WRITE,
+               EV_ADD | EV_ONESHOT,
+               0,
+               0,
+               sd);
         ++changes;
         sd->set_write_tracked_by_kqueue(true);
       }
@@ -339,12 +353,13 @@
       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) {
-        // Unregister events for the file descriptor. Events will be
-        // registered again when the current event has been handled in
-        // Dart code.
-        RemoveFromKqueue(kqueue_fd_, sd);
+      if (event_mask == 0) {
+        // Event not handled, re-add to kqueue.
+        UpdateKqueue(kqueue_fd_, sd);
+      } else {
         Dart_Port port = sd->port();
         ASSERT(port != 0);
         DartUtils::PostInt32(port, event_mask);
diff --git a/runtime/bin/file_system_watcher_macos.cc b/runtime/bin/file_system_watcher_macos.cc
index 77fb6a9..2200b78 100644
--- a/runtime/bin/file_system_watcher_macos.cc
+++ b/runtime/bin/file_system_watcher_macos.cc
@@ -14,6 +14,7 @@
 
 #include "bin/eventhandler.h"
 #include "bin/fdutils.h"
+#include "bin/file.h"
 #include "bin/socket.h"
 #include "bin/thread.h"
 
@@ -49,10 +50,11 @@
 
 union FSEvent {
   struct {
+    uint32_t exists;
     uint32_t flags;
     char path[PATH_MAX];
   } data;
-  uint8_t bytes[PATH_MAX + 4];
+  uint8_t bytes[PATH_MAX + 8];
 };
 
 class FSEventsWatcher {
@@ -179,7 +181,7 @@
         CFArrayCreate(NULL, reinterpret_cast<const void**>(&path_ref), 1, NULL),
         kFSEventStreamEventIdSinceNow,
         0.10,
-        kFSEventStreamCreateFlagFileEvents);
+        kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents);
 
     node->set_ref(ref);
 
@@ -201,11 +203,12 @@
     Node* node = reinterpret_cast<Node*>(client);
     for (size_t i = 0; i < num_events; i++) {
       char *path = reinterpret_cast<char**>(event_paths)[i];
+      FSEvent event;
+      event.data.exists = File::Exists(path);
       path += node->base_path_length();
       // If path is longer the base, skip next character ('/').
       if (path[0] != '\0') path += 1;
       if (!node->recursive() && strstr(path, "/") != NULL) continue;
-      FSEvent event;
       event.data.flags = event_flags[i];
       memmove(event.data.path, path, strlen(path) + 1);
       write(node->write_fd(), event.bytes, sizeof(event));
@@ -272,7 +275,7 @@
         // The moved path is the path being watched.
         mask |= kDeleteSelf;
       } else {
-        mask |= kMove;
+        mask |= e.data.exists ? kCreate : kDelete;
       }
     }
     if (flags & kFSEventStreamEventFlagItemModified) mask |= kModifyContent;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index ef204de..59cf35a 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -689,8 +689,7 @@
 // Exit code indicating an unhandled error that is not a compilation error.
 static const int kErrorExitCode = 255;
 
-
-static int ErrorExit(int exit_code, const char* format, ...) {
+static void ErrorExit(int exit_code, const char* format, ...) {
   va_list arguments;
   va_start(arguments, format);
   Log::VPrintErr(format, arguments);
@@ -702,14 +701,17 @@
 
   Dart_Cleanup();
 
-  return exit_code;
+  exit(exit_code);
 }
 
 
-static int DartErrorExit(Dart_Handle error) {
+static void DartExitOnError(Dart_Handle error) {
+  if (!Dart_IsError(error)) {
+    return;
+  }
   const int exit_code = Dart_IsCompilationError(error) ?
       kCompilationErrorExitCode : kErrorExitCode;
-  return ErrorExit(exit_code, "%s\n", Dart_GetError(error));
+  ErrorExit(exit_code, "%s\n", Dart_GetError(error));
 }
 
 
@@ -754,7 +756,7 @@
 }
 
 
-int main(int argc, char** argv) {
+void main(int argc, char** argv) {
   char* script_name;
   CommandLineOptions vm_options(argc);
   CommandLineOptions dart_options(argc);
@@ -780,18 +782,18 @@
                      &verbose_debug_seen) < 0) {
     if (has_help_option) {
       PrintUsage();
-      return 0;
+      exit(0);
     } else if (has_version_option) {
       PrintVersion();
-      return 0;
+      exit(0);
     } else if (print_flags_seen) {
       // Will set the VM flags, print them out and then we exit as no
       // script was specified on the command line.
       Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
-      return 0;
+      exit(0);
     } else {
       PrintUsage();
-      return kErrorExitCode;
+      exit(kErrorExitCode);
     }
   }
 
@@ -799,7 +801,7 @@
     OSError err;
     fprintf(stderr, "Error determinig current directory: %s\n", err.message());
     fflush(stderr);
-    return kErrorExitCode;
+    exit(kErrorExitCode);
   }
 
   Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
@@ -813,7 +815,7 @@
                        DartUtils::EntropySource)) {
     fprintf(stderr, "%s", "VM initialization failed\n");
     fflush(stderr);
-    return kErrorExitCode;
+    exit(kErrorExitCode);
   }
 
   // Start the debugger wire protocol handler if necessary.
@@ -854,7 +856,7 @@
     Log::PrintErr("%s\n", error);
     free(error);
     delete [] isolate_name;
-    return is_compile_error ? kCompilationErrorExitCode : kErrorExitCode;
+    exit(is_compile_error ? kCompilationErrorExitCode : kErrorExitCode);
   }
   delete [] isolate_name;
 
@@ -871,10 +873,7 @@
     uint8_t* buffer = NULL;
     intptr_t size = 0;
     result = Dart_CreateScriptSnapshot(&buffer, &size);
-    if (Dart_IsError(result)) {
-      Log::PrintErr("%s\n", Dart_GetError(result));
-      return DartErrorExit(result);
-    }
+    DartExitOnError(result);
 
     // Write the magic number to indicate file is a script snapshot.
     DartUtils::WriteMagicNumber(snapshot_file);
@@ -894,40 +893,34 @@
 
     if (has_compile_all) {
       result = Dart_CompileAll();
-      if (Dart_IsError(result)) {
-        return DartErrorExit(result);
-      }
+      DartExitOnError(result);
     }
 
     if (Dart_IsNull(root_lib)) {
-      return ErrorExit(kErrorExitCode,
-                       "Unable to find root library for '%s'\n",
-                       script_name);
+      ErrorExit(kErrorExitCode,
+                "Unable to find root library for '%s'\n",
+                script_name);
     }
     if (has_print_script) {
       result = GenerateScriptSource();
-      if (Dart_IsError(result)) {
-        return DartErrorExit(result);
-      }
+      DartExitOnError(result);
     } else {
       // The helper function _getMainClosure creates a closure for the main
       // entry point which is either explicitly or implictly exported from the
       // root library.
       Dart_Handle main_closure = Dart_Invoke(
           builtin_lib, Dart_NewStringFromCString("_getMainClosure"), 0, NULL);
-      if (Dart_IsError(main_closure)) {
-        return DartErrorExit(result);
-      }
+      DartExitOnError(main_closure);
 
       // Set debug breakpoint if specified on the command line before calling
       // the main function.
       if (breakpoint_at != NULL) {
         result = SetBreakpoint(breakpoint_at, root_lib);
         if (Dart_IsError(result)) {
-          return ErrorExit(kErrorExitCode,
-                           "Error setting breakpoint at '%s': %s\n",
-                           breakpoint_at,
-                           Dart_GetError(result));
+          ErrorExit(kErrorExitCode,
+                    "Error setting breakpoint at '%s': %s\n",
+                    breakpoint_at,
+                    Dart_GetError(result));
         }
       }
 
@@ -948,22 +941,18 @@
       Dart_Handle initial_startup_msg = Dart_NewList(3);
       result = Dart_ListSetAt(initial_startup_msg, 1,
                               CreateRuntimeOptions(&dart_options));
-      if (Dart_IsError(result)) {
-        return DartErrorExit(result);
-      }
+      DartExitOnError(result);
       Dart_Port main_port = Dart_GetMainPortId();
       bool posted = Dart_Post(main_port, initial_startup_msg);
       if (!posted) {
-        return ErrorExit(kErrorExitCode,
-                         "Failed posting startup message to main "
-                         "isolate control port.");
+        ErrorExit(kErrorExitCode,
+                  "Failed posting startup message to main "
+                  "isolate control port.");
       }
 
       // Keep handling messages until the last active receive port is closed.
       result = Dart_RunLoop();
-      if (Dart_IsError(result)) {
-        return DartErrorExit(result);
-      }
+      DartExitOnError(result);
     }
   }
 
@@ -993,12 +982,13 @@
 
   Platform::Cleanup();
 
-  return Process::GlobalExitCode();
+  exit(Process::GlobalExitCode());
 }
 
 }  // namespace bin
 }  // namespace dart
 
 int main(int argc, char** argv) {
-  return dart::bin::main(argc, argv);
+  dart::bin::main(argc, argv);
+  UNREACHABLE();
 }
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index e4ee1ab..175d07e 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -103,21 +103,17 @@
 void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) {
   RawAddr addr;
   GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
-  int64_t port = 0;
-  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &port)) {
-    intptr_t socket = Socket::CreateConnect(addr, port);
-    OSError error;
-    if (socket >= 0) {
-      Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
-      Dart_SetReturnValue(args, Dart_True());
-    } else {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
-    }
+  int64_t port = DartUtils::GetInt64ValueCheckRange(
+      Dart_GetNativeArgument(args, 2),
+      0,
+      65535);
+  intptr_t socket = Socket::CreateConnect(addr, port);
+  OSError error;
+  if (socket >= 0) {
+    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
+    Dart_SetReturnValue(args, Dart_True());
   } 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);
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
   }
 }
 
@@ -285,9 +281,8 @@
 
 
 void FUNCTION_NAME(Socket_GetStdioHandle)(Dart_NativeArguments args) {
-  intptr_t num =
-      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
-  ASSERT(num == 0 || num == 1 || num == 2);
+  int64_t num = DartUtils::GetInt64ValueCheckRange(
+      Dart_GetNativeArgument(args, 1), 0, 2);
   intptr_t socket = Socket::GetStdioHandle(num);
   Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
   Dart_SetReturnValue(args, Dart_NewBoolean(socket >= 0));
@@ -303,31 +298,29 @@
 
 void FUNCTION_NAME(ServerSocket_CreateBindListen)(Dart_NativeArguments args) {
   RawAddr addr;
-  int64_t port = 0;
-  int64_t backlog = 0;
   GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
-  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &port) &&
-      DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &backlog)) {
-    bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
-    intptr_t socket = ServerSocket::CreateBindListen(
-        addr, port, backlog, v6_only);
-    OSError error;
-    if (socket >= 0) {
-      Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
-      Dart_SetReturnValue(args, Dart_True());
-    } else {
-      if (socket == -5) {
-        OSError os_error(-1, "Invalid host", OSError::kUnknown);
-        Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
-      } else {
-        Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
-      }
-    }
+  int64_t port = DartUtils::GetInt64ValueCheckRange(
+      Dart_GetNativeArgument(args, 2),
+      0,
+      65535);
+  int64_t backlog = DartUtils::GetInt64ValueCheckRange(
+      Dart_GetNativeArgument(args, 3),
+      0,
+      65535);
+  bool v6_only = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 4));
+  intptr_t socket = ServerSocket::CreateBindListen(
+      addr, port, backlog, v6_only);
+  OSError error;
+  if (socket >= 0) {
+    Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket);
+    Dart_SetReturnValue(args, Dart_True());
   } 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);
+    if (socket == -5) {
+      OSError os_error(-1, "Invalid host", OSError::kUnknown);
+      Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
+    } else {
+      Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
+    }
   }
 }
 
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 789dd00..1480f1f 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -615,7 +615,9 @@
       if (isClosedRead) {
         close();
       } else {
+        bool connected = eventPort != null;
         sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND);
+        if (!connected) disconnectFromEventHandler();
       }
       isClosedWrite = true;
     }
@@ -626,7 +628,9 @@
       if (isClosedWrite) {
         close();
       } else {
+        bool connected = eventPort != null;
         sendToEventHandler(1 << SHUTDOWN_READ_COMMAND);
+        if (!connected) disconnectFromEventHandler();
       }
       isClosedRead = true;
     }
diff --git a/runtime/bin/vmservice/client/.gitignore b/runtime/bin/vmservice/client/.gitignore
index 4653995..54dafe2 100644
--- a/runtime/bin/vmservice/client/.gitignore
+++ b/runtime/bin/vmservice/client/.gitignore
@@ -1 +1,2 @@
 bootstrap_css
+out
diff --git a/runtime/bin/vmservice/client/build.dart b/runtime/bin/vmservice/client/build.dart
index 71faf8b..627da4e2 100644
--- a/runtime/bin/vmservice/client/build.dart
+++ b/runtime/bin/vmservice/client/build.dart
@@ -13,9 +13,12 @@
 
 compileToJs(_) {
   print("Running dart2js");
-	var dart_path = Platform.executable;
-	var bin_path = dart_path.substring(0, dart_path.lastIndexOf(Platform.pathSeparator));
-	var dart2js_path = "$bin_path${Platform.pathSeparator}dart2js";
+  var dart_path = Platform.executable;
+  var dart2js_path = 'dart2js';
+  if (dart_path.lastIndexOf(Platform.pathSeparator) != -1) {
+    var bin_path = dart_path.substring(0, dart_path.lastIndexOf(Platform.pathSeparator));
+    dart2js_path = "$bin_path${Platform.pathSeparator}dart2js";
+  }
   var result =
     Process.runSync(dart2js_path,
         [ '--minify', '-o', 'out/web/index.html_bootstrap.dart.js',
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html b/runtime/bin/vmservice/client/deployed/web/index.html
index fedfc5f..94b6cc8 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html
+++ b/runtime/bin/vmservice/client/deployed/web/index.html
@@ -18,12 +18,12 @@
       <div class="panel panel-danger">
         <div class="panel-heading">Error</div>
         <div class="panel-body">
-	        <template if="{{ (error_obj == null) || (error_obj['type'] != '@LanguageError') }}">
-	          <p>{{ error }}</p>
-	        </template>
-	        <template if="{{ (error_obj != null) &amp;&amp; (error_obj['type'] == '@LanguageError') }}">
-	          <pre>{{ error_obj['error_msg'] }}</pre>
-	        </template>
+          <template if="{{ (error_obj == null) || (error_obj['type'] != 'LanguageError') }}">
+            <p>{{ error }}</p>
+          </template>
+          <template if="{{ (error_obj != null) &amp;&amp; (error_obj['type'] == 'LanguageError') }}">
+            <pre>{{ error_obj['error_msg'] }}</pre>
+          </template>
         </div>
       </div>
     </div>
@@ -108,7 +108,8 @@
     </div>
   </template>
   
-</polymer-element><polymer-element name="disassembly-entry" extends="observatory-element">
+</polymer-element>
+<polymer-element name="disassembly-entry" extends="observatory-element">
   <template>
   <div class="row">
     <template if="{{ instruction['type'] == 'DisassembledInstructionComment' }}">
@@ -260,7 +261,7 @@
   <template>
   	<div class="row">
   	  <div class="col-md-1">
-  	  	<img src="packages/observatory/src/observatory_elements/img/isolate_icon.png" class="img-polaroid">	
+  	  	<img src="img/isolate_icon.png" class="img-polaroid">	
   	  </div>
   	  <div class="col-md-1">{{ isolate }}</div>
   	  <div class="col-md-10">{{ name }}</div>
@@ -317,16 +318,78 @@
     </template>
   </template>
   
-</polymer-element><polymer-element name="library-view" extends="observatory-element">
+</polymer-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>
+  <table class="table table-hover">
+    <tbody>
+      <tr template="" repeat="{{ script in library['scripts']}}">
+        <td>
+          {{ script['kind'] }}
+        </td>
+        <td>
+          <a href="{{ app.locationManager.currentIsolateScriptLink(script['id'], script['name']) }}">{{ script['name'] }}</a>
+        </td>
+      </tr>
+    </tbody>
+  </table>
   <div class="alert alert-info">Imported Libraries</div>
   <table class="table table-hover">
     <tbody>
       <tr template="" repeat="{{ lib in library['libraries'] }}">
         <td>
           <a href="{{ app.locationManager.currentIsolateObjectLink(lib['id'])}}">
-            {{ lib['name'] }}
+            {{ lib['url'] }}
+          </a>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div class="alert alert-info">Variables</div>
+  <table class="table table-hover">
+    <tbody>
+      <tr template="" repeat="{{ variable in library['variables'] }}">
+        <td>
+          <template if="{{ variable['final'] }}">
+            final
+          </template>
+          <template if="{{ variable['const'] }}">
+            const
+          </template>
+          <template if="{{ (variable['declared_type']['name'] == 'dynamic' &amp;&amp; !variable['final'] &amp;&amp; !variable['const']) }}">
+            var
+          </template>
+          <template if="{{ (variable['declared_type']['name'] != 'dynamic') }}">
+            <a href="{{ app.locationManager.currentIsolateClassLink(variable['declared_type']['id']) }}">
+              {{ variable['declared_type']['user_name'] }}
+            </a>
+          </template>
+          <a href="{{ app.locationManager.currentIsolateObjectLink(variable['id'])}}">
+            {{ variable['user_name'] }}
+          </a>
+        </td>
+        <td>
+          <template if="{{ (variable['value']['type'] == 'null') }}">
+            {{ "null" }}
+          </template>
+          <template if="{{ (variable['value']['type'] != 'null') }}">
+            <a href="{{ app.locationManager.currentIsolateObjectLink(variable['value']['id'])}}">
+              {{ variable['value']['preview'] }}
+            </a>
+          </template>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div class="alert alert-info">Functions</div>
+  <table class="table table-hover">
+    <tbody>
+      <tr template="" repeat="{{ func in library['functions'] }}">
+        <td>
+          <a href="{{ app.locationManager.currentIsolateObjectLink(func['id'])}}">
+            {{ func['user_name'] }}
           </a>
         </td>
       </tr>
@@ -355,6 +418,29 @@
       </tr>
     </tbody>
   </table>
+
+  </template>
+  
+</polymer-element><polymer-element name="source-view" extends="observatory-element">
+  <template>
+  <div class="row">
+    <div class="col-md-8 col-md-offset-2">
+      <div class="panel-heading">{{ source.url }}</div>
+      <div class="panel-body">
+        <div class="row">
+          <div><strong>Source</strong></div>
+        </div>
+        <pre>        <template repeat="{{ line in source.lines }}">{{line.paddedLine}} {{line.src}}
+        </template>
+        </pre>
+      </div>
+    </div>
+  </div>
+  </template>
+  
+</polymer-element><polymer-element name="script-view" extends="observatory-element">
+  <template>
+    <source-view app="{{ app }}" source="{{ script['source'] }}"></source-view>
   </template>
   
 </polymer-element><polymer-element name="stack-trace" extends="observatory-element">
@@ -413,6 +499,9 @@
     <template if="{{ messageType == 'Code' }}">
       <code-view app="{{ app }}" code="{{ message }}"></code-view>
     </template>
+    <template if="{{ messageType == 'Script' }}">
+      <script-view app="{{ app }}" script="{{ message }}"></script-view>
+    </template>
     <!-- Add new views and message types in the future here. -->
   </template>
   
@@ -447,4 +536,4 @@
 </polymer-element>
   <observatory-application></observatory-application>
 
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart
index b00f899..4d2d042 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart
+++ b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart
@@ -14,12 +14,14 @@
 import 'package:observatory/src/observatory_elements/isolate_list.dart' as i9;
 import 'package:observatory/src/observatory_elements/json_view.dart' as i10;
 import 'package:observatory/src/observatory_elements/library_view.dart' as i11;
-import 'package:observatory/src/observatory_elements/stack_trace.dart' as i12;
-import 'package:observatory/src/observatory_elements/message_viewer.dart' as i13;
-import 'package:observatory/src/observatory_elements/navigation_bar.dart' as i14;
-import 'package:observatory/src/observatory_elements/response_viewer.dart' as i15;
-import 'package:observatory/src/observatory_elements/observatory_application.dart' as i16;
-import 'index.html.0.dart' as i17;
+import 'package:observatory/src/observatory_elements/source_view.dart' as i12;
+import 'package:observatory/src/observatory_elements/script_view.dart' as i13;
+import 'package:observatory/src/observatory_elements/stack_trace.dart' as i14;
+import 'package:observatory/src/observatory_elements/message_viewer.dart' as i15;
+import 'package:observatory/src/observatory_elements/navigation_bar.dart' as i16;
+import 'package:observatory/src/observatory_elements/response_viewer.dart' as i17;
+import 'package:observatory/src/observatory_elements/observatory_application.dart' as i18;
+import 'index.html.0.dart_modified.dart' as i19;
 
 void main() {
   configureForDeployment([
@@ -35,12 +37,14 @@
       'package:observatory/src/observatory_elements/isolate_list.dart',
       'package:observatory/src/observatory_elements/json_view.dart',
       'package:observatory/src/observatory_elements/library_view.dart',
+      'package:observatory/src/observatory_elements/source_view.dart',
+      'package:observatory/src/observatory_elements/script_view.dart',
       'package:observatory/src/observatory_elements/stack_trace.dart',
       'package:observatory/src/observatory_elements/message_viewer.dart',
       'package:observatory/src/observatory_elements/navigation_bar.dart',
       'package:observatory/src/observatory_elements/response_viewer.dart',
       'package:observatory/src/observatory_elements/observatory_application.dart',
-      'index.html.0.dart',
+      'index.html.0.dart_modified.dart',
     ]);
-  i17.main();
+  i19.polymerMainWrapper();
 }
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 f838e39..f571390 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
@@ -904,36 +904,35 @@
   // 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(object, name, descriptor) {
+  PathObserver.defineProperty = function(target, name, object, path) {
     // TODO(rafaelw): Validate errors
-    var obj = descriptor.object;
-    var path = getPath(descriptor.path);
-    var notify = notifyFunction(object, name);
+    path = getPath(path);
+    var notify = notifyFunction(target, name);
 
-    var observer = new PathObserver(obj, descriptor.path,
+    var observer = new PathObserver(object, path,
         function(newValue, oldValue) {
           if (notify)
             notify(PROP_UPDATE_TYPE, oldValue);
         }
     );
 
-    Object.defineProperty(object, name, {
+    Object.defineProperty(target, name, {
       get: function() {
-        return path.getValueFrom(obj);
+        return path.getValueFrom(object);
       },
       set: function(newValue) {
-        path.setValueFrom(obj, newValue);
+        path.setValueFrom(object, newValue);
       },
       configurable: true
     });
 
     return {
       close: function() {
-        var oldValue = path.getValueFrom(obj);
+        var oldValue = path.getValueFrom(object);
         if (notify)
           observer.deliver();
         observer.close();
-        Object.defineProperty(object, name, {
+        Object.defineProperty(target, name, {
           value: oldValue,
           writable: true,
           configurable: true
@@ -1419,7 +1418,7 @@
     'delete': PROP_DELETE_TYPE,
     splice: ARRAY_SPLICE_TYPE
   };
-})(typeof global !== 'undefined' && global ? global : this);
+})(typeof global !== 'undefined' && global ? global : this || window);
 
 /*
  * Copyright 2012 The Polymer Authors. All rights reserved.
@@ -1462,7 +1461,7 @@
 // Use of this source code is goverened by a BSD-style
 // license that can be found in the LICENSE file.
 
-var ShadowDOMPolyfill = {};
+window.ShadowDOMPolyfill = {};
 
 (function(scope) {
   'use strict';
@@ -1490,16 +1489,19 @@
       throw new Error('Assertion failed');
   };
 
+  var defineProperty = Object.defineProperty;
+  var getOwnPropertyNames = Object.getOwnPropertyNames;
+  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
+
   function mixin(to, from) {
-    Object.getOwnPropertyNames(from).forEach(function(name) {
-      Object.defineProperty(to, name,
-                            Object.getOwnPropertyDescriptor(from, name));
+    getOwnPropertyNames(from).forEach(function(name) {
+      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
     });
     return to;
   };
 
   function mixinStatics(to, from) {
-    Object.getOwnPropertyNames(from).forEach(function(name) {
+    getOwnPropertyNames(from).forEach(function(name) {
       switch (name) {
         case 'arguments':
         case 'caller':
@@ -1509,8 +1511,7 @@
         case 'toString':
           return;
       }
-      Object.defineProperty(to, name,
-                            Object.getOwnPropertyDescriptor(from, name));
+      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
     });
     return to;
   };
@@ -1525,7 +1526,7 @@
   // Mozilla's old DOM bindings are bretty busted:
   // https://bugzilla.mozilla.org/show_bug.cgi?id=855844
   // Make sure they are create before we start modifying things.
-  Object.getOwnPropertyNames(window);
+  getOwnPropertyNames(window);
 
   function getWrapperConstructor(node) {
     var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
@@ -1587,28 +1588,39 @@
         function() { return this.impl[name].apply(this.impl, arguments); };
   }
 
-  function installProperty(source, target, allowMethod) {
-    Object.getOwnPropertyNames(source).forEach(function(name) {
+  function getDescriptor(source, name) {
+    try {
+      return Object.getOwnPropertyDescriptor(source, name);
+    } catch (ex) {
+      // JSC and V8 both use data properties instead of accessors which can
+      // cause getting the property desciptor to throw an exception.
+      // https://bugs.webkit.org/show_bug.cgi?id=49739
+      return dummyDescriptor;
+    }
+  }
+
+  function installProperty(source, target, allowMethod, opt_blacklist) {
+    var names = getOwnPropertyNames(source);
+    for (var i = 0; i < names.length; i++) {
+      var name = names[i];
+      if (name === 'polymerBlackList_')
+        continue;
+
       if (name in target)
-        return;
+        continue;
+
+      if (source.polymerBlackList_ && source.polymerBlackList_[name])
+        continue;
 
       if (isFirefox) {
         // Tickle Firefox's old bindings.
         source.__lookupGetter__(name);
       }
-      var descriptor;
-      try {
-        descriptor = Object.getOwnPropertyDescriptor(source, name);
-      } catch (ex) {
-        // JSC and V8 both use data properties instead of accessors which can
-        // cause getting the property desciptor to throw an exception.
-        // https://bugs.webkit.org/show_bug.cgi?id=49739
-        descriptor = dummyDescriptor;
-      }
+      var descriptor = getDescriptor(source, name);
       var getter, setter;
       if (allowMethod && typeof descriptor.value === 'function') {
         target[name] = getMethod(name);
-        return;
+        continue;
       }
 
       var isEvent = isEventHandlerName(name);
@@ -1624,13 +1636,13 @@
           setter = getSetter(name);
       }
 
-      Object.defineProperty(target, name, {
+      defineProperty(target, name, {
         get: getter,
         set: setter,
         configurable: descriptor.configurable,
         enumerable: descriptor.enumerable
       });
-    });
+    }
   }
 
   /**
@@ -1655,6 +1667,12 @@
     addForwardingProperties(nativePrototype, wrapperPrototype);
     if (opt_instance)
       registerInstanceProperties(wrapperPrototype, opt_instance);
+    defineProperty(wrapperPrototype, 'constructor', {
+      value: wrapperConstructor,
+      configurable: true,
+      enumerable: false,
+      writable: true
+    });
   }
 
   function isWrapperFor(wrapperConstructor, nativeConstructor) {
@@ -1665,11 +1683,7 @@
   /**
    * Creates a generic wrapper constructor based on |object| and its
    * constructor.
-   * Sometimes the constructor does not have an associated instance
-   * (CharacterData for example). In that case you can pass the constructor that
-   * you want to map the object to using |opt_nativeConstructor|.
    * @param {Node} object
-   * @param {Function=} opt_nativeConstructor
    * @return {Function} The generated constructor.
    */
   function registerObject(object) {
@@ -1782,7 +1796,7 @@
   }
 
   function defineGetter(constructor, name, getter) {
-    Object.defineProperty(constructor.prototype, name, {
+    defineProperty(constructor.prototype, name, {
       get: getter,
       configurable: true,
       enumerable: true
@@ -1831,7 +1845,430 @@
   scope.wrapIfNeeded = wrapIfNeeded;
   scope.wrappers = wrappers;
 
-})(this.ShadowDOMPolyfill);
+})(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.
+ */
+
+(function(context) {
+  'use strict';
+
+  var OriginalMutationObserver = window.MutationObserver;
+  var callbacks = [];
+  var pending = false;
+  var timerFunc;
+
+  function handle() {
+    pending = false;
+    var copies = callbacks.slice(0);
+    callbacks = [];
+    for (var i = 0; i < copies.length; i++) {
+      (0, copies[i])();
+    }
+  }
+
+  if (OriginalMutationObserver) {
+    var counter = 1;
+    var observer = new OriginalMutationObserver(handle);
+    var textNode = document.createTextNode(counter);
+    observer.observe(textNode, {characterData: true});
+
+    timerFunc = function() {
+      counter = (counter + 1) % 2;
+      textNode.data = counter;
+    };
+
+  } else {
+    timerFunc = window.setImmediate || window.setTimeout;
+  }
+
+  function setEndOfMicrotask(func) {
+    callbacks.push(func);
+    if (pending)
+      return;
+    pending = true;
+    timerFunc(handle, 0);
+  }
+
+  context.setEndOfMicrotask = setEndOfMicrotask;
+
+})(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.
+ */
+
+(function(scope) {
+  'use strict';
+
+  var setEndOfMicrotask = scope.setEndOfMicrotask
+  var wrapIfNeeded = scope.wrapIfNeeded
+  var wrappers = scope.wrappers;
+
+  var registrationsTable = new WeakMap();
+  var globalMutationObservers = [];
+  var isScheduled = false;
+
+  function scheduleCallback(observer) {
+    if (isScheduled)
+      return;
+    setEndOfMicrotask(notifyObservers);
+    isScheduled = true;
+  }
+
+  // http://dom.spec.whatwg.org/#mutation-observers
+  function notifyObservers() {
+    isScheduled = false;
+
+    do {
+      var notifyList = globalMutationObservers.slice();
+      var anyNonEmpty = false;
+      for (var i = 0; i < notifyList.length; i++) {
+        var mo = notifyList[i];
+        var queue = mo.takeRecords();
+        removeTransientObserversFor(mo);
+        if (queue.length) {
+          mo.callback_(queue, mo);
+          anyNonEmpty = true;
+        }
+      }
+    } while (anyNonEmpty);
+  }
+
+  /**
+   * @param {string} type
+   * @param {Node} target
+   * @constructor
+   */
+  function MutationRecord(type, target) {
+    this.type = type;
+    this.target = target;
+    this.addedNodes = new wrappers.NodeList();
+    this.removedNodes = new wrappers.NodeList();
+    this.previousSibling = null;
+    this.nextSibling = null;
+    this.attributeName = null;
+    this.attributeNamespace = null;
+    this.oldValue = null;
+  }
+
+  /**
+   * Registers transient observers to ancestor and its ancesors for the node
+   * which was removed.
+   * @param {!Node} ancestor
+   * @param {!Node} node
+   */
+  function registerTransientObservers(ancestor, node) {
+    for (; ancestor; ancestor = ancestor.parentNode) {
+      var registrations = registrationsTable.get(ancestor);
+      if (!registrations)
+        continue;
+      for (var i = 0; i < registrations.length; i++) {
+        var registration = registrations[i];
+        if (registration.options.subtree)
+          registration.addTransientObserver(node);
+      }
+    }
+  }
+
+  function removeTransientObserversFor(observer) {
+    for (var i = 0; i < observer.nodes_.length; i++) {
+      var node = observer.nodes_[i];
+      var registrations = registrationsTable.get(node);
+      if (!registrations)
+        return;
+      for (var j = 0; j < registrations.length; j++) {
+        var registration = registrations[j];
+        if (registration.observer === observer)
+          registration.removeTransientObservers();
+      }
+    }
+  }
+
+  // http://dom.spec.whatwg.org/#queue-a-mutation-record
+  function enqueueMutation(target, type, data) {
+    // 1.
+    var interestedObservers = Object.create(null);
+    var associatedStrings = Object.create(null);
+
+    // 2.
+    for (var node = target; node; node = node.parentNode) {
+      // 3.
+      var registrations = registrationsTable.get(node);
+      if (!registrations)
+        continue;
+      for (var j = 0; j < registrations.length; j++) {
+        var registration = registrations[j];
+        var options = registration.options;
+        // 1.
+        if (node !== target && !options.subtree)
+          continue;
+
+        // 2.
+        if (type === 'attributes' && !options.attributes)
+          continue;
+
+        // 3. If type is "attributes", options's attributeFilter is present, and
+        // either options's attributeFilter does not contain name or namespace
+        // is non-null, continue.
+        if (type === 'attributes' && options.attributeFilter &&
+            (data.namespace !== null ||
+             options.attributeFilter.indexOf(data.name) === -1)) {
+          continue;
+        }
+
+        // 4.
+        if (type === 'characterData' && !options.characterData)
+          continue;
+
+        // 5.
+        if (type === 'childList' && !options.childList)
+          continue;
+
+        // 6.
+        var observer = registration.observer;
+        interestedObservers[observer.uid_] = observer;
+
+        // 7. If either type is "attributes" and options's attributeOldValue is
+        // true, or type is "characterData" and options's characterDataOldValue
+        // is true, set the paired string of registered observer's observer in
+        // interested observers to oldValue.
+        if (type === 'attributes' && options.attributeOldValue ||
+            type === 'characterData' && options.characterDataOldValue) {
+          associatedStrings[observer.uid_] = data.oldValue;
+        }
+      }
+    }
+
+    var anyRecordsEnqueued = false;
+
+    // 4.
+    for (var uid in interestedObservers) {
+      var observer = interestedObservers[uid];
+      var record = new MutationRecord(type, target);
+
+      // 2.
+      if ('name' in data && 'namespace' in data) {
+        record.attributeName = data.name;
+        record.attributeNamespace = data.namespace;
+      }
+
+      // 3.
+      if (data.addedNodes)
+        record.addedNodes = data.addedNodes;
+
+      // 4.
+      if (data.removedNodes)
+        record.removedNodes = data.removedNodes;
+
+      // 5.
+      if (data.previousSibling)
+        record.previousSibling = data.previousSibling;
+
+      // 6.
+      if (data.nextSibling)
+        record.nextSibling = data.nextSibling;
+
+      // 7.
+      if (associatedStrings[uid] !== undefined)
+        record.oldValue = associatedStrings[uid];
+
+      // 8.
+      observer.records_.push(record);
+
+      anyRecordsEnqueued = true;
+    }
+
+    if (anyRecordsEnqueued)
+      scheduleCallback();
+  }
+
+  var slice = Array.prototype.slice;
+
+  /**
+   * @param {!Object} options
+   * @constructor
+   */
+  function MutationObserverOptions(options) {
+    this.childList = !!options.childList;
+    this.subtree = !!options.subtree;
+
+    // 1. If either options' attributeOldValue or attributeFilter is present
+    // and options' attributes is omitted, set options' attributes to true.
+    if (!('attributes' in options) &&
+        ('attributeOldValue' in options || 'attributeFilter' in options)) {
+      this.attributes = true;
+    } else {
+      this.attributes = !!options.attributes;
+    }
+
+    // 2. If options' characterDataOldValue is present and options'
+    // characterData is omitted, set options' characterData to true.
+    if ('characterDataOldValue' in options && !('characterData' in options))
+      this.characterData = true;
+    else
+      this.characterData = !!options.characterData;
+
+    // 3. & 4.
+    if (!this.attributes &&
+        (options.attributeOldValue || 'attributeFilter' in options) ||
+        // 5.
+        !this.characterData && options.characterDataOldValue) {
+      throw new TypeError();
+    }
+
+    this.characterData = !!options.characterData;
+    this.attributeOldValue = !!options.attributeOldValue;
+    this.characterDataOldValue = !!options.characterDataOldValue;
+    if ('attributeFilter' in options) {
+      if (options.attributeFilter == null ||
+          typeof options.attributeFilter !== 'object') {
+        throw new TypeError();
+      }
+      this.attributeFilter = slice.call(options.attributeFilter);
+    } else {
+      this.attributeFilter = null;
+    }
+  }
+
+  var uidCounter = 0;
+
+  /**
+   * The class that maps to the DOM MutationObserver interface.
+   * @param {Function} callback.
+   * @constructor
+   */
+  function MutationObserver(callback) {
+    this.callback_ = callback;
+    this.nodes_ = [];
+    this.records_ = [];
+    this.uid_ = ++uidCounter;
+
+    // This will leak. There is no way to implement this without WeakRefs :'(
+    globalMutationObservers.push(this);
+  }
+
+  MutationObserver.prototype = {
+    // http://dom.spec.whatwg.org/#dom-mutationobserver-observe
+    observe: function(target, options) {
+      target = wrapIfNeeded(target);
+
+      var newOptions = new MutationObserverOptions(options);
+
+      // 6.
+      var registration;
+      var registrations = registrationsTable.get(target);
+      if (!registrations)
+        registrationsTable.set(target, registrations = []);
+
+      for (var i = 0; i < registrations.length; i++) {
+        if (registrations[i].observer === this) {
+          registration = registrations[i];
+          // 6.1.
+          registration.removeTransientObservers();
+          // 6.2.
+          registration.options = newOptions;
+        }
+      }
+
+      // 7.
+      if (!registration) {
+        registration = new Registration(this, target, newOptions);
+        registrations.push(registration);
+        this.nodes_.push(target);
+      }
+    },
+
+    // http://dom.spec.whatwg.org/#dom-mutationobserver-disconnect
+    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) {
+            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;
+    }
+  };
+
+  /**
+   * Class used to represent a registered observer.
+   * @param {MutationObserver} observer
+   * @param {Node} target
+   * @param {MutationObserverOptions} options
+   * @constructor
+   */
+  function Registration(observer, target, options) {
+    this.observer = observer;
+    this.target = target;
+    this.options = options;
+    this.transientObservedNodes = [];
+  }
+
+  Registration.prototype = {
+    /**
+     * 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.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 = [];
+
+      for (var i = 0; i < transientObservedNodes.length; i++) {
+        var node = transientObservedNodes[i];
+        var registrations = registrationsTable.get(node);
+        for (var j = 0; j < registrations.length; j++) {
+          if (registrations[j] === this) {
+            registrations.splice(j, 1);
+            // Each node can only have one registered observer associated with
+            // this observer.
+            break;
+          }
+        }
+      }
+    }
+  };
+
+  scope.enqueueMutation = enqueueMutation;
+  scope.registerTransientObservers = registerTransientObservers;
+  scope.wrappers.MutationObserver = MutationObserver;
+  scope.wrappers.MutationRecord = MutationRecord;
+
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -2014,17 +2451,6 @@
     return false;
   }
 
-  var mutationEventsAreSilenced = 0;
-
-  function muteMutationEvents() {
-    mutationEventsAreSilenced++;
-  }
-
-  function unmuteMutationEvents() {
-    mutationEventsAreSilenced--;
-  }
-
-  var OriginalMutationEvent = window.MutationEvent;
 
   function dispatchOriginalEvent(originalEvent) {
     // Make sure this event is only dispatched once.
@@ -2032,15 +2458,9 @@
       return;
     handledEventsTable.set(originalEvent, true);
 
-    // Don't do rendering if this is a mutation event since rendering might
-    // mutate the DOM which would fire more events and we would most likely
-    // just iloop.
-    if (originalEvent instanceof OriginalMutationEvent) {
-      if (mutationEventsAreSilenced)
-        return;
-    } else {
-      scope.renderAllPending();
-    }
+    // Render before dispatching the event to ensure that the event path is
+    // correct.
+    scope.renderAllPending();
 
     var target = wrap(originalEvent.target);
     var event = wrap(originalEvent);
@@ -2210,6 +2630,7 @@
   };
 
   var OriginalEvent = window.Event;
+  OriginalEvent.prototype.polymerBlackList_ = {returnValue: true};
 
   /**
    * Creates a new Event wrapper or wraps an existin native Event object.
@@ -2325,13 +2746,6 @@
   var MouseEvent = registerGenericEvent('MouseEvent', UIEvent, mouseEventProto);
   var FocusEvent = registerGenericEvent('FocusEvent', UIEvent, focusEventProto);
 
-  var MutationEvent = registerGenericEvent('MutationEvent', Event, {
-    initMutationEvent: getInitFunction('initMutationEvent', 3),
-    get relatedNode() {
-      return wrap(this.impl.relatedNode);
-    },
-  });
-
   // In case the browser does not support event constructors we polyfill that
   // by calling `createEvent('Foo')` and `initFooEvent` where the arguments to
   // `initFooEvent` are derived from the registered default event init dict.
@@ -2398,12 +2812,41 @@
     configureEventConstructor('FocusEvent', {relatedTarget: null}, 'UIEvent');
   }
 
+  function BeforeUnloadEvent(impl) {
+    Event.call(this);
+  }
+  BeforeUnloadEvent.prototype = Object.create(Event.prototype);
+  mixin(BeforeUnloadEvent.prototype, {
+    get returnValue() {
+      return this.impl.returnValue;
+    },
+    set returnValue(v) {
+      this.impl.returnValue = v;
+    }
+  });
+
   function isValidListener(fun) {
     if (typeof fun === 'function')
       return true;
     return fun && fun.handleEvent;
   }
 
+  function isMutationEvent(type) {
+    switch (type) {
+      case 'DOMAttrModified':
+      case 'DOMAttributeNameChanged':
+      case 'DOMCharacterDataModified':
+      case 'DOMElementNameChanged':
+      case 'DOMNodeInserted':
+      case 'DOMNodeInsertedIntoDocument':
+      case 'DOMNodeRemoved':
+      case 'DOMNodeRemovedFromDocument':
+      case 'DOMSubtreeModified':
+        return true;
+    }
+    return false;
+  }
+
   var OriginalEventTarget = window.EventTarget;
 
   /**
@@ -2438,7 +2881,7 @@
 
   EventTarget.prototype = {
     addEventListener: function(type, fun, capture) {
-      if (!isValidListener(fun))
+      if (!isValidListener(fun) || isMutationEvent(type))
         return;
 
       var listener = new Listener(type, fun, capture);
@@ -2568,18 +3011,16 @@
   scope.elementFromPoint = elementFromPoint;
   scope.getEventHandlerGetter = getEventHandlerGetter;
   scope.getEventHandlerSetter = getEventHandlerSetter;
-  scope.muteMutationEvents = muteMutationEvents;
-  scope.unmuteMutationEvents = unmuteMutationEvents;
   scope.wrapEventTargetMethods = wrapEventTargetMethods;
+  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
   scope.wrappers.CustomEvent = CustomEvent;
   scope.wrappers.Event = Event;
   scope.wrappers.EventTarget = EventTarget;
   scope.wrappers.FocusEvent = FocusEvent;
   scope.wrappers.MouseEvent = MouseEvent;
-  scope.wrappers.MutationEvent = MutationEvent;
   scope.wrappers.UIEvent = UIEvent;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2012 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -2626,7 +3067,8 @@
   scope.addWrapNodeListMethod = addWrapNodeListMethod;
   scope.wrapNodeList = wrapNodeList;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2012 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.
@@ -2636,9 +3078,11 @@
 
   var EventTarget = scope.wrappers.EventTarget;
   var NodeList = scope.wrappers.NodeList;
-  var defineWrapGetter = scope.defineWrapGetter;
   var assert = scope.assert;
+  var defineWrapGetter = scope.defineWrapGetter;
+  var enqueueMutation = scope.enqueueMutation;
   var mixin = scope.mixin;
+  var registerTransientObservers = scope.registerTransientObservers;
   var registerWrapper = scope.registerWrapper;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
@@ -2648,6 +3092,36 @@
     assert(node instanceof Node);
   }
 
+  function createOneElementNodeList(node) {
+    var nodes = new NodeList();
+    nodes[0] = node;
+    nodes.length = 1;
+    return nodes;
+  }
+
+  var surpressMutations = false;
+
+  /**
+   * Called before node is inserted into a node to enqueue its removal from its
+   * old parent.
+   * @param {!Node} node The node that is about to be removed.
+   * @param {!Node} parent The parent node that the node is being removed from.
+   * @param {!NodeList} nodes The collected nodes.
+   */
+  function enqueueRemovalForInsertedNodes(node, parent, nodes) {
+    enqueueMutation(parent, 'childList', {
+      removedNodes: nodes,
+      previousSibling: node.previousSibling,
+      nextSibling: node.nextSibling
+    });
+  }
+
+  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
+    enqueueMutation(df, 'childList', {
+      removedNodes: nodes
+    });
+  }
+
   /**
    * Collects nodes from a DocumentFragment or a Node for removal followed
    * by an insertion.
@@ -2655,60 +3129,95 @@
    * This updates the internal pointers for node, previousNode and nextNode.
    */
   function collectNodes(node, parentNode, previousNode, nextNode) {
-    if (!(node instanceof DocumentFragment)) {
-      if (node.parentNode)
-        node.parentNode.removeChild(node);
-      node.parentNode_ = parentNode;
-      node.previousSibling_ = previousNode;
-      node.nextSibling_ = nextNode;
+    if (node instanceof DocumentFragment) {
+      var nodes = collectNodesForDocumentFragment(node);
+
+      // The extra loop is to work around bugs with DocumentFragments in IE.
+      surpressMutations = true;
+      for (var i = nodes.length - 1; i >= 0; i--) {
+        node.removeChild(nodes[i]);
+        nodes[i].parentNode_ = parentNode;
+      }
+      surpressMutations = false;
+
+      for (var i = 0; i < nodes.length; i++) {
+        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
+        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
+      }
+
       if (previousNode)
-        previousNode.nextSibling_ = node;
+        previousNode.nextSibling_ = nodes[0];
       if (nextNode)
-        nextNode.previousSibling_ = node;
-      return [node];
+        nextNode.previousSibling_ = nodes[nodes.length - 1];
+
+      return nodes;
     }
 
-    var nodes = [];
-    for (var child = node.firstChild; child; child = child.nextSibling) {
-      nodes.push(child);
+    var nodes = createOneElementNodeList(node);
+    var oldParent = node.parentNode;
+    if (oldParent) {
+      // This will enqueue the mutation record for the removal as needed.
+      oldParent.removeChild(node);
     }
 
-    for (var i = nodes.length - 1; i >= 0; i--) {
-      node.removeChild(nodes[i]);
-      nodes[i].parentNode_ = parentNode;
-    }
-
-    for (var i = 0; i < nodes.length; i++) {
-      nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
-      nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
-    }
-
+    node.parentNode_ = parentNode;
+    node.previousSibling_ = previousNode;
+    node.nextSibling_ = nextNode;
     if (previousNode)
-      previousNode.nextSibling_ = nodes[0];
+      previousNode.nextSibling_ = node;
     if (nextNode)
-      nextNode.previousSibling_ = nodes[nodes.length - 1];
+      nextNode.previousSibling_ = node;
 
     return nodes;
   }
 
-  function collectNodesNoNeedToUpdatePointers(node) {
-    if (node instanceof DocumentFragment) {
-      var nodes = [];
-      var i = 0;
-      for (var child = node.firstChild; child; child = child.nextSibling) {
-        nodes[i++] = child;
-      }
-      return nodes;
+  function collectNodesNative(node) {
+    if (node instanceof DocumentFragment)
+      return collectNodesForDocumentFragment(node);
+
+    var nodes = createOneElementNodeList(node);
+    var oldParent = node.parentNode;
+    if (oldParent)
+      enqueueRemovalForInsertedNodes(node, oldParent, nodes);
+    return nodes;
+  }
+
+  function collectNodesForDocumentFragment(node) {
+    var nodes = new NodeList();
+    var i = 0;
+    for (var child = node.firstChild; child; child = child.nextSibling) {
+      nodes[i++] = child;
     }
-    return [node];
+    nodes.length = i;
+    enqueueRemovalForInsertedDocumentFragment(node, nodes);
+    return nodes;
+  }
+
+  function snapshotNodeList(nodeList) {
+    // NodeLists are not live at the moment so just return the same object.
+    return nodeList;
+  }
+
+  // http://dom.spec.whatwg.org/#node-is-inserted
+  function nodeWasAdded(node) {
+    node.nodeIsInserted_();
   }
 
   function nodesWereAdded(nodes) {
     for (var i = 0; i < nodes.length; i++) {
-      nodes[i].nodeWasAdded_();
+      nodeWasAdded(nodes[i]);
     }
   }
 
+  // http://dom.spec.whatwg.org/#node-is-removed
+  function nodeWasRemoved(node) {
+    // Nothing at this point in time.
+  }
+
+  function nodesWereRemoved(nodes) {
+    // Nothing at this point in time.
+  }
+
   function ensureSameOwnerDocument(parent, child) {
     var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ?
         parent : parent.ownerDocument;
@@ -2851,69 +3360,56 @@
   Node.prototype = Object.create(EventTarget.prototype);
   mixin(Node.prototype, {
     appendChild: function(childWrapper) {
-      assertIsNodeWrapper(childWrapper);
-
-      var nodes;
-
-      if (this.invalidateShadowRenderer() || invalidateParent(childWrapper)) {
-        var previousNode = this.lastChild;
-        var nextNode = null;
-        nodes = collectNodes(childWrapper, this, previousNode, nextNode);
-
-        this.lastChild_ = nodes[nodes.length - 1];
-        if (!previousNode)
-          this.firstChild_ = nodes[0];
-
-        originalAppendChild.call(this.impl, unwrapNodesForInsertion(this, nodes));
-      } else {
-        nodes = collectNodesNoNeedToUpdatePointers(childWrapper)
-        ensureSameOwnerDocument(this, childWrapper);
-        originalAppendChild.call(this.impl, unwrap(childWrapper));
-      }
-
-      nodesWereAdded(nodes);
-
-      return childWrapper;
+      return this.insertBefore(childWrapper, null);
     },
 
     insertBefore: function(childWrapper, refWrapper) {
-      // TODO(arv): Unify with appendChild
-      if (!refWrapper)
-        return this.appendChild(childWrapper);
-
       assertIsNodeWrapper(childWrapper);
-      assertIsNodeWrapper(refWrapper);
-      assert(refWrapper.parentNode === this);
+
+      refWrapper = refWrapper || null;
+      refWrapper && assertIsNodeWrapper(refWrapper);
+      refWrapper && assert(refWrapper.parentNode === this);
 
       var nodes;
+      var previousNode =
+          refWrapper ? refWrapper.previousSibling : this.lastChild;
 
-      if (this.invalidateShadowRenderer() || invalidateParent(childWrapper)) {
-        var previousNode = refWrapper.previousSibling;
-        var nextNode = refWrapper;
-        nodes = collectNodes(childWrapper, this, previousNode, nextNode);
+      var useNative = !this.invalidateShadowRenderer() &&
+                      !invalidateParent(childWrapper);
 
-        if (this.firstChild === refWrapper)
-          this.firstChild_ = nodes[0];
+      if (useNative)
+        nodes = collectNodesNative(childWrapper);
+      else
+        nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
 
-        // insertBefore refWrapper no matter what the parent is?
-        var refNode = unwrap(refWrapper);
-        var parentNode = refNode.parentNode;
-
-        if (parentNode) {
-          originalInsertBefore.call(
-              parentNode,
-              unwrapNodesForInsertion(this, nodes),
-              refNode);
-        } else {
-          adoptNodesIfNeeded(this, nodes);
-        }
-      } else {
-        nodes = collectNodesNoNeedToUpdatePointers(childWrapper);
+      if (useNative) {
         ensureSameOwnerDocument(this, childWrapper);
         originalInsertBefore.call(this.impl, unwrap(childWrapper),
                                   unwrap(refWrapper));
+      } 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?
+        if (parentNode) {
+          originalInsertBefore.call(parentNode,
+              unwrapNodesForInsertion(this, nodes), refNode);
+        } else {
+          adoptNodesIfNeeded(this, nodes);
+        }
       }
 
+      enqueueMutation(this, 'childList', {
+        addedNodes: nodes,
+        nextSibling: refWrapper,
+        previousSibling: previousNode
+      });
+
       nodesWereAdded(nodes);
 
       return childWrapper;
@@ -2939,15 +3435,15 @@
       }
 
       var childNode = unwrap(childWrapper);
-      if (this.invalidateShadowRenderer()) {
+      var childWrapperNextSibling = childWrapper.nextSibling;
+      var childWrapperPreviousSibling = childWrapper.previousSibling;
 
+      if (this.invalidateShadowRenderer()) {
         // We need to remove the real node from the DOM before updating the
         // pointers. This is so that that mutation event is dispatched before
         // the pointers have changed.
         var thisFirstChild = this.firstChild;
         var thisLastChild = this.lastChild;
-        var childWrapperNextSibling = childWrapper.nextSibling;
-        var childWrapperPreviousSibling = childWrapper.previousSibling;
 
         var parentNode = childNode.parentNode;
         if (parentNode)
@@ -2970,6 +3466,16 @@
         removeChildOriginalHelper(this.impl, childNode);
       }
 
+      if (!surpressMutations) {
+        enqueueMutation(this, 'childList', {
+          removedNodes: createOneElementNodeList(childWrapper),
+          nextSibling: childWrapperNextSibling,
+          previousSibling: childWrapperPreviousSibling
+        });
+      }
+
+      registerTransientObservers(this, childWrapper);
+
       return childWrapper;
     },
 
@@ -2983,16 +3489,22 @@
       }
 
       var oldChildNode = unwrap(oldChildWrapper);
+      var nextNode = oldChildWrapper.nextSibling;
+      var previousNode = oldChildWrapper.previousSibling;
       var nodes;
 
-      if (this.invalidateShadowRenderer() ||
-          invalidateParent(newChildWrapper)) {
-        var previousNode = oldChildWrapper.previousSibling;
-        var nextNode = oldChildWrapper.nextSibling;
+      var useNative = !this.invalidateShadowRenderer() &&
+                      !invalidateParent(newChildWrapper);
+
+      if (useNative) {
+        nodes = collectNodesNative(newChildWrapper);
+      } else {
         if (nextNode === newChildWrapper)
           nextNode = newChildWrapper.nextSibling;
         nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
+      }
 
+      if (!useNative) {
         if (this.firstChild === oldChildWrapper)
           this.firstChild_ = nodes[0];
         if (this.lastChild === oldChildWrapper)
@@ -3009,25 +3521,32 @@
               oldChildNode);
         }
       } else {
-        nodes = collectNodesNoNeedToUpdatePointers(newChildWrapper);
         ensureSameOwnerDocument(this, newChildWrapper);
         originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
                                   oldChildNode);
       }
 
+      enqueueMutation(this, 'childList', {
+        addedNodes: nodes,
+        removedNodes: createOneElementNodeList(oldChildWrapper),
+        nextSibling: nextNode,
+        previousSibling: previousNode
+      });
+
+      nodeWasRemoved(oldChildWrapper);
       nodesWereAdded(nodes);
 
       return oldChildWrapper;
     },
 
     /**
-     * Called after a node was added. Subclasses override this to invalidate
+     * Called after a node was inserted. Subclasses override this to invalidate
      * the renderer as needed.
      * @private
      */
-    nodeWasAdded_: function() {
+    nodeIsInserted_: function() {
       for (var child = this.firstChild; child; child = child.nextSibling) {
-        child.nodeWasAdded_();
+        child.nodeIsInserted_();
       }
     },
 
@@ -3084,6 +3603,8 @@
       return s;
     },
     set textContent(textContent) {
+      var removedNodes = snapshotNodeList(this.childNodes);
+
       if (this.invalidateShadowRenderer()) {
         removeAllChildNodes(this);
         if (textContent !== '') {
@@ -3093,6 +3614,16 @@
       } else {
         this.impl.textContent = textContent;
       }
+
+      var addedNodes = snapshotNodeList(this.childNodes);
+
+      enqueueMutation(this, 'childList', {
+        addedNodes: addedNodes,
+        removedNodes: removedNodes
+      });
+
+      nodesWereRemoved(removedNodes);
+      nodesWereAdded(addedNodes);
     },
 
     get childNodes() {
@@ -3106,9 +3637,6 @@
     },
 
     cloneNode: function(deep) {
-      if (!this.invalidateShadowRenderer())
-        return wrap(this.impl.cloneNode(deep));
-
       var clone = wrap(this.impl.cloneNode(false));
       if (deep) {
         for (var child = this.firstChild; child; child = child.nextSibling) {
@@ -3151,9 +3679,14 @@
   delete Node.prototype.querySelectorAll;
   Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
 
+  scope.nodeWasAdded = nodeWasAdded;
+  scope.nodeWasRemoved = nodeWasRemoved;
+  scope.nodesWereAdded = nodesWereAdded;
+  scope.nodesWereRemoved = nodesWereRemoved;
+  scope.snapshotNodeList = snapshotNodeList;
   scope.wrappers.Node = Node;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -3227,7 +3760,7 @@
   scope.GetElementsByInterface = GetElementsByInterface;
   scope.SelectorsInterface = SelectorsInterface;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3297,7 +3830,7 @@
   scope.ChildNodeInterface = ChildNodeInterface;
   scope.ParentNodeInterface = ParentNodeInterface;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3308,6 +3841,7 @@
 
   var ChildNodeInterface = scope.ChildNodeInterface;
   var Node = scope.wrappers.Node;
+  var enqueueMutation = scope.enqueueMutation;
   var mixin = scope.mixin;
   var registerWrapper = scope.registerWrapper;
 
@@ -3323,6 +3857,16 @@
     },
     set textContent(value) {
       this.data = value;
+    },
+    get data() {
+      return this.impl.data;
+    },
+    set data(value) {
+      var oldValue = this.impl.data;
+      enqueueMutation(this, 'characterData', {
+        oldValue: oldValue
+      });
+      this.impl.data = value;
     }
   });
 
@@ -3332,7 +3876,7 @@
                   document.createTextNode(''));
 
   scope.wrappers.CharacterData = CharacterData;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3347,6 +3891,7 @@
   var ParentNodeInterface = scope.ParentNodeInterface;
   var SelectorsInterface = scope.SelectorsInterface;
   var addWrapNodeListMethod = scope.addWrapNodeListMethod;
+  var enqueueMutation = scope.enqueueMutation;
   var mixin = scope.mixin;
   var oneOf = scope.oneOf;
   var registerWrapper = scope.registerWrapper;
@@ -3374,6 +3919,17 @@
       renderer.invalidate();
   }
 
+  function enqueAttributeChange(element, name, oldValue) {
+    // This is not fully spec compliant. We should use localName (which might
+    // have a different case than name) and the namespace (which requires us
+    // to get the Attr object).
+    enqueueMutation(element, 'attributes', {
+      name: name,
+      namespace: null,
+      oldValue: oldValue
+    });
+  }
+
   function Element(node) {
     Node.call(this, node);
   }
@@ -3394,12 +3950,16 @@
     },
 
     setAttribute: function(name, value) {
+      var oldValue = this.impl.getAttribute(name);
       this.impl.setAttribute(name, value);
+      enqueAttributeChange(this, name, oldValue);
       invalidateRendererBasedOnAttribute(this, name);
     },
 
     removeAttribute: function(name) {
+      var oldValue = this.impl.getAttribute(name);
       this.impl.removeAttribute(name);
+      enqueAttributeChange(this, name, oldValue);
       invalidateRendererBasedOnAttribute(this, name);
     },
 
@@ -3450,7 +4010,7 @@
   // that reflect attributes.
   scope.matchesName = matchesName;
   scope.wrappers.Element = Element;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3461,8 +4021,12 @@
 
   var Element = scope.wrappers.Element;
   var defineGetter = scope.defineGetter;
+  var enqueueMutation = scope.enqueueMutation;
   var mixin = scope.mixin;
+  var nodesWereAdded = scope.nodesWereAdded;
+  var nodesWereRemoved = scope.nodesWereRemoved;
   var registerWrapper = scope.registerWrapper;
+  var snapshotNodeList = scope.snapshotNodeList;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
 
@@ -3564,10 +4128,21 @@
       return getInnerHTML(this);
     },
     set innerHTML(value) {
+      var removedNodes = snapshotNodeList(this.childNodes);
+
       if (this.invalidateShadowRenderer())
         setInnerHTML(this, value, this.tagName);
       else
         this.impl.innerHTML = value;
+      var addedNodes = snapshotNodeList(this.childNodes);
+
+      enqueueMutation(this, 'childList', {
+        addedNodes: addedNodes,
+        removedNodes: removedNodes
+      });
+
+      nodesWereRemoved(removedNodes);
+      nodesWereAdded(addedNodes);
     },
 
     get outerHTML() {
@@ -3651,7 +4226,8 @@
   // TODO: Find a better way to share these two with WrapperShadowRoot.
   scope.getInnerHTML = getInnerHTML;
   scope.setInnerHTML = setInnerHTML
-})(this.ShadowDOMPolyfill);
+})(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.
@@ -3682,7 +4258,7 @@
                   document.createElement('canvas'));
 
   scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3724,7 +4300,8 @@
     registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
 
   scope.wrappers.HTMLContentElement = HTMLContentElement;
-})(this.ShadowDOMPolyfill);
+})(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.
@@ -3767,7 +4344,7 @@
 
   scope.wrappers.HTMLImageElement = HTMLImageElement;
   scope.wrappers.Image = Image;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3794,7 +4371,7 @@
     registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
 
   scope.wrappers.HTMLShadowElement = HTMLShadowElement;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3806,10 +4383,8 @@
   var HTMLElement = scope.wrappers.HTMLElement;
   var getInnerHTML = scope.getInnerHTML;
   var mixin = scope.mixin;
-  var muteMutationEvents = scope.muteMutationEvents;
   var registerWrapper = scope.registerWrapper;
   var setInnerHTML = scope.setInnerHTML;
-  var unmuteMutationEvents = scope.unmuteMutationEvents;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
 
@@ -3838,11 +4413,9 @@
     var doc = getTemplateContentsOwner(templateElement.ownerDocument);
     var df = unwrap(doc.createDocumentFragment());
     var child;
-    muteMutationEvents();
     while (child = templateElement.firstChild) {
       df.appendChild(child);
     }
-    unmuteMutationEvents();
     return df;
   }
 
@@ -3879,7 +4452,8 @@
     registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
 
   scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
-})(this.ShadowDOMPolyfill);
+})(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.
@@ -3901,7 +4475,7 @@
                   document.createElement('audio'));
 
   scope.wrappers.HTMLMediaElement = HTMLMediaElement;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -3944,7 +4518,7 @@
 
   scope.wrappers.HTMLAudioElement = HTMLAudioElement;
   scope.wrappers.Audio = Audio;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -4008,7 +4582,7 @@
 
   scope.wrappers.HTMLOptionElement = HTMLOptionElement;
   scope.wrappers.Option = Option;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -4040,7 +4614,8 @@
   HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
   registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
   scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
-})(this.ShadowDOMPolyfill);
+})(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.
@@ -4076,10 +4651,11 @@
     }
   });
 
-  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D);
+  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D,
+                  document.createElement('canvas').getContext('2d'));
 
   scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -4119,10 +4695,111 @@
     }
   });
 
-  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext);
+  // Blink/WebKit has broken DOM bindings. Usually we would create an instance
+  // of the object and pass it into registerWrapper as a "blueprint" but
+  // creating WebGL contexts is expensive and might fail so we use a dummy
+  // object with dummy instance properties for these broken browsers.
+  var instanceProperties = /WebKit/.test(navigator.userAgent) ?
+      {drawingBufferHeight: null, drawingBufferWidth: null} : {};
+
+  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext,
+      instanceProperties);
 
   scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
-})(this.ShadowDOMPolyfill);
+})(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.
+
+(function(scope) {
+  'use strict';
+
+  var registerWrapper = scope.registerWrapper;
+  var unwrap = scope.unwrap;
+  var unwrapIfNeeded = scope.unwrapIfNeeded;
+  var wrap = scope.wrap;
+
+  var OriginalRange = window.Range;
+
+  function Range(impl) {
+    this.impl = impl;
+  }
+  Range.prototype = {
+    get startContainer() {
+      return wrap(this.impl.startContainer);
+    },
+    get endContainer() {
+      return wrap(this.impl.endContainer);
+    },
+    get commonAncestorContainer() {
+      return wrap(this.impl.commonAncestorContainer);
+    },
+    setStart: function(refNode,offset) {
+      this.impl.setStart(unwrapIfNeeded(refNode), offset);
+    },
+    setEnd: function(refNode,offset) {
+      this.impl.setEnd(unwrapIfNeeded(refNode), offset);
+    },
+    setStartBefore: function(refNode) {
+      this.impl.setStartBefore(unwrapIfNeeded(refNode));
+    },
+    setStartAfter: function(refNode) {
+      this.impl.setStartAfter(unwrapIfNeeded(refNode));
+    },
+    setEndBefore: function(refNode) {
+      this.impl.setEndBefore(unwrapIfNeeded(refNode));
+    },
+    setEndAfter: function(refNode) {
+      this.impl.setEndAfter(unwrapIfNeeded(refNode));
+    },
+    selectNode: function(refNode) {
+      this.impl.selectNode(unwrapIfNeeded(refNode));
+    },
+    selectNodeContents: function(refNode) {
+      this.impl.selectNodeContents(unwrapIfNeeded(refNode));
+    },
+    compareBoundaryPoints: function(how, sourceRange) {
+      return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));
+    },
+    extractContents: function() {
+      return wrap(this.impl.extractContents());
+    },
+    cloneContents: function() {
+      return wrap(this.impl.cloneContents());
+    },
+    insertNode: function(node) {
+      this.impl.insertNode(unwrapIfNeeded(node));
+    },
+    surroundContents: function(newParent) {
+      this.impl.surroundContents(unwrapIfNeeded(newParent));
+    },
+    cloneRange: function() {
+      return wrap(this.impl.cloneRange());
+    },
+    isPointInRange: function(node, offset) {
+      return this.impl.isPointInRange(unwrapIfNeeded(node), offset);
+    },
+    comparePoint: function(node, offset) {
+      return this.impl.comparePoint(unwrapIfNeeded(node), offset);
+    },
+    intersectsNode: function(node) {
+      return this.impl.intersectsNode(unwrapIfNeeded(node));
+    }
+  };
+
+  // IE9 does not have createContextualFragment.
+  if (OriginalRange.prototype.createContextualFragment) {
+    Range.prototype.createContextualFragment = function(html) {
+      return wrap(this.impl.createContextualFragment(html));
+    };
+  }
+
+  registerWrapper(window.Range, Range, document.createRange());
+
+  scope.wrappers.Range = Range;
+
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -4149,7 +4826,7 @@
   scope.wrappers.DocumentFragment = DocumentFragment;
   scope.wrappers.Text = Text;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -4214,7 +4891,9 @@
   });
 
   scope.wrappers.ShadowRoot = ShadowRoot;
-})(this.ShadowDOMPolyfill);
+
+})(window.ShadowDOMPolyfill);
+
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -4229,9 +4908,7 @@
   var ShadowRoot = scope.wrappers.ShadowRoot;
   var assert = scope.assert;
   var mixin = scope.mixin;
-  var muteMutationEvents = scope.muteMutationEvents;
   var oneOf = scope.oneOf;
-  var unmuteMutationEvents = scope.unmuteMutationEvents;
   var unwrap = scope.unwrap;
   var wrap = scope.wrap;
 
@@ -4575,11 +5252,8 @@
         this.renderNode(shadowRoot, renderNode, node, false);
       }
 
-      if (topMostRenderer) {
-        //muteMutationEvents();
+      if (topMostRenderer)
         renderNode.sync();
-        //unmuteMutationEvents();
-      }
 
       this.dirty = false;
     },
@@ -4849,8 +5523,8 @@
     return getDistributedChildNodes(this);
   };
 
-  HTMLShadowElement.prototype.nodeWasAdded_ =
-  HTMLContentElement.prototype.nodeWasAdded_ = function() {
+  HTMLShadowElement.prototype.nodeIsInserted_ =
+  HTMLContentElement.prototype.nodeIsInserted_ = function() {
     // Invalidate old renderer if any.
     this.invalidateShadowRenderer();
 
@@ -4875,7 +5549,8 @@
     remove: remove,
   };
 
-})(this.ShadowDOMPolyfill);
+})(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.
@@ -4929,7 +5604,7 @@
 
   elementsWithFormProperty.forEach(createWrapperConstructor);
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -5013,6 +5688,8 @@
       doc.adoptNode(oldShadowRoot);
   }
 
+  var originalImportNode = document.importNode;
+
   mixin(Document.prototype, {
     adoptNode: function(node) {
       if (node.parentNode)
@@ -5022,6 +5699,17 @@
     },
     elementFromPoint: function(x, y) {
       return elementFromPoint(this, this, x, y);
+    },
+    importNode: function(node, deep) {
+      // We need to manually walk the tree to ensure we do not include rendered
+      // shadow trees.
+      var clone = wrap(originalImportNode.call(this.impl, unwrap(node), false));
+      if (deep) {
+        for (var child = node.firstChild; child; child = child.nextSibling) {
+          clone.appendChild(this.importNode(child, true));
+        }
+      }
+      return clone;
     }
   });
 
@@ -5140,6 +5828,7 @@
     window.HTMLDocument || window.Document,  // Gecko adds these to HTMLDocument
   ], [
     'adoptNode',
+    'importNode',
     'contains',
     'createComment',
     'createDocumentFragment',
@@ -5221,7 +5910,7 @@
   scope.wrappers.DOMImplementation = DOMImplementation;
   scope.wrappers.Document = Document;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -5271,188 +5960,7 @@
 
   scope.wrappers.Window = Window;
 
-})(this.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.
-
-(function(scope) {
-  'use strict';
-
-  var defineGetter = scope.defineGetter;
-  var defineWrapGetter = scope.defineWrapGetter;
-  var registerWrapper = scope.registerWrapper;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrapNodeList = scope.wrapNodeList;
-  var wrappers = scope.wrappers;
-
-  var OriginalMutationObserver = window.MutationObserver ||
-      window.WebKitMutationObserver;
-
-  if (!OriginalMutationObserver)
-    return;
-
-  var OriginalMutationRecord = window.MutationRecord;
-
-  function MutationRecord(impl) {
-    this.impl = impl;
-  }
-
-  MutationRecord.prototype = {
-    get addedNodes() {
-      return wrapNodeList(this.impl.addedNodes);
-    },
-    get removedNodes() {
-      return wrapNodeList(this.impl.removedNodes);
-    }
-  };
-
-  ['target', 'previousSibling', 'nextSibling'].forEach(function(name) {
-    defineWrapGetter(MutationRecord, name);
-  });
-
-  // WebKit/Blink treats these as instance properties so we override
-  [
-    'type',
-    'attributeName',
-    'attributeNamespace',
-    'oldValue'
-  ].forEach(function(name) {
-    defineGetter(MutationRecord, name, function() {
-      return this.impl[name];
-    });
-  });
-
-  if (OriginalMutationRecord)
-    registerWrapper(OriginalMutationRecord, MutationRecord);
-
-  function wrapRecord(record) {
-    return new MutationRecord(record);
-  }
-
-  function wrapRecords(records) {
-    return records.map(wrapRecord);
-  }
-
-  function MutationObserver(callback) {
-    var self = this;
-    this.impl = new OriginalMutationObserver(function(mutations, observer) {
-      callback.call(self, wrapRecords(mutations), self);
-    });
-  }
-
-  var OriginalNode = window.Node;
-
-  MutationObserver.prototype = {
-    observe: function(target, options) {
-      this.impl.observe(unwrapIfNeeded(target), options);
-    },
-    disconnect: function() {
-      this.impl.disconnect();
-    },
-    takeRecords: function() {
-      return wrapRecords(this.impl.takeRecords());
-    }
-  };
-
-  scope.wrappers.MutationObserver = MutationObserver;
-  scope.wrappers.MutationRecord = MutationRecord;
-
-})(this.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.
-
-(function(scope) {
-  'use strict';
-
-  var registerWrapper = scope.registerWrapper;
-  var unwrap = scope.unwrap;
-  var unwrapIfNeeded = scope.unwrapIfNeeded;
-  var wrap = scope.wrap;
-
-  var OriginalRange = window.Range;
-
-  function Range(impl) {
-    this.impl = impl;
-  }
-  Range.prototype = {
-    get startContainer() {
-      return wrap(this.impl.startContainer);
-    },
-    get endContainer() {
-      return wrap(this.impl.endContainer);
-    },
-    get commonAncestorContainer() {
-      return wrap(this.impl.commonAncestorContainer);
-    },
-    setStart: function(refNode,offset) {
-      this.impl.setStart(unwrapIfNeeded(refNode), offset);
-    },
-    setEnd: function(refNode,offset) {
-      this.impl.setEnd(unwrapIfNeeded(refNode), offset);
-    },
-    setStartBefore: function(refNode) {
-      this.impl.setStartBefore(unwrapIfNeeded(refNode));
-    },
-    setStartAfter: function(refNode) {
-      this.impl.setStartAfter(unwrapIfNeeded(refNode));
-    },
-    setEndBefore: function(refNode) {
-      this.impl.setEndBefore(unwrapIfNeeded(refNode));
-    },
-    setEndAfter: function(refNode) {
-      this.impl.setEndAfter(unwrapIfNeeded(refNode));
-    },
-    selectNode: function(refNode) {
-      this.impl.selectNode(unwrapIfNeeded(refNode));
-    },
-    selectNodeContents: function(refNode) {
-      this.impl.selectNodeContents(unwrapIfNeeded(refNode));
-    },
-    compareBoundaryPoints: function(how, sourceRange) {
-      return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));
-    },
-    extractContents: function() {
-      return wrap(this.impl.extractContents());
-    },
-    cloneContents: function() {
-      return wrap(this.impl.cloneContents());
-    },
-    insertNode: function(node) {
-      this.impl.insertNode(unwrapIfNeeded(node));
-    },
-    surroundContents: function(newParent) {
-      this.impl.surroundContents(unwrapIfNeeded(newParent));
-    },
-    cloneRange: function() {
-      return wrap(this.impl.cloneRange());
-    },
-    isPointInRange: function(node, offset) {
-      return this.impl.isPointInRange(unwrapIfNeeded(node), offset);
-    },
-    comparePoint: function(node, offset) {
-      return this.impl.comparePoint(unwrapIfNeeded(node), offset);
-    },
-    intersectsNode: function(node) {
-      return this.impl.intersectsNode(unwrapIfNeeded(node));
-    }
-  };
-
-  // IE9 does not have createContextualFragment.
-  if (OriginalRange.prototype.createContextualFragment) {
-    Range.prototype.createContextualFragment = function(html) {
-      return wrap(this.impl.createContextualFragment(html));
-    };
-  }
-
-  registerWrapper(window.Range, Range);
-
-  scope.wrappers.Range = Range;
-
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
 
 // Copyright 2013 The Polymer Authors. All rights reserved.
 // Use of this source code is goverened by a BSD-style
@@ -5554,7 +6062,8 @@
   // Export for testing.
   scope.knownElements = elements;
 
-})(this.ShadowDOMPolyfill);
+})(window.ShadowDOMPolyfill);
+
 /*
  * Copyright 2013 The Polymer Authors. All rights reserved.
  * Use of this source code is governed by a BSD-style
@@ -6043,11 +6552,16 @@
     return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) {
       p1 = polyfillHostNoCombinator;
       if (p2) {
-        if (p2.match(polyfillHost)) {
-          return p1 + p2.replace(polyfillHost, '') + p3;
-        } else {
-          return p1 + p2 + p3 + ', ' + p2 + ' ' + p1 + p3;
+        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);
+          }
         }
+        return r.join(',');
       } else {
         return p1 + p3;
       }
@@ -6057,7 +6571,7 @@
    * Convert ^ and ^^ combinators by replacing with space.
   */
   convertCombinators: function(cssText) {
-    return cssText.replace('^^', ' ').replace('^', ' ');
+    return cssText.replace(/\^\^/g, ' ').replace(/\^/g, ' ');
   },
   // change a selector like 'div' to 'name div'
   scopeRules: function(cssRules, name, typeExtension) {
@@ -6069,7 +6583,7 @@
         cssText += this.propertiesFromRule(rule) + '\n}\n\n';
       } else if (rule.media) {
         cssText += '@media ' + rule.media.mediaText + ' {\n';
-        cssText += this.scopeRules(rule.cssRules, name);
+        cssText += this.scopeRules(rule.cssRules, name, typeExtension);
         cssText += '\n}\n\n';
       } else if (rule.cssText) {
         cssText += rule.cssText + '\n\n';
@@ -6082,8 +6596,9 @@
     parts.forEach(function(p) {
       p = p.trim();
       if (this.selectorNeedsScoping(p, name, typeExtension)) {
-        p = strict ? this.applyStrictSelectorScope(p, name) :
-          this.applySimpleSelectorScope(p, name, typeExtension);
+        p = (strict && !p.match(polyfillHostNoCombinator)) ? 
+            this.applyStrictSelectorScope(p, name) :
+            this.applySimpleSelectorScope(p, name, typeExtension);
       }
       r.push(p);
     }, this);
@@ -6131,14 +6646,7 @@
         polyfillHost);
   },
   propertiesFromRule: function(rule) {
-    var properties = rule.style.cssText;
-    // TODO(sorvell): Chrome cssom incorrectly removes quotes from the content
-    // property. (https://code.google.com/p/chromium/issues/detail?id=247231)
-    if (rule.style.content && !rule.style.content.match(/['"]+/)) {
-      properties = 'content: \'' + rule.style.content + '\';\n' + 
-        rule.style.cssText.replace(/content:[^;]*;/g, '');
-    }
-    return properties;
+    return rule.style.cssText;
   }
 };
 
@@ -6152,15 +6660,18 @@
     cssPolyfillUnscopedRuleCommentRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
     cssPseudoRe = /::(x-[^\s{,(]*)/gim,
     cssPartRe = /::part\(([^)]*)\)/gim,
-    // note: :host pre-processed to -host.
-    cssColonHostRe = /(-host)(?:\(([^)]*)\))?([^,{]*)/gim,
+    // note: :host pre-processed to -shadowcsshost.
+    polyfillHost = '-shadowcsshost',
+    cssColonHostRe = new RegExp('(' + polyfillHost +
+        ')(?:\\((' +
+        '(?:\\([^)(]*\\)|[^)(]*)+?' +
+        ')\\))?([^,{]*)', 'gim'),
     selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
     hostRe = /@host/gim,
     colonHostRe = /\:host/gim,
-    polyfillHost = '-host',
     /* host name without combinator */
-    polyfillHostNoCombinator = '-host-no-combinator',
-    polyfillHostRe = /-host/gim;
+    polyfillHostNoCombinator = polyfillHost + '-no-combinator',
+    polyfillHostRe = new RegExp(polyfillHost, 'gim');
 
 function stylesToCssText(styles, preserveComments) {
   var cssText = '';
@@ -7786,7 +8297,7 @@
 call$3:function(a,b,c){return this.nn.call(this.wc,a,b,c)}}]
 $$.zy=[H,{"":"Tp;call$2,$name",$is_bh:true}]
 $$.Nb=[H,{"":"Tp;call$1,$name",$is_HB:true,$is_Dv:true}]
-$$.HB=[H,{"":"Tp;call$0,$name",$is_X0:true}]
+$$.Fy=[H,{"":"Tp;call$0,$name",$is_X0:true}]
 $$.eU=[H,{"":"Tp;call$7,$name"}]
 $$.ADW=[P,{"":"Tp;call$2,$name",
 call$1:function(a){return this.call$2(a,null)},
@@ -7805,7 +8316,7 @@
 call$catchAll:function(){return{onError:null,radix:null}},
 $is_HB:true,
 $is_Dv:true}]
-;init.mangledNames={gAQ:"iconClass",gB:"length",gDb:"_cachedDeclarations",gEI:"prefix",gF1:"isolate",gFJ:"__$cls",gFT:"__$instruction",gFU:"_cachedMethodsMap",gG1:"message",gH8:"_fieldsDescriptor",gHt:"_fieldsMetadata",gKM:"$",gLy:"_cachedSetters",gM2:"_cachedVariables",gMj:"function",gNI:"instruction",gOk:"_cachedMetadata",gP:"value",gP2:"_collapsed",gPw:"__$isolate",gPy:"__$error",gQG:"app",gQq:"__$trace",gRu:"cls",gT1:"_cachedGetters",gTn:"json",gTx:"_jsConstructorOrInterceptor",gUF:"_cachedTypeVariables",gVA:"__$displayValue",gVB:"error_obj",gWL:"_mangledName",gXB:"_message",gXf:"__$iconClass",gZ6:"locationManager",gZw:"__$code",ga:"a",gai:"displayValue",gb:"b",gb0:"_cachedConstructors",gcC:"hash",geb:"__$json",ghO:"__$error_obj",gi0:"__$name",gi2:"isolates",giI:"__$library",gjO:"id",gjd:"_cachedMethods",gkc:"error",gkf:"_count",gle:"_metadata",glw:"requestManager",gn2:"responses",gnI:"isolateManager",gnz:"_owner",goc:"name",gpz:"_jsConstructorCache",gqN:"_superclass",gql:"__$function",gqm:"_cachedSuperinterfaces",gt0:"field",gtB:"_cachedFields",gtD:"library",gtH:"__$app",gtN:"trace",gtT:"code",guA:"_cachedMembers",gvH:"index",gvt:"__$field",gxj:"collapsed",gzd:"currentHash"};init.mangledGlobalNames={DI:"_closeIconClass",Vl:"_openIconClass"};(function (reflectionData) {
+;init.mangledNames={gB:"length",gCr:"_mangledName",gCt:"paddedLine",gDb:"_cachedDeclarations",gEI:"prefix",gF1:"isolate",gFF:"source",gFJ:"__$cls",gFT:"__$instruction",gFU:"_cachedMethodsMap",gG1:"message",gH8:"_fieldsDescriptor",gHX:"__$displayValue",gHt:"_fieldsMetadata",gKM:"$",gLA:"src",gLy:"_cachedSetters",gM2:"_cachedVariables",gMj:"function",gNI:"instruction",gNl:"script",gO3:"url",gOk:"_cachedMetadata",gP:"value",gPw:"__$isolate",gPy:"__$error",gQG:"app",gQq:"__$trace",gRu:"cls",gT1:"_cachedGetters",gTn:"json",gTx:"_jsConstructorOrInterceptor",gUF:"_cachedTypeVariables",gUy:"_collapsed",gUz:"__$script",gVB:"error_obj",gXB:"_message",gXJ:"lines",gXR:"scripts",gZ6:"locationManager",gZw:"__$code",ga:"a",gai:"displayValue",gb:"b",gb0:"_cachedConstructors",gcC:"hash",geb:"__$json",gfY:"kind",ghO:"__$error_obj",ghm:"__$app",gi0:"__$name",gi2:"isolates",giI:"__$library",gjO:"id",gjd:"_cachedMethods",gkc:"error",gkf:"_count",gl7:"iconClass",glD:"currentHashUri",gle:"_metadata",glw:"requestManager",gn2:"responses",gnI:"isolateManager",gnz:"_owner",goc:"name",gpz:"_jsConstructorCache",gqN:"_superclass",gql:"__$function",gqm:"_cachedSuperinterfaces",gt0:"field",gtB:"_cachedFields",gtD:"library",gtN:"trace",gtT:"code",guA:"_cachedMembers",gvH:"index",gvX:"__$source",gvt:"__$field",gxj:"collapsed",gzd:"currentHash",gzh:"__$iconClass"};init.mangledGlobalNames={DI:"_closeIconClass",Vl:"_openIconClass"};(function (reflectionData) {
   function map(x){x={x:x};delete x.x;return x}
   if (!init.libraries) init.libraries = [];
   if (!init.mangledNames) init.mangledNames = map();
@@ -7915,22 +8426,31 @@
 if(typeof z!=="number")throw z.g()
 return J.UQ(y,z+2)[b]},Gv:{"":"a;",
 n:function(a,b){return a===b},
+"+==:1:0":0,
 giO:function(a){return H.eQ(a)},
+"+hashCode":0,
 bu:function(a){return H.a5(a)},
+"+toString:0:0":0,
 T:function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},
 "+noSuchMethod:1:0":0,
 gbx:function(a){return new H.cu(H.dJ(a),null)},
 $isGv:true,
 "%":"DOMImplementation|SVGAnimatedEnumeration|SVGAnimatedNumberList|SVGAnimatedString"},kn:{"":"bool/Gv;",
 bu:function(a){return String(a)},
+"+toString:0:0":0,
 giO:function(a){return a?519018:218159},
+"+hashCode":0,
 gbx:function(a){return C.HL},
 $isbool:true},PE:{"":"Gv;",
 n:function(a,b){return null==b},
+"+==:1:0":0,
 bu:function(a){return"null"},
+"+toString:0:0":0,
 giO:function(a){return 0},
+"+hashCode":0,
 gbx:function(a){return C.GX}},QI:{"":"Gv;",
 giO:function(a){return 0},
+"+hashCode":0,
 gbx:function(a){return C.CS}},Tm:{"":"QI;"},is:{"":"QI;"},Q:{"":"List/Gv;",
 h:function(a,b){if(!!a.fixed$length)H.vh(P.f("add"))
 a.push(b)},
@@ -8003,12 +8523,14 @@
 gor:function(a){return a.length!==0},
 "+isNotEmpty":0,
 bu:function(a){return H.mx(a,"[","]")},
+"+toString:0:0":0,
 tt:function(a,b){return P.F(a,b,H.W8(a,"Q",0))},
 br:function(a){return this.tt(a,!0)},
 gA:function(a){var z=new H.a7(a,a.length,0,null)
 H.VM(z,[H.W8(a,"Q",0)])
 return z},
 giO:function(a){return H.eQ(a)},
+"+hashCode":0,
 gB:function(a){return a.length},
 "+length":0,
 sB:function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(new P.AT(b))
@@ -8054,9 +8576,13 @@
 HG:function(a){return this.yu(this.UD(a))},
 UD:function(a){if(a<0)return-Math.round(-a)
 else return Math.round(a)},
+WZ:function(a,b){if(b<2||b>36)throw H.b(P.C3(b))
+return a.toString(b)},
 bu:function(a){if(a===0&&1/a<0)return"-0.0"
 else return""+a},
+"+toString:0:0":0,
 giO:function(a){return a&0x1FFFFFFF},
+"+hashCode":0,
 J:function(a){return-a},
 g:function(a,b){if(typeof b!=="number")throw H.b(new P.AT(b))
 return a+b},
@@ -8087,7 +8613,7 @@
 F:function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
 return a>=b},
 $isnum:true,
-static:{"":"Cv,nr",}},im:{"":"int/P;",
+static:{"":"l8,nr",}},im:{"":"int/P;",
 gbx:function(a){return C.yw},
 $isdouble:true,
 $isnum:true,
@@ -8179,12 +8705,14 @@
 else z=a<b?-1:1
 return z},
 bu:function(a){return a},
+"+toString:0:0":0,
 giO:function(a){var z,y,x
 for(z=a.length,y=0,x=0;x<z;++x){y=536870911&y+a.charCodeAt(x)
 y=536870911&y+((524287&y)<<10>>>0)
 y^=y>>6}y=536870911&y+((67108863&y)<<3>>>0)
 y^=y>>11
 return 536870911&y+((16383&y)<<15>>>0)},
+"+hashCode":0,
 gbx:function(a){return C.Db},
 gB:function(a){return a.length},
 "+length":0,
@@ -8286,7 +8814,7 @@
 return z.YQ(a)}else{z=new H.NO(new H.X1())
 z.mR=new H.aJ(null)
 return z.YQ(a)}},Hh:function(a){if($globalState.ji===!0)return new H.II(null).QS(a)
-else return a},vM:function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},kV:function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},PK:{"":"Tp;a",
+else return a},VO:function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},kV:function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},PK:{"":"Tp;a",
 call$0:function(){this.a.call$1([])},
 "+call:0:0":0,
 $isEH:true,
@@ -8373,8 +8901,8 @@
 P.rT(C.RT,this)},
 "+call:0:0":0,
 $isEH:true,
-$is_X0:true},IY:{"":"a;F1*,i3,G1*",
-VU:function(){this.F1.vV(this.i3)},
+$is_X0:true},IY:{"":"a;F1*,xh,G1*",
+VU:function(){this.F1.vV(this.xh)},
 $isIY:true},JH:{"":"a;"},jl:{"":"Tp;a,b,c,d,e",
 call$0:function(){H.Kc(this.a,this.b,this.c,this.d,this.e)},
 "+call:0:0":0,
@@ -8385,7 +8913,9 @@
 if(b==null)return!1
 z=J.x(b)
 return typeof b==="object"&&b!==null&&!!z.$isJM&&J.xC(this.JE,b.JE)},
+"+==:1:0":0,
 giO:function(a){return this.JE.gng()},
+"+hashCode":0,
 $isJM:true,
 $isbC:true},Ua:{"":"Tp;b,c",
 call$0:function(){var z,y,x,w,v,u,t
@@ -8421,12 +8951,14 @@
 if(b==null)return!1
 z=J.x(b)
 return typeof b==="object"&&b!==null&&!!z.$isns&&J.xC(this.Ws,b.Ws)&&J.xC(this.tv,b.tv)&&J.xC(this.bv,b.bv)},
+"+==:1:0":0,
 giO:function(a){var z,y,x
-z=J.Eh(this.Ws,16)
-y=J.Eh(this.tv,8)
+z=J.c1(this.Ws,16)
+y=J.c1(this.tv,8)
 x=this.bv
 if(typeof x!=="number")throw H.s(x)
 return(z^y^x)>>>0},
+"+hashCode":0,
 $isns:true,
 $isbC:true},wd:{"":"Tp;a,b",
 call$0:function(){var z,y,x,w
@@ -8517,7 +9049,7 @@
 Hn:function(a){},
 F4:function(){}},HU:{"":"a;",
 YQ:function(a){var z,y
-if(H.vM(a))return this.Pq(a)
+if(H.VO(a))return this.Pq(a)
 y=this.mR
 y.Hn(y)
 z=null
@@ -8777,11 +9309,11 @@
 if(q==null){if(c==null)z=[]
 else{z=c.gvc(c)
 z=P.F(z,!0,H.W8(z,"mW",0))}return J.jf(a,new H.LI(C.Ka,r,0,x,z,null))}return q.apply(a,x)},pL:function(a){if(a=="String")return C.Kn
-if(a=="int")return C.c1
+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.E3
+if(a=="List")return C.l0
 return init.allClasses[a]},Pq:function(){var z={x:0}
 delete z.x
 return z},s:function(a){throw H.b(P.u(a))},e:function(a,b){if(a==null)J.q8(a)
@@ -9062,6 +9594,7 @@
 gor:function(a){return!J.xC(this.gB(this),0)},
 "+isNotEmpty":0,
 bu:function(a){return P.vW(this)},
+"+toString:0:0":0,
 q3:function(){throw H.b(P.f("Cannot modify unmodifiable Map"))},
 u:function(a,b,c){return this.q3()},
 "+[]=:2:0":0,
@@ -9250,6 +9783,7 @@
 bu:function(a){var z=this.Sp
 if(z==null)return"NullError: "+H.d(this.Zf)
 return"NullError: Cannot call \""+H.d(z)+"\" on null"},
+"+toString:0:0":0,
 $ismp:true,
 $isGe:true},az:{"":"Ge;Zf,Sp,lv",
 bu:function(a){var z,y
@@ -9258,6 +9792,7 @@
 y=this.lv
 if(y==null)return"NoSuchMethodError: Cannot call \""+z+"\" ("+H.d(this.Zf)+")"
 return"NoSuchMethodError: Cannot call \""+z+"\" on \""+y+"\" ("+H.d(this.Zf)+")"},
+"+toString:0:0":0,
 $ismp:true,
 $isGe:true,
 static:{T3:function(a,b){var z,y
@@ -9266,7 +9801,8 @@
 z=z?null:b.receiver
 return new H.az(a,y,z)}}},vV:{"":"Ge;Zf",
 bu:function(a){var z=this.Zf
-return C.xB.gl0(z)?"Error":"Error: "+z}},Hk:{"":"Tp;a",
+return C.xB.gl0(z)?"Error":"Error: "+z},
+"+toString:0:0":0},Hk:{"":"Tp;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},
@@ -9281,7 +9817,8 @@
 y=typeof z==="object"?z.stack:null
 z=y==null?"":y
 this.bQ=z
-return z}},dr:{"":"Tp;a",
+return z},
+"+toString:0:0":0},dr:{"":"Tp;a",
 call$0:function(){return this.a.call$0()},
 "+call:0:0":0,
 $isEH:true,
@@ -9303,6 +9840,7 @@
 $isEH:true,
 $is_X0:true},Tp:{"":"a;",
 bu:function(a){return"Closure"},
+"+toString:0:0":0,
 $isTp:true,
 $isEH:true},v:{"":"Tp;wc<,nn<,lv,Pp>",
 n:function(a,b){var z
@@ -9311,17 +9849,21 @@
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isv)return!1
 return this.wc===b.wc&&this.nn===b.nn&&this.lv===b.lv},
+"+==:1:0":0,
 giO:function(a){var z,y
 z=this.lv
 if(z==null)y=H.eQ(this.wc)
 else y=typeof z!=="object"?J.v1(z):H.eQ(z)
 return(y^H.eQ(this.nn))>>>0},
+"+hashCode":0,
 $isv:true},Z3:{"":"a;Jy"},D2:{"":"a;Jy"},GT:{"":"a;oc>"},Pe:{"":"Ge;G1>",
 bu:function(a){return this.G1},
+"+toString:0:0":0,
 $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>",
 bu:function(a){return"RuntimeError: "+this.G1},
-static:{Pa:function(a){return new H.Eq(a)}}},cu:{"":"a;IE<,rE",
+"+toString:0:0":0,
+static:{Ef:function(a){return new H.Eq(a)}}},cu:{"":"a;IE<,rE",
 bu:function(a){var z,y,x
 z=this.rE
 if(z!=null)return z
@@ -9330,11 +9872,14 @@
 y=x==null?y:x
 this.rE=y
 return y},
+"+toString:0:0":0,
 giO:function(a){return J.v1(this.IE)},
+"+hashCode":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
 return typeof b==="object"&&b!==null&&!!z.$iscu&&J.xC(this.IE,b.IE)},
+"+==:1:0":0,
 $iscu:true,
 $isuq:true},Lm:{"":"a;h7<,oc>,kU>"},dC:{"":"Tp;a",
 call$1:function(a){return this.a(a)},
@@ -9435,14 +9980,14 @@
 t:function(a,b){if(!J.xC(b,0))H.vh(P.N(b))
 return this.zO},
 "+[]:1:0":0,
-$isOd:true}}],["app_bootstrap","index.html_bootstrap.dart",,E,{E2:function(){$.x2=["package:observatory/src/observatory_elements/observatory_element.dart","package:observatory/src/observatory_elements/error_view.dart","package:observatory/src/observatory_elements/class_view.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/json_view.dart","package:observatory/src/observatory_elements/library_view.dart","package:observatory/src/observatory_elements/stack_trace.dart","package:observatory/src/observatory_elements/message_viewer.dart","package:observatory/src/observatory_elements/navigation_bar.dart","package:observatory/src/observatory_elements/response_viewer.dart","package:observatory/src/observatory_elements/observatory_application.dart","index.html.0.dart"]
+$isOd:true}}],["app_bootstrap","index.html_bootstrap.dart",,E,{E2:function(){$.x2=["package:observatory/src/observatory_elements/observatory_element.dart","package:observatory/src/observatory_elements/error_view.dart","package:observatory/src/observatory_elements/class_view.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/json_view.dart","package:observatory/src/observatory_elements/library_view.dart","package:observatory/src/observatory_elements/source_view.dart","package:observatory/src/observatory_elements/script_view.dart","package:observatory/src/observatory_elements/stack_trace.dart","package:observatory/src/observatory_elements/message_viewer.dart","package:observatory/src/observatory_elements/navigation_bar.dart","package:observatory/src/observatory_elements/response_viewer.dart","package:observatory/src/observatory_elements/observatory_application.dart","index.html.0.dart"]
 $.uP=!1
-A.Ok()}},1],["class_view_element","package:observatory/src/observatory_elements/class_view.dart",,Z,{aC:{"":["Vf;FJ%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+A.Ok()}},1],["class_view_element","package:observatory/src/observatory_elements/class_view.dart",,Z,{aC:{"":["Vf;FJ%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gRu:function(a){return a.FJ
-"32,33,34"},
+"34,35,36"},
 "+cls":1,
-sRu:function(a,b){a.FJ=this.pD(a,C.XA,a.FJ,b)
-"35,28,32,33"},
+sRu:function(a,b){a.FJ=this.ct(a,C.XA,a.FJ,b)
+"37,28,34,35"},
 "+cls=":1,
 "@":function(){return[C.aQ]},
 static:{zg:function(a){var z,y,x,w,v
@@ -9458,12 +10003,12 @@
 C.kk.ZL(a)
 C.kk.FH(a)
 return a
-"9"},"+new ClassViewElement$created:0:0":1}},"+ClassViewElement": [36],Vf:{"":"uL+Pi;",$isd3:true}}],["code_view_element","package:observatory/src/observatory_elements/code_view.dart",,F,{Be:{"":["tu;Zw%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"9"},"+new ClassViewElement$created:0:0":1}},"+ClassViewElement": [38],Vf:{"":"uL+Pi;",$isd3:true}}],["code_view_element","package:observatory/src/observatory_elements/code_view.dart",,F,{Be:{"":["tu;Zw%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gtT:function(a){return a.Zw
-"32,33,34"},
+"34,35,36"},
 "+code":1,
-stT:function(a,b){a.Zw=this.pD(a,C.b1,a.Zw,b)
-"35,28,32,33"},
+stT:function(a,b){a.Zw=this.ct(a,C.b1,a.Zw,b)
+"37,28,34,35"},
 "+code=":1,
 grK:function(a){var z=a.Zw
 if(z!=null&&J.UQ(z,"is_optimized")!=null)return"panel panel-success"
@@ -9487,41 +10032,41 @@
 C.YD.ZL(a)
 C.YD.FH(a)
 return a
-"10"},"+new CodeViewElement$created:0:0":1}},"+CodeViewElement": [37],tu:{"":"uL+Pi;",$isd3:true}}],["collapsible_content_element","package:observatory/src/observatory_elements/collapsible_content.dart",,R,{i6:{"":["Vc;Xf%-,VA%-,P2%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
-gAQ:function(a){return a.Xf
-"8,33,38"},
+"10"},"+new CodeViewElement$created:0:0":1}},"+CodeViewElement": [39],tu:{"":"uL+Pi;",$isd3:true}}],["collapsible_content_element","package:observatory/src/observatory_elements/collapsible_content.dart",,R,{i6:{"":["Vc;zh%-,HX%-,Uy%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",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
+"8,35,40"},
 "+iconClass":1,
-sAQ:function(a,b){a.Xf=this.pD(a,C.Di,a.Xf,b)
-"35,28,8,33"},
+sl7:function(a,b){a.zh=this.ct(a,C.Di,a.zh,b)
+"37,28,8,35"},
 "+iconClass=":1,
-gai:function(a){return a.VA
-"8,33,38"},
+gai:function(a){return a.HX
+"8,35,40"},
 "+displayValue":1,
-sai:function(a,b){a.VA=this.pD(a,C.Jw,a.VA,b)
-"35,28,8,33"},
+sai:function(a,b){a.HX=this.ct(a,C.Jw,a.HX,b)
+"37,28,8,35"},
 "+displayValue=":1,
-gxj:function(a){return a.P2
-"39"},
+gxj:function(a){return a.Uy
+"41"},
 "+collapsed":1,
-sxj:function(a,b){a.P2=b
-this.dR(a)
-"35,40,39"},
+sxj:function(a,b){a.Uy=b
+this.SS(a)
+"37,42,41"},
 "+collapsed=":1,
 i4:function(a){Z.uL.prototype.i4.call(this,a)
-this.dR(a)
-"35"},
+this.SS(a)
+"37"},
 "+enteredView:0:0":1,
-rS:function(a,b,c,d){a.P2=a.P2!==!0
-this.dR(a)
-this.dR(a)
-"35,41,42,43,35,44,45"},
+rS:function(a,b,c,d){a.Uy=a.Uy!==!0
+this.SS(a)
+this.SS(a)
+"37,43,44,45,37,46,47"},
 "+toggleDisplay:3:0":1,
-dR:function(a){var z,y
-z=a.P2
-y=a.Xf
-if(z===!0){a.Xf=this.pD(a,C.Di,y,"glyphicon glyphicon-chevron-down")
-a.VA=this.pD(a,C.Jw,a.VA,"none")}else{a.Xf=this.pD(a,C.Di,y,"glyphicon glyphicon-chevron-up")
-a.VA=this.pD(a,C.Jw,a.VA,"block")}"35"},
+SS:function(a){var z,y
+z=a.Uy
+y=a.zh
+if(z===!0){a.zh=this.ct(a,C.Di,y,"glyphicon glyphicon-chevron-down")
+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")}"37"},
 "+_refresh:0:0":1,
 "@":function(){return[C.Gu]},
 static:{"":"Vl<-,DI<-",IT:function(a){var z,y,x,w,v
@@ -9531,16 +10076,16 @@
 w=W.cv
 v=new V.br(P.Py(null,null,null,x,w),null,null)
 H.VM(v,[x,w])
-a.Xf="glyphicon glyphicon-chevron-down"
-a.VA="none"
-a.P2=!0
+a.zh="glyphicon glyphicon-chevron-down"
+a.HX="none"
+a.Uy=!0
 a.Ye=z
 a.mT=y
 a.KM=v
 C.j8.ZL(a)
 C.j8.FH(a)
 return a
-"11"},"+new CollapsibleContentElement$created:0:0":1}},"+CollapsibleContentElement": [46],Vc:{"":"uL+Pi;",$isd3:true}}],["custom_element.polyfill","package:custom_element/polyfill.dart",,B,{G9:function(){if($.LX()==null)return!0
+"11"},"+new CollapsibleContentElement$created:0:0":1}},"+CollapsibleContentElement": [48],Vc:{"":"uL+Pi;",$isd3:true}}],["custom_element.polyfill","package:custom_element/polyfill.dart",,B,{G9:function(){if($.LX()==null)return!0
 var z=J.UQ($.LX(),"CustomElements")
 if(z==null)return"register" in document
 return J.xC(J.UQ(z,"ready"),!0)},zO:{"":"Tp;",
@@ -9761,7 +10306,7 @@
 H.VM(z,[c,d])
 return z}}},xy:{"":"i1;Kw,ew",$asi1:null,
 $ascX:function(a,b){return[b]},
-$isqC:true},MH:{"":"Fl;mD,RX,ew",
+$isqC:true},MH:{"":"eL;mD,RX,ew",
 ei:function(a){return this.ew.call$1(a)},
 G:function(){var z=this.RX
 if(z.G()){this.mD=this.ei(z.gl())
@@ -9769,7 +10314,7 @@
 return!1},
 gl:function(){return this.mD},
 "+current":0,
-$asFl:function(a,b){return[b]}},A8:{"":"aL;qb,ew",
+$aseL:function(a,b){return[b]}},A8:{"":"aL;qb,ew",
 ei:function(a){return this.ew.call$1(a)},
 gB:function(a){return J.q8(this.qb)},
 "+length":0,
@@ -9782,13 +10327,13 @@
 H.VM(z,[H.W8(this,"U5",0)])
 return z},
 $asmW:null,
-$ascX:null},SO:{"":"Fl;RX,ew",
+$ascX:null},SO:{"":"eL;RX,ew",
 ei:function(a){return this.ew.call$1(a)},
 G:function(){for(var z=this.RX;z.G();)if(this.ei(z.gl())===!0)return!0
 return!1},
 gl:function(){return this.RX.gl()},
 "+current":0,
-$asFl:null},zs:{"":"mW;Kw,ew",
+$aseL:null},zs:{"":"mW;Kw,ew",
 gA:function(a){var z=J.GP(this.Kw)
 z=new H.rR(z,this.ew,C.Gw,null)
 H.VM(z,[H.W8(this,"zs",0),H.W8(this,"zs",1)])
@@ -9802,13 +10347,13 @@
 for(var z=this.RX;!this.IO.G();){this.mD=null
 if(z.G()){this.IO=null
 this.IO=J.GP(this.ei(z.gl()))}else return!1}this.mD=this.IO.gl()
-return!0}},AM:{"":"mW;Kw,xZ",
+return!0}},vZ:{"":"mW;Kw,xZ",
 eR:function(a,b){if(b<0)throw H.b(new P.bJ("value "+b))
-return H.ke(this.Kw,this.xZ+b,H.W8(this,"AM",0))},
+return H.ke(this.Kw,this.xZ+b,H.W8(this,"vZ",0))},
 gA:function(a){var z=this.Kw
 z=z.gA(z)
 z=new H.U1(z,this.xZ)
-H.VM(z,[H.W8(this,"AM",0)])
+H.VM(z,[H.W8(this,"vZ",0)])
 return z},
 q1:function(a,b,c){if(this.xZ<0)throw H.b(P.C3(this.xZ))},
 $asmW:null,
@@ -9818,26 +10363,26 @@
 y=new H.d5(a,b)
 H.VM(y,[z])
 y.q1(a,b,z)
-return y}return H.bk(a,b,c)},bk:function(a,b,c){var z=new H.AM(a,b)
+return y}return H.bk(a,b,c)},bk:function(a,b,c){var z=new H.vZ(a,b)
 H.VM(z,[c])
 z.q1(a,b,c)
-return z}}},d5:{"":"AM;Kw,xZ",
+return z}}},d5:{"":"vZ;Kw,xZ",
 gB:function(a){var z,y
 z=this.Kw
 y=J.xH(z.gB(z),this.xZ)
 if(J.J5(y,0))return y
 return 0},
 "+length":0,
-$asAM:null,
+$asvZ:null,
 $ascX:null,
-$isqC:true},U1:{"":"Fl;RX,xZ",
+$isqC:true},U1:{"":"eL;RX,xZ",
 G:function(){var z,y
 for(z=this.RX,y=0;y<this.xZ;++y)z.G()
 this.xZ=0
 return z.G()},
 gl:function(){return this.RX.gl()},
 "+current":0,
-$asFl:null},SJ:{"":"a;",
+$aseL:null},SJ:{"":"a;",
 G:function(){return!1},
 gl:function(){return},
 "+current":0},SU:{"":"a;",
@@ -9869,8 +10414,11 @@
 if(b==null)return!1
 z=J.x(b)
 return typeof b==="object"&&b!==null&&!!z.$isGD&&J.xC(this.hr,b.hr)},
+"+==:1:0":0,
 giO:function(a){return 536870911&664597*J.v1(this.hr)},
+"+hashCode":0,
 bu:function(a){return"Symbol(\""+H.d(this.hr)+"\")"},
+"+toString:0:0":0,
 $isGD:true,
 $iswv:true,
 static:{"":"zP",le:function(a){var z=J.U6(a)
@@ -10023,14 +10571,15 @@
 $isEH:true,
 $is_X0:true},jU:{"":"a;",
 bu:function(a){return this.gOO()},
+"+toString:0:0":0,
 IB:function(a){throw H.b(P.SY(null))},
 Hy:function(a,b){throw H.b(P.SY(null))},
-$isQF:true},Lj:{"":"jU;MA",
+$isej:true},Lj:{"":"jU;MA",
 gOO:function(){return"Isolate"},
 gcZ:function(){var z=$.At().gvU().nb
 z=z.gUQ(z)
 return z.XG(z,new H.mb())},
-$isQF:true},mb:{"":"Tp;",
+$isej:true},mb:{"":"Tp;",
 call$1:function(a){return a.grv()},
 "+call:1:0":0,
 $isEH:true,
@@ -10039,22 +10588,25 @@
 gvd:function(){return H.fb(this.gh7(),this.gIf())},
 gkw:function(){return J.co(J.Z0(this.gIf()),"_")},
 bu:function(a){return this.gOO()+" on '"+H.d(J.Z0(this.gIf()))+"'"},
-gEO:function(){throw H.b(H.Pa("Should not call _methods"))},
-qj:function(a,b){throw H.b(H.Pa("Should not call _invoke"))},
+"+toString:0:0":0,
+gEO:function(){throw H.b(H.Ef("Should not call _methods"))},
+qj:function(a,b){throw H.b(H.Ef("Should not call _invoke"))},
 gmW:function(a){return H.vh(P.SY(null))},
 $isNL:true,
-$isQF:true},cw:{"":"EE;h7<,xW,LQ,If",
+$isej:true},cw:{"":"EE;h7<,xW,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.xC(this.If,b.If)&&J.xC(this.h7,b.h7)},
+"+==:1:0":0,
 giO:function(a){return(1073741823&J.v1(C.Gp.IE)^17*J.v1(this.If)^19*J.v1(this.h7))>>>0},
+"+hashCode":0,
 gOO:function(){return"TypeVariableMirror"},
 $iscw:true,
 $isFw:true,
-$isX9:true,
+$isL9u:true,
 $isNL:true,
-$isQF:true},EE:{"":"am;If",
+$isej:true},EE:{"":"am;If",
 gOO:function(){return"TypeMirror"},
 gh7:function(){return},
 gc9:function(){return H.vh(P.SY(null))},
@@ -10062,9 +10614,9 @@
 gw8:function(){return C.hU},
 gHA:function(){return!0},
 gJi:function(){return this},
-$isX9:true,
+$isL9u:true,
 $isNL:true,
-$isQF:true},Uz:{"":"uh;FP<,aP,wP,le,LB,rv<,ae<,SD,tB,P8,mX,T1,Ly,M2,uA,Db,Ok,If",
+$isej:true},Uz:{"":"uh;FP<,aP,wP,le,LB,rv<,ae<,SD,tB,P8,mX,T1,Ly,M2,uA,Db,Ok,If",
 gOO:function(){return"LibraryMirror"},
 gvd:function(){return this.If},
 gEO:function(){return this.gm8()},
@@ -10108,7 +10660,7 @@
 if(typeof y==="object"&&y!==null&&!!z.$isZk)if(!("$reflectable" in y.dl))H.Hz(J.Z0(a))
 return H.vn(y.qj(b,c))},
 "+invoke:3:0":0,
-"*invoke":[35],
+"*invoke":[37],
 CI:function(a,b){return this.F2(a,b,null)},
 "+invoke:2:0":0,
 Z0:function(a){return $[a]},
@@ -10137,7 +10689,7 @@
 y.push(p)
 p.nz=this}++v}this.SD=y
 return y},
-gKn:function(){var z,y
+gTH:function(){var z,y
 z=this.tB
 if(z!=null)return z
 y=[]
@@ -10154,7 +10706,7 @@
 H.VM(z,[P.wv,P.RS])
 this.mX=z
 return z},
-gII:function(){var z=this.T1
+gE4:function(){var z=this.T1
 if(z!=null)return z
 z=new H.Gj(P.L5(null,null,null,null,null))
 H.VM(z,[P.wv,P.RS])
@@ -10170,7 +10722,7 @@
 z=this.M2
 if(z!=null)return z
 y=P.L5(null,null,null,null,null)
-for(z=this.gKn(),z.toString,x=new H.a7(z,z.length,0,null),H.VM(x,[H.W8(z,"Q",0)]);x.G();){w=x.mD
+for(z=this.gTH(),z.toString,x=new H.a7(z,z.length,0,null),H.VM(x,[H.W8(z,"Q",0)]);x.G();){w=x.mD
 y.u(y,w.gIf(),w)}z=new H.Gj(y)
 H.VM(z,[P.wv,P.RY])
 this.M2=z
@@ -10184,14 +10736,14 @@
 z=new H.Kv(y)
 x=this.gmu().nb
 x.aN(x,z)
-x=this.gII().nb
+x=this.gE4().nb
 x.aN(x,z)
 x=this.gF8().nb
 x.aN(x,z)
 x=this.gZ3().nb
 x.aN(x,z)
 z=new H.Gj(y)
-H.VM(z,[P.wv,P.QF])
+H.VM(z,[P.wv,P.ej])
 this.uA=z
 return z},
 "+members":0,
@@ -10214,8 +10766,8 @@
 return z},
 gh7:function(){return},
 $isD4:true,
-$isQF:true,
-$isNL:true},uh:{"":"am+M2;",$isQF:true},Kv:{"":"Tp;a",
+$isej:true,
+$isNL:true},uh:{"":"am+M2;",$isej:true},Kv:{"":"Tp;a",
 call$2:function(a,b){var z=this.a
 z.u(z,a,b)},
 "+call:2:0":0,
@@ -10242,13 +10794,12 @@
 gvd:function(){return this.gIf()},
 glc:function(a){return J.GK(this.XW)},
 "+members":0,
-gtx:function(){return this.XW.gtx()},
 gZ3:function(){return this.XW.gZ3()},
 gYK:function(){return this.XW.gYK()},
 "+declarations":0,
 F2:function(a,b,c){throw H.b(P.lr(this,a,b,c,null))},
 "+invoke:3:0":0,
-"*invoke":[35],
+"*invoke":[37],
 CI:function(a,b){return this.F2(a,b,null)},
 "+invoke:2:0":0,
 rN:function(a){throw H.b(P.lr(this,a,null,null,null))},
@@ -10261,16 +10812,16 @@
 gNy:function(){throw H.b(P.SY(null))},
 gw8:function(){return C.hU},
 $isMs:true,
-$isQF:true,
-$isX9:true,
-$isNL:true},y1:{"":"EE+M2;",$isQF:true},M2:{"":"a;",$isQF:true},iu:{"":"M2;Ax<",
+$isej:true,
+$isL9u:true,
+$isNL:true},y1:{"":"EE+M2;",$isej:true},M2:{"":"a;",$isej:true},iu:{"":"M2;Ax<",
 gr9:function(a){return H.jO(J.bB(this.Ax).IE)},
 F2:function(a,b,c){var z,y
 z=J.Z0(a)
 y=z+":"+b.length+":0"
 return this.tu(a,0,y,b)},
 "+invoke:3:0":0,
-"*invoke":[35],
+"*invoke":[37],
 CI:function(a,b){return this.F2(a,b,null)},
 "+invoke:2:0":0,
 tu:function(a,b,c,d){var z,y,x,w,v,u,t,s
@@ -10302,11 +10853,14 @@
 y=z==null?y==null:z===y
 z=y}else z=!1
 return z},
+"+==:1:0":0,
 giO:function(a){return(H.CU(this.Ax)^909522486)>>>0},
+"+hashCode":0,
 bu:function(a){return"InstanceMirror on "+H.d(P.hl(this.Ax))},
+"+toString:0:0":0,
 $isiu:true,
 $isvr:true,
-$isQF:true},mg:{"":"Tp;",
+$isej:true},mg:{"":"Tp;",
 call$1:function(a){return init.metadata[a]},
 "+call:1:0":0,
 $isEH:true,
@@ -10321,14 +10875,14 @@
 $isEH:true,
 $is_bh:true},bl:{"":"am;NK,EZ,ut,Db,uA,b0,M2,T1,Ly,FU,jd,qN,qm,If",
 gOO:function(){return"ClassMirror"},
-gWL:function(){return H.d(this.NK.gWL())+"<"+this.EZ+">"},
+gCr:function(){return H.d(this.NK.gCr())+"<"+this.EZ+">"},
 "+_mangledName":0,
 gNy:function(){return this.NK.gNy()},
 gw8:function(){var z,y,x,w,v,u,t,s
 z=this.ut
 if(z!=null)return z
 y=P.A(null,null)
-z=new H.Ef(y)
+z=new H.tB(y)
 x=this.EZ
 if(C.xB.u8(x,"<")===-1)H.bQ(x.split(","),new H.Tc(z))
 else{for(w=x.length,v=0,u="",t=0;t<w;++t){s=x[t]
@@ -10344,12 +10898,6 @@
 z=this.NK.ly(this)
 this.jd=z
 return z},
-gtx:function(){var z=this.FU
-if(z!=null)return z
-z=new H.Gj(H.Vv(this.gEO()))
-H.VM(z,[P.wv,P.RS])
-this.FU=z
-return z},
 gDI:function(){var z=this.b0
 if(z!=null)return z
 z=new H.Gj(H.Fk(this.gEO()))
@@ -10392,12 +10940,12 @@
 gc9:function(){return this.NK.gc9()},
 gAY:function(){var z=this.qN
 if(z!=null)return z
-z=H.Jf(this,init.metadata[J.UQ(init.typeInformation[this.NK.gWL()],0)])
+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)},
 "+invoke:3:0":0,
-"*invoke":[35],
+"*invoke":[37],
 CI:function(a,b){return this.F2(a,b,null)},
 "+invoke:2:0":0,
 gHA:function(){return!1},
@@ -10407,13 +10955,14 @@
 z=this.NK.MR(this)
 this.qm=z
 return z},
+gkw:function(){return this.NK.gkw()},
 gmW:function(a){return J.UX(this.NK)},
 gvd:function(){return this.NK.gvd()},
 gIf:function(){return this.NK.gIf()},
 $isMs:true,
-$isQF:true,
-$isX9:true,
-$isNL:true},Ef:{"":"Tp;a",
+$isej:true,
+$isL9u:true,
+$isNL:true},tB:{"":"Tp;a",
 call$1:function(a){var z,y,x
 z=H.BU(a,null,new H.Oo())
 y=this.a
@@ -10440,7 +10989,7 @@
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},Wf:{"":"Un;WL<-,Tx<-,H8<-,Ht<-,pz<-,le@-,qN@-,jd@-,tB@-,b0@-,FU@-,T1@-,Ly@-,M2@-,uA@-,Db@-,Ok@-,qm@-,UF@-,nz@-,If",
+$is_Dv:true},Wf:{"":"Un;Cr<-,Tx<-,H8<-,Ht<-,pz<-,le@-,qN@-,jd@-,tB@-,b0@-,FU@-,T1@-,Ly@-,M2@-,uA@-,Db@-,Ok@-,qm@-,UF@-,nz@-,If",
 gOO:function(){return"ClassMirror"
 "8"},
 "+_prettyName":1,
@@ -10449,7 +10998,7 @@
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&!!y.$isGv)return z.constructor
 else return z
-"35"},
+"37"},
 "+_jsConstructor":1,
 gDI:function(){var z=this.b0
 if(z!=null)return z
@@ -10457,7 +11006,7 @@
 H.VM(z,[P.wv,P.RS])
 this.b0=z
 return z
-"47"},
+"49"},
 "+constructors":1,
 ly:function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k
 z=this.gaB().prototype
@@ -10483,7 +11032,7 @@
     if (hasOwnProperty.call(victim, key)) result.push(key);
   }
   return result;
-})(init.statics[this.WL], Object.prototype.hasOwnProperty)
+})(init.statics[this.Cr], Object.prototype.hasOwnProperty)
 w=J.U6(y)
 r=w.gB(y)
 if(typeof r!=="number")throw H.s(r)
@@ -10502,14 +11051,14 @@
 l=!1}s=H.Sd(k,o,!l,l)
 x.push(s)
 s.nz=a}return x
-"48,49,50"},
+"50,51,52"},
 "+_getMethodsWithOwner:1:0":1,
 gEO:function(){var z=this.jd
 if(z!=null)return z
 z=this.ly(this)
 this.jd=z
 return z
-"48"},
+"50"},
 "+_methods":1,
 ws:function(a){var z,y,x,w
 z=[]
@@ -10520,17 +11069,17 @@
 y=this.Ht
 if(y!=null){x=[x]
 C.Nm.Ay(x,y)}H.jw(a,x,!1,z)
-w=init.statics[this.WL]
+w=init.statics[this.Cr]
 if(w!=null)H.jw(a,w[""],!0,z)
 return z
-"51,52,50"},
+"53,54,52"},
 "+_getFieldsWithOwner:1:0":1,
-gKn:function(){var z=this.tB
+gTH:function(){var z=this.tB
 if(z!=null)return z
 z=this.ws(this)
 this.tB=z
 return z
-"51"},
+"53"},
 "+_fields":1,
 gtx:function(){var z=this.FU
 if(z!=null)return z
@@ -10538,26 +11087,26 @@
 H.VM(z,[P.wv,P.RS])
 this.FU=z
 return z
-"47"},
+"49"},
 "+methods":1,
 gZ3:function(){var z,y,x
 z=this.M2
 if(z!=null)return z
 y=P.L5(null,null,null,null,null)
-for(z=J.GP(this.gKn());z.G();){x=z.gl()
+for(z=J.GP(this.gTH());z.G();){x=z.gl()
 y.u(y,x.gIf(),x)}z=new H.Gj(y)
 H.VM(z,[P.wv,P.RY])
 this.M2=z
 return z
-"53"},
+"55"},
 "+variables":1,
 glc:function(a){var z=this.uA
 if(z!=null)return z
 z=new H.Gj(H.vE(this.gEO(),this.gZ3()))
-H.VM(z,[P.wv,P.QF])
+H.VM(z,[P.wv,P.ej])
 this.uA=z
 return z
-"54"},
+"56"},
 "+members":1,
 gYK:function(){var z,y
 z=this.Db
@@ -10571,23 +11120,23 @@
 H.VM(z,[P.wv,P.NL])
 this.Db=z
 return z
-"55"},
+"57"},
 "+declarations":1,
 PU:function(a,b){var z,y
 z=J.UQ(this.gZ3(),a)
 if(z!=null&&z.gFo()&&!z.gV5()){y=z.gao()
-if(!(y in $))throw H.b(H.Pa("Cannot find \""+y+"\" in current isolate."))
+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))
-"56,57,58,59,0"},
+"58,59,60,61,0"},
 "+setField:2:0":1,
 rN:function(a){var z,y
 z=J.UQ(this.gZ3(),a)
 if(z!=null&&z.gFo()){y=z.gao()
-if(!(y in $))throw H.b(H.Pa("Cannot find \""+y+"\" in current isolate."))
+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))
-"56,57,58"},
+"58,59,60"},
 "+getField:1:0":1,
 gh7:function(){var z,y,x,w,v,u,t
 if(this.nz==null){z=this.Tx
@@ -10606,7 +11155,7 @@
 z=new H.MH(null,y,z.ew)
 z.$builtinTypeInfo=[u,t]
 for(;z.G();)for(y=J.GP(z.mD);y.G();)J.pP(y.gl())}if(this.nz==null)throw H.b(new P.lj("Class \""+H.d(J.Z0(this.If))+"\" has no owner"))}return this.nz
-"60"},
+"62"},
 "+owner":1,
 gc9:function(){var z=this.Ok
 if(z!=null)return z
@@ -10615,10 +11164,10 @@
 H.VM(z,[P.vr])
 this.Ok=z
 return z
-"61"},
+"63"},
 "+metadata":1,
 gAY:function(){var z,y,x,w,v,u
-if(this.qN==null){z=init.typeInformation[this.WL]
+if(this.qN==null){z=init.typeInformation[this.Cr]
 if(z!=null)this.qN=H.Jf(this,init.metadata[J.UQ(z,0)])
 else{y=this.H8
 x=J.uH(y,";")
@@ -10627,9 +11176,9 @@
 x=J.rY(w)
 v=x.Fr(w,"+")
 u=v.length
-if(u>1){if(u!==2)throw H.b(H.Pa("Strange mixin: "+H.d(y)))
+if(u>1){if(u!==2)throw H.b(H.Ef("Strange mixin: "+H.d(y)))
 this.qN=H.jO(v[0])}else this.qN=x.n(w,"")?this:H.jO(w)}}return J.xC(this.qN,this)?null:this.qN
-"62"},
+"64"},
 "+superclass":1,
 F2:function(a,b,c){var z
 if(c!=null&&J.FN(c)!==!0)throw H.b(P.f("Named arguments are not implemented."))
@@ -10637,33 +11186,33 @@
 if(z==null||!z.gFo())throw H.b(P.lr(this,a,b,c,null))
 if(!z.yR())H.Hz(J.Z0(a))
 return H.vn(z.qj(b,c))
-"56,63,58,64,65,66,67"},
+"58,65,60,66,67,68,69"},
 "+invoke:3:0":1,
-"*invoke":[35],
+"*invoke":[37],
 CI:function(a,b){return this.F2(a,b,null)},
 "+invoke:2:0":1,
 gHA:function(){return!0
-"39"},
+"41"},
 "+isOriginalDeclaration":1,
 gJi:function(){return this
-"62"},
+"64"},
 "+originalDeclaration":1,
 MR:function(a){var z,y,x
-z=init.typeInformation[this.WL]
+z=init.typeInformation[this.Cr]
 if(z!=null){y=new H.A8(J.Pr(z,1),new H.t0(a))
 H.VM(y,[null,null])
 x=y.br(y)}else x=C.Me
 y=new P.Yp(x)
 H.VM(y,[P.Ms])
 return y
-"68,69,50"},
+"70,71,52"},
 "+_getSuperinterfacesWithOwner:1:0":1,
 gkZ:function(){var z=this.qm
 if(z!=null)return z
 z=this.MR(this)
 this.qm=z
 return z
-"68"},
+"70"},
 "+superinterfaces":1,
 gNy:function(){var z,y,x,w,v
 z=this.UF
@@ -10676,34 +11225,34 @@
 H.VM(z,[null])
 this.UF=z
 return z
-"70"},
+"72"},
 "+typeVariables":1,
 gw8:function(){return C.hU
-"71"},
+"73"},
 "+typeArguments":1,
 $isWf:true,
 $isMs:true,
-$isQF:true,
-$isX9:true,
-$isNL:true},"+JsClassMirror": [72, 62],Un:{"":"EE+M2;",$isQF:true},Ei:{"":"Tp;a-",
+$isej:true,
+$isL9u:true,
+$isNL:true},"+JsClassMirror": [74, 64],Un:{"":"EE+M2;",$isej:true},Ei:{"":"Tp;a-",
 call$2:function(a,b){J.kW(this.a,a,b)
-"35,73,58,28,74"},
+"37,75,60,28,76"},
 "+call:2:0":1,
 $isEH:true,
-$is_bh:true},"+JsClassMirror_declarations_addToResult": [75],U7:{"":"Tp;b-",
+$is_bh:true},"+JsClassMirror_declarations_addToResult": [77],U7:{"":"Tp;b-",
 call$1:function(a){J.kW(this.b,a.gIf(),a)
 return a
-"35,76,35"},
+"37,78,37"},
 "+call:1:0":1,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},"+JsClassMirror_declarations_closure": [75],t0:{"":"Tp;a-",
+$is_Dv:true},"+JsClassMirror_declarations_closure": [77],t0:{"":"Tp;a-",
 call$1:function(a){return H.Jf(this.a,init.metadata[a])
-"62,77,27"},
+"64,79,27"},
 "+call:1:0":1,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},"+JsClassMirror__getSuperinterfacesWithOwner_lookupType": [75],Ld:{"":"am;ao<,V5<,Fo<,n6,nz,le,If",
+$is_Dv:true},"+JsClassMirror__getSuperinterfacesWithOwner_lookupType": [77],Ld:{"":"am;ao<,V5<,Fo<,n6,nz,le,If",
 gOO:function(){return"VariableMirror"},
 "+_prettyName":0,
 gr9:function(a){return $.Cr()},
@@ -10718,7 +11267,7 @@
 a.H7(this.ao,b)},
 $isRY:true,
 $isNL:true,
-$isQF:true,
+$isej:true,
 static:{"":"Z8",pS:function(a,b,c,d){var z,y,x,w,v,u,t,s,r,q
 z=J.U6(a)
 y=z.gB(a)
@@ -10754,7 +11303,7 @@
   return null;
 }
 (y)
-if(w==null)throw H.b(H.Pa("Cannot find callName on \""+H.d(y)+"\""))
+if(w==null)throw H.b(H.Ef("Cannot find callName on \""+H.d(y)+"\""))
 v=w.split("$")
 if(1>=v.length)throw H.e(v,1)
 u=H.BU(v[1],null,null)
@@ -10769,14 +11318,17 @@
 return x},
 "+function":0,
 bu:function(a){return"ClosureMirror on '"+H.d(P.hl(this.Ax))+"'"},
+"+toString:0:0":0,
+gFF:function(a){return H.vh(P.SY(null))},
+"+source":0,
 $isvr:true,
-$isQF:true},Zk:{"":"am;dl,Yq,lT<,hB<,Fo<,xV<,qx,nz,le,G6,Cr,If",
+$isej:true},Zk:{"":"am;dl,Yq,lT<,hB<,Fo<,xV<,qx,nz,le,G6,H3,If",
 gOO:function(){return"MethodMirror"},
 "+_prettyName":0,
-gJx:function(){var z=this.Cr
+gJx:function(){var z=this.H3
 if(z!=null)return z
 this.gc9()
-return this.Cr},
+return this.H3},
 yR:function(){return"$reflectable" in this.dl},
 gh7:function(){return this.nz},
 "+owner":0,
@@ -10803,13 +11355,13 @@
 if(t>=w)throw H.e(x,t)
 x[t]=new H.fu(this,null,p)}}y=new P.Yp(x)
 H.VM(y,[P.Ys])
-this.Cr=y
+this.H3=y
 y=new P.Yp(J.C0(z,H.Yf))
 H.VM(y,[null])
 this.le=y}return this.le},
 "+metadata":0,
 qj:function(a,b){if(b!=null&&J.FN(b)!==!0)throw H.b(P.f("Named arguments are not implemented."))
-if(!this.Fo&&!this.xV)throw H.b(H.Pa("Cannot invoke instance method without receiver."))
+if(!this.Fo&&!this.xV)throw H.b(H.Ef("Cannot invoke instance method without receiver."))
 if(!J.xC(this.Yq,J.q8(a))||this.dl==null)throw H.b(P.lr(this.nz,this.If,a,b,null))
 return this.dl.apply($,P.F(a,!0,null))},
 IB:function(a){if(this.lT)return this.qj([],null)
@@ -10820,7 +11372,7 @@
 $isZk:true,
 $isRS:true,
 $isNL:true,
-$isQF:true,
+$isej:true,
 static:{Sd:function(a,b,c,d){var z,y,x,w,v,u,t
 z=J.uH(a,":")
 if(0>=z.length)throw H.e(z,0)
@@ -10847,15 +11399,15 @@
 $isYs:true,
 $isRY:true,
 $isNL:true,
-$isQF:true},ng:{"":"am;WL<,CM,If",
+$isej:true},ng:{"":"am;Cr<,CM,If",
 gP:function(a){return this.CM},
 "+value":0,
 r6:function(a,b){return this.gP(a).call$1(b)},
 gOO:function(){return"TypedefMirror"},
 "+_prettyName":0,
-$isX9:true,
+$isL9u:true,
 $isNL:true,
-$isQF:true},Ar:{"":"a;d9,o3,yA,zM,h7<",
+$isej:true},Ar:{"":"a;d9,o3,yA,zM,h7<",
 gHA:function(){return!0},
 "+isOriginalDeclaration":0,
 gJx:function(){var z,y,x,w,v,u,t
@@ -10899,15 +11451,16 @@
 z=w+"'"
 this.o3=z
 return z},
+"+toString:0:0":0,
 $isMs:true,
-$isQF:true,
-$isX9:true,
+$isej:true,
+$isL9u:true,
 $isNL:true},jB:{"":"Tp;a",
 call$1:function(a){var z,y,x
 z=init.metadata[a]
 y=this.a
 x=H.w2(y.a.gNy(),J.DA(z))
-return J.UQ(y.a.gw8(),x).gWL()},
+return J.UQ(y.a.gw8(),x).gCr()},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
@@ -10947,6 +11500,7 @@
 $isL8:true,
 static:{kT:function(){throw H.b(P.f("Cannot modify an unmodifiable Map"))}}},Zz:{"":"Ge;hu",
 bu:function(a){return"Unsupported operation: "+this.hu},
+"+toString:0:0":0,
 $ismp:true,
 $isGe:true,
 static:{WE:function(a){return new H.Zz(a)}}},"":"uN<"}],["dart._js_names","dart:_js_names",,H,{hY:function(a,b){var z,y,x,w,v,u,t
@@ -11084,7 +11638,7 @@
 gZ9:function(){return new P.Ip(this,P.JI.prototype.LP,null,"LP")},
 $asyU:null,
 $asMO:null,
-static:{"":"HO,HC,fw",}},WV:{"":"a;nL<,QC<,iE@,SJ@",
+static:{"":"kb,HC,fw",}},WV:{"":"a;nL<,QC<,iE@,SJ@",
 gP4:function(){return(this.Gv&2)!==0},
 SL:function(){var z=this.Ip
 if(z!=null)return z
@@ -11249,10 +11803,10 @@
 this.au(z)
 return z},
 ml:function(a){return this.Rx(a,null)},
-co:function(a,b){var z=P.RP(a,b,null)
+pU:function(a,b){var z=P.RP(a,b,null)
 this.au(z)
 return z},
-OA:function(a){return this.co(a,null)},
+OA:function(a){return this.pU(a,null)},
 wM:function(a){var z=P.X4(a,H.W8(this,"vs",0))
 this.au(z)
 return z},
@@ -11281,7 +11835,13 @@
 P.HZ(this,z)},
 Lp:function(a){return this.K5(a,null)},
 gbY:function(){return new P.CQ(this,P.vs.prototype.K5,null,"K5")},
-OH:function(a){if(this.Gv!==0)H.vh(new P.lj("Future already completed"))
+OH:function(a){var z,y
+z=J.x(a)
+y=typeof a==="object"&&a!==null&&!!z.$isb8
+if(y);if(y)z=typeof a!=="object"||a===null||!z.$isvs||a.Gv<4
+else z=!1
+if(z){this.rX(a)
+return}if(this.Gv!==0)H.vh(new P.lj("Future already completed"))
 this.Gv=1
 this.Lj.wr(new P.rH(this,a))},
 CG:function(a,b){if(this.Gv!==0)H.vh(new P.lj("Future already completed"))
@@ -11290,7 +11850,7 @@
 L7:function(a,b){this.OH(a)},
 $isvs:true,
 $isb8:true,
-static:{"":"Gn,Ry,cp,oN,NK",Dt:function(a){var z=new P.vs(0,$.X3,null,null,null,null,null,null)
+static:{"":"Gn,JE,cp,oN,NK",Dt:function(a){var z=new P.vs(0,$.X3,null,null,null,null,null,null)
 H.VM(z,[a])
 return z},Ab:function(a,b){var z=new P.vs(0,$.X3,null,null,null,null,null,null)
 H.VM(z,[b])
@@ -11362,7 +11922,7 @@
 $is_Dv:true},dm:{"":"Tp;b",
 call$2:function(a,b){this.b.K5(a,b)},
 "+call:2:0":0,
-"*call":[35],
+"*call":[37],
 call$1:function(a){return this.call$2(a,null)},
 "+call:1:0":0,
 $isEH:true,
@@ -11431,7 +11991,7 @@
 if(typeof y!=="object"||y===null||!x.$isvs){z.a=P.Dt(null)
 z.a.E6(a,b)}P.HZ(z.a,this.h)},
 "+call:2:0":0,
-"*call":[35],
+"*call":[37],
 call$1:function(a){return this.call$2(a,null)},
 "+call:1:0":0,
 $isEH:true,
@@ -11743,12 +12303,14 @@
 SY:function(){this.ghG().w6(C.Wj)}},Gh:{"":"XB;nL<,p4<,Z9<,QC<,iP,Gv,Ip"},XB:{"":"ms+lk;",$asms:null},ly:{"":"cK;nL<,p4<,Z9<,QC<,iP,Gv,Ip"},cK:{"":"ms+vp;",$asms:null},O9:{"":"ez;Y8",
 w4:function(a){return this.Y8.ET(a)},
 giO:function(a){return(H.eQ(this.Y8)^892482866)>>>0},
+"+hashCode":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},
+"+==:1:0":0,
 $isO9:true,
 $asez:null,
 $asqh:null},yU:{"":"KA;Y8<,dB,o7,Bd,Lj,Gv,lz,Ri",
@@ -11907,9 +12469,9 @@
 return x},
 fN:function(a){},
 gnL:function(){return new H.Pm(this,P.ez.prototype.fN,null,"fN")},
-$asqh:null},fI:{"":"a;LD@"},LV:{"":"fI;P>,LD",
+$asqh:null},lx:{"":"a;LD@"},LV:{"":"lx;P>,LD",
 r6:function(a,b){return this.P.call$1(b)},
-pP:function(a){a.Iv(this.P)}},DS:{"":"fI;kc>,I4<,LD",
+pP:function(a){a.Iv(this.P)}},DS:{"":"lx;kc>,I4<,LD",
 pP:function(a){a.pb(this.kc,this.I4)}},dp:{"":"a;",
 pP:function(a){a.SY()},
 gLD:function(){return},
@@ -12434,6 +12996,7 @@
 for(y=0;y<z;y+=2)if(this.C2(a[y],b)===!0)return y
 return-1},
 bu:function(a){return P.vW(this)},
+"+toString:0:0":0,
 $ask6:null,
 $asL8:null,
 static:{MP:function(a,b,c,d,e){var z=new P.jG(d)
@@ -12606,6 +13169,7 @@
 for(y=0;y<z;++y)if(J.xC(a[y].gkh(),b))return y
 return-1},
 bu:function(a){return P.vW(this)},
+"+toString:0:0":0,
 $isFo:true,
 $isL8:true},iX:{"":"Tp;a",
 call$1:function(a){var z=this.a
@@ -12946,6 +13510,7 @@
 z[x]=w}return z},
 br:function(a){return this.tt(a,!0)},
 bu:function(a){return H.mx(this,"{","}")},
+"+toString:0:0":0,
 $asmW:null,
 $ascX:null,
 $isqC:true,
@@ -13004,6 +13569,7 @@
 if(w.n(y,0))return x
 y=w.W(y,1)}throw H.b(P.N(b))},
 bu:function(a){return P.FO(this)},
+"+toString:0:0":0,
 $iscX:true,
 $ascX:null},ar:{"":"a+lD;",$isList:true,$asWO:null,$isqC:true,$iscX:true,$ascX:null},lD:{"":"a;",
 gA:function(a){var z=new H.a7(a,this.gB(a),0,null)
@@ -13146,6 +13712,7 @@
 z.We(a,", ")
 z.KF("]")}finally{y=$.xb()
 y.Rz(y,a)}return z.gvM()},
+"+toString:0:0":0,
 $isList:true,
 $asWO:null,
 $isqC:true,
@@ -13206,6 +13773,7 @@
 this.qT=this.qT+1
 return!0}}return!1},
 bu:function(a){return H.mx(this,"{","}")},
+"+toString:0:0":0,
 Ux:function(){var z,y,x,w
 if(this.av===this.HV)throw H.b(P.w("No elements"))
 this.qT=this.qT+1
@@ -13408,6 +13976,7 @@
 return z},
 "+values":0,
 bu:function(a){return P.vW(this)},
+"+toString:0:0":0,
 $isBa:true,
 $asXt:function(a,b){return[a]},
 $asL8:null,
@@ -13531,7 +14100,7 @@
 $aswI:function(){return[J.O,P.a]}},z0:{"":"ob;lH",
 goc:function(a){return"utf-8"},
 "+name":0,
-gZE:function(){return new P.Vx()}},Vx:{"":"wI;",
+gZE:function(){return new P.E3()}},E3:{"":"wI;",
 WJ:function(a){var z,y,x
 z=a.length
 y=P.A(z*3,J.im)
@@ -13539,7 +14108,7 @@
 x=new P.Rw(0,0,y)
 if(x.fJ(a,0,z)!==z)x.Lb(C.xB.j(a,z-1),0)
 return C.Nm.D6(x.EN,0,x.An)},
-$aswI:function(){return[J.O,[J.Q,J.im]]}},Rw:{"":"a;WF,An,EN",
+$aswI:function(){return[J.O,[J.Q,J.im]]}},Rw:{"":"a;vn,An,EN",
 Lb:function(a,b){var z,y,x,w,v
 z=this.EN
 y=this.An
@@ -13616,7 +14185,80 @@
 this.An=u+1
 if(u<0||u>=y)throw H.e(z,u)
 z[u]=(128|v&63)>>>0}}return w},
-static:{"":"Ij",}}}],["dart.core","dart:core",,P,{Te:function(a){return},Wc:function(a,b){return J.oE(a,b)},hl:function(a){var z,y,x,w,v,u
+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,a.length)
+y.fZ()
+return z.vM},
+$aswI:function(){return[[J.Q,J.im],J.O]}},jZ:{"":"a;lH,aS,rU,Hu,iU,VN",
+cO:function(a){this.fZ()},
+fZ:function(){if(this.iU>0){if(this.lH!==!0)throw H.b(P.cD("Unfinished UTF-8 octet sequence"))
+this.aS.KF(P.fc(65533))
+this.Hu=0
+this.iU=0
+this.VN=0}},
+ME:function(a,b,c){var z,y,x,w,v,u,t,s,r,q
+z=this.Hu
+y=this.iU
+x=this.VN
+this.Hu=0
+this.iU=0
+this.VN=0
+$loop$0:for(w=this.aS,v=this.lH!==!0,u=b;!0;u=q){$multibyte$2:{if(y>0){t=a.length
+do{if(u===c)break $loop$0
+if(u<0||u>=t)throw H.e(a,u)
+s=a[u]
+if((s&192)!==128){if(v)throw H.b(P.cD("Bad UTF-8 encoding 0x"+C.jn.WZ(s,16)))
+this.rU=!1
+r=P.O8(1,65533,J.im)
+r.$builtinTypeInfo=[J.im]
+t=H.eT(r)
+w.vM=w.vM+t
+y=0
+break $multibyte$2}else{z=(z<<6|s&63)>>>0;--y;++u}}while(y>0)
+t=x-1
+if(t<0||t>=4)throw H.e(C.Gb,t)
+if(z<=C.Gb[t]){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){r=P.O8(1,z,J.im)
+r.$builtinTypeInfo=[J.im]
+t=H.eT(r)
+w.vM=w.vM+t}this.rU=!1}}for(;u<c;u=q){q=u+1
+if(u<0||u>=a.length)throw H.e(a,u)
+s=a[u]
+if(s<0){if(v)throw H.b(P.cD("Negative UTF-8 code unit: -0x"+C.jn.WZ(-s,16)))
+r=P.O8(1,65533,J.im)
+r.$builtinTypeInfo=[J.im]
+t=H.eT(r)
+w.vM=w.vM+t}else if(s<=127){this.rU=!1
+r=P.O8(1,s,J.im)
+r.$builtinTypeInfo=[J.im]
+t=H.eT(r)
+w.vM=w.vM+t}else{if((s&224)===192){z=s&31
+y=1
+x=1
+continue $loop$0}if((s&240)===224){z=s&15
+y=2
+x=2
+continue $loop$0}if((s&248)===240&&s<245){z=s&7
+y=3
+x=3
+continue $loop$0}if(v)throw H.b(P.cD("Bad UTF-8 encoding 0x"+C.jn.WZ(s,16)))
+this.rU=!1
+r=P.O8(1,65533,J.im)
+r.$builtinTypeInfo=[J.im]
+t=H.eT(r)
+w.vM=w.vM+t
+z=65533
+y=0
+x=0}}break $loop$0}if(y>0){this.Hu=z
+this.iU=y
+this.VN=x}},
+static:{"":"a3",}}}],["dart.core","dart:core",,P,{Te:function(a){return},Wc:function(a,b){return J.oE(a,b)},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("")
 z.vM="\""
@@ -13676,16 +14318,20 @@
 "+call:2:0":0,
 $isEH:true,
 $is_bh:true},K8:{"":"a;OF",
-bu:function(a){return"Deprecated feature. Will be removed "+this.OF}},a2:{"":"a;",
+bu:function(a){return"Deprecated feature. Will be removed "+this.OF},
+"+toString:0:0":0},a2:{"":"a;",
 bu:function(a){return this?"true":"false"},
+"+toString:0:0":0,
 $isbool:true},fR:{"":"a;"},iP:{"":"a;rq<,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.rq===b.rq&&this.aL===b.aL},
+"+==:1:0":0,
 iM:function(a,b){return C.CD.iM(this.rq,b.grq())},
 giO:function(a){return this.rq},
+"+hashCode":0,
 bu:function(a){var z,y,x,w,v,u,t,s
 z=new P.pl()
 y=new P.Hn().call$1(H.tJ(this))
@@ -13697,11 +14343,12 @@
 s=new P.Zl().call$1(H.o1(this))
 if(this.aL)return H.d(y)+"-"+H.d(x)+"-"+H.d(w)+" "+H.d(v)+":"+H.d(u)+":"+H.d(t)+"."+H.d(s)+"Z"
 else return H.d(y)+"-"+H.d(x)+"-"+H.d(w)+" "+H.d(v)+":"+H.d(u)+":"+H.d(t)+"."+H.d(s)},
+"+toString:0:0":0,
 h:function(a,b){return P.Wu(this.rq+b.gVs(),this.aL)},
 EK:function(){H.U8(this)},
 RM:function(a,b){if(Math.abs(a)>8640000000000000)throw H.b(new P.AT(a))},
 $isiP:true,
-static:{"":"Oj,bI,df,yM,h2,JE,nm,DU,H9,EN,k3,cR,E0,Ke,lT,Nr,bm,o4,Kz,J7,TO,I2",Gl:function(a){var z,y,x,w,v,u,t,s,r,q,p,o,n
+static:{"":"Oj,bI,df,yM,h2,OK,nm,DU,H9,Gio,k3,cR,E0,Ke,lT,Nr,bm,o4,Kz,J7,TO,I2",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.oH
@@ -13781,7 +14428,9 @@
 z=J.x(b)
 if(typeof b!=="object"||b===null||!z.$isa6)return!1
 return this.Fq===b.Fq},
+"+==:1:0":0,
 giO:function(a){return this.Fq&0x1FFFFFFF},
+"+hashCode":0,
 iM:function(a,b){return C.CD.iM(this.Fq,b.gFq())},
 bu:function(a){var z,y,x,w,v
 z=new P.DW()
@@ -13791,6 +14440,7 @@
 w=z.call$1(C.CD.JV(C.CD.Z(y,1000000),60))
 v=new P.P7().call$1(C.CD.JV(y,1000000))
 return H.d(C.CD.Z(y,3600000000))+":"+H.d(x)+":"+H.d(w)+"."+H.d(v)},
+"+toString:0:0":0,
 $isa6:true,
 static:{"":"Bp,S4,dk,Lo,RD,b2,q9,Ie,Do,f4,vd,IJ,V6,Vk,fm,rG",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;",
 call$1:function(a){var z=J.Wx(a)
@@ -13812,12 +14462,15 @@
 $is_Dv:true},Ge:{"":"a;",
 gI4:function(){return new H.XO(this.$thrownJsError,null)},
 $isGe:true},LK:{"":"Ge;",
-bu:function(a){return"Throw of null."}},AT:{"":"Ge;G1>",
+bu:function(a){return"Throw of null."},
+"+toString:0:0":0},AT:{"":"Ge;G1>",
 bu:function(a){var z=this.G1
 if(z!=null)return"Illegal argument(s): "+H.d(z)
 return"Illegal argument(s)"},
+"+toString:0:0":0,
 static:{u:function(a){return new P.AT(a)}}},bJ:{"":"AT;G1",
 bu:function(a){return"RangeError: "+H.d(this.G1)},
+"+toString:0:0":0,
 static:{C3:function(a){return new P.bJ(a)},N:function(a){return new P.bJ("value "+H.d(a))},"+new RangeError$value:1:0":0,TE:function(a,b,c){return new P.bJ("value "+H.d(a)+" not in range "+H.d(b)+".."+H.d(c))}}},mp:{"":"Ge;uF,UP,mP,SA,vG",
 bu:function(a){var z,y,x,w,v,u
 z={}
@@ -13837,33 +14490,43 @@
 z.b=z.b+1}}y=this.SA
 if(y!=null)J.kH(y,new P.CL(z))
 return"NoSuchMethodError : method not found: '"+H.d(this.UP)+"'\nReceiver: "+H.d(P.hl(this.uF))+"\nArguments: ["+H.d(z.a)+"]"},
+"+toString:0:0":0,
 $ismp:true,
 static:{lr:function(a,b,c,d,e){return new P.mp(a,b,c,d,e)}}},ub:{"":"Ge;G1>",
 bu:function(a){return"Unsupported operation: "+this.G1},
+"+toString:0:0":0,
 $isub:true,
 static:{f:function(a){return new P.ub(a)}}},ds:{"":"Ge;G1>",
 bu:function(a){var z=this.G1
 return z!=null?"UnimplementedError: "+H.d(z):"UnimplementedError"},
+"+toString:0:0":0,
 $isub:true,
 $isGe:true,
 static:{SY:function(a){return new P.ds(a)}}},lj:{"":"Ge;G1>",
 bu:function(a){return"Bad state: "+this.G1},
+"+toString:0:0":0,
 static:{w:function(a){return new P.lj(a)}}},UV:{"":"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))+"."},
+"+toString:0:0":0,
 static:{a4:function(a){return new P.UV(a)}}},VS:{"":"a;",
 bu:function(a){return"Stack Overflow"},
+"+toString:0:0":0,
 gI4:function(){return},
 $isGe:true},t7:{"":"Ge;Wo",
 bu:function(a){return"Reading static variable '"+this.Wo+"' during its initialization"},
+"+toString:0:0":0,
 static:{Gz:function(a){return new P.t7(a)}}},HG:{"":"a;G1>",
 bu:function(a){var z=this.G1
 if(z==null)return"Exception"
-return"Exception: "+H.d(z)}},aE:{"":"a;G1>",
+return"Exception: "+H.d(z)},
+"+toString:0:0":0},aE:{"":"a;G1>",
 bu:function(a){return"FormatException: "+H.d(this.G1)},
+"+toString:0:0":0,
 static:{cD:function(a){return new P.aE(a)}}},kM:{"":"a;oc>",
 bu:function(a){return"Expando:"+this.oc},
+"+toString:0:0":0,
 t:function(a,b){var z=H.of(b,"expando$values")
 return z==null?null:H.of(z,this.Qz())},
 "+[]:1:0":0,
@@ -13877,11 +14540,15 @@
 $.Ss=y+1
 z="expando$key$"+y
 H.aw(this,"expando$key",z)}return z},
-static:{"":"bZ,rt,Ss",}},EH:{"":"a;",$isEH:true},cX:{"":"a;",$iscX:true,$ascX:null},Fl:{"":"a;"},L8:{"":"a;",$isL8:true},c8:{"":"a;",
-bu:function(a){return"null"}},a:{"":";",
+static:{"":"bZ,rt,Ss",}},EH:{"":"a;",$isEH:true},cX:{"":"a;",$iscX:true,$ascX:null},eL:{"":"a;"},L8:{"":"a;",$isL8:true},c8:{"":"a;",
+bu:function(a){return"null"},
+"+toString:0:0":0},a:{"":";",
 n:function(a,b){return this===b},
+"+==:1:0":0,
 giO:function(a){return H.eQ(this)},
+"+hashCode":0,
 bu:function(a){return H.a5(this)},
+"+toString:0:0":0,
 T:function(a,b){throw H.b(P.lr(this,b.gWa(),b.gnd(),b.gVm(),null))},
 "+noSuchMethod:1:0":0,
 gbx:function(a){return new H.cu(H.dJ(this),null)},
@@ -13924,6 +14591,7 @@
 y=typeof y==="string"?y:H.d(y)
 this.vM=this.vM+y}}},
 bu:function(a){return this.vM},
+"+toString:0:0":0,
 PD:function(a){if(typeof a==="string")this.vM=a
 else this.KF(a)},
 static:{p9:function(a){var z=new P.Rn("")
@@ -13940,6 +14608,9 @@
 if(y.n(z,"https"))return 443}return this.HC},
 gIi:function(a){return this.r0},
 Ja:function(a,b){return this.tP.call$1(b)},
+ghY:function(){if(this.yW==null){var z=new P.dD(P.Ak(this.tP,C.dy))
+H.VM(z,[null,null])
+this.yW=z}return this.yW},
 x6:function(a,b){var z,y
 z=a==null
 if(z&&!0)return""
@@ -14004,20 +14675,23 @@
 z.KF(y)}y=this.BJ
 if(""!==y){z.KF("#")
 z.KF(y)}return z.vM},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 if(typeof b!=="object"||b===null||!z.$isiD)return!1
 return J.xC(this.Fi,b.Fi)&&J.xC(this.iV,b.iV)&&J.xC(this.gJf(this),z.gJf(b))&&J.xC(this.gGL(this),z.gGL(b))&&J.xC(this.r0,b.r0)&&J.xC(this.tP,b.tP)&&J.xC(this.BJ,b.BJ)},
+"+==:1:0":0,
 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.gGL(this),z.call$2(this.r0,z.call$2(this.tP,z.call$2(this.BJ,1)))))))},
+"+hashCode":0,
 n3:function(a,b,c,d,e,f,g,h,i){var z=J.x(h)
 if(z.n(h,"http")&&J.xC(e,80))this.HC=0
 else if(z.n(h,"https")&&J.xC(e,443))this.HC=0
 else this.HC=e
 this.r0=this.x6(c,d)},
 $isiD:true,
-static:{"":"Um,B4,Bx,iR,LM,iI,nR,jJ,d2,q7,ux,vI,il,tC,IL,Q5,vl,yt,fC,O5,eq,qf,Tx,y3,Cn,R1,oe,vT,K7,nL,H5,zst,eK,bf,Sp,nU,uj,SQ,SD",r6:function(a){var z,y,x,w,v,u,t,s
+static:{"":"Um,B4,Bx,iR,LM,iI,nR,jJ,d2,q7,ux,vI,bL,tC,IL,Q5,zk,om,fC,O5,eq,qf,Tx,y3,Cn,R1,oe,vT,K7,nL,H5,zst,eK,bf,nc,nU,uj,SQ,SD",r6:function(a){var z,y,x,w,v,u,t,s
 z=a.oH
 if(1>=z.length)throw H.e(z,1)
 y=z[1]
@@ -14132,7 +14806,7 @@
 return J.AG(z)},n7:function(a){if(a!=null&&!J.xC(a,""))return H.BU(a,null,null)
 else return 0},K6:function(a,b){if(a!=null)return a
 if(b!=null)return b
-return""},q5:function(a){var z,y
+return""},Ak:function(a,b){return H.n3(J.uH(a,"&"),H.B7([],P.L5(null,null,null,null,null)),new P.qz(b))},q5:function(a){var z,y
 z=new P.hQ()
 y=a.split(".")
 if(y.length!==4)z.call$1("IPv4 address should contain exactly 4 parts")
@@ -14160,11 +14834,11 @@
 if(r&&!q)z.call$1("expected a part after last `:`")
 if(!r)try{J.bi(x,y.call$2(w,J.q8(a)))}catch(p){H.Ru(p)
 try{v=P.q5(J.ZZ(a,w))
-s=J.Eh(J.UQ(v,0),8)
+s=J.c1(J.UQ(v,0),8)
 o=J.UQ(v,1)
 if(typeof o!=="number")throw H.s(o)
 J.bi(x,(s|o)>>>0)
-o=J.Eh(J.UQ(v,2),8)
+o=J.c1(J.UQ(v,2),8)
 s=J.UQ(v,3)
 if(typeof s!=="number")throw H.s(s)
 J.bi(x,(o|s)>>>0)}catch(p){H.Ru(p)
@@ -14197,7 +14871,36 @@
 v=C.Nm.gA(C.dy.gZE().WJ(v))
 for(;v.G();){t=z.call$1(v.mD)
 t=typeof t==="string"?t:H.d(t)
-y.vM=y.vM+t}}++w}return y.vM}}},hb:{"":"Tp;",
+y.vM=y.vM+t}}++w}return y.vM},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=(w|32)>>>0
+if(97<=w&&w<=102)y=y*16+w-87
+else throw H.b(new P.AT("Invalid URL encoding"))}}return y},pE:function(a,b,c){var z,y,x,w,v,u,t,s
+z=P.p9("")
+y=P.A(null,J.im)
+H.VM(y,[J.im])
+x=J.U6(a)
+w=b.lH
+v=0
+while(!0){u=x.gB(a)
+if(typeof u!=="number")throw H.s(u)
+if(!(v<u))break
+t=x.j(a,v)
+if(t!==37){if(c&&t===43)z.vM=z.vM+" "
+else{s=P.O8(1,t,J.im)
+s.$builtinTypeInfo=[J.im]
+u=H.eT(s)
+z.vM=z.vM+u}++v}else{C.Nm.sB(y,0)
+for(;t===37;){++v
+u=J.xH(x.gB(a),2)
+if(typeof u!=="number")throw H.s(u)
+if(v>u)throw H.b(new P.AT("Truncated URI"))
+y.push(P.oh(a,v))
+v+=2
+if(v===x.gB(a))break
+t=x.j(a,v)}u=new P.GY(w).WJ(y)
+z.vM=z.vM+u}}return z.vM}}},hb:{"":"Tp;",
 call$1:function(a){var z,y
 z=J.Wx(a)
 if(z.C(a,128)){y=z.m(a,4)
@@ -14292,6 +14995,16 @@
 call$2:function(a,b){return J.mQ(J.WB(J.p0(b,31),J.v1(a)),1073741823)},
 "+call:2:0":0,
 $isEH:true,
+$is_bh:true},qz:{"":"Tp;a",
+call$2:function(a,b){var z,y,x,w
+z=J.U6(b)
+y=z.u8(b,"=")
+if(y===-1){if(!z.n(b,""))J.kW(a,P.pE(b,this.a,!0),"")}else if(y!==0){x=z.JT(b,0,y)
+w=z.yn(b,y+1)
+z=this.a
+J.kW(a,P.pE(x,z,!0),P.pE(w,z,!0))}return a},
+"+call:2:0":0,
+$isEH:true,
 $is_bh:true},hQ:{"":"Tp;",
 call$1:function(a){throw H.b(P.cD("Illegal IPv4 address, "+H.d(a)))},
 "+call:1:0":0,
@@ -14339,7 +15052,28 @@
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true}}],["dart.dom.html","dart:html",,W,{lq:function(){return window
+$is_Dv:true},dD:{"":"a;iY",
+PF:function(a){return this.iY.PF(a)},
+"+containsValue:1:0":0,
+x4:function(a){return this.iY.x4(a)},
+"+containsKey:1:0":0,
+t:function(a,b){return J.UQ(this.iY,b)},
+"+[]:1:0":0,
+u:function(a,b,c){throw H.b(P.f("Cannot modify an unmodifiable map"))},
+"+[]=:2:0":0,
+Rz:function(a,b){throw H.b(P.f("Cannot modify an unmodifiable map"))},
+aN:function(a,b){return J.kH(this.iY,b)},
+gvc:function(a){return J.iY(this.iY)},
+"+keys":0,
+gUQ:function(a){return J.hI(this.iY)},
+"+values":0,
+gB:function(a){return J.q8(this.iY)},
+"+length":0,
+gl0:function(a){return J.FN(this.iY)},
+"+isEmpty":0,
+gor:function(a){return J.pO(this.iY)},
+"+isNotEmpty":0,
+$isL8:true}}],["dart.dom.html","dart:html",,W,{lq:function(){return window
 "12"},"+window":1,UE:function(a){if(P.F7()===!0)return"webkitTransitionEnd"
 else if(P.dg()===!0)return"oTransitionEnd"
 return"transitionend"},r3:function(a,b){return document.createElement(a)},It:function(a,b,c){return W.lt(a,null,null,b,null,null,null,c).ml(new W.Kx())},lt:function(a,b,c,d,e,f,g,h){var z,y,x,w
@@ -14347,7 +15081,7 @@
 y=new P.Zf(P.Dt(z))
 H.VM(y,[z])
 x=new XMLHttpRequest()
-C.W3.xI(x,"GET",a,!0)
+C.W3.i3(x,"GET",a,!0)
 z=C.fK.aM(x)
 w=new W.Ov(0,z.uv,z.Ph,W.aF(new W.bU(y,x)),z.Sg)
 H.VM(w,[H.W8(z,"RO",0)])
@@ -14372,7 +15106,7 @@
 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},m7:function(a){return a},YT:function(a,b){return new W.vZ(a,b)},GO:function(a){return J.TD(a)},Yb:function(a){return J.W7(a)},Qp:function(a,b,c,d){return J.qd(a,b,c,d)},wi:function(a,b,c,d,e){var z,y,x,w,v,u,t,s,r,q
+return}else return a},m7:function(a){return a},YT:function(a,b){return new W.uY(a,b)},GO:function(a){return J.TD(a)},Yb:function(a){return J.W7(a)},Qp:function(a,b,c,d){return J.qd(a,b,c,d)},wi:function(a,b,c,d,e){var z,y,x,w,v,u,t,s,r,q
 z=J.Fb(d)
 if(z==null)throw H.b(new P.AT(d))
 y=z.prototype
@@ -14411,24 +15145,29 @@
 q={prototype: s}
 if(!J.xC(w,"HTMLElement"))if(!v)q.extends=e
 b.register(c,q)},aF:function(a){if(J.xC($.X3,C.NU))return a
-return $.X3.oj(a,!0)},qE:{"":"cv;","%":"HTMLAppletElement|HTMLBRElement|HTMLBaseFontElement|HTMLBodyElement|HTMLCanvasElement|HTMLContentElement|HTMLDListElement|HTMLDataListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLFontElement|HTMLFrameElement|HTMLFrameSetElement|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;Tt|GN|ir|Xf|uL|Vf|aC|tu|Be|Vc|i6|WZ|Fv|pv|I3|Vfx|Gk|Dsd|Ds|u7|tuj|St|Vct|vj|D13|CX|Nh|ih|F1|XP|NQ|WZq|uw"},Yy:{"":"Gv;",$isList:true,
+return $.X3.oj(a,!0)},qE:{"":"cv;","%":"HTMLAppletElement|HTMLBRElement|HTMLBaseFontElement|HTMLBodyElement|HTMLCanvasElement|HTMLContentElement|HTMLDListElement|HTMLDataListElement|HTMLDetailsElement|HTMLDialogElement|HTMLDirectoryElement|HTMLDivElement|HTMLFontElement|HTMLFrameElement|HTMLFrameSetElement|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;Tt|GN|ir|Xf|uL|Vf|aC|tu|Be|Vc|i6|WZ|Fv|pv|I3|Vfx|Gk|Dsd|Ds|u7|tuj|St|Vct|vj|D13|CX|BK|ih|F1|XP|NQ|WZq|fI|pva|kK|cda|uw"},Yy:{"":"Gv;",$isList:true,
 $asWO:function(){return[W.M5]},
 $isqC:true,
 $iscX:true,
 $ascX:function(){return[W.M5]},
 "%":"EntryArray"},Ps:{"":"qE;cC:hash%,LU:href=,N:target=,r9:type%",
 bu:function(a){return a.toString()},
-"%":"HTMLAnchorElement"},fY:{"":"qE;cC:hash=,LU:href=,N:target=","%":"HTMLAreaElement"},nB:{"":"qE;LU:href=,N:target=","%":"HTMLBaseElement"},Az:{"":"Gv;r9:type=",$isAz:true,"%":";Blob"},QW:{"":"qE;MB:form=,oc:name%,r9:type%,P:value%",
+"+toString:0:0":0,
+"%":"HTMLAnchorElement"},fY:{"":"qE;cC:hash=,LU:href=,N:target=","%":"HTMLAreaElement"},nB:{"":"qE;LU:href=,N:target=","%":"HTMLBaseElement"},i3:{"":"ea;O3:url=","%":"BeforeLoadEvent"},Az:{"":"Gv;r9:type=",$isAz:true,"%":";Blob"},QW:{"":"qE;MB:form=,oc:name%,r9:type%,P:value%",
 r6:function(a,b){return this.value.call$1(b)},
 "%":"HTMLButtonElement"},OM:{"":"KV;B:length=",$isGv:true,"%":"Comment;CharacterData"},QQ:{"":"ea;tT:code=","%":"CloseEvent"},oJ:{"":"BV;B:length=",
 T2:function(a,b){var z=a.getPropertyValue(b)
 return z!=null?z:""},
+hV:function(a,b,c,d){var z
+try{if(d==null)d=""
+a.setProperty(b,c,d)
+if(!!a.setAttribute)a.setAttribute(b,c)}catch(z){H.Ru(z)}},
 "%":"CSS2Properties|CSSStyleDeclaration|MSStyleCSSProperties"},DG:{"":"ea;",
 gey:function(a){var z=a._dartDetail
 if(z!=null)return z
 return P.o7(a.detail,!0)},
 $isDG:true,
-"%":"CustomEvent"},YN:{"":"KV;",
+"%":"CustomEvent"},QF:{"":"KV;",
 JP:function(a){return a.createDocumentFragment()},
 Kb:function(a,b){return a.getElementById(b)},
 gEr:function(a){return C.mt.aM(a)},
@@ -14437,19 +15176,21 @@
 Md:function(a,b){return W.vD(a.querySelectorAll(b),null)},
 Ja:function(a,b){return a.querySelector(b)},
 pr:function(a,b){return W.vD(a.querySelectorAll(b),null)},
-$isYN:true,
+$isQF:true,
 "%":"Document|HTMLDocument|SVGDocument"},bA:{"":"KV;",
 Md:function(a,b){return W.vD(a.querySelectorAll(b),null)},
 Ja:function(a,b){return a.querySelector(b)},
 pr:function(a,b){return W.vD(a.querySelectorAll(b),null)},
 $isGv:true,
-"%":";DocumentFragment"},Wq:{"":"KV;",$isGv:true,"%":"DocumentType"},rz:{"":"Gv;G1:message=,oc:name=","%":";DOMError"},BK:{"":"Gv;G1:message=",
+"%":";DocumentFragment"},Wq:{"":"KV;",$isGv:true,"%":"DocumentType"},rz:{"":"Gv;G1:message=,oc:name=","%":";DOMError"},Nh:{"":"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"
 return z},
 "+name":0,
 bu:function(a){return a.toString()},
+"+toString:0:0":0,
+$isNh:true,
 "%":"DOMException"},cv:{"":"KV;xr:className%,jO:id%",
 gQg:function(a){return new W.E9(a)},
 Md:function(a,b){return W.vD(a.querySelectorAll(b),null)},
@@ -14463,6 +15204,7 @@
 aC:function(a,b,c,d){},
 gjU:function(a){return a.localName},
 bu:function(a){return a.localName},
+"+toString:0:0":0,
 WO:function(a,b){if(!!a.matches)return a.matches(b)
 else if(!!a.webkitMatchesSelector)return a.webkitMatchesSelector(b)
 else if(!!a.mozMatchesSelector)return a.mozMatchesSelector(b)
@@ -14482,10 +15224,10 @@
 ZL:function(a){},
 $iscv:true,
 $isGv:true,
-"%":";Element"},Fs:{"":"qE;oc:name%,LA:src=,r9:type%","%":"HTMLEmbedElement"},SX:{"":"ea;kc:error=,G1:message=","%":"ErrorEvent"},ea:{"":"Gv;It:_selector},Xt:bubbles=,Ii:path=,r9:type=",
+"%":";Element"},Fs:{"":"qE;oc:name%,LA:src%,r9:type%","%":"HTMLEmbedElement"},SX:{"":"ea;kc:error=,G1:message=","%":"ErrorEvent"},ea:{"":"Gv;It:_selector},Xt:bubbles=,Ii:path=,r9:type=",
 gN:function(a){return W.bt(a.target)},
 $isea:true,
-"%":"AudioProcessingEvent|AutocompleteErrorEvent|BeforeLoadEvent|BeforeUnloadEvent|CSSFontFaceLoadEvent|DeviceMotionEvent|DeviceOrientationEvent|HashChangeEvent|IDBVersionChangeEvent|MIDIConnectionEvent|MIDIMessageEvent|MediaKeyNeededEvent|MediaStreamEvent|MediaStreamTrackEvent|MessageEvent|MutationEvent|OfflineAudioCompletionEvent|OverflowEvent|PageTransitionEvent|PopStateEvent|RTCDTMFToneChangeEvent|RTCDataChannelEvent|RTCIceCandidateEvent|SecurityPolicyViolationEvent|SpeechInputEvent|SpeechRecognitionEvent|TrackEvent|WebGLContextEvent|WebKitAnimationEvent;Event"},D0:{"":"Gv;",
+"%":"AudioProcessingEvent|AutocompleteErrorEvent|BeforeUnloadEvent|CSSFontFaceLoadEvent|DeviceMotionEvent|DeviceOrientationEvent|HashChangeEvent|IDBVersionChangeEvent|MIDIConnectionEvent|MIDIMessageEvent|MediaKeyNeededEvent|MediaStreamEvent|MediaStreamTrackEvent|MutationEvent|OfflineAudioCompletionEvent|OverflowEvent|PageTransitionEvent|PopStateEvent|RTCDTMFToneChangeEvent|RTCDataChannelEvent|RTCIceCandidateEvent|SecurityPolicyViolationEvent|SpeechInputEvent|SpeechRecognitionEvent|TrackEvent|WebGLContextEvent|WebKitAnimationEvent;Event"},D0:{"":"Gv;",
 gI:function(a){return new W.Jn(a)},
 On:function(a,b,c,d){return a.addEventListener(b,H.tR(c,1),d)},
 Y9:function(a,b,c,d){return a.removeEventListener(b,H.tR(c,1),d)},
@@ -14514,12 +15256,12 @@
 $isXj:true,
 "%":"HTMLCollection|HTMLFormControlsCollection|HTMLOptionsCollection"},fJ:{"":"Vi;iC:responseText=,ys:status=,po:statusText=",
 R3:function(a,b,c,d,e,f){return a.open(b,c,d,f,e)},
-xI:function(a,b,c,d){return a.open(b,c,d)},
+i3:function(a,b,c,d){return a.open(b,c,d)},
 wR:function(a,b){return a.send(b)},
 $isfJ:true,
-"%":"XMLHttpRequest"},Vi:{"":"D0;","%":";XMLHttpRequestEventTarget"},tX:{"":"qE;oc:name%,LA:src=","%":"HTMLIFrameElement"},Sg:{"":"Gv;",$isSg:true,"%":"ImageData"},pA:{"":"qE;LA:src=",
+"%":"XMLHttpRequest"},Vi:{"":"D0;","%":";XMLHttpRequestEventTarget"},tX:{"":"qE;oc:name%,LA:src%","%":"HTMLIFrameElement"},Sg:{"":"Gv;",$isSg:true,"%":"ImageData"},pA:{"":"qE;LA:src%",
 tZ:function(a){return this.complete.call$0()},
-"%":"HTMLImageElement"},Mi:{"":"qE;Tq:checked%,MB:form=,qC:list=,oc:name%,LA:src=,r9:type%,P:value%",
+"%":"HTMLImageElement"},Mi:{"":"qE;Tq:checked%,MB:form=,qC:list=,oc:name%,LA:src%,r9:type%,P:value%",
 RR:function(a,b){return this.accept.call$1(b)},
 r6:function(a,b){return this.value.call$1(b)},
 $isMi:true,
@@ -14531,10 +15273,14 @@
 r6:function(a,b){return this.value.call$1(b)},
 "%":"HTMLLIElement"},eP:{"":"qE;MB:form=","%":"HTMLLabelElement"},AL:{"":"qE;MB:form=","%":"HTMLLegendElement"},Og:{"":"qE;LU:href=,r9:type%",$isOg:true,"%":"HTMLLinkElement"},cS:{"":"Gv;cC:hash%,LU:href=",
 bu:function(a){return a.toString()},
+"+toString:0:0":0,
 $iscS:true,
-"%":"Location"},M6:{"":"qE;oc:name%","%":"HTMLMapElement"},El:{"":"qE;kc:error=,LA:src=",
+"%":"Location"},M6:{"":"qE;oc:name%","%":"HTMLMapElement"},El:{"":"qE;kc:error=,LA:src%",
 yy:function(a){return a.pause()},
-"%":"HTMLAudioElement|HTMLMediaElement|HTMLVideoElement"},zm:{"":"Gv;tT:code=","%":"MediaError"},SV:{"":"Gv;tT:code=","%":"MediaKeyError"},aB:{"":"ea;G1:message=","%":"MediaKeyEvent"},ku:{"":"ea;G1:message=","%":"MediaKeyMessageEvent"},cW:{"":"D0;jO:id=","%":"MediaStream"},la:{"":"qE;jb:content=,oc:name%","%":"HTMLMetaElement"},Vn:{"":"qE;P:value%",
+"%":"HTMLAudioElement|HTMLMediaElement|HTMLVideoElement"},zm:{"":"Gv;tT:code=","%":"MediaError"},SV:{"":"Gv;tT:code=","%":"MediaKeyError"},aB:{"":"ea;G1:message=","%":"MediaKeyEvent"},ku:{"":"ea;G1:message=","%":"MediaKeyMessageEvent"},cW:{"":"D0;jO:id=","%":"MediaStream"},cx:{"":"ea;",
+gFF:function(a){return W.bt(a.source)},
+"+source":0,
+"%":"MessageEvent"},la:{"":"qE;jb:content=,oc:name%","%":"HTMLMetaElement"},Vn:{"":"qE;P:value%",
 r6:function(a,b){return this.value.call$1(b)},
 "%":"HTMLMeterElement"},bn:{"":"Im;",
 LV:function(a,b,c){return a.send(b,c)},
@@ -14549,6 +15295,7 @@
 if(z!=null)z.removeChild(a)},
 bu:function(a){var z=a.nodeValue
 return z==null?J.Gv.prototype.bu.call(this,a):z},
+"+toString:0:0":0,
 jx:function(a,b){return a.appendChild(b)},
 Yv:function(a,b){return a.cloneNode(b)},
 tg:function(a,b){return a.contains(b)},
@@ -14585,17 +15332,17 @@
 r6:function(a,b){return this.value.call$1(b)},
 "%":"HTMLParamElement"},p3:{"":"Gv;tT:code=,G1:message=","%":"PositionError"},qW:{"":"OM;N:target=","%":"ProcessingInstruction"},KR:{"":"qE;P:value%",
 r6:function(a,b){return this.value.call$1(b)},
-"%":"HTMLProgressElement"},ew:{"":"ea;",$isew:true,"%":"ProgressEvent|ResourceProgressEvent|XMLHttpRequestProgressEvent"},j2:{"":"qE;LA:src=,r9:type%",$isj2:true,"%":"HTMLScriptElement"},lp:{"":"qE;MB:form=,B:length%,oc:name%,ig:selectedIndex%,r9:type=,P:value%",
+"%":"HTMLProgressElement"},ew:{"":"ea;",$isew:true,"%":"XMLHttpRequestProgressEvent;ProgressEvent"},bX:{"":"ew;O3:url=","%":"ResourceProgressEvent"},j2:{"":"qE;LA:src%,r9:type%",$isj2:true,"%":"HTMLScriptElement"},lp:{"":"qE;MB:form=,B:length%,oc:name%,ig:selectedIndex%,r9:type=,P:value%",
 r6:function(a,b){return this.value.call$1(b)},
 $islp:true,
 "%":"HTMLSelectElement"},I0:{"":"bA;pQ:applyAuthorStyles=",
 Yv:function(a,b){return a.cloneNode(b)},
 Kb:function(a,b){return a.getElementById(b)},
 $isI0:true,
-"%":"ShadowRoot"},QR:{"":"qE;LA:src=,r9:type%","%":"HTMLSourceElement"},zD:{"":"ea;kc:error=,G1:message=","%":"SpeechRecognitionError"},G0:{"":"ea;oc:name=","%":"SpeechSynthesisEvent"},wb:{"":"ea;G3:key=,zZ:newValue=,jL:oldValue=","%":"StorageEvent"},fq:{"":"qE;r9:type%","%":"HTMLStyleElement"},yY:{"":"qE;jb:content=",$isyY:true,"%":"HTMLTemplateElement"},kJ:{"":"OM;",$iskJ:true,"%":"CDATASection|Text"},AE:{"":"qE;MB:form=,oc:name%,r9:type=,P:value%",
+"%":"ShadowRoot"},QR:{"":"qE;LA:src%,r9:type%","%":"HTMLSourceElement"},zD:{"":"ea;kc:error=,G1:message=","%":"SpeechRecognitionError"},G0:{"":"ea;oc:name=","%":"SpeechSynthesisEvent"},wb:{"":"ea;G3:key=,zZ:newValue=,jL:oldValue=,O3:url=","%":"StorageEvent"},fq:{"":"qE;r9:type%","%":"HTMLStyleElement"},yY:{"":"qE;jb:content=",$isyY:true,"%":"HTMLTemplateElement"},kJ:{"":"OM;",$iskJ:true,"%":"CDATASection|Text"},AE:{"":"qE;MB:form=,oc:name%,r9:type=,P:value%",
 r6:function(a,b){return this.value.call$1(b)},
 $isAE:true,
-"%":"HTMLTextAreaElement"},RH:{"":"qE;fY:kind=,LA:src=","%":"HTMLTrackElement"},Lq:{"":"ea;",$isLq:true,"%":"TransitionEvent|WebKitTransitionEvent"},Mf:{"":"ea;","%":"CompositionEvent|FocusEvent|SVGZoomEvent|TextEvent|TouchEvent;UIEvent"},K5:{"":"D0;oc:name%,ys:status=",
+"%":"HTMLTextAreaElement"},RH:{"":"qE;fY:kind%,LA:src%","%":"HTMLTrackElement"},Lq:{"":"ea;",$isLq:true,"%":"TransitionEvent|WebKitTransitionEvent"},Mf:{"":"ea;","%":"CompositionEvent|FocusEvent|SVGZoomEvent|TextEvent|TouchEvent;UIEvent"},K5:{"":"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.H2(z)
@@ -14621,6 +15368,7 @@
 geT:function(a){return W.uV(a.parent)},
 cO:function(a){return a.close()},
 bu:function(a){return a.toString()},
+"+toString:0:0":0,
 gEr:function(a){return C.mt.aM(a)},
 gVl:function(a){return C.T1.aM(a)},
 gLm:function(a){return C.io.aM(a)},
@@ -14629,7 +15377,7 @@
 $isD0:true,
 "%":"DOMWindow|Window"},UM:{"":"KV;oc:name=,P:value%",
 r6:function(a,b){return this.value.call$1(b)},
-"%":"Attr"},rh:{"":"Gb;",
+"%":"Attr"},rh:{"":"ma;",
 gB:function(a){return a.length},
 "+length":0,
 t:function(a,b){var z=a.length
@@ -14656,14 +15404,17 @@
 "+error:1:0":0,
 gkc:function(a){return new P.C7(this,W.QZ.prototype.Wt,a,"Wt")},
 To:function(a){return typeof console!="undefined"?console.info(a):null},
-ZF:function(a,b){return typeof console!="undefined"?console.trace(b):null},
+WL:function(a,b){return typeof console!="undefined"?console.trace(b):null},
 "+trace:1:0":0,
-gtN:function(a){return new P.C7(this,W.QZ.prototype.ZF,a,"ZF")},
-static:{"":"wk",}},BV:{"":"Gv+E1;"},E1:{"":"a;",
+gtN:function(a){return new P.C7(this,W.QZ.prototype.WL,a,"WL")},
+static:{"":"wk",}},BV:{"":"Gv+id;"},id:{"":"a;",
 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")}},wz:{"":"ar;Sn,Sc",
+gLA:function(a){return this.T2(a,"src")},
+"+src":0,
+sLA:function(a,b){this.hV(a,"src",b,"")},
+"+src=":0},wz:{"":"ar;Sn,Sc",
 gB:function(a){return this.Sn.length},
 "+length":0,
 t:function(a,b){var z=this.Sn
@@ -14769,7 +15520,7 @@
 "+[]:1:0":0,
 $asar:function(){return[W.KV]},
 $asWO:function(){return[W.KV]},
-$ascX:function(){return[W.KV]}},nj:{"":"Gv+lD;",$isList:true,$asWO:null,$isqC:true,$iscX:true,$ascX:null},rl:{"":"nj+Gm;",$asWO:null,$ascX:null,$isList:true,$isqC:true,$iscX:true},RAp:{"":"Gv+lD;",$isList:true,$asWO:null,$isqC:true,$iscX:true,$ascX:null},Gb:{"":"RAp+Gm;",$asWO:null,$ascX:null,$isList:true,$isqC:true,$iscX:true},cf:{"":"a;",
+$ascX:function(){return[W.KV]}},nj:{"":"Gv+lD;",$isList:true,$asWO:null,$isqC:true,$iscX:true,$ascX:null},rl:{"":"nj+Gm;",$asWO:null,$ascX:null,$isList:true,$isqC:true,$iscX:true},RAp:{"":"Gv+lD;",$isList:true,$asWO:null,$isqC:true,$iscX:true,$ascX:null},ma:{"":"RAp+Gm;",$asWO:null,$ascX:null,$isList:true,$isqC:true,$iscX:true},cf:{"":"a;",
 PF:function(a){var z,y
 for(z=this.gUQ(this),y=new H.a7(z,z.length,0,null),H.VM(y,[H.W8(z,"Q",0)]);y.G(););return!1},
 "+containsValue:1:0":0,
@@ -15008,7 +15759,7 @@
 "+current":0,
 static:{yB:function(a,b){var z=new W.W9(a,J.q8(a),-1,null)
 H.VM(z,[b])
-return z}}},vZ:{"":"Tp;a,b",
+return z}}},uY:{"":"Tp;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)},
@@ -15016,13 +15767,13 @@
 $isEH:true,
 $is_HB:true,
 $is_Dv:true},dW:{"":"a;Ui",
-gmW:function(a){return W.zX(this.Ui.location)},
+gmW:function(a){return W.tF(this.Ui.location)},
 geT:function(a){return W.P1(this.Ui.parent)},
 cO:function(a){return this.Ui.close()},
 $isD0:true,
 $isGv:true,
 static:{P1:function(a){if(a===window)return a
-else return new W.dW(a)}}},PA:{"":"a;mf",static:{zX:function(a){if(a===C.ol.gmW(window))return a
+else return new W.dW(a)}}},PA:{"":"a;mf",static:{tF:function(a){if(a===C.ol.gmW(window))return a
 else return new W.PA(a)}}},H2:{"":"a;WK",
 gcC:function(a){return this.WK.hash},
 "+hash":0,
@@ -15030,15 +15781,16 @@
 "+hash=":0,
 gLU:function(a){return this.WK.href},
 bu:function(a){return this.WK.toString()},
+"+toString:0:0":0,
 $iscS:true,
-$isGv:true}}],["dart.dom.indexed_db","dart:indexed_db",,P,{hF:{"":"Gv;",$ishF:true,"%":"IDBKeyRange"}}],["dart.dom.svg","dart:svg",,P,{Y0:{"":"tp;N:target=,LU:href=",$isGv:true,"%":"SVGAElement"},ZJ:{"":"Eo;LU:href=",$isGv:true,"%":"SVGAltGlyphElement"},ui:{"":"MB;",$isGv:true,"%":"SVGAnimateColorElement|SVGAnimateElement|SVGAnimateMotionElement|SVGAnimateTransformElement|SVGAnimationElement|SVGSetElement"},D6:{"":"tp;",$isGv:true,"%":"SVGCircleElement"},DQ:{"":"tp;",$isGv:true,"%":"SVGClipPathElement"},Sm:{"":"tp;",$isGv:true,"%":"SVGDefsElement"},es:{"":"tp;",$isGv:true,"%":"SVGEllipseElement"},eG:{"":"MB;",$isGv:true,"%":"SVGFEBlendElement"},lv:{"":"MB;r9:type=,UQ:values=",$isGv:true,"%":"SVGFEColorMatrixElement"},pf:{"":"MB;",$isGv:true,"%":"SVGFEComponentTransferElement"},NV:{"":"MB;kp:operator=",$isGv:true,"%":"SVGFECompositeElement"},W1:{"":"MB;",$isGv:true,"%":"SVGFEConvolveMatrixElement"},zo:{"":"MB;",$isGv:true,"%":"SVGFEDiffuseLightingElement"},wf:{"":"MB;",$isGv:true,"%":"SVGFEDisplacementMapElement"},bb:{"":"MB;",$isGv:true,"%":"SVGFEFloodElement"},tk:{"":"MB;",$isGv:true,"%":"SVGFEGaussianBlurElement"},me:{"":"MB;LU:href=",$isGv:true,"%":"SVGFEImageElement"},qN:{"":"MB;",$isGv:true,"%":"SVGFEMergeElement"},d4:{"":"MB;kp:operator=",$isGv:true,"%":"SVGFEMorphologyElement"},MI:{"":"MB;",$isGv:true,"%":"SVGFEOffsetElement"},kK:{"":"MB;",$isGv:true,"%":"SVGFESpecularLightingElement"},um:{"":"MB;",$isGv:true,"%":"SVGFETileElement"},Fu:{"":"MB;r9:type=",$isGv:true,"%":"SVGFETurbulenceElement"},OE:{"":"MB;LU:href=",$isGv:true,"%":"SVGFilterElement"},l6:{"":"tp;",$isGv:true,"%":"SVGForeignObjectElement"},BA:{"":"tp;",$isGv:true,"%":"SVGGElement"},tp:{"":"MB;",$isGv:true,"%":";SVGGraphicsElement"},rE:{"":"tp;LU:href=",$isGv:true,"%":"SVGImageElement"},CC:{"":"tp;",$isGv:true,"%":"SVGLineElement"},uz:{"":"MB;",$isGv:true,"%":"SVGMarkerElement"},Yd:{"":"MB;",$isGv:true,"%":"SVGMaskElement"},AD:{"":"tp;",$isGv:true,"%":"SVGPathElement"},Gr:{"":"MB;LU:href=",$isGv:true,"%":"SVGPatternElement"},tc:{"":"tp;",$isGv:true,"%":"SVGPolygonElement"},GH:{"":"tp;",$isGv:true,"%":"SVGPolylineElement"},NJ:{"":"tp;",$isGv:true,"%":"SVGRectElement"},nd:{"":"MB;r9:type%,LU:href=",$isGv:true,"%":"SVGScriptElement"},EU:{"":"MB;r9:type%","%":"SVGStyleElement"},MB:{"":"cv;",
+$isGv:true}}],["dart.dom.indexed_db","dart:indexed_db",,P,{hF:{"":"Gv;",$ishF:true,"%":"IDBKeyRange"}}],["dart.dom.svg","dart:svg",,P,{HB:{"":"tp;N:target=,LU:href=",$isGv:true,"%":"SVGAElement"},ZJ:{"":"Eo;LU:href=",$isGv:true,"%":"SVGAltGlyphElement"},ui:{"":"MB;",$isGv:true,"%":"SVGAnimateColorElement|SVGAnimateElement|SVGAnimateMotionElement|SVGAnimateTransformElement|SVGAnimationElement|SVGSetElement"},D6:{"":"tp;",$isGv:true,"%":"SVGCircleElement"},DQ:{"":"tp;",$isGv:true,"%":"SVGClipPathElement"},Sm:{"":"tp;",$isGv:true,"%":"SVGDefsElement"},es:{"":"tp;",$isGv:true,"%":"SVGEllipseElement"},eG:{"":"MB;",$isGv:true,"%":"SVGFEBlendElement"},lv:{"":"MB;r9:type=,UQ:values=",$isGv:true,"%":"SVGFEColorMatrixElement"},pf:{"":"MB;",$isGv:true,"%":"SVGFEComponentTransferElement"},NV:{"":"MB;kp:operator=",$isGv:true,"%":"SVGFECompositeElement"},W1:{"":"MB;",$isGv:true,"%":"SVGFEConvolveMatrixElement"},zo:{"":"MB;",$isGv:true,"%":"SVGFEDiffuseLightingElement"},wf:{"":"MB;",$isGv:true,"%":"SVGFEDisplacementMapElement"},bb:{"":"MB;",$isGv:true,"%":"SVGFEFloodElement"},tk:{"":"MB;",$isGv:true,"%":"SVGFEGaussianBlurElement"},me:{"":"MB;LU:href=",$isGv:true,"%":"SVGFEImageElement"},qN:{"":"MB;",$isGv:true,"%":"SVGFEMergeElement"},d4:{"":"MB;kp:operator=",$isGv:true,"%":"SVGFEMorphologyElement"},MI:{"":"MB;",$isGv:true,"%":"SVGFEOffsetElement"},xX:{"":"MB;",$isGv:true,"%":"SVGFESpecularLightingElement"},um:{"":"MB;",$isGv:true,"%":"SVGFETileElement"},Fu:{"":"MB;r9:type=",$isGv:true,"%":"SVGFETurbulenceElement"},OE:{"":"MB;LU:href=",$isGv:true,"%":"SVGFilterElement"},l6:{"":"tp;",$isGv:true,"%":"SVGForeignObjectElement"},BA:{"":"tp;",$isGv:true,"%":"SVGGElement"},tp:{"":"MB;",$isGv:true,"%":";SVGGraphicsElement"},rE:{"":"tp;LU:href=",$isGv:true,"%":"SVGImageElement"},CC:{"":"tp;",$isGv:true,"%":"SVGLineElement"},uz:{"":"MB;",$isGv:true,"%":"SVGMarkerElement"},Yd:{"":"MB;",$isGv:true,"%":"SVGMaskElement"},AD:{"":"tp;",$isGv:true,"%":"SVGPathElement"},Gr:{"":"MB;LU:href=",$isGv:true,"%":"SVGPatternElement"},tc:{"":"tp;",$isGv:true,"%":"SVGPolygonElement"},GH:{"":"tp;",$isGv:true,"%":"SVGPolylineElement"},NJ:{"":"tp;",$isGv:true,"%":"SVGRectElement"},nd:{"":"MB;r9:type%,LU:href=",$isGv:true,"%":"SVGScriptElement"},EU:{"":"MB;r9:type%","%":"SVGStyleElement"},MB:{"":"cv;",
 gDD:function(a){if(a._cssClassSet==null)a._cssClassSet=new P.O7(a)
 return a._cssClassSet},
 "%":"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:{"":"tp;",
 Kb:function(a,b){return a.getElementById(b)},
 $ishy:true,
 $isGv:true,
-"%":"SVGSVGElement"},r8:{"":"tp;",$isGv:true,"%":"SVGSwitchElement"},aS:{"":"MB;",$isGv:true,"%":"SVGSymbolElement"},qF:{"":"tp;",$isGv:true,"%":";SVGTextContentElement"},Rk:{"":"qF;bP:method=,LU:href=",$isGv:true,"%":"SVGTextPathElement"},Eo:{"":"qF;","%":"SVGTSpanElement|SVGTextElement;SVGTextPositioningElement"},ox:{"":"tp;LU:href=",$isGv:true,"%":"SVGUseElement"},ZD:{"":"MB;",$isGv:true,"%":"SVGViewElement"},wD:{"":"MB;LU:href=",$isGv:true,"%":"SVGGradientElement|SVGLinearGradientElement|SVGRadialGradientElement"},mj:{"":"MB;",$isGv:true,"%":"SVGCursorElement"},cB:{"":"MB;",$isGv:true,"%":"SVGFEDropShadowElement"},nb:{"":"MB;",$isGv:true,"%":"SVGGlyphRefElement"},xt:{"":"MB;",$isGv:true,"%":"SVGMPathElement"},O7:{"":"As;CE",
+"%":"SVGSVGElement"},r8:{"":"tp;",$isGv:true,"%":"SVGSwitchElement"},aS:{"":"MB;",$isGv:true,"%":"SVGSymbolElement"},qF:{"":"tp;",$isGv:true,"%":";SVGTextContentElement"},xN:{"":"qF;bP:method=,LU:href=",$isGv:true,"%":"SVGTextPathElement"},Eo:{"":"qF;","%":"SVGTSpanElement|SVGTextElement;SVGTextPositioningElement"},ox:{"":"tp;LU:href=",$isGv:true,"%":"SVGUseElement"},ZD:{"":"MB;",$isGv:true,"%":"SVGViewElement"},wD:{"":"MB;LU:href=",$isGv:true,"%":"SVGGradientElement|SVGLinearGradientElement|SVGRadialGradientElement"},mj:{"":"MB;",$isGv:true,"%":"SVGCursorElement"},cB:{"":"MB;",$isGv:true,"%":"SVGFEDropShadowElement"},nb:{"":"MB;",$isGv:true,"%":"SVGGlyphRefElement"},xt:{"":"MB;",$isGv:true,"%":"SVGMPathElement"},O7:{"":"As;CE",
 lF:function(){var z,y,x,w,v
 z=new W.E9(this.CE).MW.getAttribute("class")
 y=P.Ls(null,null,null,J.O)
@@ -15083,15 +15835,18 @@
 this.eh[b]=P.wY(c)},
 "+[]=:2:0":0,
 giO:function(a){return 0},
+"+hashCode":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},
+"+==:1:0":0,
 Bm:function(a){return a in this.eh},
 bu:function(a){var z,y
 try{z=String(this.eh)
 return z}catch(y){H.Ru(y)
 return P.a.prototype.bu.call(this,this)}},
+"+toString:0:0":0,
 V7:function(a,b){var z,y
 z=this.eh
 if(b==null)y=null
@@ -15191,7 +15946,7 @@
 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()},yq:function(a){if(J.xC(a,C.HH)){$.At().toString
-return $.Cr()}return H.jO(a.gIE())},QF:{"":"a;",$isQF:true},NL:{"":"a;",$isNL:true,$isQF:true},vr:{"":"a;",$isvr:true,$isQF:true},D4:{"":"a;",$isD4:true,$isQF:true,$isNL:true},X9:{"":"a;",$isX9:true,$isNL:true,$isQF:true},Ms:{"":"a;",$isMs:true,$isQF:true,$isX9:true,$isNL:true},Fw:{"":"X9;",$isFw:true},RS:{"":"a;",$isRS:true,$isNL:true,$isQF:true},RY:{"":"a;",$isRY:true,$isNL:true,$isQF:true},Ys:{"":"a;",$isYs:true,$isRY:true,$isNL:true,$isQF:true},vg:{"":"a;c1,m2,nV,V3"}}],["dart.typed_data","dart:typed_data",,P,{AS:{"":"Gv;",
+return $.Cr()}return H.jO(a.gIE())},ej:{"":"a;",$isej:true},NL:{"":"a;",$isNL:true,$isej:true},vr:{"":"a;",$isvr:true,$isej:true},D4:{"":"a;",$isD4:true,$isej:true,$isNL:true},L9u:{"":"a;",$isL9u:true,$isNL:true,$isej:true},Ms:{"":"a;",$isMs:true,$isej:true,$isL9u:true,$isNL:true},Fw:{"":"L9u;",$isFw:true},RS:{"":"a;",$isRS:true,$isNL:true,$isej:true},RY:{"":"a;",$isRY:true,$isNL:true,$isej:true},Ys:{"":"a;",$isYs:true,$isRY:true,$isNL:true,$isej:true},vg:{"":"a;c1,m2,nV,V3"}}],["dart.typed_data","dart:typed_data",,P,{AS:{"":"Gv;",
 aq: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(P.u("Invalid list index "+H.d(b)))},
@@ -15319,7 +16074,7 @@
 $isqC:true,
 $iscX:true,
 $isXj:true,
-"%":"Int8Array"},hn:{"":"TkQ;",
+"%":"Int8Array"},ycx:{"":"TkQ;",
 gB:function(a){return C.i7(a)},
 "+length":0,
 t:function(a,b){var z=C.i7(a)
@@ -15427,12 +16182,12 @@
 $iscX:true,
 $ascX:function(){return[J.im]},
 $isXj:true,
-static:{"":"U9",}}}],["disassembly_entry_element","package:observatory/src/observatory_elements/disassembly_entry.dart",,E,{Fv:{"":["WZ;FT%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+static:{"":"U9",}}}],["disassembly_entry_element","package:observatory/src/observatory_elements/disassembly_entry.dart",,E,{Fv:{"":["WZ;FT%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gNI:function(a){return a.FT
-"32,33,34"},
+"34,35,36"},
 "+instruction":1,
-sNI:function(a,b){a.FT=this.pD(a,C.eJ,a.FT,b)
-"35,28,32,33"},
+sNI:function(a,b){a.FT=this.ct(a,C.eJ,a.FT,b)
+"37,28,34,35"},
 "+instruction=":1,
 "@":function(){return[C.Vy]},
 static:{AH:function(a){var z,y,x,w,v,u
@@ -15451,18 +16206,18 @@
 C.Tl.ZL(a)
 C.Tl.FH(a)
 return a
-"13"},"+new DisassemblyEntryElement$created:0:0":1}},"+DisassemblyEntryElement": [78],WZ:{"":"uL+Pi;",$isd3:true}}],["error_view_element","package:observatory/src/observatory_elements/error_view.dart",,F,{I3:{"":["pv;Py%-,hO%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"13"},"+new DisassemblyEntryElement$created:0:0":1}},"+DisassemblyEntryElement": [80],WZ:{"":"uL+Pi;",$isd3:true}}],["error_view_element","package:observatory/src/observatory_elements/error_view.dart",,F,{I3:{"":["pv;Py%-,hO%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,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
-"8,33,34"},
+"8,35,36"},
 "+error":1,
-skc:function(a,b){a.Py=this.pD(a,C.yh,a.Py,b)
-"35,28,8,33"},
+skc:function(a,b){a.Py=this.ct(a,C.yh,a.Py,b)
+"37,28,8,35"},
 "+error=":1,
 gVB:function(a){return a.hO
-"35,33,34"},
+"37,35,36"},
 "+error_obj":1,
-sVB:function(a,b){a.hO=this.pD(a,C.Yn,a.hO,b)
-"35,28,35,33"},
+sVB:function(a,b){a.hO=this.ct(a,C.Yn,a.hO,b)
+"37,28,37,35"},
 "+error_obj=":1,
 "@":function(){return[C.uW]},
 static:{TW:function(a){var z,y,x,w,v
@@ -15479,12 +16234,12 @@
 C.OD.ZL(a)
 C.OD.FH(a)
 return a
-"14"},"+new ErrorViewElement$created:0:0":1}},"+ErrorViewElement": [79],pv:{"":"uL+Pi;",$isd3:true}}],["field_view_element","package:observatory/src/observatory_elements/field_view.dart",,A,{Gk:{"":["Vfx;vt%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"14"},"+new ErrorViewElement$created:0:0":1}},"+ErrorViewElement": [81],pv:{"":"uL+Pi;",$isd3:true}}],["field_view_element","package:observatory/src/observatory_elements/field_view.dart",,A,{Gk:{"":["Vfx;vt%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",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
-"32,33,34"},
+"34,35,36"},
 "+field":1,
-st0:function(a,b){a.vt=this.pD(a,C.WQ,a.vt,b)
-"35,28,32,33"},
+st0:function(a,b){a.vt=this.ct(a,C.WQ,a.vt,b)
+"37,28,34,35"},
 "+field=":1,
 "@":function(){return[C.mv]},
 static:{cY:function(a){var z,y,x,w,v
@@ -15500,14 +16255,14 @@
 C.lS.ZL(a)
 C.lS.FH(a)
 return a
-"15"},"+new FieldViewElement$created:0:0":1}},"+FieldViewElement": [80],Vfx:{"":"uL+Pi;",$isd3:true}}],["function_view_element","package:observatory/src/observatory_elements/function_view.dart",,N,{Ds:{"":["Dsd;ql%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"15"},"+new FieldViewElement$created:0:0":1}},"+FieldViewElement": [82],Vfx:{"":"uL+Pi;",$isd3:true}}],["function_view_element","package:observatory/src/observatory_elements/function_view.dart",,N,{Ds:{"":["Dsd;ql%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gMj:function(a){return a.ql
-"32,33,34"},
+"34,35,36"},
 "+function":1,
-sMj:function(a,b){a.ql=this.pD(a,C.nf,a.ql,b)
-"35,28,32,33"},
+sMj:function(a,b){a.ql=this.ct(a,C.nf,a.ql,b)
+"37,28,34,35"},
 "+function=":1,
-"@":function(){return[C.nu]},
+"@":function(){return[C.Uc]},
 static:{p7:function(a){var z,y,x,w,v
 z=$.Nd()
 y=P.Py(null,null,null,J.O,W.I0)
@@ -15521,7 +16276,7 @@
 C.PJ.ZL(a)
 C.PJ.FH(a)
 return a
-"16"},"+new FunctionViewElement$created:0:0":1}},"+FunctionViewElement": [81],Dsd:{"":"uL+Pi;",$isd3:true}}],["html_common","dart:html_common",,P,{jD:function(a){return P.Wu(a.getTime(),!0)},o7:function(a,b){var z=[]
+"16"},"+new FunctionViewElement$created:0:0":1}},"+FunctionViewElement": [83],Dsd:{"":"uL+Pi;",$isd3:true}}],["html_common","dart:html_common",,P,{jD:function(a){return P.Wu(a.getTime(),!0)},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)},dg:function(){if($.L4==null)$.L4=J.Vw(window.navigator.userAgent,"Opera",0)
 return $.L4},F7:function(){if($.PN==null)$.PN=P.dg()!==!0&&J.Vw(window.navigator.userAgent,"WebKit",0)
 return $.PN},CA:{"":"Tp;a,b",
@@ -15580,6 +16335,7 @@
 $is_Dv:true},As:{"":"a;",
 bu:function(a){var z=this.lF()
 return z.zV(z," ")},
+"+toString:0:0":0,
 gA:function(a){var z=this.lF()
 z=new P.zQ(z,z.zN,null,null)
 H.VM(z,[null])
@@ -15637,7 +16393,7 @@
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true}}],["isolate_list_element","package:observatory/src/observatory_elements/isolate_list.dart",,L,{u7:{"":["uL;tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+$is_Dv:true}}],["isolate_list_element","package:observatory/src/observatory_elements/isolate_list.dart",,L,{u7:{"":["uL;hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.jF]},
 static:{ip:function(a){var z,y,x,w,v
 z=$.Nd()
@@ -15652,18 +16408,18 @@
 C.Dh.ZL(a)
 C.Dh.FH(a)
 return a
-"17"},"+new IsolateListElement$created:0:0":1}},"+IsolateListElement": [24]}],["isolate_summary_element","package:observatory/src/observatory_elements/isolate_summary.dart",,D,{St:{"":["tuj;Pw%-,i0%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"17"},"+new IsolateListElement$created:0:0":1}},"+IsolateListElement": [24]}],["isolate_summary_element","package:observatory/src/observatory_elements/isolate_summary.dart",,D,{St:{"":["tuj;Pw%-,i0%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gF1:function(a){return a.Pw
-"27,33,34"},
+"27,35,36"},
 "+isolate":1,
-sF1:function(a,b){a.Pw=this.pD(a,C.Y2,a.Pw,b)
-"35,28,27,33"},
+sF1:function(a,b){a.Pw=this.ct(a,C.Y2,a.Pw,b)
+"37,28,27,35"},
 "+isolate=":1,
 goc:function(a){return a.i0
-"8,33,34"},
+"8,35,36"},
 "+name":1,
-soc:function(a,b){a.i0=this.pD(a,C.YS,a.i0,b)
-"35,28,8,33"},
+soc:function(a,b){a.i0=this.ct(a,C.YS,a.i0,b)
+"37,28,8,35"},
 "+name=":1,
 "@":function(){return[C.aM]},
 static:{N5:function(a){var z,y,x,w,v
@@ -15680,19 +16436,19 @@
 C.nM.ZL(a)
 C.nM.FH(a)
 return a
-"18"},"+new IsolateSummaryElement$created:0:0":1}},"+IsolateSummaryElement": [82],tuj:{"":"uL+Pi;",$isd3:true}}],["json_view_element","package:observatory/src/observatory_elements/json_view.dart",,Z,{vj:{"":["Vct;eb%-,kf%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"18"},"+new IsolateSummaryElement$created:0:0":1}},"+IsolateSummaryElement": [84],tuj:{"":"uL+Pi;",$isd3:true}}],["json_view_element","package:observatory/src/observatory_elements/json_view.dart",,Z,{vj:{"":["Vct;eb%-,kf%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gTn:function(a){return a.eb
-"35,33,34"},
+"37,35,36"},
 "+json":1,
-sTn:function(a,b){a.eb=this.pD(a,C.Gd,a.eb,b)
-"35,28,35,33"},
+sTn:function(a,b){a.eb=this.ct(a,C.Gd,a.eb,b)
+"37,28,37,35"},
 "+json=":1,
 i4:function(a){Z.uL.prototype.i4.call(this,a)
 a.kf=0
-"35"},
+"37"},
 "+enteredView:0:0":1,
-yC:function(a,b){this.pD(a,C.eR,"a","b")
-"35,83,35"},
+yC:function(a,b){this.ct(a,C.eR,"a","b")
+"37,85,37"},
 "+jsonChanged:1:0":1,
 gE8:function(a){return J.AG(a.eb)
 "8"},
@@ -15715,17 +16471,17 @@
 y=J.x(z)
 if(typeof z==="object"&&z!==null&&(z.constructor===Array||!!y.$isList))return z
 return[]
-"65"},
+"67"},
 "+list":1,
 gvc:function(a){var z,y
 z=a.eb
 y=J.RE(z)
 if(typeof z==="object"&&z!==null&&!!y.$isL8)return J.qA(y.gvc(z))
 return[]
-"65"},
+"67"},
 "+keys":1,
 r6:function(a,b){return J.UQ(a.eb,b)
-"35,73,8"},
+"37,75,8"},
 "+value:1:0":1,
 gP:function(a){return new P.C7(this,Z.vj.prototype.r6,a,"r6")},
 "@":function(){return[C.HN]},
@@ -15741,17 +16497,17 @@
 a.Ye=z
 a.mT=y
 a.KM=v
-C.jZ.ZL(a)
-C.jZ.FH(a)
+C.GB.ZL(a)
+C.GB.FH(a)
 return a
-"19"},"+new JsonViewElement$created:0:0":1}},"+JsonViewElement": [84],Vct:{"":"uL+Pi;",$isd3:true}}],["library_view_element","package:observatory/src/observatory_elements/library_view.dart",,M,{CX:{"":["D13;iI%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"19"},"+new JsonViewElement$created:0:0":1}},"+JsonViewElement": [86],Vct:{"":"uL+Pi;",$isd3:true}}],["library_view_element","package:observatory/src/observatory_elements/library_view.dart",,M,{CX:{"":["D13;iI%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gtD:function(a){return a.iI
-"32,33,34"},
+"34,35,36"},
 "+library":1,
-stD:function(a,b){a.iI=this.pD(a,C.EV,a.iI,b)
-"35,28,32,33"},
+stD:function(a,b){a.iI=this.ct(a,C.EV,a.iI,b)
+"37,28,34,35"},
 "+library=":1,
-"@":function(){return[C.Oy]},
+"@":function(){return[C.Ob]},
 static:{SP:function(a){var z,y,x,w,v,u
 z=H.B7([],P.L5(null,null,null,null,null))
 z=R.Jk(z)
@@ -15768,7 +16524,7 @@
 C.MG.ZL(a)
 C.MG.FH(a)
 return a
-"20"},"+new LibraryViewElement$created:0:0":1}},"+LibraryViewElement": [85],D13:{"":"uL+Pi;",$isd3:true}}],["logging","package:logging/logging.dart",,N,{TJ:{"":"a;oc>,eT>,yz,Cj>,wd,Gs",
+"20"},"+new LibraryViewElement$created:0:0":1}},"+LibraryViewElement": [87],D13:{"":"uL+Pi;",$isd3:true}}],["logging","package:logging/logging.dart",,N,{TJ:{"":"a;oc>,eT>,yz,Cj>,wd,Gs",
 gB8:function(){var z,y,x
 z=this.eT
 y=z==null||J.xC(J.DA(z),"")
@@ -15818,6 +16574,7 @@
 if(b==null)return!1
 z=J.x(b)
 return typeof b==="object"&&b!==null&&!!z.$isNg&&this.P===b.P},
+"+==:1:0":0,
 C:function(a,b){var z=J.Vm(b)
 if(typeof z!=="number")throw H.s(z)
 return this.P<z},
@@ -15834,18 +16591,21 @@
 if(typeof z!=="number")throw H.s(z)
 return this.P-z},
 giO:function(a){return this.P},
+"+hashCode":0,
 bu:function(a){return this.oc},
+"+toString:0:0":0,
 $isNg:true,
-static:{"":"bR,tm,pR,X8,IQ,Fn,Eb,BC,JY,bo",}},HV:{"":"a;OR<,G1>,iJ,Fl,O0,kc>,I4<",
+static:{"":"bR,tm,pR,X8,IQ,Pk,Eb,BC,JY,bo",}},HV:{"":"a;OR<,G1>,iJ,Fl,O0,kc>,I4<",
 bu:function(a){return"["+this.OR.oc+"] "+this.iJ+": "+this.G1},
-static:{"":"xO",}}}],["message_viewer_element","package:observatory/src/observatory_elements/message_viewer.dart",,L,{Nh:{"":["uL;XB%-,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"+toString:0:0":0,
+static:{"":"xO",}}}],["message_viewer_element","package:observatory/src/observatory_elements/message_viewer.dart",,L,{BK:{"":["uL;XB%-,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gG1:function(a){return a.XB
-"32,34"},
+"34,36"},
 "+message":1,
 sG1:function(a,b){a.XB=b
-this.pD(a,C.KY,"",this.gQW(a))
-this.pD(a,C.wt,[],this.glc(a))
-"35,86,32,34"},
+this.ct(a,C.KY,"",this.gQW(a))
+this.ct(a,C.wt,[],this.glc(a))
+"37,88,34,36"},
 "+message=":1,
 gQW:function(a){var z=a.XB
 if(z==null||J.UQ(z,"type")==null)return"Error"
@@ -15855,7 +16615,7 @@
 glc:function(a){var z=a.XB
 if(z==null||J.UQ(z,"members")==null)return[]
 return J.UQ(a.XB,"members")
-"87"},
+"89"},
 "+members":1,
 "@":function(){return[C.c0]},
 static:{rJ:function(a){var z,y,x,w,v
@@ -15871,7 +16631,7 @@
 C.Wp.ZL(a)
 C.Wp.FH(a)
 return a
-"21"},"+new MessageViewerElement$created:0:0":1}},"+MessageViewerElement": [24]}],["metadata","/Users/iposva/Downloads/dart/dart-sdk/lib/html/html_common/metadata.dart",,B,{fA:{"":"a;T9,Jt",static:{"":"Xd,en,yS,PZ,xa",}},tz:{"":"a;"},jR:{"":"a;oc>"},PO:{"":"a;"},c5:{"":"a;"}}],["navigation_bar_element","package:observatory/src/observatory_elements/navigation_bar.dart",,Q,{ih:{"":["uL;tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"21"},"+new MessageViewerElement$created:0:0":1}},"+MessageViewerElement": [24]}],["metadata","../../../../../../../../../dart/dart-sdk/lib/html/html_common/metadata.dart",,B,{fA:{"":"a;T9,Jt",static:{"":"Xd,en,yS,PZ,xa",}},tz:{"":"a;"},jR:{"":"a;oc>"},PO:{"":"a;"},c5:{"":"a;"}}],["navigation_bar_element","package:observatory/src/observatory_elements/navigation_bar.dart",,Q,{ih:{"":["uL;hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",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,v
 z=$.Nd()
@@ -15887,6 +16647,7 @@
 C.Xg.FH(a)
 return a
 "22"},"+new NavigationBarElement$created:0:0":1}},"+NavigationBarElement": [24]}],["observatory","package:observatory/observatory.dart",,L,{mL:{"":["Pi;Z6<-,lw<-,nI<-,VJ,Ai",function(){return[C.mI]},function(){return[C.mI]},function(){return[C.mI]},null,null],
+AQ:function(a){return J.UQ(this.nI.gi2(),a)},
 US:function(){var z,y,x
 z=this.Z6
 z.sJR(this)
@@ -15900,13 +16661,34 @@
 z=R.Jk([])
 y=P.L5(null,null,null,J.im,L.bv)
 y=R.Jk(y)
-y=new L.mL(new L.dZ(null,"",null,null),new L.jI(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,"",null,null,null),new L.jI(null,null,"http://127.0.0.1:8181",z,null,null),new L.pt(null,y,null,null),null,null)
 y.US()
-return y}}},bv:{"":["Pi;jO>-,oc>-,VJ,Ai",function(){return[C.mI]},function(){return[C.mI]},null,null],
-bu:function(a){return H.d(this.jO)+" "+H.d(this.oc)},
+return y}}},bv:{"":["Pi;nk,YG,XR<-,VJ,Ai",null,null,function(){return[C.mI]},null,null],
+gjO:function(a){return this.nk
+"27,35,40"},
+"+id":1,
+sjO:function(a,b){this.nk=F.Wi(this,C.EN,this.nk,b)
+"37,28,27,35"},
+"+id=":1,
+goc:function(a){return this.YG
+"8,35,40"},
+"+name":1,
+soc:function(a,b){this.YG=F.Wi(this,C.YS,this.YG,b)
+"37,28,8,35"},
+"+name=":1,
+bu:function(a){return H.d(this.nk)+" "+H.d(this.YG)},
+"+toString:0:0":0,
 $isbv:true},pt:{"":["Pi;JR?,i2<-,VJ,Ai",null,function(){return[C.mI]},null,null],
 yi:function(){J.kH(this.JR.lw.gn2(),new L.dY(this))},
 gVY:function(){return new P.Ip(this,L.pt.prototype.yi,null,"yi")},
+AQ:function(a){var z,y,x,w
+z=this.i2
+y=J.U6(z)
+x=y.t(z,a)
+if(x==null){w=P.L5(null,null,null,J.O,L.Pf)
+w=R.Jk(w)
+x=new L.bv(a,"",w,null,null)
+y.u(z,a,x)}return x},
 LZ:function(a){var z=[]
 J.kH(this.i2,new L.vY(a,z))
 H.bQ(z,new L.dS(this))
@@ -15932,23 +16714,31 @@
 $isEH:true,
 $is_HB:true,
 $is_Dv:true},ZW:{"":"Tp;d",
-call$1:function(a){var z,y,x,w
+call$1:function(a){var z,y,x,w,v
 z=J.U6(a)
 y=z.t(a,"id")
 x=z.t(a,"name")
 z=this.d.i2
 w=J.U6(z)
-if(w.t(z,y)==null)w.u(z,y,new L.bv(y,x,null,null))},
+if(w.t(z,y)==null){v=P.L5(null,null,null,J.O,L.Pf)
+v=R.Jk(v)
+w.u(z,y,new L.bv(y,x,v,null,null))}else J.DF(w.t(z,y),x)},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},dZ:{"":"Pi;JR?,IT,VJ,Ai",
+$is_Dv:true},dZ:{"":"Pi;JR?,IT,Jj,VJ,Ai",
 gzd:function(){return this.IT
-"8,33,38"},
+"8,35,40"},
 "+currentHash":1,
 szd:function(a){this.IT=F.Wi(this,C.h1,this.IT,a)
-"35,28,8,33"},
+"37,28,8,35"},
 "+currentHash=":1,
+glD:function(){return this.Jj
+"90,35,40"},
+"+currentHashUri":1,
+slD:function(a){this.Jj=F.Wi(this,C.tv,this.Jj,a)
+"37,28,90,35"},
+"+currentHashUri=":1,
 kI:function(){var z,y
 z=C.PP.aM(window)
 y=new W.Ov(0,z.uv,z.Ph,W.aF(new L.Qe(this)),z.Sg)
@@ -15967,6 +16757,8 @@
 z=J.q8(z[0])
 if(typeof z!=="number")throw H.s(z)
 return C.xB.JT(x,w,v+z)},
+gAT:function(){return J.xC(J.UQ(this.Jj.ghY().iY,"type"),"Script")},
+gDe:function(){return P.pE(J.UQ(this.Jj.ghY().iY,"name"),C.dy,!0)},
 R6:function(){var z,y
 z=this.vI()
 if(z==null)return 0
@@ -15981,31 +16773,42 @@
 z=J.Co(C.ol.gmW(window))
 this.IT=F.Wi(this,C.h1,this.IT,z)
 y=J.ZZ(this.IT,1)
+z=P.r6($.cO().ej(y))
+this.Jj=F.Wi(this,C.tv,this.Jj,z)
 this.JR.lw.ox(y)},
 PI:function(a){var z=this.R6()
 if(J.xC(z,0))return"#/isolates/"
 return"#/isolates/"+H.d(z)+"/"+H.d(a)
-"8,88,8,38"},
+"8,91,8,40"},
 "+currentIsolateRelativeLink:1:0":1,
 Ao:function(a){var z=this.R6()
 if(J.xC(z,0))return"#/isolates/"
 return"#/isolates/"+H.d(z)+"/objects/"+H.d(a)
-"8,89,27,38"},
+"8,92,27,40"},
 "+currentIsolateObjectLink:1:0":1,
 dL:function(a){var z=this.R6()
 if(J.xC(z,0))return"#/isolates/"
 return"#/isolates/"+H.d(z)+"/classes/"+H.d(a)
-"8,90,27,38"},
+"8,93,27,40"},
 "+currentIsolateClassLink:1:0":1,
+WW:function(a,b){var z=this.R6()
+if(J.xC(z,0))return"#/isolates/"
+return this.yX(z,a,b)
+"8,92,27,7,8,40"},
+"+currentIsolateScriptLink:2:0":1,
 r4:function(a,b){return"#/isolates/"+H.d(a)+"/"+H.d(b)
-"8,91,27,88,8,38"},
+"8,94,27,91,8,40"},
 "+relativeLink:2:0":1,
 Dd:function(a,b){return"#/isolates/"+H.d(a)+"/objects/"+H.d(b)
-"8,91,27,89,27,38"},
+"8,94,27,92,27,40"},
 "+objectLink:2:0":1,
 bD:function(a,b){return"#/isolates/"+H.d(a)+"/classes/"+H.d(b)
-"8,91,27,90,27,38"},
+"8,94,27,93,27,40"},
 "+classLink:2:0":1,
+yX:function(a,b,c){var z=P.jW(C.kg,c,!0)
+return"#/isolates/"+H.d(a)+"/objects/"+H.d(b)+"?type=Script&name="+z
+"8,94,27,92,27,7,8,40"},
+"+scriptLink:3:0":1,
 static:{"":"kx,K3D,qY",}},Qe:{"":"Tp;a",
 call$1:function(a){var z=this.a
 if(z.S7())return
@@ -16016,16 +16819,16 @@
 $is_Dv:true},Nu:{"":"Pi;JR?,e0?",
 pG:function(){return this.e0.call$0()},
 gEI:function(){return this.oJ
-"8,33,38"},
+"8,35,40"},
 "+prefix":1,
 sEI:function(a){this.oJ=F.Wi(this,C.qb,this.oJ,a)
-"35,28,8,33"},
+"37,28,8,35"},
 "+prefix=":1,
 gn2:function(){return this.vm
-"87,33,38"},
+"89,35,40"},
 "+responses":1,
 sn2:function(a){this.vm=F.Wi(this,C.wH,this.vm,a)
-"35,28,87,33"},
+"37,28,89,35"},
 "+responses=":1,
 Qn:function(a){var z,y
 z=C.lM.kV(a)
@@ -16040,21 +16843,107 @@
 y=H.d(z.gys(a))+" "+z.gpo(a)
 if(z.gys(a)===0)y="No service found. Did you run with --enable-vm-service ?"
 this.dq([H.B7(["type","RequestError","error",y],P.L5(null,null,null,null,null))])},
-ox:function(a){this.ym(this,a).ml(new L.pF(this)).OA(new L.Ha(this))}},pF:{"":"Tp;a",
-call$1:function(a){this.a.Qn(a)},
+ox:function(a){var z
+if(this.JR.Z6.gAT()){z=this.JR.Z6.gDe()
+this.iG(z,a).ml(new L.pF(this,z))}else this.ym(this,a).ml(new L.Ha(this)).OA(new L.nu(this))},
+iG:function(a,b){var z,y,x
+z=this.JR.Z6.R6()
+y=this.JR.nI.AQ(z)
+x=J.UQ(y.gXR(),a)
+if(x!=null)return P.Ab(x,null)
+return this.ym(this,b).ml(new L.be(a,y)).OA(new L.Pg(this))}},pF:{"":"Tp;a,b",
+call$1:function(a){var z=this.a
+if(a!=null)z.dq([H.B7(["type","Script","source",a],P.L5(null,null,null,null,null))])
+else z.dq([H.B7(["type","RequestError","error","Source for "+this.b+" could not be loaded."],P.L5(null,null,null,null,null))])},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},Ha:{"":"Tp;b",
-call$1:function(a){this.b.AI(J.l2(a))},
+$is_Dv:true},Ha:{"":"Tp;c",
+call$1:function(a){this.c.Qn(a)},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},nu:{"":"Tp;d",
+call$1:function(a){this.d.AI(J.l2(a))},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},be:{"":"Tp;a,b",
+call$1:function(a){var z=L.Sp(C.lM.kV(a))
+J.kW(this.b.gXR(),this.a,z)
+return z},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},Pg:{"":"Tp;c",
+call$1:function(a){this.c.AI(J.l2(a))
+return},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
 $is_Dv:true},jI:{"":"Nu;JR,e0,oJ,vm,VJ,Ai",
-ym:function(a,b){return W.It(J.WB(this.oJ,b),null,null)}}}],["observatory_application_element","package:observatory/src/observatory_elements/observatory_application.dart",,V,{F1:{"":["uL;tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+ym:function(a,b){return W.It(J.WB(this.oJ,b),null,null)}},Zw:{"":["Pi;Rd,n7,LA>-,Vg,VJ,Ai",null,null,function(){return[C.mI]},null,null,null],
+gCt:function(){return this.Vg
+"8,35,40"},
+"+paddedLine":1,
+sCt:function(a){var z=this.Vg
+if(this.gUV(this)&&!J.xC(z,a)){z=new T.qI(this,C.X9,z,a)
+z.$builtinTypeInfo=[null]
+this.SZ(this,z)}this.Vg=a
+"37,28,8,35"},
+"+paddedLine=":1,
+QQ:function(a,b,c){var z,y,x,w,v
+z=""+this.Rd
+this.Vg=F.Wi(this,C.X9,this.Vg,z)
+for(y=J.q8(this.Vg),z=this.n7;x=J.Wx(y),x.C(y,z);y=x.g(y,1)){w=" "+H.d(this.Vg)
+v=this.Vg
+if(this.gUV(this)&&!J.xC(v,w)){v=new T.qI(this,C.X9,v,w)
+v.$builtinTypeInfo=[null]
+this.SZ(this,v)}this.Vg=w}},
+static:{il:function(a,b,c){var z=new L.Zw(a,b,c,null,null,null)
+z.QQ(a,b,c)
+return z}}},Pf:{"":"Pi;WF,uM,ZQ,VJ,Ai",
+gfY:function(a){return this.WF
+"8,35,40"},
+"+kind":1,
+sfY:function(a,b){this.WF=F.Wi(this,C.fy,this.WF,b)
+"37,28,8,35"},
+"+kind=":1,
+gO3:function(a){return this.uM
+"8,35,40"},
+"+url":1,
+sO3:function(a,b){this.uM=F.Wi(this,C.Fh,this.uM,b)
+"37,28,8,35"},
+"+url=":1,
+gXJ:function(){return this.ZQ
+"95,35,40"},
+"+lines":1,
+sXJ:function(a){this.ZQ=F.Wi(this,C.Cv,this.ZQ,a)
+"37,28,95,35"},
+"+lines=":1,
+Cn:function(a){var z,y,x,w,v
+z=J.uH(a,"\n")
+y=(""+(z.length+1)).length
+for(x=0;x<z.length;x=w){w=x+1
+v=L.il(w,y,z[x])
+J.bi(this.ZQ,v)}},
+bu:function(a){return"ScriptSource"},
+"+toString:0:0":0,
+EQ:function(a){var z,y
+z=J.U6(a)
+y=z.t(a,"kind")
+this.WF=F.Wi(this,C.fy,this.WF,y)
+y=z.t(a,"name")
+this.uM=F.Wi(this,C.Fh,this.uM,y)
+this.Cn(z.t(a,"source"))},
+$isPf:true,
+static:{Sp:function(a){var z=R.Jk([])
+z=new L.Pf("","",z,null,null)
+z.EQ(a)
+return z}}}}],["observatory_application_element","package:observatory/src/observatory_elements/observatory_application.dart",,V,{F1:{"":["uL;hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 ZB:function(a){var z=L.AK()
-a.tH=this.pD(a,C.wh,a.tH,z)
-"35"},
+a.hm=this.ct(a,C.wh,a.hm,z)
+"37"},
 "@":function(){return[C.bd]},
 static:{fv:function(a){var z,y,x,w,v
 z=$.Nd()
@@ -16070,21 +16959,21 @@
 C.k0.FH(a)
 C.k0.ZB(a)
 return a
-"23"},"+new ObservatoryApplicationElement$created:0:0":1}},"+ObservatoryApplicationElement": [24]}],["observatory_element","package:observatory/src/observatory_elements/observatory_element.dart",,Z,{uL:{"":["Xf;tH%-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"23"},"+new ObservatoryApplicationElement$created:0:0":1}},"+ObservatoryApplicationElement": [24]}],["observatory_element","package:observatory/src/observatory_elements/observatory_element.dart",,Z,{uL:{"":["Xf;hm%-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 i4:function(a){A.dM.prototype.i4.call(this,a)
-"35"},
+"37"},
 "+enteredView:0:0":1,
 Nz:function(a){A.dM.prototype.Nz.call(this,a)
-"35"},
+"37"},
 "+leftView:0:0":1,
-gQG:function(a){return a.tH
-"92,33,34"},
+gQG:function(a){return a.hm
+"96,35,36"},
 "+app":1,
-sQG:function(a,b){a.tH=this.pD(a,C.wh,a.tH,b)
-"35,28,92,33"},
+sQG:function(a,b){a.hm=this.ct(a,C.wh,a.hm,b)
+"37,28,96,35"},
 "+app=":1,
 gpQ:function(a){return!0
-"39"},
+"41"},
 "+applyAuthorStyles":1,
 "@":function(){return[C.J0]},
 static:{Hx:function(a){var z,y,x,w,v
@@ -16097,10 +16986,10 @@
 a.Ye=z
 a.mT=y
 a.KM=v
-C.Pf.ZL(a)
-C.Pf.FH(a)
+C.mk.ZL(a)
+C.mk.FH(a)
 return a
-"24"},"+new ObservatoryElement$created:0:0":1}},"+ObservatoryElement": [93],Xf:{"":"ir+Pi;",$isd3:true}}],["observe.src.change_notifier","package:observe/src/change_notifier.dart",,O,{Pi:{"":"a;",
+"24"},"+new ObservatoryElement$created:0:0":1}},"+ObservatoryElement": [97],Xf:{"":"ir+Pi;",$isd3:true}}],["observe.src.change_notifier","package:observe/src/change_notifier.dart",,O,{Pi:{"":"a;",
 gqh:function(a){var z,y
 if(a.VJ==null){z=this.gqw(a)
 a.VJ=P.bK(this.gl1(a),z,!0,null)}z=a.VJ
@@ -16129,7 +17018,7 @@
 if(z!=null){y=z.iE
 z=y==null?z!=null:y!==z}else z=!1
 return z},
-pD:function(a,b,c,d){return F.Wi(a,b,c,d)},
+ct:function(a,b,c,d){return F.Wi(a,b,c,d)},
 SZ:function(a,b){var z,y
 z=a.VJ
 if(z!=null){y=z.iE
@@ -16139,12 +17028,13 @@
 P.rb(this.gDx(a))}a.Ai.push(b)},
 $isd3:true}}],["observe.src.change_record","package:observe/src/change_record.dart",,T,{yj:{"":"a;",$isyj:true},qI:{"":"yj;WA<,oc>,jL>,zZ>",
 bu:function(a){return"#<PropertyChangeRecord "+H.d(this.oc)+" from: "+H.d(this.jL)+" to: "+H.d(this.zZ)+">"},
+"+toString:0:0":0,
 $isqI:true}}],["observe.src.compound_path_observer","package:observe/src/compound_path_observer.dart",,Y,{J3:{"":"Pi;b9,kK,Sv,rk,YX,B6,VJ,Ai",
 kb:function(a){return this.rk.call$1(a)},
 gB:function(a){return this.b9.length},
 "+length":0,
 gP:function(a){return this.Sv
-"35,33"},
+"37,35"},
 "+value":1,
 r6:function(a,b){return this.gP(a).call$1(b)},
 wE:function(a){var z,y,x,w
@@ -16210,7 +17100,7 @@
 $.Td=!1},Ht:function(){var z={}
 z.a=!1
 z=new O.o5(z)
-return new P.wJ(null,null,null,null,new O.zI(z),new O.id(z),null,null,null,null,null,null)},o5:{"":"Tp;a",
+return new P.wJ(null,null,null,null,new O.zI(z),new O.bF(z),null,null,null,null,null,null)},o5:{"":"Tp;a",
 call$2:function(a,b){var z=this.a
 if(z.a)return
 z.a=!0
@@ -16231,7 +17121,7 @@
 return this.f.call$0()},
 "+call:0:0":0,
 $isEH:true,
-$is_X0:true},id:{"":"Tp;g",
+$is_X0:true},bF:{"":"Tp;g",
 call$4:function(a,b,c,d){if(d==null)return d
 return new O.iV(this.g,b,c,d)},
 "+call:4:0":0,
@@ -16443,13 +17333,14 @@
 if(typeof z!=="number")throw H.s(z)
 return a<z},
 bu:function(a){return"#<ListChangeRecord index: "+H.d(this.jr)+", removed: "+H.d(this.Uj)+", addedCount: "+H.d(this.dM)+">"},
+"+toString:0:0":0,
 $isW4:true,
 static:{XM:function(a,b,c,d){var z
 if(d==null)d=[]
 if(c==null)c=0
 z=new P.Yp(d)
 z.$builtinTypeInfo=[null]
-return new G.W4(a,z,d,b,c)}}}}],["observe.src.metadata","package:observe/src/metadata.dart",,K,{Fa:{"":"a;"},ma:{"":"a;"}}],["observe.src.observable","package:observe/src/observable.dart",,F,{Wi:function(a,b,c,d){var z,y
+return new G.W4(a,z,d,b,c)}}}}],["observe.src.metadata","package:observe/src/metadata.dart",,K,{ndx:{"":"a;"},Hm:{"":"a;"}}],["observe.src.observable","package:observe/src/observable.dart",,F,{Wi:function(a,b,c,d){var z,y
 z=J.RE(a)
 if(z.gUV(a)&&!J.xC(c,d)){y=new T.qI(a,b,c,d)
 H.VM(y,[null])
@@ -16469,13 +17360,14 @@
 $isEH:true,
 $is_bh:true}}],["observe.src.observable_box","package:observe/src/observable_box.dart",,A,{xh:{"":"Pi;",
 gP:function(a){return this.L1
-"94,33"},
+"98,35"},
 "+value":1,
 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)
-"35,95,94,33"},
+"37,99,98,35"},
 "+value=":1,
-bu:function(a){return"#<"+H.d(new H.cu(H.dJ(this),null))+" value: "+H.d(this.L1)+">"}}}],["observe.src.observable_list","package:observe/src/observable_list.dart",,Q,{wn:{"":"uF;b3,xg,h3,VJ,Ai",
+bu:function(a){return"#<"+H.d(new H.cu(H.dJ(this),null))+" value: "+H.d(this.L1)+">"},
+"+toString:0:0":0}}],["observe.src.observable_list","package:observe/src/observable_list.dart",,Q,{wn:{"":"uF;b3,xg,h3,VJ,Ai",
 gRT:function(){var z,y
 if(this.xg==null)this.xg=P.bK(new Q.cj(this),null,!0,null)
 z=this.xg
@@ -16484,18 +17376,21 @@
 H.VM(y,[H.W8(z,"WV",0)])
 return y},
 gB:function(a){return this.h3.length
-"27,33"},
+"27,35"},
 "+length":1,
 sB:function(a,b){var z,y,x,w,v,u,t
 z=this.h3
 y=z.length
 if(y===b)return
-this.pD(this,C.Wn,y,b)
+this.ct(this,C.Wn,y,b)
+x=y===0
+w=J.x(b)
+this.ct(this,C.ai,x,w.n(b,0))
+this.ct(this,C.nZ,!x,!w.n(b,0))
 x=this.xg
-if(x!=null){w=x.iE
-x=w==null?x!=null:w!==x}else x=!1
-if(x){x=J.Wx(b)
-if(x.C(b,y)){if(x.C(b,0)||x.D(b,z.length))H.vh(P.TE(b,0,z.length))
+if(x!=null){v=x.iE
+x=v==null?x!=null:v!==x}else x=!1
+if(x)if(w.C(b,y)){if(w.C(b,0)||w.D(b,z.length))H.vh(P.TE(b,0,z.length))
 if(typeof b!=="number")throw H.s(b)
 if(y<b||y>z.length)H.vh(P.TE(y,b,z.length))
 x=new H.nH(z,b,y)
@@ -16508,17 +17403,17 @@
 if(v.D(w,u))H.vh(P.TE(w,0,u))}x=x.br(x)
 w=new P.Yp(x)
 w.$builtinTypeInfo=[null]
-this.iH(new G.W4(this,w,x,b,0))}else{x=x.W(b,y)
+this.iH(new G.W4(this,w,x,b,0))}else{x=w.W(b,y)
 t=[]
 w=new P.Yp(t)
 w.$builtinTypeInfo=[null]
-this.iH(new G.W4(this,w,t,y,x))}}C.Nm.sB(z,b)
-"35,28,27,33"},
+this.iH(new G.W4(this,w,t,y,x))}C.Nm.sB(z,b)
+"37,28,27,35"},
 "+length=":1,
 t:function(a,b){var z=this.h3
 if(b>>>0!==b||b>=z.length)throw H.e(z,b)
 return z[b]
-"96,26,27,33"},
+"100,26,27,35"},
 "+[]:1:0":1,
 u:function(a,b,c){var z,y,x,w
 z=this.h3
@@ -16532,12 +17427,18 @@
 w.$builtinTypeInfo=[null]
 this.iH(new G.W4(this,w,x,b,1))}if(b>=z.length)throw H.e(z,b)
 z[b]=c
-"35,26,27,28,96,33"},
+"37,26,27,28,100,35"},
 "+[]=:2:0":1,
+gl0:function(a){return P.lD.prototype.gl0.call(this,this)
+"41,35"},
+"+isEmpty":1,
+gor:function(a){return P.lD.prototype.gor.call(this,this)
+"41,35"},
+"+isNotEmpty":1,
 h:function(a,b){var z,y,x,w
 z=this.h3
 y=z.length
-this.pD(this,C.Wn,y,y+1)
+this.Fg(y,y+1)
 x=this.xg
 if(x!=null){w=x.iE
 x=w==null?x!=null:w!==x}else x=!1
@@ -16547,7 +17448,7 @@
 z=this.h3
 y=z.length
 C.Nm.Ay(z,b)
-this.pD(this,C.Wn,y,z.length)
+this.Fg(y,z.length)
 x=z.length-y
 z=this.xg
 if(z!=null){w=z.iE
@@ -16564,7 +17465,12 @@
 x=c-b
 w=this.h3
 v=w.length
-this.pD(this,C.Wn,v,v-x)
+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
@@ -16588,6 +17494,12 @@
 if(!z)return
 if(this.b3==null){this.b3=[]
 P.rb(this.gL6())}this.b3.push(a)},
+Fg: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))},
 oC:function(){var z,y,x
 z=this.b3
 if(z==null)return!1
@@ -16618,36 +17530,37 @@
 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)+">"},
+"+toString:0:0":0,
 $isHA:true},br:{"":"Pi;Zp,VJ,Ai",
 gvc:function(a){var z=this.Zp
 return z.gvc(z)
-"97,33"},
+"101,35"},
 "+keys":1,
 gUQ:function(a){var z=this.Zp
 return z.gUQ(z)
-"98,33"},
+"102,35"},
 "+values":1,
 gB:function(a){var z=this.Zp
 return z.gB(z)
-"27,33"},
+"27,35"},
 "+length":1,
 gl0:function(a){var z=this.Zp
 return z.gB(z)===0
-"39,33"},
+"41,35"},
 "+isEmpty":1,
 gor:function(a){var z=this.Zp
 return z.gB(z)!==0
-"39,33"},
+"41,35"},
 "+isNotEmpty":1,
 PF:function(a){return this.Zp.PF(a)
-"39,28,0,33"},
+"41,28,0,35"},
 "+containsValue:1:0":1,
 x4:function(a){return this.Zp.x4(a)
-"39,73,0,33"},
+"41,75,0,35"},
 "+containsKey:1:0":1,
 t:function(a,b){var z=this.Zp
 return z.t(z,b)
-"99,73,0,33"},
+"103,75,0,35"},
 "+[]:1:0":1,
 u:function(a,b,c){var z,y,x,w,v
 z=this.Zp
@@ -16664,7 +17577,7 @@
 z.$builtinTypeInfo=[null,null]
 this.SZ(this,z)}else if(!J.xC(x,c)){z=new V.HA(b,x,c,!1,!1)
 z.$builtinTypeInfo=[null,null]
-this.SZ(this,z)}"35,73,100,28,99,33"},
+this.SZ(this,z)}"37,75,104,28,103,35"},
 "+[]=:2:0":1,
 Ay:function(a,b){b.aN(b,new V.zT(this))},
 Rz:function(a,b){var z,y,x,w,v
@@ -16681,6 +17594,7 @@
 aN:function(a,b){var z=this.Zp
 return z.aN(z,b)},
 bu:function(a){return P.vW(this)},
+"+toString:0:0":0,
 $asL8:null,
 $isL8:true,
 static:{WF:function(a,b,c){var z=V.Bq(a,b,c)
@@ -16764,7 +17678,7 @@
 if(0>=a.length)throw H.e(a,0)
 if(a[0]===".")return!1
 return $.tN().zD(a)},D7:{"":"Pi;Ii>,YB,BK,kN,cs,cT,VJ,Ai",
-E4:function(a){return this.cT.call$1(a)},
+AR:function(a){return this.cT.call$1(a)},
 gWA:function(){var z=this.kN
 if(0>=z.length)throw H.e(z,0)
 return z[0]},
@@ -16775,7 +17689,7 @@
 z=y==null?z!=null:y!==z}else z=!1
 if(!z)this.ov()
 return C.Nm.grZ(this.kN)
-"35,33"},
+"37,35"},
 "+value":1,
 r6:function(a,b){return this.gP(a).call$1(b)},
 sP:function(a,b){var z,y,x,w
@@ -16793,7 +17707,7 @@
 if(w>=z.length)throw H.e(z,w)
 if(L.h6(x,z[w],b)){z=this.kN
 if(y>=z.length)throw H.e(z,y)
-z[y]=b}"35,95,0,33"},
+z[y]=b}"37,99,0,35"},
 "+value=":1,
 w3:function(a){O.Pi.prototype.w3.call(this,this)
 this.ov()
@@ -16818,7 +17732,7 @@
 v=v[w]
 if(w>=z.length)throw H.e(z,w)
 u=L.yf(v,z[w])
-if(w===y&&x)u=this.E4(u)
+if(w===y&&x)u=this.AR(u)
 v=this.kN;++w
 if(w>=v.length)throw H.e(v,w)
 v[w]=u}},
@@ -16833,7 +17747,7 @@
 t=t[w]
 if(w>=z.length)throw H.e(z,w)
 u=L.yf(t,z[w])
-if(w===y&&x)u=this.E4(u)
+if(w===y&&x)u=this.AR(u)
 if(v==null?u==null:v===u){this.Rl(a,w)
 return}t=this.kN
 if(s>=t.length)throw H.e(t,s)
@@ -17092,7 +18006,9 @@
 y=new H.KW(z,a)
 if(!y.gA(y).G())return
 return J.UQ(y.gFV(y),0)},
-bu:function(a){return this.goc(this)}},BE:{"":"OO;oc>,mI<,DF<,nK<,Ew<,TL"},Qb:{"":"OO;oc>,mI<,DF<,nK<,Ew<,TL"},xI:{"":"OO;oc>,mI<,DF<,nK<,Ew<,TL<,qW"},q1:{"":"a;S,SF,aA,dY,Yj",
+bu:function(a){return this.goc(this)},
+"+toString:0:0":0,
+static:{"":"ak<",}},BE:{"":"OO;oc>,mI<,DF<,nK<,Ew<,TL"},Qb:{"":"OO;oc>,mI<,DF<,nK<,Ew<,TL"},xI:{"":"OO;oc>,mI<,DF<,nK<,Ew<,TL<,qW"},q1:{"":"a;S,SF,aA,dY,Yj",
 IV:function(){var z,y
 z=this.Yj
 while(!0){y=this.dY
@@ -17114,7 +18030,8 @@
 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}}}],["polymer","package:polymer/polymer.dart",,A,{JX:function(){var z,y
+return z.vM},
+"+toString:0:0":0},"":"O3<"}],["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"
 y=document.querySelector("head")
@@ -17130,43 +18047,57 @@
 if(J.xC(a,$.Tf()))return b
 b=A.oF(a.gAY(),b)
 for(z=J.GP(J.hI(a.gYK()));z.G();){y=z.gl()
+if(y.gFo()||y.gkw())continue
 x=J.x(y)
-if(typeof y!=="object"||y===null||!x.$isRY||y.gV5()||y.gFo()||y.gkw())continue
-for(x=J.GP(y.gc9());x.G();){w=x.gl().gAx()
-v=J.x(w)
-if(typeof w==="object"&&w!==null&&!!v.$isyL){if(b==null)b=H.B7([],P.L5(null,null,null,null,null))
-b.u(b,y.gIf(),y)
-break}}}for(z=J.GP(J.hI(a.gYK()));z.G();){u=z.gl()
-x=J.x(u)
-if(typeof u!=="object"||u===null||!x.$isRS||!u.glT()||u.Fo||u.gkw())continue
-for(x=J.GP(u.gc9());x.G();){w=x.gl().gAx()
-v=J.x(w)
-if(typeof w==="object"&&w!==null&&!!v.$isyL){if(A.bc(a,u)){if(b==null)b=H.B7([],P.L5(null,null,null,null,null))
-b.u(b,u.gIf(),u)}break}}}return b},bc:function(a,b){var z,y
+if(!(typeof y==="object"&&y!==null&&!!x.$isRY&&!y.gV5()))w=typeof y==="object"&&y!==null&&!!x.$isRS&&y.glT()
+else w=!0
+if(w)for(w=J.GP(y.gc9());w.G();){v=w.mD.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(b,y.gIf(),y)}break}}}return b},Oy:function(a,b){var z,y
+do{z=J.UQ(a.gYK(),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},bc:function(a,b){var z,y
 z=H.le(H.d(J.Z0(b.gIf()))+"=")
 y=J.UQ(a.gYK(),new H.GD(z))
 z=J.x(y)
 return typeof y==="object"&&y!==null&&!!z.$isRS&&y.ghB()},hO:function(a,b,c){var z,y
 if($.LX()==null||a==null)return
-if($.LX().Bm("ShadowDOMPolyfill"))return
+if(!$.LX().Bm("ShadowDOMPolyfill"))return
 z=J.UQ($.LX(),"Platform")
 if(z==null)return
 y=J.UQ(z,"ShadowCSS")
 if(y==null)return
-y.V7("shimStyling",[a,b,c])},Hl:function(a){var z
-if(a==null||$.LX()==null)return""
-z=J.UQ(P.Oe(a),"__resource")
-return z!=null?z:""},oY:function(a){var z=J.UQ($.pT(),a)
+y.V7("shimStyling",[a,b,c])},Hl:function(a){var z,y,x,w,v,u,t
+if(a==null)return""
+w=J.RE(a)
+z=w.gLU(a)
+if(J.xC(z,""))z=w.gQg(a).MW.getAttribute("href")
+if($.LX()!=null&&$.LX().Bm("HTMLImports")){v=J.UQ(P.Oe(a),"__resource")
+if(v!=null)return v
+$.vM().J4("failed to get stylesheet text href=\""+H.d(z)+"\"")
+return""}try{w=new XMLHttpRequest()
+C.W3.i3(w,"GET",z,!1)
+w.send()
+w=w.responseText
+return w}catch(u){w=H.Ru(u)
+t=J.x(w)
+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}},oY:function(a){var z=J.UQ($.pT(),a)
 return z!=null?z:a},Ad:function(a,b){var z,y
 if(b==null)b=C.hG
 z=$.Ej()
 z.u(z,a,b)
 z=$.p2()
 y=z.Rz(z,a)
-if(y!=null)J.Or(y)},zM:function(a){A.om(a,new A.Mq())},om:function(a,b){var z
+if(y!=null)J.Or(y)},zM:function(a){A.Vx(a,new A.Mq())},Vx:function(a,b){var z
 if(a==null)return
 b.call$1(a)
-for(z=a.firstChild;z!=null;z=z.nextSibling)A.om(z,b)},p1:function(a,b,c,d){var z
+for(z=a.firstChild;z!=null;z=z.nextSibling)A.Vx(z,b)},p1:function(a,b,c,d){var z
 if($.ZH().mL(C.R5))$.ZH().J4("["+H.d(c)+"]: bindProperties: ["+H.d(d)+"] to ["+J.Ro(a)+"].["+H.d(b)+"]")
 z=L.ao(c,d,null)
 if(z.gP(z)==null)z.sP(z,H.vn(a).rN(b).Ax)
@@ -17175,10 +18106,14 @@
 for(;z=J.TZ(a),z!=null;a=z);y=$.od()
 return y.t(y,a)},HR:function(a,b,c){var z,y,x
 z=H.vn(a)
-y=J.UQ(H.jO(J.bB(z.Ax).IE).gtx(),b)
+y=A.Rk(H.jO(J.bB(z.Ax).IE),b)
 if(y!=null){x=y.gJx()
 x=x.ev(x,new A.uJ())
-C.Nm.sB(c,x.gB(x))}return z.CI(b,c).Ax},ZI:function(a,b){var z,y
+C.Nm.sB(c,x.gB(x))}return z.CI(b,c).Ax},Rk:function(a,b){var z,y
+do{z=J.UQ(a.gYK(),b)
+y=J.x(z)
+if(typeof z==="object"&&z!==null&&!!y.$isRS)return z
+a=a.gAY()}while(a!=null)},ZI:function(a,b){var z,y
 if(a==null)return
 z=document.createElement("style",null)
 z.textContent=a.textContent
@@ -17225,7 +18160,7 @@
 t=t.MM
 if(t.Gv!==0)H.vh(new P.lj("Future already completed"))
 t.CG(w,x)}}},GA:function(a,b,c,d){var z,y,x,w,v,u
-if(c==null)c=P.Ls(null,null,null,W.YN)
+if(c==null)c=P.Ls(null,null,null,W.QF)
 if(d==null){d=[]
 d.$builtinTypeInfo=[J.O]}if(a==null){z="warning: "+H.d(b)+" not found."
 y=$.oK
@@ -17252,37 +18187,17 @@
 z=$.UG().nb
 v=z.t(z,w)
 if(v!=null)x=v}if(x==null){$.M7().To(H.d(y)+" library not found")
-return}z=x.gmu().nb
-z=z.gUQ(z)
-u=z.Kw
-u=u.gA(u)
-t=H.Y9(z.$asi1,H.oX(z))
-s=t==null?null:t[0]
-t=H.Y9(z.$asi1,H.oX(z))
-r=t==null?null:t[1]
-z=new H.MH(null,u,z.ew)
-z.$builtinTypeInfo=[s,r]
-for(;z.G();)A.h5(x,z.mD)
-z=J.pP(x)
-z=z.gUQ(z)
-u=z.Kw
-u=u.gA(u)
-t=H.Y9(z.$asi1,H.oX(z))
-s=t==null?null:t[0]
-t=H.Y9(z.$asi1,H.oX(z))
-r=t==null?null:t[1]
-z=new H.MH(null,u,z.ew)
-z.$builtinTypeInfo=[s,r]
-for(;z.G();){q=z.mD
-for(u=J.GP(q.gc9());u.G();){p=u.gl().gAx()
-s=J.x(p)
-if(typeof p==="object"&&p!==null&&!!s.$isV3){s=p.ns
-o=M.Lh(q)
-if(o==null)o=C.hG
-r=$.Ej()
-r.u(r,s,o)
-r=$.p2()
-n=r.Rz(r,s)
+return}for(z=J.vo(J.hI(x.gYK()),new A.Fn()),z=z.gA(z),u=z.RX;z.G();)A.h5(x,u.gl())
+for(z=J.vo(J.hI(x.gYK()),new A.e3()),z=z.gA(z),u=z.RX;z.G();){t=u.gl()
+for(s=J.GP(t.gc9());s.G();){r=s.gl().gAx()
+q=J.x(r)
+if(typeof r==="object"&&r!==null&&!!q.$isV3){q=r.ns
+p=M.Lh(t)
+if(p==null)p=C.hG
+o=$.Ej()
+o.u(o,q,p)
+o=$.p2()
+n=o.Rz(o,q)
 if(n!=null)J.Or(n)}}}},h5:function(a,b){var z,y,x
 for(z=J.GP(b.gc9());y=!1,z.G();)if(z.gl().gAx()===C.za){y=!0
 break}if(!y)return
@@ -17343,7 +18258,7 @@
 z=a.Dg
 if(z!=null)a.Q0=this.Pv(a,z)
 this.oq(a,y)},
-fj:function(a,b,c){var z,y
+fj:function(a,b,c){var z,y,x
 this.uG(a)
 this.W3(a,a.EX)
 this.Mi(a)
@@ -17352,8 +18267,10 @@
 this.u5(a)
 A.hO(this.gr3(a),b,c)
 z=P.re(a.di)
-y=J.UQ(z.gtx(),C.Qi)
-if(y!=null&&y.gFo()&&y.guU())z.CI(C.Qi,[a])},
+y=J.UQ(z.gYK(),C.Qi)
+if(y!=null){x=J.x(y)
+x=typeof y==="object"&&y!==null&&!!x.$isRS&&y.gFo()&&y.guU()}else x=!1
+if(x)z.CI(C.Qi,[a])},
 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")
@@ -17374,9 +18291,7 @@
 z=z!=null&&z.x4(w)}else z=!1
 if(z)continue
 v=new H.GD(H.le(w))
-u=J.UQ(b.gYK(),v)
-z=J.x(u)
-if(typeof u==="object"&&u!==null&&!!z.$isRS){if(!u.glT()||!A.bc(b,u))u=null}else if(typeof u!=="object"||u===null||!z.$isRY)u=null
+u=A.Oy(b,v)
 if(u==null){window
 z=$.UT()
 t="property for attribute "+w+" of polymer-element name="+a.S6+" not found."
@@ -17438,6 +18353,8 @@
 new W.E9(z).MW.setAttribute("element",a.S6+"-"+c)
 return z},
 oq:function(a,b){var z,y,x,w
+if(J.xC(b,$.Tf()))return
+this.oq(a,b.gAY())
 for(z=J.GP(J.hI(b.gYK()));z.G();){y=z.gl()
 x=J.x(y)
 if(typeof y!=="object"||y===null||!x.$isRS||y.gFo()||!y.guU())continue
@@ -17493,16 +18410,16 @@
 $isEH:true,
 $is_bh:true},w12:{"":"Tp;",
 call$0:function(){var z=P.L5(null,null,null,J.O,J.O)
-C.FS.aN(C.FS,new A.fTP(z))
+C.FS.aN(C.FS,new A.ppY(z))
 return z},
 "+call:0:0":0,
 $isEH:true,
-$is_X0:true},fTP:{"":"Tp;a",
+$is_X0:true},ppY:{"":"Tp;a",
 call$2:function(a,b){var z=this.a
 z.u(z,b,a)},
 "+call:2:0":0,
 $isEH:true,
-$is_bh:true},yL:{"":"Fa;",$isyL:true},dM:{"":["a;KM=-",function(){return[C.nJ]}],
+$is_bh:true},yL:{"":"ndx;",$isyL:true},dM:{"":["a;KM=-",function(){return[C.nJ]}],
 gpQ:function(a){return!1},
 "+applyAuthorStyles":0,
 Pa:function(a){if(W.uV(this.gM0(a).defaultView)!=null||$.M0>0)this.Ec(a)},
@@ -17530,7 +18447,7 @@
 z=J.RE(b)
 y=z.Ja(b,"template")
 if(y!=null)if(J.Vs(a.ZI).MW.hasAttribute("lightdom")===!0){this.vs(a,y)
-x=null}else x=this.TH(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
@@ -17546,7 +18463,7 @@
 this.jx(a,y)
 this.lj(a,a)
 return y},
-TH:function(a,b){var z,y
+Tp:function(a,b){var z,y
 if(b==null)return
 this.gKE(a)
 z=this.er(a)
@@ -17620,7 +18537,7 @@
 z=a.TQ
 if(z!=null){z.TP(z)
 a.TQ=null}if(b===!0)return
-A.om(this.gKE(a),new A.TV())},
+A.Vx(this.gKE(a),new A.TV())},
 oW:function(a){return this.BT(a,null)},
 Xl:function(a){var z,y,x,w,v,u,t
 z=a.ZI
@@ -17747,7 +18664,7 @@
 y=z.t(z,a)
 if(y!=null){z=this.b
 x=J.RE(b)
-J.GS(z,a,x.gzZ(b),x.gjL(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:0":0,
 $isEH:true,
@@ -17842,8 +18759,8 @@
 a.Ye=z
 a.mT=y
 a.KM=v
-C.GB.ZL(a)
-C.GB.FH(a)
+C.Iv.ZL(a)
+C.Iv.FH(a)
 return a},"+new PolymerElement$created:0:0":0}},Tt:{"":["qE+dM;KM=-",function(){return[C.nJ]}],$isdM:true,$ishs:true,$isd3:true,$iscv:true,$isGv:true,$isKV:true,$isD0:true},GN:{"":"Tt+Pi;",$isd3:true},k8:{"":"a;jL>,zZ*",$isk8:true},HJ:{"":"e9;nF"},S0:{"":"a;Ow,VC",
 E5:function(){return this.Ow.call$0()},
 TP:function(a){var z=this.VC
@@ -17859,12 +18776,24 @@
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
+$is_Dv:true},Fn:{"":"Tp;",
+call$1:function(a){var z=J.x(a)
+return typeof a==="object"&&a!==null&&!!z.$isRS},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},e3:{"":"Tp;",
+call$1:function(a){var z=J.x(a)
+return typeof a==="object"&&a!==null&&!!z.$isMs},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
 $is_Dv:true},pM:{"":"Tp;",
 call$1:function(a){return!a.gQ2()},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},Mh:{"":"a;"}}],["polymer.deserialize","package:polymer/deserialize.dart",,Z,{Zh:function(a,b,c){var z,y,x
+$is_Dv:true},jh:{"":"a;"}}],["polymer.deserialize","package:polymer/deserialize.dart",,Z,{Zh:function(a,b,c){var z,y,x
 z=J.UQ($.WJ(),c.gvd())
 if(z!=null)return z.call$2(a,b)
 try{y=C.lM.kV(J.JA(a,"'","\""))
@@ -17876,7 +18805,7 @@
 z.u(z,C.nz,new Z.pp())
 z.u(z,C.Ts,new Z.Nq())
 z.u(z,C.PC,new Z.nl())
-z.u(z,C.md,new Z.ej())
+z.u(z,C.md,new Z.ik())
 return z},
 "+call:0:0":0,
 $isEH:true,
@@ -17908,7 +18837,7 @@
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},ej:{"":"Tp;",
+$is_Dv:true},ik:{"":"Tp;",
 call$2:function(a,b){return H.IH(a,new Z.HK(b))},
 "+call:2:0":0,
 $isEH:true,
@@ -17957,8 +18886,8 @@
 gca:function(){return new T.Dw(this,T.e9.prototype.yt,null,"yt")},
 A5:function(a){return new T.uK(this)}},Xy:{"":"Tp;a,b,c",
 call$2:function(a,b){var z=J.x(a)
-if(typeof a!=="object"||a===null||!z.$isz6)a=new K.z6(null,a,V.WF(this.a.nF,null,null),null)
-z=J.x(b)
+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.xC(this.b,"class"))return T.FL(this.c,a,T.qP)
 if(z&&J.xC(this.b,"style"))return T.FL(this.c,a,T.Fx)
@@ -17967,7 +18896,9 @@
 $isEH:true,
 $is_bh:true},uK:{"":"Tp;a",
 call$1:function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isz6?a:new K.z6(null,a,V.WF(this.a.nF,null,null),null)},
+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:0":0,
 $isEH:true,
 $is_HB:true,
@@ -17981,14 +18912,14 @@
 F.Wi(this,C.ls,z,this.uK)},
 gnc:function(){return new H.Pm(this,T.mY.prototype.vr,null,"vr")},
 gP:function(a){return this.uK
-"35,33"},
+"37,35"},
 "+value":1,
 r6:function(a,b){return this.gP(a).call$1(b)},
 sP:function(a,b){var z,y,x,w
 try{K.jX(this.jf,b,this.qc)}catch(y){x=H.Ru(y)
 w=J.x(x)
 if(typeof x==="object"&&x!==null&&!!w.$isB0){z=x
-$.IS().A3("Error evaluating expression '"+H.d(this.jf)+"': "+J.z2(z))}else throw y}"35,101,35,33"},
+$.IS().A3("Error evaluating expression '"+H.d(this.jf)+"': "+J.z2(z))}else throw y}"37,105,37,35"},
 "+value=":1,
 Va:function(a,b,c){var z,y,x,w,v
 y=this.jf
@@ -18036,25 +18967,23 @@
 H.VM(x,[U.hw])
 for(;w=z.a,v=J.RE(w),typeof w==="object"&&w!==null&&!!v.$isuk;){if(!J.xC(v.gkp(w),"|"))break
 x.push(v.gT8(w))
-z.a=v.gBb(w)}z=z.a
-w=J.x(z)
-if(typeof z==="object"&&z!==null&&!!w.$isw6){u=w.gP(z)
+z.a=v.gBb(w)}w=z.a
+v=J.x(w)
+if(typeof w==="object"&&w!==null&&!!v.$isw6){u=v.gP(w)
 t=C.OL
-s=!1}else if(typeof z==="object"&&z!==null&&!!w.$isRW){t=z.ghP()
-if(J.xC(w.gbP(z),"[]")){w=z.gre()
-if(0>=w.length)throw H.e(w,0)
-w=w[0]
+s=!1}else if(typeof w==="object"&&w!==null&&!!v.$iszX){w=w.gJn()
 v=J.x(w)
 if(typeof w!=="object"||w===null||!v.$isno)y.call$0()
-z=z.gre()
-if(0>=z.length)throw H.e(z,0)
-u=J.Vm(z[0])
-s=!0}else{if(w.gbP(z)!=null){if(z.gre()!=null)y.call$0()
-u=w.gbP(z)}else{y.call$0()
-u=null}s=!1}}else{y.call$0()
+z=z.a
+t=z.ghP()
+u=J.Vm(z.gJn())
+s=!0}else{if(typeof w==="object"&&w!==null&&!!v.$isx9){t=w.ghP()
+u=v.goc(w)}else if(typeof w==="object"&&w!==null&&!!v.$isRW){t=w.ghP()
+if(v.gbP(w)!=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=new H.a7(x,x.length,0,null),H.VM(z,[H.W8(x,"Q",0)]);z.G();){r=z.mD
+u=null}s=!1}for(z=new H.a7(x,x.length,0,null),H.VM(z,[H.W8(x,"Q",0)]);z.G();){r=z.mD
 q=J.UK(r,new K.G1(c,P.NZ(null,null)))
 J.UK(q,new K.Ed(c))
 q.gLv()
@@ -18195,6 +19124,7 @@
 x.Iv(z)}},
 bu:function(a){var z=this.KL
 return z.bu(z)},
+"+toString:0:0":0,
 $ishw:true},Ed:{"":"a0;Jd",
 xn:function(a){a.yc(a,this.Jd)},
 ky:function(a){J.UK(a.gT8(a),this)
@@ -18202,6 +19132,18 @@
 W9:function(a){return new K.Wh(a,null,null,null,P.bK(null,null,!1,null))},
 LT:function(a){var z=a.wz
 return z.RR(z,this)},
+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},
+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},
 Y7:function(a){var z,y,x,w,v
 z=J.UK(a.ghP(),this)
 y=a.gre()
@@ -18333,44 +19275,95 @@
 $ishw:true},ky:{"":"Ay;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
-z=$.bF()
+Qh:function(a){var z,y,x,w
+z=$.e6()
 y=this.KL
 x=z.t(z,y.gkp(y))
 if(J.xC(y.gkp(y),"&&")||J.xC(y.gkp(y),"||")){z=this.Bb.gLv()
 if(z==null)z=!1
 y=this.T8.gLv()
 this.Lv=x.call$2(z,y==null?!1:y)}else if(J.xC(y.gkp(y),"==")||J.xC(y.gkp(y),"!="))this.Lv=x.call$2(this.Bb.gLv(),this.T8.gLv())
-else{z=this.Bb.gLv()
-if(z==null||this.T8.gLv()==null)this.Lv=null
-else this.Lv=x.call$2(z,this.T8.gLv())}},
+else{z=this.Bb
+if(z.gLv()==null||this.T8.gLv()==null)this.Lv=null
+else{if(J.xC(y.gkp(y),"|")){y=z.gLv()
+w=J.x(y)
+w=typeof y==="object"&&y!==null&&!!w.$iswn
+y=w}else y=!1
+if(y)this.tj=H.Go(z.gLv(),"$iswn").gRT().yI(new K.uA(this,a))
+this.Lv=x.call$2(z.gLv(),this.T8.gLv())}}},
 RR:function(a,b){return b.im(this)},
 $asAy:function(){return[U.uk]},
 $isuk:true,
-$ishw:true},fa:{"":"Ay;hP<,re<,KL,bO,tj,Lv,k6",
-glT:function(){return this.KL.glT()},
+$ishw:true},uA:{"":"Tp;a,b",
+call$1:function(a){return this.a.DX(this.b)},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},vl:{"":"Ay;hP<,KL,bO,tj,Lv,k6",
+goc:function(a){var z=this.KL
+return z.goc(z)},
+"+name":0,
+Qh:function(a){var z,y,x
+z=this.hP.gLv()
+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
+y=J.RE(z)
+if(typeof z==="object"&&z!==null&&!!y.$isd3)this.tj=y.gqh(z).yI(new K.Li(this,a,x))},
+RR:function(a,b){return b.co(this)},
+$asAy:function(){return[U.x9]},
+$isx9:true,
+$ishw:true},Li:{"":"Tp;a,b,c",
+call$1:function(a){if(J.ja(a,new K.WK(this.c))===!0)this.a.DX(this.b)},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},WK:{"":"Tp;d",
+call$1:function(a){var z=J.x(a)
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.xC(a.oc,this.d)},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},iT:{"":"Ay;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.gqh(z).yI(new K.tE(this,a,y))},
+RR:function(a,b){return b.CU(this)},
+$asAy:function(){return[U.zX]},
+$iszX:true,
+$ishw:true},tE:{"":"Tp;a,b,c",
+call$1:function(a){if(J.ja(a,new K.GS(this.c))===!0)this.a.DX(this.b)},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},GS:{"":"Tp;d",
+call$1:function(a){var z=J.x(a)
+return typeof a==="object"&&a!==null&&!!z.$isHA&&J.xC(a.G3,this.d)},
+"+call:1:0":0,
+$isEH:true,
+$is_HB:true,
+$is_Dv:true},fa:{"":"Ay;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,v,u
+Qh:function(a){var z,y,x,w
 z=this.re
-if(z==null)y=[]
-else{z.toString
+z.toString
 z=new H.A8(z,new K.WW())
 H.VM(z,[null,null])
-y=z.tt(z,!1)}x=this.hP.gLv()
-if(x==null)this.Lv=null
-else{z=this.KL
-if(z.gbP(z)==null)if(z.glT())this.Lv=x
-else this.Lv=K.Ku(x,y)
-else if(J.xC(z.gbP(z),"[]")){if(0>=y.length)throw H.e(y,0)
-w=y[0]
-z=J.U6(x)
-this.Lv=z.t(x,w)
-if(typeof x==="object"&&x!==null&&!!z.$isd3)this.tj=z.gqh(x).yI(new K.vQ(this,a,w))}else{v=H.vn(x)
-u=new H.GD(H.le(z.gbP(z)))
-this.Lv=z.glT()?v.rN(u).Ax:v.F2(u,y,null).Ax
+y=z.br(z)
+x=this.hP.gLv()
+if(x==null){this.Lv=null
+return}z=this.KL
+if(z.gbP(z)==null)this.Lv=K.Ku(x,y)
+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.gqh(x).yI(new K.jh(this,a,u))}}},
+if(typeof x==="object"&&x!==null&&!!z.$isd3)this.tj=z.gqh(x).yI(new K.vQ(this,a,w))}},
 RR:function(a,b){return b.Y7(this)},
 $asAy:function(){return[U.RW]},
 $isRW:true,
@@ -18386,18 +19379,7 @@
 $is_HB:true,
 $is_Dv:true},a9:{"":"Tp;d",
 call$1:function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isHA&&J.xC(a.G3,this.d)},
-"+call:1:0":0,
-$isEH:true,
-$is_HB:true,
-$is_Dv:true},jh:{"":"Tp;e,f,g",
-call$1:function(a){if(J.ja(a,new K.e3(this.g))===!0)this.e.DX(this.f)},
-"+call:1:0":0,
-$isEH:true,
-$is_HB:true,
-$is_Dv:true},e3:{"":"Tp;h",
-call$1:function(a){var z=J.x(a)
-return typeof a==="object"&&a!==null&&!!z.$isqI&&J.xC(a.oc,this.h)},
+return typeof a==="object"&&a!==null&&!!z.$isqI&&J.xC(a.oc,this.d)},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
@@ -18427,6 +19409,7 @@
 $is_HB:true,
 $is_Dv:true},B0:{"":"a;G1>",
 bu:function(a){return"EvalException: "+this.G1},
+"+toString:0:0":0,
 $isB0:true,
 static:{yN:function(a){return new K.B0(a)}}}}],["polymer_expressions.expression","package:polymer_expressions/expression.dart",,U,{ZP:function(a,b){var z,y,x
 z=J.x(a)
@@ -18448,111 +19431,165 @@
 a=536870911&a+((67108863&a)<<3>>>0)
 a=(a^C.jn.m(a,11))>>>0
 return 536870911&a+((16383&a)<<15>>>0)},Fq:{"":"a;",
+Bf:function(a,b,c){return new U.zX(b,c)},
+"+index:2:0":0,
+gvH:function(a){return new A.Y7(this,U.Fq.prototype.Bf,a,"Bf")},
 F2:function(a,b,c){return new U.RW(a,b,c)},
-"+invoke:3:0":0,
-"*invoke":[35],
-CI:function(a,b){return this.F2(a,b,null)},
-"+invoke:2:0":0},hw:{"":"a;",$ishw:true},EZ:{"":"hw;",
+"+invoke:3:0":0},hw:{"":"a;",$ishw:true},EZ:{"":"hw;",
 RR:function(a,b){return b.W9(this)},
 $isEZ:true},no:{"":"hw;P>",
 r6:function(a,b){return this.P.call$1(b)},
 RR:function(a,b){return b.I6(this)},
 bu:function(a){var z=this.P
 return typeof z==="string"?"\""+H.d(z)+"\"":H.d(z)},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=H.RB(b,"$isno",[H.W8(this,"no",0)],"$asno")
 return z&&J.xC(J.Vm(b),this.P)},
+"+==:1:0":0,
 giO:function(a){return J.v1(this.P)},
+"+hashCode":0,
 $isno:true},kB:{"":"hw;Pu>",
 RR:function(a,b){return b.o0(this)},
 bu:function(a){return"{"+H.d(this.Pu)+"}"},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$iskB&&U.ZP(z.gPu(b),this.Pu)},
+"+==:1:0":0,
 giO:function(a){return U.au(this.Pu)},
+"+hashCode":0,
 $iskB:true},ae:{"":"hw;G3>,v4<",
 RR:function(a,b){return b.YV(this)},
 bu:function(a){return H.d(this.G3)+": "+H.d(this.v4)},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$isae&&J.xC(z.gG3(b),this.G3)&&J.xC(b.gv4(),this.v4)},
+"+==:1:0":0,
 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))},
+"+hashCode":0,
 $isae:true},Iq:{"":"hw;wz",
 RR:function(a,b){return b.LT(this)},
 bu:function(a){return"("+H.d(this.wz)+")"},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.x(b)
 return typeof b==="object"&&b!==null&&!!z.$isIq&&J.xC(b.wz,this.wz)},
+"+==:1:0":0,
 giO:function(a){return J.v1(this.wz)},
+"+hashCode":0,
 $isIq:true},w6:{"":"hw;P>",
 r6:function(a,b){return this.P.call$1(b)},
 RR:function(a,b){return b.qv(this)},
 bu:function(a){return this.P},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$isw6&&J.xC(z.gP(b),this.P)},
+"+==:1:0":0,
 giO:function(a){return J.v1(this.P)},
+"+hashCode":0,
 $isw6:true},jK:{"":"hw;kp>,wz<",
 RR:function(a,b){return b.Hx(this)},
 bu:function(a){return H.d(this.kp)+" "+H.d(this.wz)},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$isjK&&J.xC(z.gkp(b),this.kp)&&J.xC(b.gwz(),this.wz)},
+"+==:1:0":0,
 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))},
+"+hashCode":0,
 $isjK:true},uk:{"":"hw;kp>,Bb>,T8>",
 RR:function(a,b){return b.im(this)},
 bu:function(a){return"("+H.d(this.Bb)+" "+H.d(this.kp)+" "+H.d(this.T8)+")"},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$isuk&&J.xC(z.gkp(b),this.kp)&&J.xC(z.gBb(b),this.Bb)&&J.xC(z.gT8(b),this.T8)},
+"+==:1:0":0,
 giO:function(a){var z,y,x
 z=J.v1(this.kp)
 y=J.v1(this.Bb)
 x=J.v1(this.T8)
 return U.Up(U.Zm(U.Zm(U.Zm(0,z),y),x))},
+"+hashCode":0,
 $isuk:true},K9:{"":"hw;Bb>,T8>",
 RR:function(a,b){return b.ky(this)},
 bu:function(a){return"("+H.d(this.Bb)+" in "+H.d(this.T8)+")"},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$isK9&&J.xC(z.gBb(b),this.Bb)&&J.xC(z.gT8(b),this.T8)},
+"+==:1:0":0,
 giO:function(a){var z,y
 z=this.Bb
 z=z.giO(z)
 y=J.v1(this.T8)
 return U.Up(U.Zm(U.Zm(0,z),y))},
-$isK9:true},RW:{"":"hw;hP<,bP>,re<",
+"+hashCode":0,
+$isK9:true},zX:{"":"hw;hP<,Jn<",
+RR:function(a,b){return b.CU(this)},
+bu:function(a){return H.d(this.hP)+"["+H.d(this.Jn)+"]"},
+"+toString:0:0":0,
+n:function(a,b){var z
+if(b==null)return!1
+z=J.x(b)
+return typeof b==="object"&&b!==null&&!!z.$iszX&&J.xC(b.ghP(),this.hP)&&J.xC(b.gJn(),this.Jn)},
+"+==:1:0":0,
+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))},
+"+hashCode":0,
+$iszX:true},x9:{"":"hw;hP<,oc>",
+RR:function(a,b){return b.co(this)},
+bu:function(a){return H.d(this.hP)+"."+H.d(this.oc)},
+"+toString:0:0":0,
+n:function(a,b){var z
+if(b==null)return!1
+z=J.RE(b)
+return typeof b==="object"&&b!==null&&!!z.$isx9&&J.xC(b.ghP(),this.hP)&&J.xC(z.goc(b),this.oc)},
+"+==:1:0":0,
+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))},
+"+hashCode":0,
+$isx9:true},RW:{"":"hw;hP<,bP>,re<",
 RR:function(a,b){return b.Y7(this)},
-glT:function(){return this.re==null},
 bu:function(a){return H.d(this.hP)+"."+H.d(this.bP)+"("+H.d(this.re)+")"},
+"+toString:0:0":0,
 n:function(a,b){var z
 if(b==null)return!1
 z=J.RE(b)
 return typeof b==="object"&&b!==null&&!!z.$isRW&&J.xC(b.ghP(),this.hP)&&J.xC(z.gbP(b),this.bP)&&U.ZP(b.gre(),this.re)},
+"+==:1:0":0,
 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))},
+"+hashCode":0,
 $isRW:true},xs:{"":"Tp;",
 call$2:function(a,b){return U.Zm(a,J.v1(b))},
 "+call:2:0":0,
 $isEH:true,
-$is_bh:true}}],["polymer_expressions.parser","package:polymer_expressions/parser.dart",,T,{FX:{"":"a;Sk,Ix,ku,fL,lQ",
+$is_bh:true}}],["polymer_expressions.parser","package:polymer_expressions/parser.dart",,T,{FX:{"":"a;Sk,Ix,ku,fL",
 oK:function(){var z,y
 this.ku=this.Ix.zl()
 z=this.ku
@@ -18563,34 +19600,29 @@
 this.w5()
 return this.o9()},
 Gd:function(a,b){var z
-if(a!=null){z=J.Iz(this.lQ)
-z=z==null?a!=null:z!==a}else z=!1
-if(!z)z=b!=null&&!J.xC(J.Vm(this.lQ),b)
+if(!(a!=null&&!J.xC(J.Iz(this.fL.mD),a)))z=b!=null&&!J.xC(J.Vm(this.fL.mD),b)
 else z=!0
-if(z)throw H.b(Y.RV("Expected "+b+": "+H.d(this.lQ)))
-this.lQ=this.fL.G()?this.fL.mD:null},
+if(z)throw H.b(Y.RV("Expected "+b+": "+H.d(this.fL.mD)))
+this.fL.G()},
 w5:function(){return this.Gd(null,null)},
-o9:function(){if(this.lQ==null){this.Sk.toString
+o9:function(){if(this.fL.mD==null){this.Sk.toString
 return C.OL}var z=this.Dl()
 return z==null?null:this.BH(z,0)},
-BH:function(a,b){var z,y,x,w,v,u
-for(z=this.Sk;y=this.lQ,y!=null;){x=J.RE(y)
-w=x.gfY(y)
-if(w===9)if(J.xC(x.gP(y),"(")){v=this.qk()
+BH:function(a,b){var z,y,x,w
+for(z=this.Sk;y=this.fL.mD,y!=null;)if(J.xC(J.Iz(y),9))if(J.xC(J.Vm(this.fL.mD),"(")){x=this.qk()
 z.toString
-a=new U.RW(a,null,v)}else if(J.xC(J.Vm(this.lQ),"[")){u=this.bK()
-v=u==null?[]:[u]
+a=new U.RW(a,null,x)}else if(J.xC(J.Vm(this.fL.mD),"[")){w=this.bK()
 z.toString
-a=new U.RW(a,"[]",v)}else break
-else if(w===3){this.w5()
-a=this.ct(a,this.Dl())}else if(w===10&&J.xC(x.gP(y),"in"))a=this.xo(a)
-else{y=this.lQ
-if(J.Iz(y)===8&&J.J5(y.gG8(),b))a=this.Tw(a)
-else break}}return a},
-ct:function(a,b){var z,y
+a=new U.zX(a,w)}else break
+else if(J.xC(J.Iz(this.fL.mD),3)){this.w5()
+a=this.qL(a,this.Dl())}else if(J.xC(J.Iz(this.fL.mD),10)&&J.xC(J.Vm(this.fL.mD),"in"))a=this.xo(a)
+else if(J.xC(J.Iz(this.fL.mD),8)&&J.J5(this.fL.mD.gG8(),b))a=this.Tw(a)
+else break
+return a},
+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.RW(a,z,null)}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.$isRW){z=b.ghP()
 y=J.x(z)
 y=typeof z==="object"&&z!==null&&!!y.$isw6
 z=y}else z=!1
@@ -18598,73 +19630,66 @@
 y=b.gre()
 this.Sk.toString
 return new U.RW(a,z,y)}else throw H.b(Y.RV("expected identifier: "+H.d(b)))}},
-Tw:function(a){var z,y,x,w
-z=this.lQ
+Tw:function(a){var z,y,x
+z=this.fL.mD
 this.w5()
 y=this.Dl()
-while(!0){x=this.lQ
-if(x!=null){w=J.Iz(x)
-x=(w===8||w===3||w===9)&&J.xZ(x.gG8(),z.gG8())}else x=!1
+while(!0){x=this.fL.mD
+if(x!=null)x=(J.xC(J.Iz(x),8)||J.xC(J.Iz(this.fL.mD),3)||J.xC(J.Iz(this.fL.mD),9))&&J.xZ(this.fL.mD.gG8(),z.gG8())
+else x=!1
 if(!x)break
-y=this.BH(y,this.lQ.gG8())}x=J.Vm(z)
+y=this.BH(y,this.fL.mD.gG8())}x=J.Vm(z)
 this.Sk.toString
 return new U.uk(x,a,y)},
 Dl:function(){var z,y,x,w
-z=this.lQ
-y=J.RE(z)
-if(y.gfY(z)===8){x=y.gP(z)
-z=J.x(x)
-if(z.n(x,"+")||z.n(x,"-")){this.w5()
-z=J.Iz(this.lQ)
-if(z===6){z=H.BU(H.d(x)+H.d(J.Vm(this.lQ)),null,null)
+if(J.xC(J.Iz(this.fL.mD),8)){z=J.Vm(this.fL.mD)
+y=J.x(z)
+if(y.n(z,"+")||y.n(z,"-")){this.w5()
+if(J.xC(J.Iz(this.fL.mD),6)){y=H.BU(H.d(z)+H.d(J.Vm(this.fL.mD)),null,null)
 this.Sk.toString
-x=new U.no(z)
-x.$builtinTypeInfo=[null]
+z=new U.no(y)
+z.$builtinTypeInfo=[null]
 this.w5()
-return x}else{y=this.Sk
-if(z===7){z=H.IH(H.d(x)+H.d(J.Vm(this.lQ)),null)
+return z}else{y=this.Sk
+if(J.xC(J.Iz(this.fL.mD),7)){x=H.IH(H.d(z)+H.d(J.Vm(this.fL.mD)),null)
 y.toString
-x=new U.no(z)
-x.$builtinTypeInfo=[null]
+z=new U.no(x)
+z.$builtinTypeInfo=[null]
 this.w5()
-return x}else{w=this.BH(this.lb(),11)
+return z}else{w=this.BH(this.lb(),11)
 y.toString
-return new U.jK(x,w)}}}else if(z.n(x,"!")){this.w5()
+return new U.jK(z,w)}}}else if(y.n(z,"!")){this.w5()
 w=this.BH(this.lb(),11)
 this.Sk.toString
-return new U.jK(x,w)}}return this.lb()},
-lb:function(){var z,y,x
-z=this.lQ
-y=J.RE(z)
-switch(y.gfY(z)){case 10:x=y.gP(z)
-z=J.x(x)
-if(z.n(x,"this")){this.w5()
+return new U.jK(z,w)}}return this.lb()},
+lb:function(){var z,y
+switch(J.Iz(this.fL.mD)){case 10:z=J.Vm(this.fL.mD)
+y=J.x(z)
+if(y.n(z,"this")){this.w5()
 this.Sk.toString
-return new U.w6("this")}else if(z.n(x,"in"))return
-throw H.b(new P.AT("unrecognized keyword: "+H.d(x)))
+return new U.w6("this")}else if(y.n(z,"in"))return
+throw H.b(new P.AT("unrecognized keyword: "+H.d(z)))
 case 2:return this.Cy()
 case 1:return this.qF()
 case 6:return this.Ud()
 case 7:return this.tw()
-case 9:if(J.xC(y.gP(z),"("))return this.Pj()
-else if(J.xC(J.Vm(this.lQ),"{"))return this.Wc()
+case 9:if(J.xC(J.Vm(this.fL.mD),"("))return this.Pj()
+else if(J.xC(J.Vm(this.fL.mD),"{"))return this.Wc()
 return
 default:return}},
-Wc:function(){var z,y,x,w,v
+Wc:function(){var z,y,x,w
 z=[]
 y=this.Sk
 do{this.w5()
-x=this.lQ
-w=J.RE(x)
-if(w.gfY(x)===9&&J.xC(w.gP(x),"}"))break
-x=J.Vm(this.lQ)
+if(J.xC(J.Iz(this.fL.mD),9)&&J.xC(J.Vm(this.fL.mD),"}"))break
+x=J.Vm(this.fL.mD)
 y.toString
-v=new U.no(x)
-v.$builtinTypeInfo=[null]
+w=new U.no(x)
+w.$builtinTypeInfo=[null]
 this.w5()
 this.Gd(5,":")
-z.push(new U.ae(v,this.o9()))
-x=this.lQ}while(x!=null&&J.xC(J.Vm(x),","))
+z.push(new U.ae(w,this.o9()))
+x=this.fL.mD}while(x!=null&&J.xC(J.Vm(x),","))
 this.Gd(9,"}")
 return new U.kB(z)},
 xo:function(a){var z,y
@@ -18675,15 +19700,15 @@
 this.Sk.toString
 return new U.K9(a,y)},
 Cy:function(){var z,y,x
-if(J.xC(J.Vm(this.lQ),"true")){this.w5()
+if(J.xC(J.Vm(this.fL.mD),"true")){this.w5()
 this.Sk.toString
 z=new U.no(!0)
 H.VM(z,[null])
-return z}if(J.xC(J.Vm(this.lQ),"false")){this.w5()
+return z}if(J.xC(J.Vm(this.fL.mD),"false")){this.w5()
 this.Sk.toString
 z=new U.no(!1)
 H.VM(z,[null])
-return z}if(J.xC(J.Vm(this.lQ),"null")){this.w5()
+return z}if(J.xC(J.Vm(this.fL.mD),"null")){this.w5()
 this.Sk.toString
 z=new U.no(null)
 H.VM(z,[null])
@@ -18692,49 +19717,40 @@
 if(x==null)return y
 else{this.Sk.toString
 return new U.RW(y,null,x)}},
-nt:function(){var z,y,x
-z=this.lQ
-y=J.RE(z)
-if(y.gfY(z)!==2)throw H.b(Y.RV("expected identifier: "+H.d(z)+".value"))
-x=y.gP(z)
+nt:function(){if(!J.xC(J.Iz(this.fL.mD),2))throw H.b(Y.RV("expected identifier: "+H.d(this.fL.mD)+".value"))
+var z=J.Vm(this.fL.mD)
 this.w5()
 this.Sk.toString
-return new U.w6(x)},
-qk:function(){var z,y,x
-z=this.lQ
-if(z!=null){y=J.RE(z)
-z=y.gfY(z)===9&&J.xC(y.gP(z),"(")}else z=!1
-if(z){x=[]
+return new U.w6(z)},
+qk:function(){var z,y
+z=this.fL.mD
+if(z!=null&&J.xC(J.Iz(z),9)&&J.xC(J.Vm(this.fL.mD),"(")){y=[]
 do{this.w5()
-z=this.lQ
-y=J.RE(z)
-if(y.gfY(z)===9&&J.xC(y.gP(z),")"))break
-x.push(this.o9())
-z=this.lQ}while(z!=null&&J.xC(J.Vm(z),","))
+if(J.xC(J.Iz(this.fL.mD),9)&&J.xC(J.Vm(this.fL.mD),")"))break
+y.push(this.o9())
+z=this.fL.mD}while(z!=null&&J.xC(J.Vm(z),","))
 this.Gd(9,")")
-return x}return},
-bK:function(){var z,y,x
-z=this.lQ
-if(z!=null){y=J.RE(z)
-z=y.gfY(z)===9&&J.xC(y.gP(z),"[")}else z=!1
-if(z){this.w5()
-x=this.o9()
+return y}return},
+bK:function(){var z,y
+z=this.fL.mD
+if(z!=null&&J.xC(J.Iz(z),9)&&J.xC(J.Vm(this.fL.mD),"[")){this.w5()
+y=this.o9()
 this.Gd(9,"]")
-return x}return},
+return y}return},
 Pj:function(){this.w5()
 var z=this.o9()
 this.Gd(9,")")
 this.Sk.toString
 return new U.Iq(z)},
 qF:function(){var z,y
-z=J.Vm(this.lQ)
+z=J.Vm(this.fL.mD)
 this.Sk.toString
 y=new U.no(z)
 H.VM(y,[null])
 this.w5()
 return y},
 pT:function(a){var z,y
-z=H.BU(H.d(a)+H.d(J.Vm(this.lQ)),null,null)
+z=H.BU(H.d(a)+H.d(J.Vm(this.fL.mD)),null,null)
 this.Sk.toString
 y=new U.no(z)
 H.VM(y,[null])
@@ -18742,7 +19758,7 @@
 return y},
 Ud:function(){return this.pT("")},
 yj:function(a){var z,y
-z=H.IH(H.d(a)+H.d(J.Vm(this.lQ)),null)
+z=H.IH(H.d(a)+H.d(J.Vm(this.fL.mD)),null)
 this.Sk.toString
 y=new U.no(z)
 H.VM(y,[null])
@@ -18754,10 +19770,22 @@
 H.VM(z,[Y.Pn])
 y=P.p9("")
 x=new U.Fq()
-return new T.FX(x,new Y.hc(z,y,new P.WU(a,0,0,null),null),null,null,null)}}}}],["polymer_expressions.src.globals","package:polymer_expressions/src/globals.dart",,K,{Dc:function(a){var z=new K.Bt(a)
+return new T.FX(x,new Y.hc(z,y,new P.WU(a,0,0,null),null),null,null)}}}}],["polymer_expressions.src.globals","package:polymer_expressions/src/globals.dart",,K,{Dc:function(a){var z=new K.Bt(a)
 H.VM(z,[null])
 return z},Ae:{"":"a;vH>-,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.$isAe&&J.xC(b.vH,this.vH)&&J.xC(b.P,this.P)
+"37,106,37"},
+"+==:1:0":1,
+giO:function(a){return J.v1(this.P)
+"27"},
+"+hashCode":1,
+bu:function(a){return"("+H.d(this.vH)+", "+H.d(this.P)+")"
+"8"},
+"+toString:0:0":1,
 $isAe:true,
 "@":function(){return[C.nJ]},
 "<>":[3],
@@ -18786,7 +19814,7 @@
 H.VM(z,[H.W8(this,"Bt",0)])
 return z},
 $asmW:function(a){return[[K.Ae,a]]},
-$ascX:function(a){return[[K.Ae,a]]}},vR:{"":"Fl;Ee,wX,CD",
+$ascX:function(a){return[[K.Ae,a]]}},vR:{"":"eL;Ee,wX,CD",
 gl:function(){return this.CD},
 "+current":0,
 G:function(){var z,y
@@ -18798,7 +19826,7 @@
 this.CD=z
 return!0}this.CD=null
 return!1},
-$asFl:function(a){return[[K.Ae,a]]}}}],["polymer_expressions.src.mirrors","package:polymer_expressions/src/mirrors.dart",,Z,{xq:function(a,b){var z,y,x
+$aseL:function(a){return[[K.Ae,a]]}}}],["polymer_expressions.src.mirrors","package:polymer_expressions/src/mirrors.dart",,Z,{xq:function(a,b){var z,y,x
 if(a.gYK().x4(b)===!0)return J.UQ(a.gYK(),b)
 z=a.gAY()
 if(z!=null&&!J.xC(z.gvd(),C.PU)){y=Z.xq(a.gAY(),b)
@@ -18820,6 +19848,7 @@
 default:return a}},Pn:{"":"a;fY>,P>,G8<",
 r6:function(a,b){return this.P.call$1(b)},
 bu:function(a){return"("+this.fY+", '"+this.P+"')"},
+"+toString:0:0":0,
 $isPn:true},hc:{"":"a;MV,wV,jI,x0",
 zl:function(){var z,y,x,w,v
 z=this.jI
@@ -18917,11 +19946,18 @@
 u.$builtinTypeInfo=[J.im]
 v=H.eT(u)}this.MV.push(new Y.Pn(8,v,C.dj.t(C.dj,v)))}},hA:{"":"a;G1>",
 bu:function(a){return"ParseException: "+this.G1},
+"+toString:0:0":0,
 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)},
 gnG:function(){return new H.Pm(this,S.fr.prototype.DV,null,"DV")}},a0:{"":"fr;",
 W9:function(a){return this.xn(a)},
-LT:function(a){a.RR(a,this)
+LT:function(a){var z=a.wz
+z.RR(z,this)
+this.xn(a)},
+co:function(a){J.UK(a.ghP(),this)
+this.xn(a)},
+CU:function(a){J.UK(a.ghP(),this)
+J.UK(a.gJn(),this)
 this.xn(a)},
 Y7:function(a){var z,y
 J.UK(a.ghP(),this)
@@ -18943,7 +19979,7 @@
 this.xn(a)},
 ky:function(a){J.UK(a.gBb(a),this)
 J.UK(a.gT8(a),this)
-this.xn(a)}}}],["response_viewer_element","package:observatory/src/observatory_elements/response_viewer.dart",,Q,{NQ:{"":["uL;tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+this.xn(a)}}}],["response_viewer_element","package:observatory/src/observatory_elements/response_viewer.dart",,Q,{NQ:{"":["uL;hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 "@":function(){return[C.Ig]},
 static:{Zo:function(a){var z,y,x,w,v
 z=$.Nd()
@@ -18958,12 +19994,54 @@
 C.Cc.ZL(a)
 C.Cc.FH(a)
 return a
-"30"},"+new ResponseViewerElement$created:0:0":1}},"+ResponseViewerElement": [24]}],["stack_trace_element","package:observatory/src/observatory_elements/stack_trace.dart",,X,{uw:{"":["WZq;Qq%-,VJ,Ai,tH-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+"30"},"+new ResponseViewerElement$created:0:0":1}},"+ResponseViewerElement": [24]}],["script_view_element","package:observatory/src/observatory_elements/script_view.dart",,U,{fI:{"":["WZq;Uz%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",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
+"34,35,36"},
+"+script":1,
+sNl:function(a,b){a.Uz=this.ct(a,C.fX,a.Uz,b)
+"37,28,34,35"},
+"+script=":1,
+"@":function(){return[C.Er]},
+static:{Ry:function(a){var z,y,x,w,v
+z=$.Nd()
+y=P.Py(null,null,null,J.O,W.I0)
+x=J.O
+w=W.cv
+v=new V.br(P.Py(null,null,null,x,w),null,null)
+H.VM(v,[x,w])
+a.Ye=z
+a.mT=y
+a.KM=v
+C.cJ.ZL(a)
+C.cJ.FH(a)
+return a
+"31"},"+new ScriptViewElement$created:0:0":1}},"+ScriptViewElement": [107],WZq:{"":"uL+Pi;",$isd3:true}}],["source_view_element","package:observatory/src/observatory_elements/source_view.dart",,X,{kK:{"":["pva;vX%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
+gFF:function(a){return a.vX
+"108,35,36"},
+"+source":1,
+sFF:function(a,b){a.vX=this.ct(a,C.hn,a.vX,b)
+"37,28,108,35"},
+"+source=":1,
+"@":function(){return[C.H8]},
+static:{HO:function(a){var z,y,x,w,v
+z=$.Nd()
+y=P.Py(null,null,null,J.O,W.I0)
+x=J.O
+w=W.cv
+v=new V.br(P.Py(null,null,null,x,w),null,null)
+H.VM(v,[x,w])
+a.Ye=z
+a.mT=y
+a.KM=v
+C.Ks.ZL(a)
+C.Ks.FH(a)
+return a
+"32"},"+new SourceViewElement$created:0:0":1}},"+SourceViewElement": [109],pva:{"":"uL+Pi;",$isd3:true}}],["stack_trace_element","package:observatory/src/observatory_elements/stack_trace.dart",,X,{uw:{"":["cda;Qq%-,VJ,Ai,hm-,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM-",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,function(){return[C.nJ]}],
 gtN:function(a){return a.Qq
-"32,33,34"},
+"34,35,36"},
 "+trace":1,
-stN:function(a,b){a.Qq=this.pD(a,C.kw,a.Qq,b)
-"35,28,32,33"},
+stN:function(a,b){a.Qq=this.ct(a,C.kw,a.Qq,b)
+"37,28,34,35"},
 "+trace=":1,
 "@":function(){return[C.js]},
 static:{bV:function(a){var z,y,x,w,v,u
@@ -18982,7 +20060,7 @@
 C.bg.ZL(a)
 C.bg.FH(a)
 return a
-"31"},"+new StackTraceElement$created:0:0":1}},"+StackTraceElement": [102],WZq:{"":"uL+Pi;",$isd3:true}}],["template_binding","package:template_binding/template_binding.dart",,M,{IP:function(a){var z=J.RE(a)
+"33"},"+new StackTraceElement$created:0:0":1}},"+StackTraceElement": [110],cda:{"":"uL+Pi;",$isd3:true}}],["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.io.f0(a)
 switch(z.gr9(a)){case"checkbox":return $.FF().aM(a)
 case"radio":case"select-multiple":case"select-one":return z.gEr(a)
@@ -18997,7 +20075,7 @@
 for(y=a.firstChild,x=0;y!=null;y=y.nextSibling,x=w){w=x+1
 if(x>=z.length)throw H.e(z,x)
 M.HP(y,z[x],c,d,e)}},bM:function(a){var z,y
-for(;z=J.RE(a),y=z.gKV(a),y!=null;a=y);if(typeof a==="object"&&a!==null&&!!z.$isYN||typeof a==="object"&&a!==null&&!!z.$isI0||typeof a==="object"&&a!==null&&!!z.$ishy)return a
+for(;z=J.RE(a),y=z.gKV(a),y!=null;a=y);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},pN:function(a,b){var z,y
 z=J.x(a)
 if(typeof a==="object"&&a!==null&&!!z.$iscv)return M.F5(a,b)
@@ -19138,23 +20216,23 @@
 y.sr9(z,"checkbox")
 x=[]
 w=y.gVl(z)
-v=new W.Ov(0,w.uv,w.Ph,W.aF(new M.ik(x)),w.Sg)
+v=new W.Ov(0,w.uv,w.Ph,W.aF(new M.LfS(x)),w.Sg)
 H.VM(v,[H.W8(w,"RO",0)])
 v.Zz()
 y=y.gEr(z)
-v=new W.Ov(0,y.uv,y.Ph,W.aF(new M.LfS(x)),y.Sg)
+v=new W.Ov(0,y.uv,y.Ph,W.aF(new M.fTP(x)),y.Sg)
 H.VM(v,[H.W8(y,"RO",0)])
 v.Zz()
 z.dispatchEvent(W.H6("click",!1,0,!0,!0,0,0,!1,0,!1,null,0,0,!1,window))
 return x.length===1?C.mt:C.Nm.gFV(x)},
 "+call:0:0":0,
 $isEH:true,
-$is_X0:true},ik:{"":"Tp;a",
+$is_X0:true},LfS:{"":"Tp;a",
 call$1:function(a){this.a.push(C.T1)},
 "+call:1:0":0,
 $isEH:true,
 $is_HB:true,
-$is_Dv:true},LfS:{"":"Tp;b",
+$is_Dv:true},fTP:{"":"Tp;b",
 call$1:function(a){this.b.push(C.mt)},
 "+call:1:0":0,
 $isEH:true,
@@ -19788,15 +20866,15 @@
 $$=null
 init.globalFunctions.NB=H.NB=new H.zy(H.Mg,"NB")
 init.globalFunctions.Rm=H.Rm=new H.Nb(H.vx,"Rm")
-init.globalFunctions.Eu=H.Eu=new H.HB(H.Ju,"Eu")
+init.globalFunctions.Eu=H.Eu=new H.Fy(H.Ju,"Eu")
 init.globalFunctions.eH=H.eH=new H.eU(H.ft,"eH")
 init.globalFunctions.Qv=H.Qv=new H.zy(H.pe,"Qv")
-init.globalFunctions.qg=E.qg=new H.HB(E.E2,"qg")
+init.globalFunctions.qg=E.qg=new H.Fy(E.E2,"qg")
 init.globalFunctions.Yf=H.Yf=new H.Nb(H.vn,"Yf")
-init.globalFunctions.qZ=P.qZ=new H.HB(P.BG,"qZ")
+init.globalFunctions.qZ=P.qZ=new H.Fy(P.BG,"qZ")
 init.globalFunctions.Xw=P.Xw=new H.Nb(P.YE,"Xw")
 init.globalFunctions.AY=P.AY=new P.ADW(P.SZ,"AY")
-init.globalFunctions.No=P.No=new H.HB(P.ax,"No")
+init.globalFunctions.No=P.No=new H.Fy(P.ax,"No")
 init.globalFunctions.xP=P.xP=new P.Ri(P.L2,"xP")
 init.globalFunctions.AI=P.AI=new P.kq(P.T8,"AI")
 init.globalFunctions.MM=P.MM=new P.Ri(P.V7,"MM")
@@ -19823,7 +20901,7 @@
 init.globalFunctions.En=P.En=new H.Nb(P.wY,"En")
 init.globalFunctions.Xl=P.Xl=new H.Nb(P.dU,"Xl")
 init.globalFunctions.np=R.np=new H.Nb(R.Jk,"np")
-init.globalFunctions.PB=A.PB=new H.HB(A.ei,"PB")
+init.globalFunctions.PB=A.PB=new H.Fy(A.ei,"PB")
 init.globalFunctions.qP=T.qP=new H.Nb(T.ul,"qP")
 init.globalFunctions.Fx=T.Fx=new H.Nb(T.PX,"Fx")
 init.globalFunctions.ZO=K.ZO=new H.Nb(K.Dc,"ZO")
@@ -19869,10 +20947,15 @@
 U.EZ.$isa=true
 U.RW.$ishw=true
 U.RW.$isa=true
+U.zX.$iszX=true
+U.zX.$ishw=true
+U.zX.$isa=true
 U.uk.$ishw=true
 U.uk.$isa=true
 U.K9.$ishw=true
 U.K9.$isa=true
+U.x9.$ishw=true
+U.x9.$isa=true
 U.no.$ishw=true
 U.no.$isa=true
 U.jK.$ishw=true
@@ -19898,38 +20981,38 @@
 A.XP.$isD0=true
 A.XP.$isa=true
 P.vr.$isvr=true
-P.vr.$isQF=true
+P.vr.$isej=true
 P.vr.$isa=true
-P.D4.$isD4=true
-P.D4.$isQF=true
-P.D4.$isQF=true
-P.D4.$isa=true
-P.RS.$isQF=true
+P.NL.$isej=true
+P.NL.$isa=true
+P.RS.$isej=true
 P.RS.$isa=true
-H.Zk.$isQF=true
-H.Zk.$isQF=true
-H.Zk.$isQF=true
+H.Zk.$isej=true
+H.Zk.$isej=true
+H.Zk.$isej=true
 H.Zk.$isa=true
-P.Ys.$isQF=true
-P.Ys.$isa=true
+P.D4.$isD4=true
+P.D4.$isej=true
+P.D4.$isej=true
+P.D4.$isa=true
+P.ej.$isej=true
+P.ej.$isa=true
+P.RY.$isej=true
+P.RY.$isa=true
 P.Ms.$isMs=true
-P.Ms.$isQF=true
-P.Ms.$isQF=true
+P.Ms.$isej=true
+P.Ms.$isej=true
 P.Ms.$isa=true
-P.Fw.$isQF=true
+P.Ys.$isej=true
+P.Ys.$isa=true
+P.Fw.$isej=true
 P.Fw.$isa=true
-P.X9.$isQF=true
-P.X9.$isa=true
+P.L9u.$isej=true
+P.L9u.$isa=true
 X.TR.$isa=true
 N.TJ.$isa=true
 T.yj.$isyj=true
 T.yj.$isa=true
-P.NL.$isQF=true
-P.NL.$isa=true
-P.RY.$isQF=true
-P.RY.$isa=true
-P.QF.$isQF=true
-P.QF.$isa=true
 P.MO.$isMO=true
 P.MO.$isa=true
 F.d3.$isa=true
@@ -19953,9 +21036,9 @@
 P.uq.$isa=true
 P.iD.$isiD=true
 P.iD.$isa=true
-W.YN.$isKV=true
-W.YN.$isD0=true
-W.YN.$isa=true
+W.QF.$isKV=true
+W.QF.$isD0=true
+W.QF.$isa=true
 P.HI.$isqh=true
 P.HI.$asqh=[null]
 P.HI.$isa=true
@@ -19973,6 +21056,7 @@
 W.fJ.$isa=true
 W.ew.$isea=true
 W.ew.$isa=true
+L.Pf.$isa=true
 P.mE.$ismE=true
 P.mE.$isa=true
 P.KA.$isKA=true
@@ -19986,11 +21070,11 @@
 P.JI.$isa=true
 H.Uz.$isUz=true
 H.Uz.$isD4=true
-H.Uz.$isQF=true
-H.Uz.$isQF=true
-H.Uz.$isQF=true
-H.Uz.$isQF=true
-H.Uz.$isQF=true
+H.Uz.$isej=true
+H.Uz.$isej=true
+H.Uz.$isej=true
+H.Uz.$isej=true
+H.Uz.$isej=true
 H.Uz.$isa=true
 P.e4.$ise4=true
 P.e4.$isa=true
@@ -20020,8 +21104,8 @@
 P.iP.$isfR=true
 P.iP.$asfR=[null]
 P.iP.$isa=true
-P.fI.$isfI=true
-P.fI.$isa=true
+P.lx.$islx=true
+P.lx.$isa=true
 J.Qc=function(a){if(typeof a=="number")return J.P.prototype
 if(typeof a=="string")return J.O.prototype
 if(a==null)return a
@@ -20060,18 +21144,18 @@
 return J.ks(a)}
 C.OL=new U.EZ()
 C.Gw=new H.SJ()
-C.E3=new J.Q()
+C.l0=new J.Q()
 C.Fm=new J.kn()
 C.yX=new J.Pp()
-C.c1=new J.im()
+C.wq=new J.im()
 C.oD=new J.P()
 C.Kn=new J.O()
 C.lM=new P.by()
-C.mI=new K.Fa()
+C.mI=new K.ndx()
 C.Us=new A.yL()
-C.nJ=new K.ma()
+C.nJ=new K.Hm()
 C.Wj=new P.dp()
-C.za=new A.Mh()
+C.za=new A.jh()
 C.NU=new P.R8()
 C.v8=new P.W5()
 C.kk=Z.aC.prototype
@@ -20079,12 +21163,13 @@
 C.j8=R.i6.prototype
 C.Vy=new A.V3("disassembly-entry")
 C.J0=new A.V3("observatory-element")
+C.Er=new A.V3("script-view")
 C.aM=new A.V3("isolate-summary")
 C.Ig=new A.V3("response-viewer")
-C.nu=new A.V3("function-view")
+C.Uc=new A.V3("function-view")
 C.xW=new A.V3("code-view")
 C.aQ=new A.V3("class-view")
-C.Oy=new A.V3("library-view")
+C.Ob=new A.V3("library-view")
 C.c0=new A.V3("message-viewer")
 C.js=new A.V3("stack-trace")
 C.jF=new A.V3("isolate-list")
@@ -20093,6 +21178,7 @@
 C.bd=new A.V3("observatory-application")
 C.uW=new A.V3("error-view")
 C.HN=new A.V3("json-view")
+C.H8=new A.V3("source-view")
 C.mv=new A.V3("field-view")
 C.Tl=E.Fv.prototype
 C.RT=new P.a6(0)
@@ -20233,7 +21319,7 @@
   hooks.prototypeForTag = prototypeForTagIE;
 }
 C.A3=new P.QM(null)
-C.jZ=Z.vj.prototype
+C.GB=Z.vj.prototype
 C.VZ=new N.Ng("FINER",400)
 C.R5=new N.Ng("FINE",500)
 C.IF=new N.Ng("INFO",800)
@@ -20244,13 +21330,14 @@
   list.fixed$length = true;
   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.xu=I.makeConstantList([43,45,42,47,33,38,60,61,62,63,94,124])
 C.u0=I.makeConstantList(["==","!=","<=",">=","||","&&"])
 C.Me=H.VM(I.makeConstantList([]),[P.Ms])
 C.dn=H.VM(I.makeConstantList([]),[P.Fw])
-C.hU=H.VM(I.makeConstantList([]),[P.X9])
+C.hU=H.VM(I.makeConstantList([]),[P.L9u])
 C.xD=I.makeConstantList([])
 C.Qy=I.makeConstantList(["in","this"])
 C.kg=I.makeConstantList([0,0,24576,1023,65534,34815,65534,18431])
@@ -20266,14 +21353,16 @@
 C.kr=new H.LP(5,{name:1,extends:1,constructor:1,noscript:1,attributes:1},C.pa)
 C.ME=I.makeConstantList(["enumerate"])
 C.va=new H.LP(1,{enumerate:K.ZO},C.ME)
-C.Wp=L.Nh.prototype
+C.Wp=L.BK.prototype
 C.Xg=Q.ih.prototype
 C.t5=W.BH.prototype
 C.k0=V.F1.prototype
-C.Pf=Z.uL.prototype
+C.mk=Z.uL.prototype
 C.xk=A.XP.prototype
-C.GB=A.ir.prototype
+C.Iv=A.ir.prototype
 C.Cc=Q.NQ.prototype
+C.cJ=U.fI.prototype
+C.Ks=X.kK.prototype
 C.bg=X.uw.prototype
 C.PU=new H.GD("dart.core.Object")
 C.nz=new H.GD("dart.core.DateTime")
@@ -20288,6 +21377,7 @@
 C.to=new H.GD("createRuntimeType")
 C.Je=new H.GD("current")
 C.h1=new H.GD("currentHash")
+C.tv=new H.GD("currentHashUri")
 C.Jw=new H.GD("displayValue")
 C.nN=new H.GD("dynamic")
 C.yh=new H.GD("error")
@@ -20296,24 +21386,33 @@
 C.nf=new H.GD("function")
 C.AZ=new H.GD("dart.core.String")
 C.Di=new H.GD("iconClass")
+C.EN=new H.GD("id")
 C.eJ=new H.GD("instruction")
+C.ai=new H.GD("isEmpty")
+C.nZ=new H.GD("isNotEmpty")
 C.Y2=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.Cv=new H.GD("lines")
 C.PC=new H.GD("dart.core.int")
 C.wt=new H.GD("members")
 C.KY=new H.GD("messageType")
 C.YS=new H.GD("name")
 C.OV=new H.GD("noSuchMethod")
 C.Ws=new H.GD("operatingSystem")
+C.X9=new H.GD("paddedLine")
 C.qb=new H.GD("prefix")
 C.Qi=new H.GD("registerCallback")
 C.wH=new H.GD("responses")
 C.ok=new H.GD("dart.core.Null")
 C.md=new H.GD("dart.core.double")
+C.fX=new H.GD("script")
 C.eC=new H.GD("[]=")
+C.hn=new H.GD("source")
 C.kw=new H.GD("trace")
+C.Fh=new H.GD("url")
 C.ls=new H.GD("value")
 C.eR=new H.GD("valueType")
 C.QK=new H.GD("window")
@@ -20327,7 +21426,6 @@
 C.Ti=H.mm('wn')
 C.Mt=new H.Lm(C.Ti,"E",0)
 C.qM=H.mm('F1')
-C.NM=H.mm('Nh')
 C.nY=H.mm('a')
 C.Yc=H.mm('iP')
 C.LN=H.mm('Be')
@@ -20337,7 +21435,9 @@
 C.Op=H.mm('G8')
 C.xF=H.mm('NQ')
 C.b4=H.mm('ih')
+C.ced=H.mm('kK')
 C.hG=H.mm('ir')
+C.aj=H.mm('fI')
 C.dA=H.mm('Ms')
 C.mo=H.mm('Fv')
 C.O4=H.mm('double')
@@ -20359,6 +21459,7 @@
 C.CS=H.mm('vm')
 C.XK=H.mm('Gk')
 C.GX=H.mm('c8')
+C.WIe=H.mm('BK')
 C.vB=J.is.prototype
 C.dy=new P.z0(!1)
 C.ol=W.K5.prototype
@@ -20400,11 +21501,11 @@
 J.Co=function(a){return J.RE(a).gcC(a)}
 J.DA=function(a){return J.RE(a).goc(a)}
 J.DB=function(a,b){return J.w1(a).Ay(a,b)}
+J.DF=function(a,b){return J.RE(a).soc(a,b)}
 J.Dz=function(a,b){return J.rY(a).j(a,b)}
 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)}
-J.Eh=function(a,b){return J.Wx(a).O(a,b)}
 J.F8=function(a){return J.RE(a).gjO(a)}
 J.FN=function(a){return J.U6(a).gl0(a)}
 J.FW=function(a,b){if(typeof a=="number"&&typeof b=="number")return a/b
@@ -20412,7 +21513,6 @@
 J.GJ=function(a,b,c,d){return J.RE(a).Y9(a,b,c,d)}
 J.GK=function(a){return J.RE(a).glc(a)}
 J.GP=function(a){return J.w1(a).gA(a)}
-J.GS=function(a,b,c,d){return J.RE(a).rJ(a,b,c,d)}
 J.GW=function(a){return J.RE(a).gn4(a)}
 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
@@ -20453,6 +21553,7 @@
 J.UU=function(a,b){return J.U6(a).u8(a,b)}
 J.UW=function(a){return J.RE(a).gLU(a)}
 J.UX=function(a){return J.RE(a).gmW(a)}
+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.Vm=function(a){return J.RE(a).gP(a)}
@@ -20472,6 +21573,7 @@
 J.bh=function(a,b,c){return J.rY(a).JT(a,b,c)}
 J.bi=function(a,b){return J.w1(a).h(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.co=function(a,b){return J.rY(a).nC(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)}
@@ -20515,6 +21617,7 @@
 J.uH=function(a,b){return J.rY(a).Fr(a,b)}
 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.vX=function(a){return J.w1(a).wg(a)}
 J.vo=function(a,b){return J.w1(a).ev(a,b)}
 J.w8=function(a){return J.RE(a).gkc(a)}
@@ -20531,8 +21634,8 @@
 J.z2=function(a){return J.RE(a).gG1(a)}
 J.zZ=function(a,b){return J.RE(a).Yv(a,b)}
 J.zj=function(a){return J.RE(a).gvH(a)}
-$.Dq=["Ay","BN","BT","Ba","C","C0","C8","Ch","D","D3","D6","Dh","E","Ec","F","FH","Fr","GB","HG","Hn","Id","Ih","Im","Is","J","J3","JP","JT","JV","Ja","Jk","Kb","LV","Md","Mi","Mu","Nj","Nz","O","On","PM","Pa","Pk","Pv","R3","R4","RB","RR","Rz","SZ","T","T2","TH","TP","TW","Tc","Td","U","UD","UH","UZ","Uc","V","V1","Vr","Vy","W","W3","W4","WO","Wt","Wz","XG","XU","Xl","Y9","YU","YW","Ys","Yv","Z","Z1","Z2","ZB","ZF","ZL","ZP","Zv","aC","aN","aq","bA","bS","br","bu","cO","cn","d0","dR","dd","du","eR","ea","er","es","ev","ez","f6","fd","fj","fk","fm","g","gA","gAQ","gB","gBb","gCd","gCj","gDD","gDg","gE8","gEX","gEr","gF1","gFJ","gFT","gFV","gFe","gG0","gG1","gG3","gGL","gHs","gI","gIi","gJS","gJf","gKE","gKM","gKV","gLA","gLU","gLm","gM0","gMB","gMj","gN","gNI","gP","gP1","gP2","gPp","gPu","gPw","gPy","gQ0","gQG","gQW","gQg","gQq","gRu","gT8","gTM","gTn","gTq","gUQ","gUV","gVA","gVB","gVl","gXB","gXf","gXt","gZw","gai","gbP","gbx","gcC","geT","geb","gey","gfY","ghO","ghr","gi0","giC","giI","giO","gig","gjL","gjO","gjU","gjb","gkU","gkc","gkf","gkp","gl0","glc","gmW","gmm","gn4","goc","gor","gpQ","gpo","gq6","gqC","gqh","gql","gr3","gr9","grK","grZ","gt0","gtD","gtH","gtN","gtT","guD","gvH","gvc","gvt","gxj","gxr","gyT","gys","gzP","gzZ","h","h8","hc","i","i4","iA","iM","iw","j","jT","jx","kO","l5","l8","lj","m","mK","mv","n","nB","nC","nH","nP","ni","oB","oW","od","oo","oq","pD","pZ","pl","pr","qZ","r6","rJ","rS","sAQ","sB","sF1","sFJ","sFT","sG1","sIt","sMj","sNI","sP","sP2","sPw","sPy","sQG","sQq","sRu","sTn","sTq","sVA","sVB","sXB","sXf","sZw","sa4","sai","scC","seb","shO","si0","siI","sig","sjO","skc","skf","soc","sql","sr9","st0","stD","stH","stN","stT","svt","sxj","sxr","szZ","t","tZ","tg","tt","u","u5","u8","uG","vs","w3","wE","wL","wR","wg","x3","xI","xe","y0","yC","yc","ym","yn","yq","yu","yx","yy","z2","zV"]
-$.Au=[C.qM,V.F1,{created:V.fv},C.NM,L.Nh,{created:L.rJ},C.LN,F.Be,{created:F.Fe},C.Qa,L.u7,{created:L.ip},C.xS,P.UZ,{},C.PT,M.CX,{created:M.SP},C.Op,P.G8,{},C.xF,Q.NQ,{created:Q.Zo},C.b4,Q.ih,{created:Q.BW},C.hG,A.ir,{created:A.oa},C.mo,E.Fv,{created:E.AH},C.xE,Z.aC,{created:Z.zg},C.vuj,X.uw,{created:X.bV},C.Tq,Z.vj,{created:Z.un},C.CT,D.St,{created:D.N5},C.Q4,Z.uL,{created:Z.Hx},C.yg,F.I3,{created:F.TW},C.XU,R.i6,{created:R.IT},C.Bm,A.XP,{created:A.XL},C.Sa,N.Ds,{created:N.p7},C.XK,A.Gk,{created:A.cY}]
+$.Dq=["Ay","BN","BT","Ba","Bf","C","C0","C8","Ch","D","D3","D6","Dh","E","Ec","F","FH","Fr","GB","HG","Hn","Id","Ih","Im","Is","J","J3","JP","JT","JV","Ja","Jk","Kb","LV","Md","Mi","Mu","Nj","Nz","O","On","PM","Pa","Pk","Pv","R3","R4","RB","RR","Rz","SS","SZ","T","T2","TP","TW","Tc","Td","Tp","U","UD","UH","UZ","Uc","V","V1","Vr","Vy","W","W3","W4","WL","WO","WZ","Wt","Wz","XG","XU","Xl","Y9","YU","YW","Ys","Yv","Z","Z1","Z2","ZB","ZL","ZP","Zv","aC","aN","aq","bA","bS","br","bu","cO","cn","ct","d0","dd","du","eR","ea","er","es","ev","ez","f6","fd","fj","fk","fm","g","gA","gB","gBb","gCd","gCj","gDD","gDg","gE8","gEX","gEr","gF1","gFF","gFJ","gFT","gFV","gFe","gG0","gG1","gG3","gGL","gHX","gHs","gI","gIi","gJS","gJf","gKE","gKM","gKV","gLA","gLU","gLm","gM0","gMB","gMj","gN","gNI","gNl","gO3","gP","gP1","gPp","gPu","gPw","gPy","gQ0","gQG","gQW","gQg","gQq","gRu","gT8","gTM","gTn","gTq","gUQ","gUV","gUy","gUz","gVB","gVl","gXB","gXt","gZw","gai","gbP","gbx","gcC","geT","geb","gey","gfY","ghO","ghm","ghr","gi0","giC","giI","giO","gig","gjL","gjO","gjU","gjb","gkU","gkc","gkf","gkp","gl0","gl7","glc","gmW","gmm","gn4","goc","gor","gpQ","gpo","gq6","gqC","gqh","gql","gr3","gr9","grK","grZ","gt0","gtD","gtN","gtT","guD","gvH","gvX","gvc","gvt","gxj","gxr","gyT","gys","gzP","gzZ","gzh","h","h8","hV","hc","i","i3","i4","iA","iM","iw","j","jT","jx","kO","l5","l8","lj","m","mK","mv","n","nB","nC","nH","nP","ni","oB","oW","od","oo","oq","pZ","pl","pr","qZ","r6","rJ","rS","sB","sF1","sFF","sFJ","sFT","sG1","sHX","sIt","sLA","sMj","sNI","sNl","sO3","sP","sPw","sPy","sQG","sQq","sRu","sTn","sTq","sUy","sUz","sVB","sXB","sZw","sa4","sai","scC","seb","sfY","shO","shm","si0","siI","sig","sjO","skc","skf","sl7","soc","sql","sr9","st0","stD","stN","stT","svX","svt","sxj","sxr","szZ","szh","t","tZ","tg","tt","u","u5","u8","uG","vs","w3","wE","wL","wR","wg","x3","xe","y0","yC","yc","ym","yn","yq","yu","yx","yy","z2","zV"]
+$.Au=[C.qM,V.F1,{created:V.fv},C.LN,F.Be,{created:F.Fe},C.Qa,L.u7,{created:L.ip},C.xS,P.UZ,{},C.PT,M.CX,{created:M.SP},C.Op,P.G8,{},C.xF,Q.NQ,{created:Q.Zo},C.b4,Q.ih,{created:Q.BW},C.ced,X.kK,{created:X.HO},C.hG,A.ir,{created:A.oa},C.aj,U.fI,{created:U.Ry},C.mo,E.Fv,{created:E.AH},C.xE,Z.aC,{created:Z.zg},C.vuj,X.uw,{created:X.bV},C.Tq,Z.vj,{created:Z.un},C.CT,D.St,{created:D.N5},C.Q4,Z.uL,{created:Z.Hx},C.yg,F.I3,{created:F.TW},C.XU,R.i6,{created:R.IT},C.Bm,A.XP,{created:A.XL},C.Sa,N.Ds,{created:N.p7},C.XK,A.Gk,{created:A.cY},C.WIe,L.BK,{created:L.rJ}]
 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})
@@ -20586,6 +21689,7 @@
 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.w12().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)
@@ -20619,7 +21723,7 @@
 return z.t(z,y)})
 I.$lazy($,"_mangledNameField","AU","av",function(){return new M.w13().call$0()})
 I.$lazy($,"_logger","Kp","IS",function(){return N.Jx("polymer_expressions")})
-I.$lazy($,"_BINARY_OPERATORS","tB","bF",function(){return H.B7(["+",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(),"|",new K.w7()],P.L5(null,null,null,null,null))})
+I.$lazy($,"_BINARY_OPERATORS","AM","e6",function(){return H.B7(["+",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(),"|",new K.w7()],P.L5(null,null,null,null,null))})
 I.$lazy($,"_UNARY_OPERATORS","ju","YG",function(){return H.B7(["+",new K.w9(),"-",new K.w10(),"!",new K.w11()],P.L5(null,null,null,null,null))})
 I.$lazy($,"_checkboxEventType","S8","FF",function(){return new M.Uf().call$0()})
 I.$lazy($,"_contentsOwner","mn","LQ",function(){var z=new P.kM(null)
@@ -20632,7 +21736,7 @@
 return z})
 
 init.functionAliases={}
-init.metadata=[P.a,C.wK,C.wa,C.WX,C.Mt,C.wW,P.uq,"name",J.O,Z.aC,F.Be,R.i6,W.K5,E.Fv,F.I3,A.Gk,N.Ds,L.u7,D.St,Z.vj,M.CX,L.Nh,Q.ih,V.F1,Z.uL,[K.Ae,3],"index",J.im,"value",3,Q.NQ,X.uw,P.L8,C.nJ,C.Us,,Z.Vf,F.tu,C.mI,J.kn,"r","e",W.ea,"detail","target",W.KV,R.Vc,[P.L8,P.wv,P.RS],[J.Q,H.Zk],"methodOwner",P.NL,[J.Q,P.RY],"fieldOwner",[P.L8,P.wv,P.RY],[P.L8,P.wv,P.QF],[P.L8,P.wv,P.NL],P.vr,"fieldName",P.wv,"arg",H.Uz,[J.Q,P.vr],P.Ms,"memberName","positionalArguments",J.Q,"namedArguments",[P.L8,P.wv,null],[J.Q,P.Ms],"owner",[J.Q,P.Fw],[J.Q,P.X9],H.Un,"key",P.QF,H.Tp,"tv","i",E.WZ,F.pv,A.Vfx,N.Dsd,D.tuj,"oldValue",Z.Vct,M.D13,"m",[J.Q,P.L8],"l","objectId","cid","isolateId",L.mL,Z.Xf,5,"newValue",4,[P.cX,1],[P.cX,2],2,1,"v",X.WZq,];$=null
+init.metadata=[P.a,C.wK,C.wa,C.WX,C.Mt,C.wW,P.uq,"name",J.O,Z.aC,F.Be,R.i6,W.K5,E.Fv,F.I3,A.Gk,N.Ds,L.u7,D.St,Z.vj,M.CX,L.BK,Q.ih,V.F1,Z.uL,[K.Ae,3],"index",J.im,"value",3,Q.NQ,U.fI,X.kK,X.uw,P.L8,C.nJ,C.Us,,Z.Vf,F.tu,C.mI,J.kn,"r","e",W.ea,"detail","target",W.KV,R.Vc,[P.L8,P.wv,P.RS],[J.Q,H.Zk],"methodOwner",P.NL,[J.Q,P.RY],"fieldOwner",[P.L8,P.wv,P.RY],[P.L8,P.wv,P.ej],[P.L8,P.wv,P.NL],P.vr,"fieldName",P.wv,"arg",H.Uz,[J.Q,P.vr],P.Ms,"memberName","positionalArguments",J.Q,"namedArguments",[P.L8,P.wv,null],[J.Q,P.Ms],"owner",[J.Q,P.Fw],[J.Q,P.L9u],H.Un,"key",P.ej,H.Tp,"tv","i",E.WZ,F.pv,A.Vfx,N.Dsd,D.tuj,"oldValue",Z.Vct,M.D13,"m",[J.Q,P.L8],P.iD,"l","objectId","cid","isolateId",[J.Q,L.Zw],L.mL,Z.Xf,5,"newValue",4,[P.cX,1],[P.cX,2],2,1,"v","o",U.WZq,L.Pf,X.pva,X.cda,];$=null
 I = I.$finishIsolateConstructor(I)
 $=new I()
 function convertToFastObject(properties) {
@@ -20876,6 +21980,7 @@
 $desc=$collectedClasses.i3
 if($desc instanceof Array)$desc=$desc[1]
 i3.prototype=$desc
+i3.prototype.gO3=function(receiver){return receiver.url}
 function it(){}it.builtin$cls="it"
 if(!"name" in it)it.name="it"
 $desc=$collectedClasses.it
@@ -20992,11 +22097,11 @@
 $desc=$collectedClasses.Wy
 if($desc instanceof Array)$desc=$desc[1]
 Wy.prototype=$desc
-function YN(){}YN.builtin$cls="YN"
-if(!"name" in YN)YN.name="YN"
-$desc=$collectedClasses.YN
+function QF(){}QF.builtin$cls="QF"
+if(!"name" in QF)QF.name="QF"
+$desc=$collectedClasses.QF
 if($desc instanceof Array)$desc=$desc[1]
-YN.prototype=$desc
+QF.prototype=$desc
 function bA(){}bA.builtin$cls="bA"
 if(!"name" in bA)bA.name="bA"
 $desc=$collectedClasses.bA
@@ -21014,12 +22119,12 @@
 rz.prototype=$desc
 rz.prototype.gG1=function(receiver){return receiver.message}
 rz.prototype.goc=function(receiver){return receiver.name}
-function BK(){}BK.builtin$cls="BK"
-if(!"name" in BK)BK.name="BK"
-$desc=$collectedClasses.BK
+function Nh(){}Nh.builtin$cls="Nh"
+if(!"name" in Nh)Nh.name="Nh"
+$desc=$collectedClasses.Nh
 if($desc instanceof Array)$desc=$desc[1]
-BK.prototype=$desc
-BK.prototype.gG1=function(receiver){return receiver.message}
+Nh.prototype=$desc
+Nh.prototype.gG1=function(receiver){return receiver.message}
 function wj(){}wj.builtin$cls="wj"
 if(!"name" in wj)wj.name="wj"
 $desc=$collectedClasses.wj
@@ -21042,6 +22147,7 @@
 Fs.prototype.goc=function(receiver){return receiver.name}
 Fs.prototype.soc=function(receiver,v){return receiver.name=v}
 Fs.prototype.gLA=function(receiver){return receiver.src}
+Fs.prototype.sLA=function(receiver,v){return receiver.src=v}
 Fs.prototype.gr9=function(receiver){return receiver.type}
 Fs.prototype.sr9=function(receiver,v){return receiver.type=v}
 function SX(){}SX.builtin$cls="SX"
@@ -21167,6 +22273,7 @@
 tX.prototype.goc=function(receiver){return receiver.name}
 tX.prototype.soc=function(receiver,v){return receiver.name=v}
 tX.prototype.gLA=function(receiver){return receiver.src}
+tX.prototype.sLA=function(receiver,v){return receiver.src=v}
 function Sg(){}Sg.builtin$cls="Sg"
 if(!"name" in Sg)Sg.name="Sg"
 $desc=$collectedClasses.Sg
@@ -21178,6 +22285,7 @@
 if($desc instanceof Array)$desc=$desc[1]
 pA.prototype=$desc
 pA.prototype.gLA=function(receiver){return receiver.src}
+pA.prototype.sLA=function(receiver,v){return receiver.src=v}
 function Mi(){}Mi.builtin$cls="Mi"
 if(!"name" in Mi)Mi.name="Mi"
 $desc=$collectedClasses.Mi
@@ -21190,6 +22298,7 @@
 Mi.prototype.goc=function(receiver){return receiver.name}
 Mi.prototype.soc=function(receiver,v){return receiver.name=v}
 Mi.prototype.gLA=function(receiver){return receiver.src}
+Mi.prototype.sLA=function(receiver,v){return receiver.src=v}
 Mi.prototype.gr9=function(receiver){return receiver.type}
 Mi.prototype.sr9=function(receiver,v){return receiver.type=v}
 Mi.prototype.gP=function(receiver){return receiver.value}
@@ -21258,6 +22367,7 @@
 El.prototype=$desc
 El.prototype.gkc=function(receiver){return receiver.error}
 El.prototype.gLA=function(receiver){return receiver.src}
+El.prototype.sLA=function(receiver,v){return receiver.src=v}
 function zm(){}zm.builtin$cls="zm"
 if(!"name" in zm)zm.name="zm"
 $desc=$collectedClasses.zm
@@ -21411,11 +22521,11 @@
 G7.prototype.soc=function(receiver,v){return receiver.name=v}
 G7.prototype.gr9=function(receiver){return receiver.type}
 G7.prototype.sr9=function(receiver,v){return receiver.type=v}
-function wq(){}wq.builtin$cls="wq"
-if(!"name" in wq)wq.name="wq"
-$desc=$collectedClasses.wq
+function kl(){}kl.builtin$cls="kl"
+if(!"name" in kl)kl.name="kl"
+$desc=$collectedClasses.kl
 if($desc instanceof Array)$desc=$desc[1]
-wq.prototype=$desc
+kl.prototype=$desc
 function Ql(){}Ql.builtin$cls="Ql"
 if(!"name" in Ql)Ql.name="Ql"
 $desc=$collectedClasses.Ql
@@ -21505,6 +22615,7 @@
 $desc=$collectedClasses.bX
 if($desc instanceof Array)$desc=$desc[1]
 bX.prototype=$desc
+bX.prototype.gO3=function(receiver){return receiver.url}
 function BL(){}BL.builtin$cls="BL"
 if(!"name" in BL)BL.name="BL"
 $desc=$collectedClasses.BL
@@ -21526,6 +22637,7 @@
 if($desc instanceof Array)$desc=$desc[1]
 j2.prototype=$desc
 j2.prototype.gLA=function(receiver){return receiver.src}
+j2.prototype.sLA=function(receiver,v){return receiver.src=v}
 j2.prototype.gr9=function(receiver){return receiver.type}
 j2.prototype.sr9=function(receiver,v){return receiver.type=v}
 function yz(){}yz.builtin$cls="yz"
@@ -21565,6 +22677,7 @@
 if($desc instanceof Array)$desc=$desc[1]
 QR.prototype=$desc
 QR.prototype.gLA=function(receiver){return receiver.src}
+QR.prototype.sLA=function(receiver,v){return receiver.src=v}
 QR.prototype.gr9=function(receiver){return receiver.type}
 QR.prototype.sr9=function(receiver,v){return receiver.type=v}
 function Cp(){}Cp.builtin$cls="Cp"
@@ -21603,6 +22716,7 @@
 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}
 function fq(){}fq.builtin$cls="fq"
 if(!"name" in fq)fq.name="fq"
 $desc=$collectedClasses.fq
@@ -21630,11 +22744,11 @@
 $desc=$collectedClasses.Tb
 if($desc instanceof Array)$desc=$desc[1]
 Tb.prototype=$desc
-function Iv(){}Iv.builtin$cls="Iv"
-if(!"name" in Iv)Iv.name="Iv"
-$desc=$collectedClasses.Iv
+function tV(){}tV.builtin$cls="tV"
+if(!"name" in tV)tV.name="tV"
+$desc=$collectedClasses.tV
 if($desc instanceof Array)$desc=$desc[1]
-Iv.prototype=$desc
+tV.prototype=$desc
 function BT(){}BT.builtin$cls="BT"
 if(!"name" in BT)BT.name="BT"
 $desc=$collectedClasses.BT
@@ -21683,7 +22797,9 @@
 if($desc instanceof Array)$desc=$desc[1]
 RH.prototype=$desc
 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}
+RH.prototype.sLA=function(receiver,v){return receiver.src=v}
 function pU(){}pU.builtin$cls="pU"
 if(!"name" in pU)pU.name="pU"
 $desc=$collectedClasses.pU
@@ -21755,11 +22871,11 @@
 $desc=$collectedClasses.kc
 if($desc instanceof Array)$desc=$desc[1]
 kc.prototype=$desc
-function ij(){}ij.builtin$cls="ij"
-if(!"name" in ij)ij.name="ij"
-$desc=$collectedClasses.ij
+function Eh(){}Eh.builtin$cls="Eh"
+if(!"name" in Eh)Eh.name="Eh"
+$desc=$collectedClasses.Eh
 if($desc instanceof Array)$desc=$desc[1]
-ij.prototype=$desc
+Eh.prototype=$desc
 function ty(){}ty.builtin$cls="ty"
 if(!"name" in ty)ty.name="ty"
 $desc=$collectedClasses.ty
@@ -21805,13 +22921,13 @@
 $desc=$collectedClasses.yK
 if($desc instanceof Array)$desc=$desc[1]
 yK.prototype=$desc
-function Y0(){}Y0.builtin$cls="Y0"
-if(!"name" in Y0)Y0.name="Y0"
-$desc=$collectedClasses.Y0
+function HB(){}HB.builtin$cls="HB"
+if(!"name" in HB)HB.name="HB"
+$desc=$collectedClasses.HB
 if($desc instanceof Array)$desc=$desc[1]
-Y0.prototype=$desc
-Y0.prototype.gN=function(receiver){return receiver.target}
-Y0.prototype.gLU=function(receiver){return receiver.href}
+HB.prototype=$desc
+HB.prototype.gN=function(receiver){return receiver.target}
+HB.prototype.gLU=function(receiver){return receiver.href}
 function ZJ(){}ZJ.builtin$cls="ZJ"
 if(!"name" in ZJ)ZJ.name="ZJ"
 $desc=$collectedClasses.ZJ
@@ -21828,11 +22944,11 @@
 $desc=$collectedClasses.eZ
 if($desc instanceof Array)$desc=$desc[1]
 eZ.prototype=$desc
-function Ak(){}Ak.builtin$cls="Ak"
-if(!"name" in Ak)Ak.name="Ak"
-$desc=$collectedClasses.Ak
+function Fl(){}Fl.builtin$cls="Fl"
+if(!"name" in Fl)Fl.name="Fl"
+$desc=$collectedClasses.Fl
 if($desc instanceof Array)$desc=$desc[1]
-Ak.prototype=$desc
+Fl.prototype=$desc
 function y5(){}y5.builtin$cls="y5"
 if(!"name" in y5)y5.name="y5"
 $desc=$collectedClasses.y5
@@ -21983,11 +23099,11 @@
 $desc=$collectedClasses.ca
 if($desc instanceof Array)$desc=$desc[1]
 ca.prototype=$desc
-function kK(){}kK.builtin$cls="kK"
-if(!"name" in kK)kK.name="kK"
-$desc=$collectedClasses.kK
+function xX(){}xX.builtin$cls="xX"
+if(!"name" in xX)xX.name="xX"
+$desc=$collectedClasses.xX
 if($desc instanceof Array)$desc=$desc[1]
-kK.prototype=$desc
+xX.prototype=$desc
 function eW(){}eW.builtin$cls="eW"
 if(!"name" in eW)eW.name="eW"
 $desc=$collectedClasses.eW
@@ -22152,13 +23268,13 @@
 $desc=$collectedClasses.MT
 if($desc instanceof Array)$desc=$desc[1]
 MT.prototype=$desc
-function Rk(){}Rk.builtin$cls="Rk"
-if(!"name" in Rk)Rk.name="Rk"
-$desc=$collectedClasses.Rk
+function xN(){}xN.builtin$cls="xN"
+if(!"name" in xN)xN.name="xN"
+$desc=$collectedClasses.xN
 if($desc instanceof Array)$desc=$desc[1]
-Rk.prototype=$desc
-Rk.prototype.gbP=function(receiver){return receiver.method}
-Rk.prototype.gLU=function(receiver){return receiver.href}
+xN.prototype=$desc
+xN.prototype.gbP=function(receiver){return receiver.method}
+xN.prototype.gLU=function(receiver){return receiver.href}
 function Eo(){}Eo.builtin$cls="Eo"
 if(!"name" in Eo)Eo.name="Eo"
 $desc=$collectedClasses.Eo
@@ -22221,11 +23337,11 @@
 $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 k2(){}k2.builtin$cls="k2"
+if(!"name" in k2)k2.name="k2"
+$desc=$collectedClasses.k2
 if($desc instanceof Array)$desc=$desc[1]
-uY.prototype=$desc
+k2.prototype=$desc
 function yR(){}yR.builtin$cls="yR"
 if(!"name" in yR)yR.name="yR"
 $desc=$collectedClasses.yR
@@ -22338,11 +23454,11 @@
 $desc=$collectedClasses.ZX
 if($desc instanceof Array)$desc=$desc[1]
 ZX.prototype=$desc
-function hn(){}hn.builtin$cls="hn"
-if(!"name" in hn)hn.name="hn"
-$desc=$collectedClasses.hn
+function ycx(){}ycx.builtin$cls="ycx"
+if(!"name" in ycx)ycx.name="ycx"
+$desc=$collectedClasses.ycx
 if($desc instanceof Array)$desc=$desc[1]
-hn.prototype=$desc
+ycx.prototype=$desc
 function nE(){}nE.builtin$cls="nE"
 if(!"name" in nE)nE.name="nE"
 $desc=$collectedClasses.nE
@@ -22484,8 +23600,8 @@
 $desc=$collectedClasses.RA
 if($desc instanceof Array)$desc=$desc[1]
 RA.prototype=$desc
-function IY(F1,i3,G1){this.F1=F1
-this.i3=i3
+function IY(F1,xh,G1){this.F1=F1
+this.xh=xh
 this.G1=G1}IY.builtin$cls="IY"
 if(!"name" in IY)IY.name="IY"
 $desc=$collectedClasses.IY
@@ -22910,10 +24026,10 @@
 $desc=$collectedClasses.tQ
 if($desc instanceof Array)$desc=$desc[1]
 tQ.prototype=$desc
-function aC(FJ,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.FJ=FJ
+function aC(FJ,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.FJ=FJ
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -22939,10 +24055,10 @@
 $desc=$collectedClasses.Vf
 if($desc instanceof Array)$desc=$desc[1]
 Vf.prototype=$desc
-function Be(Zw,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Zw=Zw
+function Be(Zw,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Zw=Zw
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -22968,12 +24084,12 @@
 $desc=$collectedClasses.tu
 if($desc instanceof Array)$desc=$desc[1]
 tu.prototype=$desc
-function i6(Xf,VA,P2,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Xf=Xf
-this.VA=VA
-this.P2=P2
+function i6(zh,HX,Uy,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.zh=zh
+this.HX=HX
+this.Uy=Uy
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -22990,18 +24106,18 @@
 $desc=$collectedClasses.i6
 if($desc instanceof Array)$desc=$desc[1]
 i6.prototype=$desc
-i6.prototype.gXf=function(receiver){return receiver.Xf}
-i6.prototype.gXf.$reflectable=1
-i6.prototype.sXf=function(receiver,v){return receiver.Xf=v}
-i6.prototype.sXf.$reflectable=1
-i6.prototype.gVA=function(receiver){return receiver.VA}
-i6.prototype.gVA.$reflectable=1
-i6.prototype.sVA=function(receiver,v){return receiver.VA=v}
-i6.prototype.sVA.$reflectable=1
-i6.prototype.gP2=function(receiver){return receiver.P2}
-i6.prototype.gP2.$reflectable=1
-i6.prototype.sP2=function(receiver,v){return receiver.P2=v}
-i6.prototype.sP2.$reflectable=1
+i6.prototype.gzh=function(receiver){return receiver.zh}
+i6.prototype.gzh.$reflectable=1
+i6.prototype.szh=function(receiver,v){return receiver.zh=v}
+i6.prototype.szh.$reflectable=1
+i6.prototype.gHX=function(receiver){return receiver.HX}
+i6.prototype.gHX.$reflectable=1
+i6.prototype.sHX=function(receiver,v){return receiver.HX=v}
+i6.prototype.sHX.$reflectable=1
+i6.prototype.gUy=function(receiver){return receiver.Uy}
+i6.prototype.gUy.$reflectable=1
+i6.prototype.sUy=function(receiver,v){return receiver.Uy=v}
+i6.prototype.sUy.$reflectable=1
 function Vc(){}Vc.builtin$cls="Vc"
 if(!"name" in Vc)Vc.name="Vc"
 $desc=$collectedClasses.Vc
@@ -23083,12 +24199,12 @@
 $desc=$collectedClasses.rR
 if($desc instanceof Array)$desc=$desc[1]
 rR.prototype=$desc
-function AM(Kw,xZ){this.Kw=Kw
-this.xZ=xZ}AM.builtin$cls="AM"
-if(!"name" in AM)AM.name="AM"
-$desc=$collectedClasses.AM
+function vZ(Kw,xZ){this.Kw=Kw
+this.xZ=xZ}vZ.builtin$cls="vZ"
+if(!"name" in vZ)vZ.name="vZ"
+$desc=$collectedClasses.vZ
 if($desc instanceof Array)$desc=$desc[1]
-AM.prototype=$desc
+vZ.prototype=$desc
 function d5(Kw,xZ){this.Kw=Kw
 this.xZ=xZ}d5.builtin$cls="d5"
 if(!"name" in d5)d5.name="d5"
@@ -23277,11 +24393,11 @@
 $desc=$collectedClasses.bl
 if($desc instanceof Array)$desc=$desc[1]
 bl.prototype=$desc
-function Ef(a){this.a=a}Ef.builtin$cls="Ef"
-if(!"name" in Ef)Ef.name="Ef"
-$desc=$collectedClasses.Ef
+function tB(a){this.a=a}tB.builtin$cls="tB"
+if(!"name" in tB)tB.name="tB"
+$desc=$collectedClasses.tB
 if($desc instanceof Array)$desc=$desc[1]
-Ef.prototype=$desc
+tB.prototype=$desc
 function Oo(){}Oo.builtin$cls="Oo"
 if(!"name" in Oo)Oo.name="Oo"
 $desc=$collectedClasses.Oo
@@ -23297,7 +24413,7 @@
 $desc=$collectedClasses.Ax
 if($desc instanceof Array)$desc=$desc[1]
 Ax.prototype=$desc
-function Wf(WL,Tx,H8,Ht,pz,le,qN,jd,tB,b0,FU,T1,Ly,M2,uA,Db,Ok,qm,UF,nz,If){this.WL=WL
+function Wf(Cr,Tx,H8,Ht,pz,le,qN,jd,tB,b0,FU,T1,Ly,M2,uA,Db,Ok,qm,UF,nz,If){this.Cr=Cr
 this.Tx=Tx
 this.H8=H8
 this.Ht=Ht
@@ -23322,8 +24438,8 @@
 $desc=$collectedClasses.Wf
 if($desc instanceof Array)$desc=$desc[1]
 Wf.prototype=$desc
-Wf.prototype.gWL=function(){return this.WL}
-Wf.prototype.gWL.$reflectable=1
+Wf.prototype.gCr=function(){return this.Cr}
+Wf.prototype.gCr.$reflectable=1
 Wf.prototype.gTx=function(){return this.Tx}
 Wf.prototype.gTx.$reflectable=1
 Wf.prototype.gH8=function(){return this.H8}
@@ -23431,7 +24547,7 @@
 $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,Cr,If){this.dl=dl
+function Zk(dl,Yq,lT,hB,Fo,xV,qx,nz,le,G6,H3,If){this.dl=dl
 this.Yq=Yq
 this.lT=lT
 this.hB=hB
@@ -23441,7 +24557,7 @@
 this.nz=nz
 this.le=le
 this.G6=G6
-this.Cr=Cr
+this.H3=H3
 this.If=If}Zk.builtin$cls="Zk"
 if(!"name" in Zk)Zk.name="Zk"
 $desc=$collectedClasses.Zk
@@ -23459,14 +24575,14 @@
 if($desc instanceof Array)$desc=$desc[1]
 fu.prototype=$desc
 fu.prototype.gh7=function(){return this.h7}
-function ng(WL,CM,If){this.WL=WL
+function ng(Cr,CM,If){this.Cr=Cr
 this.CM=CM
 this.If=If}ng.builtin$cls="ng"
 if(!"name" in ng)ng.name="ng"
 $desc=$collectedClasses.ng
 if($desc instanceof Array)$desc=$desc[1]
 ng.prototype=$desc
-ng.prototype.gWL=function(){return this.WL}
+ng.prototype.gCr=function(){return this.Cr}
 function Ar(d9,o3,yA,zM,h7){this.d9=d9
 this.o3=o3
 this.yA=yA
@@ -24000,13 +25116,13 @@
 $desc=$collectedClasses.ez
 if($desc instanceof Array)$desc=$desc[1]
 ez.prototype=$desc
-function fI(LD){this.LD=LD}fI.builtin$cls="fI"
-if(!"name" in fI)fI.name="fI"
-$desc=$collectedClasses.fI
+function lx(LD){this.LD=LD}lx.builtin$cls="lx"
+if(!"name" in lx)lx.name="lx"
+$desc=$collectedClasses.lx
 if($desc instanceof Array)$desc=$desc[1]
-fI.prototype=$desc
-fI.prototype.gLD=function(){return this.LD}
-fI.prototype.sLD=function(v){return this.LD=v}
+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"
 if(!"name" in LV)LV.name="LV"
@@ -24591,18 +25707,33 @@
 $desc=$collectedClasses.z0
 if($desc instanceof Array)$desc=$desc[1]
 z0.prototype=$desc
-function Vx(){}Vx.builtin$cls="Vx"
-if(!"name" in Vx)Vx.name="Vx"
-$desc=$collectedClasses.Vx
+function E3(){}E3.builtin$cls="E3"
+if(!"name" in E3)E3.name="E3"
+$desc=$collectedClasses.E3
 if($desc instanceof Array)$desc=$desc[1]
-Vx.prototype=$desc
-function Rw(WF,An,EN){this.WF=WF
+E3.prototype=$desc
+function Rw(vn,An,EN){this.vn=vn
 this.An=An
 this.EN=EN}Rw.builtin$cls="Rw"
 if(!"name" in Rw)Rw.name="Rw"
 $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,Hu,iU,VN){this.lH=lH
+this.aS=aS
+this.rU=rU
+this.Hu=Hu
+this.iU=iU
+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 h0(a){this.a=a}h0.builtin$cls="h0"
 if(!"name" in h0)h0.name="h0"
 $desc=$collectedClasses.h0
@@ -24767,11 +25898,11 @@
 $desc=$collectedClasses.cX
 if($desc instanceof Array)$desc=$desc[1]
 cX.prototype=$desc
-function Fl(){}Fl.builtin$cls="Fl"
-if(!"name" in Fl)Fl.name="Fl"
-$desc=$collectedClasses.Fl
+function eL(){}eL.builtin$cls="eL"
+if(!"name" in eL)eL.name="eL"
+$desc=$collectedClasses.eL
 if($desc instanceof Array)$desc=$desc[1]
-Fl.prototype=$desc
+eL.prototype=$desc
 function L8(){}L8.builtin$cls="L8"
 if(!"name" in L8)L8.name="L8"
 $desc=$collectedClasses.L8
@@ -24893,6 +26024,11 @@
 $desc=$collectedClasses.XZ
 if($desc instanceof Array)$desc=$desc[1]
 XZ.prototype=$desc
+function qz(a){this.a=a}qz.builtin$cls="qz"
+if(!"name" in qz)qz.name="qz"
+$desc=$collectedClasses.qz
+if($desc instanceof Array)$desc=$desc[1]
+qz.prototype=$desc
 function hQ(){}hQ.builtin$cls="hQ"
 if(!"name" in hQ)hQ.name="hQ"
 $desc=$collectedClasses.hQ
@@ -24924,6 +26060,11 @@
 $desc=$collectedClasses.rI
 if($desc instanceof Array)$desc=$desc[1]
 rI.prototype=$desc
+function dD(iY){this.iY=iY}dD.builtin$cls="dD"
+if(!"name" in dD)dD.name="dD"
+$desc=$collectedClasses.dD
+if($desc instanceof Array)$desc=$desc[1]
+dD.prototype=$desc
 function QZ(){}QZ.builtin$cls="QZ"
 if(!"name" in QZ)QZ.name="QZ"
 $desc=$collectedClasses.QZ
@@ -24934,11 +26075,11 @@
 $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
+function id(){}id.builtin$cls="id"
+if(!"name" in id)id.name="id"
+$desc=$collectedClasses.id
 if($desc instanceof Array)$desc=$desc[1]
-E1.prototype=$desc
+id.prototype=$desc
 function wz(Sn,Sc){this.Sn=Sn
 this.Sc=Sc}wz.builtin$cls="wz"
 if(!"name" in wz)wz.name="wz"
@@ -25014,11 +26155,11 @@
 $desc=$collectedClasses.RAp
 if($desc instanceof Array)$desc=$desc[1]
 RAp.prototype=$desc
-function Gb(){}Gb.builtin$cls="Gb"
-if(!"name" in Gb)Gb.name="Gb"
-$desc=$collectedClasses.Gb
+function ma(){}ma.builtin$cls="ma"
+if(!"name" in ma)ma.name="ma"
+$desc=$collectedClasses.ma
 if($desc instanceof Array)$desc=$desc[1]
-Gb.prototype=$desc
+ma.prototype=$desc
 function cf(){}cf.builtin$cls="cf"
 if(!"name" in cf)cf.name="cf"
 $desc=$collectedClasses.cf
@@ -25150,12 +26291,12 @@
 $desc=$collectedClasses.W9
 if($desc instanceof Array)$desc=$desc[1]
 W9.prototype=$desc
-function vZ(a,b){this.a=a
-this.b=b}vZ.builtin$cls="vZ"
-if(!"name" in vZ)vZ.name="vZ"
-$desc=$collectedClasses.vZ
+function uY(a,b){this.a=a
+this.b=b}uY.builtin$cls="uY"
+if(!"name" in uY)uY.name="uY"
+$desc=$collectedClasses.uY
 if($desc instanceof Array)$desc=$desc[1]
-vZ.prototype=$desc
+uY.prototype=$desc
 function dW(Ui){this.Ui=Ui}dW.builtin$cls="dW"
 if(!"name" in dW)dW.name="dW"
 $desc=$collectedClasses.dW
@@ -25226,11 +26367,11 @@
 $desc=$collectedClasses.QS
 if($desc instanceof Array)$desc=$desc[1]
 QS.prototype=$desc
-function QF(){}QF.builtin$cls="QF"
-if(!"name" in QF)QF.name="QF"
-$desc=$collectedClasses.QF
+function ej(){}ej.builtin$cls="ej"
+if(!"name" in ej)ej.name="ej"
+$desc=$collectedClasses.ej
 if($desc instanceof Array)$desc=$desc[1]
-QF.prototype=$desc
+ej.prototype=$desc
 function NL(){}NL.builtin$cls="NL"
 if(!"name" in NL)NL.name="NL"
 $desc=$collectedClasses.NL
@@ -25246,11 +26387,11 @@
 $desc=$collectedClasses.D4
 if($desc instanceof Array)$desc=$desc[1]
 D4.prototype=$desc
-function X9(){}X9.builtin$cls="X9"
-if(!"name" in X9)X9.name="X9"
-$desc=$collectedClasses.X9
+function L9u(){}L9u.builtin$cls="L9u"
+if(!"name" in L9u)L9u.name="L9u"
+$desc=$collectedClasses.L9u
 if($desc instanceof Array)$desc=$desc[1]
-X9.prototype=$desc
+L9u.prototype=$desc
 function Ms(){}Ms.builtin$cls="Ms"
 if(!"name" in Ms)Ms.name="Ms"
 $desc=$collectedClasses.Ms
@@ -25384,10 +26525,10 @@
 $desc=$collectedClasses.UZ
 if($desc instanceof Array)$desc=$desc[1]
 UZ.prototype=$desc
-function Fv(FT,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.FT=FT
+function Fv(FT,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.FT=FT
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25413,11 +26554,11 @@
 $desc=$collectedClasses.WZ
 if($desc instanceof Array)$desc=$desc[1]
 WZ.prototype=$desc
-function I3(Py,hO,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Py=Py
+function I3(Py,hO,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Py=Py
 this.hO=hO
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25447,10 +26588,10 @@
 $desc=$collectedClasses.pv
 if($desc instanceof Array)$desc=$desc[1]
 pv.prototype=$desc
-function Gk(vt,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.vt=vt
+function Gk(vt,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.vt=vt
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25476,10 +26617,10 @@
 $desc=$collectedClasses.Vfx
 if($desc instanceof Array)$desc=$desc[1]
 Vfx.prototype=$desc
-function Ds(ql,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.ql=ql
+function Ds(ql,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.ql=ql
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25539,7 +26680,7 @@
 $desc=$collectedClasses.GE
 if($desc instanceof Array)$desc=$desc[1]
 GE.prototype=$desc
-function u7(tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.tH=tH
+function u7(hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25556,11 +26697,11 @@
 $desc=$collectedClasses.u7
 if($desc instanceof Array)$desc=$desc[1]
 u7.prototype=$desc
-function St(Pw,i0,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Pw=Pw
+function St(Pw,i0,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Pw=Pw
 this.i0=i0
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25590,11 +26731,11 @@
 $desc=$collectedClasses.tuj
 if($desc instanceof Array)$desc=$desc[1]
 tuj.prototype=$desc
-function vj(eb,kf,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.eb=eb
+function vj(eb,kf,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.eb=eb
 this.kf=kf
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25624,10 +26765,10 @@
 $desc=$collectedClasses.Vct
 if($desc instanceof Array)$desc=$desc[1]
 Vct.prototype=$desc
-function CX(iI,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.iI=iI
+function CX(iI,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.iI=iI
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25694,8 +26835,8 @@
 HV.prototype.gG1=function(receiver){return this.G1}
 HV.prototype.gkc=function(receiver){return this.kc}
 HV.prototype.gI4=function(){return this.I4}
-function Nh(XB,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.XB=XB
-this.tH=tH
+function BK(XB,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.XB=XB
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25707,15 +26848,15 @@
 this.Vk=Vk
 this.Ye=Ye
 this.mT=mT
-this.KM=KM}Nh.builtin$cls="Nh"
-if(!"name" in Nh)Nh.name="Nh"
-$desc=$collectedClasses.Nh
+this.KM=KM}BK.builtin$cls="BK"
+if(!"name" in BK)BK.name="BK"
+$desc=$collectedClasses.BK
 if($desc instanceof Array)$desc=$desc[1]
-Nh.prototype=$desc
-Nh.prototype.gXB=function(receiver){return receiver.XB}
-Nh.prototype.gXB.$reflectable=1
-Nh.prototype.sXB=function(receiver,v){return receiver.XB=v}
-Nh.prototype.sXB.$reflectable=1
+BK.prototype=$desc
+BK.prototype.gXB=function(receiver){return receiver.XB}
+BK.prototype.gXB.$reflectable=1
+BK.prototype.sXB=function(receiver,v){return receiver.XB=v}
+BK.prototype.sXB.$reflectable=1
 function fA(T9,Jt){this.T9=T9
 this.Jt=Jt}fA.builtin$cls="fA"
 if(!"name" in fA)fA.name="fA"
@@ -25743,7 +26884,7 @@
 $desc=$collectedClasses.c5
 if($desc instanceof Array)$desc=$desc[1]
 c5.prototype=$desc
-function ih(tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.tH=tH
+function ih(hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25775,18 +26916,17 @@
 mL.prototype.glw.$reflectable=1
 mL.prototype.gnI=function(){return this.nI}
 mL.prototype.gnI.$reflectable=1
-function bv(jO,oc,VJ,Ai){this.jO=jO
-this.oc=oc
+function bv(nk,YG,XR,VJ,Ai){this.nk=nk
+this.YG=YG
+this.XR=XR
 this.VJ=VJ
 this.Ai=Ai}bv.builtin$cls="bv"
 if(!"name" in bv)bv.name="bv"
 $desc=$collectedClasses.bv
 if($desc instanceof Array)$desc=$desc[1]
 bv.prototype=$desc
-bv.prototype.gjO=function(receiver){return this.jO}
-bv.prototype.gjO.$reflectable=1
-bv.prototype.goc=function(receiver){return this.oc}
-bv.prototype.goc.$reflectable=1
+bv.prototype.gXR=function(){return this.XR}
+bv.prototype.gXR.$reflectable=1
 function pt(JR,i2,VJ,Ai){this.JR=JR
 this.i2=i2
 this.VJ=VJ
@@ -25824,8 +26964,9 @@
 $desc=$collectedClasses.ZW
 if($desc instanceof Array)$desc=$desc[1]
 ZW.prototype=$desc
-function dZ(JR,IT,VJ,Ai){this.JR=JR
+function dZ(JR,IT,Jj,VJ,Ai){this.JR=JR
 this.IT=IT
+this.Jj=Jj
 this.VJ=VJ
 this.Ai=Ai}dZ.builtin$cls="dZ"
 if(!"name" in dZ)dZ.name="dZ"
@@ -25846,16 +26987,33 @@
 Nu.prototype=$desc
 Nu.prototype.sJR=function(v){return this.JR=v}
 Nu.prototype.se0=function(v){return this.e0=v}
-function pF(a){this.a=a}pF.builtin$cls="pF"
+function pF(a,b){this.a=a
+this.b=b}pF.builtin$cls="pF"
 if(!"name" in pF)pF.name="pF"
 $desc=$collectedClasses.pF
 if($desc instanceof Array)$desc=$desc[1]
 pF.prototype=$desc
-function Ha(b){this.b=b}Ha.builtin$cls="Ha"
+function Ha(c){this.c=c}Ha.builtin$cls="Ha"
 if(!"name" in Ha)Ha.name="Ha"
 $desc=$collectedClasses.Ha
 if($desc instanceof Array)$desc=$desc[1]
 Ha.prototype=$desc
+function nu(d){this.d=d}nu.builtin$cls="nu"
+if(!"name" in nu)nu.name="nu"
+$desc=$collectedClasses.nu
+if($desc instanceof Array)$desc=$desc[1]
+nu.prototype=$desc
+function be(a,b){this.a=a
+this.b=b}be.builtin$cls="be"
+if(!"name" in be)be.name="be"
+$desc=$collectedClasses.be
+if($desc instanceof Array)$desc=$desc[1]
+be.prototype=$desc
+function Pg(c){this.c=c}Pg.builtin$cls="Pg"
+if(!"name" in Pg)Pg.name="Pg"
+$desc=$collectedClasses.Pg
+if($desc instanceof Array)$desc=$desc[1]
+Pg.prototype=$desc
 function jI(JR,e0,oJ,vm,VJ,Ai){this.JR=JR
 this.e0=e0
 this.oJ=oJ
@@ -25866,7 +27024,28 @@
 $desc=$collectedClasses.jI
 if($desc instanceof Array)$desc=$desc[1]
 jI.prototype=$desc
-function F1(tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.tH=tH
+function Zw(Rd,n7,LA,Vg,VJ,Ai){this.Rd=Rd
+this.n7=n7
+this.LA=LA
+this.Vg=Vg
+this.VJ=VJ
+this.Ai=Ai}Zw.builtin$cls="Zw"
+if(!"name" in Zw)Zw.name="Zw"
+$desc=$collectedClasses.Zw
+if($desc instanceof Array)$desc=$desc[1]
+Zw.prototype=$desc
+Zw.prototype.gLA=function(receiver){return this.LA}
+Zw.prototype.gLA.$reflectable=1
+function Pf(WF,uM,ZQ,VJ,Ai){this.WF=WF
+this.uM=uM
+this.ZQ=ZQ
+this.VJ=VJ
+this.Ai=Ai}Pf.builtin$cls="Pf"
+if(!"name" in Pf)Pf.name="Pf"
+$desc=$collectedClasses.Pf
+if($desc instanceof Array)$desc=$desc[1]
+Pf.prototype=$desc
+function F1(hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25883,7 +27062,7 @@
 $desc=$collectedClasses.F1
 if($desc instanceof Array)$desc=$desc[1]
 F1.prototype=$desc
-function uL(tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.tH=tH
+function uL(hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -25900,10 +27079,10 @@
 $desc=$collectedClasses.uL
 if($desc instanceof Array)$desc=$desc[1]
 uL.prototype=$desc
-uL.prototype.gtH=function(receiver){return receiver.tH}
-uL.prototype.gtH.$reflectable=1
-uL.prototype.stH=function(receiver,v){return receiver.tH=v}
-uL.prototype.stH.$reflectable=1
+uL.prototype.ghm=function(receiver){return receiver.hm}
+uL.prototype.ghm.$reflectable=1
+uL.prototype.shm=function(receiver,v){return receiver.hm=v}
+uL.prototype.shm.$reflectable=1
 function Xf(){}Xf.builtin$cls="Xf"
 if(!"name" in Xf)Xf.name="Xf"
 $desc=$collectedClasses.Xf
@@ -25971,11 +27150,11 @@
 $desc=$collectedClasses.Zb
 if($desc instanceof Array)$desc=$desc[1]
 Zb.prototype=$desc
-function id(g){this.g=g}id.builtin$cls="id"
-if(!"name" in id)id.name="id"
-$desc=$collectedClasses.id
+function bF(g){this.g=g}bF.builtin$cls="bF"
+if(!"name" in bF)bF.name="bF"
+$desc=$collectedClasses.bF
 if($desc instanceof Array)$desc=$desc[1]
-id.prototype=$desc
+bF.prototype=$desc
 function iV(h,i,j,k){this.h=h
 this.i=i
 this.j=j
@@ -25995,16 +27174,16 @@
 W4.prototype=$desc
 W4.prototype.gWA=function(){return this.WA}
 W4.prototype.gIl=function(){return this.Il}
-function Fa(){}Fa.builtin$cls="Fa"
-if(!"name" in Fa)Fa.name="Fa"
-$desc=$collectedClasses.Fa
+function ndx(){}ndx.builtin$cls="ndx"
+if(!"name" in ndx)ndx.name="ndx"
+$desc=$collectedClasses.ndx
 if($desc instanceof Array)$desc=$desc[1]
-Fa.prototype=$desc
-function ma(){}ma.builtin$cls="ma"
-if(!"name" in ma)ma.name="ma"
-$desc=$collectedClasses.ma
+ndx.prototype=$desc
+function Hm(){}Hm.builtin$cls="Hm"
+if(!"name" in Hm)Hm.name="Hm"
+$desc=$collectedClasses.Hm
 if($desc instanceof Array)$desc=$desc[1]
-ma.prototype=$desc
+Hm.prototype=$desc
 function d3(){}d3.builtin$cls="d3"
 if(!"name" in d3)d3.name="d3"
 $desc=$collectedClasses.d3
@@ -26255,11 +27434,11 @@
 $desc=$collectedClasses.w12
 if($desc instanceof Array)$desc=$desc[1]
 w12.prototype=$desc
-function fTP(a){this.a=a}fTP.builtin$cls="fTP"
-if(!"name" in fTP)fTP.name="fTP"
-$desc=$collectedClasses.fTP
+function ppY(a){this.a=a}ppY.builtin$cls="ppY"
+if(!"name" in ppY)ppY.name="ppY"
+$desc=$collectedClasses.ppY
 if($desc instanceof Array)$desc=$desc[1]
-fTP.prototype=$desc
+ppY.prototype=$desc
 function yL(){}yL.builtin$cls="yL"
 if(!"name" in yL)yL.name="yL"
 $desc=$collectedClasses.yL
@@ -26417,16 +27596,26 @@
 $desc=$collectedClasses.Bl
 if($desc instanceof Array)$desc=$desc[1]
 Bl.prototype=$desc
+function Fn(){}Fn.builtin$cls="Fn"
+if(!"name" in Fn)Fn.name="Fn"
+$desc=$collectedClasses.Fn
+if($desc instanceof Array)$desc=$desc[1]
+Fn.prototype=$desc
+function e3(){}e3.builtin$cls="e3"
+if(!"name" in e3)e3.name="e3"
+$desc=$collectedClasses.e3
+if($desc instanceof Array)$desc=$desc[1]
+e3.prototype=$desc
 function pM(){}pM.builtin$cls="pM"
 if(!"name" in pM)pM.name="pM"
 $desc=$collectedClasses.pM
 if($desc instanceof Array)$desc=$desc[1]
 pM.prototype=$desc
-function Mh(){}Mh.builtin$cls="Mh"
-if(!"name" in Mh)Mh.name="Mh"
-$desc=$collectedClasses.Mh
+function jh(){}jh.builtin$cls="jh"
+if(!"name" in jh)jh.name="jh"
+$desc=$collectedClasses.jh
 if($desc instanceof Array)$desc=$desc[1]
-Mh.prototype=$desc
+jh.prototype=$desc
 function Md(){}Md.builtin$cls="Md"
 if(!"name" in Md)Md.name="Md"
 $desc=$collectedClasses.Md
@@ -26462,11 +27651,11 @@
 $desc=$collectedClasses.mf
 if($desc instanceof Array)$desc=$desc[1]
 mf.prototype=$desc
-function ej(){}ej.builtin$cls="ej"
-if(!"name" in ej)ej.name="ej"
-$desc=$collectedClasses.ej
+function ik(){}ik.builtin$cls="ik"
+if(!"name" in ik)ik.name="ik"
+$desc=$collectedClasses.ik
 if($desc instanceof Array)$desc=$desc[1]
-ej.prototype=$desc
+ik.prototype=$desc
 function HK(b){this.b=b}HK.builtin$cls="HK"
 if(!"name" in HK)HK.name="HK"
 $desc=$collectedClasses.HK
@@ -26761,6 +27950,60 @@
 ky.prototype=$desc
 ky.prototype.gBb=function(receiver){return this.Bb}
 ky.prototype.gT8=function(receiver){return this.T8}
+function uA(a,b){this.a=a
+this.b=b}uA.builtin$cls="uA"
+if(!"name" in uA)uA.name="uA"
+$desc=$collectedClasses.uA
+if($desc instanceof Array)$desc=$desc[1]
+uA.prototype=$desc
+function vl(hP,KL,bO,tj,Lv,k6){this.hP=hP
+this.KL=KL
+this.bO=bO
+this.tj=tj
+this.Lv=Lv
+this.k6=k6}vl.builtin$cls="vl"
+if(!"name" in vl)vl.name="vl"
+$desc=$collectedClasses.vl
+if($desc instanceof Array)$desc=$desc[1]
+vl.prototype=$desc
+vl.prototype.ghP=function(){return this.hP}
+function Li(a,b,c){this.a=a
+this.b=b
+this.c=c}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 WK(d){this.d=d}WK.builtin$cls="WK"
+if(!"name" in WK)WK.name="WK"
+$desc=$collectedClasses.WK
+if($desc instanceof Array)$desc=$desc[1]
+WK.prototype=$desc
+function iT(hP,Jn,KL,bO,tj,Lv,k6){this.hP=hP
+this.Jn=Jn
+this.KL=KL
+this.bO=bO
+this.tj=tj
+this.Lv=Lv
+this.k6=k6}iT.builtin$cls="iT"
+if(!"name" in iT)iT.name="iT"
+$desc=$collectedClasses.iT
+if($desc instanceof Array)$desc=$desc[1]
+iT.prototype=$desc
+iT.prototype.ghP=function(){return this.hP}
+iT.prototype.gJn=function(){return this.Jn}
+function tE(a,b,c){this.a=a
+this.b=b
+this.c=c}tE.builtin$cls="tE"
+if(!"name" in tE)tE.name="tE"
+$desc=$collectedClasses.tE
+if($desc instanceof Array)$desc=$desc[1]
+tE.prototype=$desc
+function GS(d){this.d=d}GS.builtin$cls="GS"
+if(!"name" in GS)GS.name="GS"
+$desc=$collectedClasses.GS
+if($desc instanceof Array)$desc=$desc[1]
+GS.prototype=$desc
 function fa(hP,re,KL,bO,tj,Lv,k6){this.hP=hP
 this.re=re
 this.KL=KL
@@ -26791,18 +28034,6 @@
 $desc=$collectedClasses.a9
 if($desc instanceof Array)$desc=$desc[1]
 a9.prototype=$desc
-function jh(e,f,g){this.e=e
-this.f=f
-this.g=g}jh.builtin$cls="jh"
-if(!"name" in jh)jh.name="jh"
-$desc=$collectedClasses.jh
-if($desc instanceof Array)$desc=$desc[1]
-jh.prototype=$desc
-function e3(h){this.h=h}e3.builtin$cls="e3"
-if(!"name" in e3)e3.name="e3"
-$desc=$collectedClasses.e3
-if($desc instanceof Array)$desc=$desc[1]
-e3.prototype=$desc
 function VA(Bb,T8,KL,bO,tj,Lv,k6){this.Bb=Bb
 this.T8=T8
 this.KL=KL
@@ -26912,6 +28143,22 @@
 K9.prototype=$desc
 K9.prototype.gBb=function(receiver){return this.Bb}
 K9.prototype.gT8=function(receiver){return this.T8}
+function zX(hP,Jn){this.hP=hP
+this.Jn=Jn}zX.builtin$cls="zX"
+if(!"name" in zX)zX.name="zX"
+$desc=$collectedClasses.zX
+if($desc instanceof Array)$desc=$desc[1]
+zX.prototype=$desc
+zX.prototype.ghP=function(){return this.hP}
+zX.prototype.gJn=function(){return this.Jn}
+function x9(hP,oc){this.hP=hP
+this.oc=oc}x9.builtin$cls="x9"
+if(!"name" in x9)x9.name="x9"
+$desc=$collectedClasses.x9
+if($desc instanceof Array)$desc=$desc[1]
+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
 this.bP=bP
 this.re=re}RW.builtin$cls="RW"
@@ -26927,11 +28174,10 @@
 $desc=$collectedClasses.xs
 if($desc instanceof Array)$desc=$desc[1]
 xs.prototype=$desc
-function FX(Sk,Ix,ku,fL,lQ){this.Sk=Sk
+function FX(Sk,Ix,ku,fL){this.Sk=Sk
 this.Ix=Ix
 this.ku=ku
-this.fL=fL
-this.lQ=lQ}FX.builtin$cls="FX"
+this.fL=fL}FX.builtin$cls="FX"
 if(!"name" in FX)FX.name="FX"
 $desc=$collectedClasses.FX
 if($desc instanceof Array)$desc=$desc[1]
@@ -26992,7 +28238,7 @@
 $desc=$collectedClasses.a0
 if($desc instanceof Array)$desc=$desc[1]
 a0.prototype=$desc
-function NQ(tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.tH=tH
+function NQ(hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -27009,10 +28255,68 @@
 $desc=$collectedClasses.NQ
 if($desc instanceof Array)$desc=$desc[1]
 NQ.prototype=$desc
-function uw(Qq,VJ,Ai,tH,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Qq=Qq
+function fI(Uz,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Uz=Uz
 this.VJ=VJ
 this.Ai=Ai
-this.tH=tH
+this.hm=hm
+this.VJ=VJ
+this.Ai=Ai
+this.VJ=VJ
+this.Ai=Ai
+this.ZI=ZI
+this.uN=uN
+this.z3=z3
+this.TQ=TQ
+this.Vk=Vk
+this.Ye=Ye
+this.mT=mT
+this.KM=KM}fI.builtin$cls="fI"
+if(!"name" in fI)fI.name="fI"
+$desc=$collectedClasses.fI
+if($desc instanceof Array)$desc=$desc[1]
+fI.prototype=$desc
+fI.prototype.gUz=function(receiver){return receiver.Uz}
+fI.prototype.gUz.$reflectable=1
+fI.prototype.sUz=function(receiver,v){return receiver.Uz=v}
+fI.prototype.sUz.$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 kK(vX,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.vX=vX
+this.VJ=VJ
+this.Ai=Ai
+this.hm=hm
+this.VJ=VJ
+this.Ai=Ai
+this.VJ=VJ
+this.Ai=Ai
+this.ZI=ZI
+this.uN=uN
+this.z3=z3
+this.TQ=TQ
+this.Vk=Vk
+this.Ye=Ye
+this.mT=mT
+this.KM=KM}kK.builtin$cls="kK"
+if(!"name" in kK)kK.name="kK"
+$desc=$collectedClasses.kK
+if($desc instanceof Array)$desc=$desc[1]
+kK.prototype=$desc
+kK.prototype.gvX=function(receiver){return receiver.vX}
+kK.prototype.gvX.$reflectable=1
+kK.prototype.svX=function(receiver,v){return receiver.vX=v}
+kK.prototype.svX.$reflectable=1
+function pva(){}pva.builtin$cls="pva"
+if(!"name" in pva)pva.name="pva"
+$desc=$collectedClasses.pva
+if($desc instanceof Array)$desc=$desc[1]
+pva.prototype=$desc
+function uw(Qq,VJ,Ai,hm,VJ,Ai,VJ,Ai,ZI,uN,z3,TQ,Vk,Ye,mT,KM){this.Qq=Qq
+this.VJ=VJ
+this.Ai=Ai
+this.hm=hm
 this.VJ=VJ
 this.Ai=Ai
 this.VJ=VJ
@@ -27033,11 +28337,11 @@
 uw.prototype.gQq.$reflectable=1
 uw.prototype.sQq=function(receiver,v){return receiver.Qq=v}
 uw.prototype.sQq.$reflectable=1
-function WZq(){}WZq.builtin$cls="WZq"
-if(!"name" in WZq)WZq.name="WZq"
-$desc=$collectedClasses.WZq
+function cda(){}cda.builtin$cls="cda"
+if(!"name" in cda)cda.name="cda"
+$desc=$collectedClasses.cda
 if($desc instanceof Array)$desc=$desc[1]
-WZq.prototype=$desc
+cda.prototype=$desc
 function V2(N1,bn,Ck){this.N1=N1
 this.bn=bn
 this.Ck=Ck}V2.builtin$cls="V2"
@@ -27077,16 +28381,16 @@
 $desc=$collectedClasses.Uf
 if($desc instanceof Array)$desc=$desc[1]
 Uf.prototype=$desc
-function ik(a){this.a=a}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 LfS(b){this.b=b}LfS.builtin$cls="LfS"
+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"
+if(!"name" in fTP)fTP.name="fTP"
+$desc=$collectedClasses.fTP
+if($desc instanceof Array)$desc=$desc[1]
+fTP.prototype=$desc
 function NP(Ca,LO,ZY,xS,PB,eS,Ii){this.Ca=Ca
 this.LO=LO
 this.ZY=ZY
@@ -27340,11 +28644,11 @@
 $desc=$collectedClasses.Nb
 if($desc instanceof Array)$desc=$desc[1]
 Nb.prototype=$desc
-function HB(call$0,$name){this.call$0=call$0
-this.$name=$name}HB.builtin$cls="HB"
-$desc=$collectedClasses.HB
+function Fy(call$0,$name){this.call$0=call$0
+this.$name=$name}Fy.builtin$cls="Fy"
+$desc=$collectedClasses.Fy
 if($desc instanceof Array)$desc=$desc[1]
-HB.prototype=$desc
+Fy.prototype=$desc
 function eU(call$7,$name){this.call$7=call$7
 this.$name=$name}eU.builtin$cls="eU"
 $desc=$collectedClasses.eU
@@ -27375,4 +28679,4 @@
 $desc=$collectedClasses.PW
 if($desc instanceof Array)$desc=$desc[1]
 PW.prototype=$desc
-return[qE,Yy,Ps,rK,fY,Mr,zx,ct,nB,i3,it,Az,QP,QW,n6,Ny,OM,QQ,MA,y4,d7,Rb,oJ,DG,mN,vH,hh,Em,Sb,rV,Wy,YN,bA,Wq,rz,BK,wj,cv,Fs,SX,ea,D0,as,T5,Aa,u5,Yu,iG,jP,U2,tA,xn,Vb,QH,ST,X2,fJ,Vi,tX,Sg,pA,Mi,Gt,In,Gx,eP,AL,Og,cS,M6,El,zm,SV,aB,ku,Ih,cW,DK,qm,ZY,cx,la,Vn,PG,xe,Hw,bn,Im,oB,Aj,oU,qT,KV,BH,mh,G7,wq,Ql,Xp,bP,mX,SN,HD,ni,p3,qj,qW,KR,ew,fs,bX,BL,MC,Mx,j2,yz,lp,kd,I0,QR,Cp,ua,zD,Ul,G0,wb,fq,h4,qk,GI,Tb,Iv,BT,yY,kJ,AE,xV,FH,y6,RH,pU,Lq,Mf,BR,r4,aG,J6,K5,UM,WS,rq,nK,kc,ij,ty,Nf,Nc,rj,rh,Zv,Q7,hF,yK,Y0,ZJ,mU,eZ,Ak,y5,nV,Zc,ui,D6,DQ,Sm,dx,es,eG,lv,pf,NV,W1,zo,wf,TU,bb,VE,zp,Xu,lu,tk,me,qN,NY,d4,MI,ca,kK,eW,um,Fu,OE,l6,BA,tp,rE,CC,PQ,uz,Yd,U0,AD,Gr,tc,GH,lo,NJ,nd,vt,rQ,EU,LR,MB,hy,r8,aS,CG,qF,MT,Rk,Eo,Dn,ox,ZD,NE,wD,BD,vRT,Fi,Qr,mj,cB,uY,yR,AX,xJ,l4,Et,NC,nb,By,xt,tG,P0,Jq,Xr,qD,Cf,AS,Kq,oI,mJ,rF,vi,ZX,hn,nE,zt,F0,Lt,Gv,kn,PE,QI,Tm,is,Q,jx,ZC,Jt,P,im,Pp,O,PK,JO,O2,aX,cC,RA,IY,JH,jl,Iy,JM,Ua,JG,ns,wd,TA,YP,yc,I9,Bj,NO,II,aJ,X1,HU,Pm,oo,OW,Dd,AP,yH,FA,Av,oH,LP,c2,WT,p8,XR,LI,A2,F3,u8,Gi,t2,Zr,ZQ,az,vV,Hk,XO,dr,TL,KX,uZ,OQ,Tp,v,Z3,D2,GT,Pe,Eq,cu,Lm,dC,wN,VX,VR,EK,KW,Pb,tQ,aC,Vf,Be,tu,i6,Vc,zO,aL,nH,a7,i1,xy,MH,A8,U5,SO,zs,rR,AM,d5,U1,SJ,SU,Tv,XC,iK,GD,Sn,nI,jU,Lj,mb,am,cw,EE,Uz,uh,Kv,oP,YX,BI,y1,M2,iu,mg,zE,bl,Ef,Oo,Tc,Ax,Wf,Un,Ei,U7,t0,Ld,Sz,Zk,fu,ng,Ar,jB,ye,Gj,Zz,Xh,Ca,Ik,JI,Ip,WV,C7,CQ,dz,tK,OR,Bg,DL,b8,j7,oV,TP,Zf,vs,da,xw,dm,rH,ZL,mi,jb,wB,Pu,qh,QC,Yl,Rv,YJ,jv,LB,DO,lz,Rl,Jb,M4,Jp,h7,pr,eN,B5,PI,j4,i9,VV,Dy,lU,xp,UH,Z5,ii,ib,MO,ms,UO,Bc,vp,lk,Gh,XB,ly,cK,O9,yU,nP,KA,Vo,qB,ez,fI,LV,DS,dp,B3,CR,ny,dR,uR,QX,YR,fB,eO,nO,t3,dq,dX,aY,wJ,e4,JB,Id,fZ,TF,Xz,Cg,Hs,uo,pK,eM,Ue,W5,R8,k6,oi,ce,o2,jG,fG,EQ,YB,iX,ou,S9,ey,xd,v6,db,Cm,N6,jg,YO,oz,b6,ef,zQ,Yp,u3,mW,ar,lD,W0,Sw,o0,a1,jp,Xt,Ba,An,LD,YI,OG,ro,DN,ZM,HW,JC,f1,Uk,wI,ob,by,QM,z0,Vx,Rw,h0,CL,K8,a2,fR,iP,MF,Rq,Hn,Zl,pl,a6,P7,DW,Ge,LK,AT,bJ,mp,ub,ds,lj,UV,VS,t7,HG,aE,kM,EH,cX,Fl,L8,c8,a,Od,mE,WU,Rn,wv,uq,iD,hb,XX,Kd,yZ,Gs,pm,Tw,wm,FB,Lk,XZ,hQ,Nw,kZ,JT,d9,rI,QZ,BV,E1,wz,B1,M5,Jn,DM,zL,ec,Kx,iO,bU,e7,nj,rl,RAp,Gb,cf,E9,nF,FK,Si,vf,Fc,hD,I4,e0,RO,eu,ie,Ea,pu,i2,b0,Ov,qO,RX,kG,Gm,W9,vZ,dW,PA,H2,O7,HI,E4,r7,Tz,Wk,DV,Hp,Nz,Jd,QS,QF,NL,vr,D4,X9,Ms,Fw,RS,RY,Ys,vg,xG,Vj,VW,RK,DH,ZK,Th,Vju,KB,RKu,na,TkQ,xGn,ZKG,VWk,w6W,DHb,z9g,G8,UZ,Fv,WZ,I3,pv,Gk,Vfx,Ds,Dsd,CA,YL,KC,xL,As,GE,u7,St,tuj,vj,Vct,CX,D13,TJ,dG,Ng,HV,Nh,fA,tz,jR,PO,c5,ih,mL,bv,pt,Zd,dY,vY,dS,ZW,dZ,Qe,Nu,pF,Ha,jI,F1,uL,Xf,Pi,yj,qI,J3,E5,o5,b5,zI,Zb,id,iV,W4,Fa,ma,d3,X6,xh,wn,uF,cj,HA,br,zT,D7,qL,C4,l9,lP,km,Qt,Dk,A0,rm,eY,OO,BE,Qb,xI,q1,Zj,XP,q6,CK,BO,ZG,Oc,MX,w12,fTP,yL,dM,Y7,WC,Xi,TV,Mq,Oa,n1,xf,L6,Rs,uJ,hm,Ji,Bf,ir,Tt,GN,k8,HJ,S0,V3,Bl,pM,Mh,Md,Lf,fT,pp,Nq,nl,mf,ej,HK,w13,o8,GL,e9,Dw,Xy,uK,mY,fE,mB,XF,iH,wJY,zOQ,W6o,MdQ,YJG,DOe,lPa,Ufa,Raa,w0,w4,w5,w7,w9,w10,w11,c4,z6,Ay,Ed,G1,Os,Dl,Wh,x5,ev,ID,jV,ek,OC,Xm,Jy,ky,fa,WW,vQ,a9,jh,e3,VA,J1,fk,wL,B0,Fq,hw,EZ,no,kB,ae,Iq,w6,jK,uk,K9,RW,xs,FX,Ae,Bt,vR,Pn,hc,hA,fr,a0,NQ,uw,WZq,V2,D8,jY,ll,Uf,ik,LfS,NP,Vh,r0,jz,SA,zV,nv,ee,XI,hs,yp,ug,DT,OB,Ra,N9,NW,HS,TG,ts,Kj,VU,Ya,XT,ic,VT,T4,TR,VD,Oh,zy,Nb,HB,eU,ADW,Ri,kq,Ag,PW]}
\ No newline at end of file
+return[qE,Yy,Ps,rK,fY,Mr,zx,ct,nB,i3,it,Az,QP,QW,n6,Ny,OM,QQ,MA,y4,d7,Rb,oJ,DG,mN,vH,hh,Em,Sb,rV,Wy,QF,bA,Wq,rz,Nh,wj,cv,Fs,SX,ea,D0,as,T5,Aa,u5,Yu,iG,jP,U2,tA,xn,Vb,QH,ST,X2,fJ,Vi,tX,Sg,pA,Mi,Gt,In,Gx,eP,AL,Og,cS,M6,El,zm,SV,aB,ku,Ih,cW,DK,qm,ZY,cx,la,Vn,PG,xe,Hw,bn,Im,oB,Aj,oU,qT,KV,BH,mh,G7,kl,Ql,Xp,bP,mX,SN,HD,ni,p3,qj,qW,KR,ew,fs,bX,BL,MC,Mx,j2,yz,lp,kd,I0,QR,Cp,ua,zD,Ul,G0,wb,fq,h4,qk,GI,Tb,tV,BT,yY,kJ,AE,xV,FH,y6,RH,pU,Lq,Mf,BR,r4,aG,J6,K5,UM,WS,rq,nK,kc,Eh,ty,Nf,Nc,rj,rh,Zv,Q7,hF,yK,HB,ZJ,mU,eZ,Fl,y5,nV,Zc,ui,D6,DQ,Sm,dx,es,eG,lv,pf,NV,W1,zo,wf,TU,bb,VE,zp,Xu,lu,tk,me,qN,NY,d4,MI,ca,xX,eW,um,Fu,OE,l6,BA,tp,rE,CC,PQ,uz,Yd,U0,AD,Gr,tc,GH,lo,NJ,nd,vt,rQ,EU,LR,MB,hy,r8,aS,CG,qF,MT,xN,Eo,Dn,ox,ZD,NE,wD,BD,vRT,Fi,Qr,mj,cB,k2,yR,AX,xJ,l4,Et,NC,nb,By,xt,tG,P0,Jq,Xr,qD,Cf,AS,Kq,oI,mJ,rF,vi,ZX,ycx,nE,zt,F0,Lt,Gv,kn,PE,QI,Tm,is,Q,jx,ZC,Jt,P,im,Pp,O,PK,JO,O2,aX,cC,RA,IY,JH,jl,Iy,JM,Ua,JG,ns,wd,TA,YP,yc,I9,Bj,NO,II,aJ,X1,HU,Pm,oo,OW,Dd,AP,yH,FA,Av,oH,LP,c2,WT,p8,XR,LI,A2,F3,u8,Gi,t2,Zr,ZQ,az,vV,Hk,XO,dr,TL,KX,uZ,OQ,Tp,v,Z3,D2,GT,Pe,Eq,cu,Lm,dC,wN,VX,VR,EK,KW,Pb,tQ,aC,Vf,Be,tu,i6,Vc,zO,aL,nH,a7,i1,xy,MH,A8,U5,SO,zs,rR,vZ,d5,U1,SJ,SU,Tv,XC,iK,GD,Sn,nI,jU,Lj,mb,am,cw,EE,Uz,uh,Kv,oP,YX,BI,y1,M2,iu,mg,zE,bl,tB,Oo,Tc,Ax,Wf,Un,Ei,U7,t0,Ld,Sz,Zk,fu,ng,Ar,jB,ye,Gj,Zz,Xh,Ca,Ik,JI,Ip,WV,C7,CQ,dz,tK,OR,Bg,DL,b8,j7,oV,TP,Zf,vs,da,xw,dm,rH,ZL,mi,jb,wB,Pu,qh,QC,Yl,Rv,YJ,jv,LB,DO,lz,Rl,Jb,M4,Jp,h7,pr,eN,B5,PI,j4,i9,VV,Dy,lU,xp,UH,Z5,ii,ib,MO,ms,UO,Bc,vp,lk,Gh,XB,ly,cK,O9,yU,nP,KA,Vo,qB,ez,lx,LV,DS,dp,B3,CR,ny,dR,uR,QX,YR,fB,eO,nO,t3,dq,dX,aY,wJ,e4,JB,Id,fZ,TF,Xz,Cg,Hs,uo,pK,eM,Ue,W5,R8,k6,oi,ce,o2,jG,fG,EQ,YB,iX,ou,S9,ey,xd,v6,db,Cm,N6,jg,YO,oz,b6,ef,zQ,Yp,u3,mW,ar,lD,W0,Sw,o0,a1,jp,Xt,Ba,An,LD,YI,OG,ro,DN,ZM,HW,JC,f1,Uk,wI,ob,by,QM,z0,E3,Rw,GY,jZ,h0,CL,K8,a2,fR,iP,MF,Rq,Hn,Zl,pl,a6,P7,DW,Ge,LK,AT,bJ,mp,ub,ds,lj,UV,VS,t7,HG,aE,kM,EH,cX,eL,L8,c8,a,Od,mE,WU,Rn,wv,uq,iD,hb,XX,Kd,yZ,Gs,pm,Tw,wm,FB,Lk,XZ,qz,hQ,Nw,kZ,JT,d9,rI,dD,QZ,BV,id,wz,B1,M5,Jn,DM,zL,ec,Kx,iO,bU,e7,nj,rl,RAp,ma,cf,E9,nF,FK,Si,vf,Fc,hD,I4,e0,RO,eu,ie,Ea,pu,i2,b0,Ov,qO,RX,kG,Gm,W9,uY,dW,PA,H2,O7,HI,E4,r7,Tz,Wk,DV,Hp,Nz,Jd,QS,ej,NL,vr,D4,L9u,Ms,Fw,RS,RY,Ys,vg,xG,Vj,VW,RK,DH,ZK,Th,Vju,KB,RKu,na,TkQ,xGn,ZKG,VWk,w6W,DHb,z9g,G8,UZ,Fv,WZ,I3,pv,Gk,Vfx,Ds,Dsd,CA,YL,KC,xL,As,GE,u7,St,tuj,vj,Vct,CX,D13,TJ,dG,Ng,HV,BK,fA,tz,jR,PO,c5,ih,mL,bv,pt,Zd,dY,vY,dS,ZW,dZ,Qe,Nu,pF,Ha,nu,be,Pg,jI,Zw,Pf,F1,uL,Xf,Pi,yj,qI,J3,E5,o5,b5,zI,Zb,bF,iV,W4,ndx,Hm,d3,X6,xh,wn,uF,cj,HA,br,zT,D7,qL,C4,l9,lP,km,Qt,Dk,A0,rm,eY,OO,BE,Qb,xI,q1,Zj,XP,q6,CK,BO,ZG,Oc,MX,w12,ppY,yL,dM,Y7,WC,Xi,TV,Mq,Oa,n1,xf,L6,Rs,uJ,hm,Ji,Bf,ir,Tt,GN,k8,HJ,S0,V3,Bl,Fn,e3,pM,jh,Md,Lf,fT,pp,Nq,nl,mf,ik,HK,w13,o8,GL,e9,Dw,Xy,uK,mY,fE,mB,XF,iH,wJY,zOQ,W6o,MdQ,YJG,DOe,lPa,Ufa,Raa,w0,w4,w5,w7,w9,w10,w11,c4,z6,Ay,Ed,G1,Os,Dl,Wh,x5,ev,ID,jV,ek,OC,Xm,Jy,ky,uA,vl,Li,WK,iT,tE,GS,fa,WW,vQ,a9,VA,J1,fk,wL,B0,Fq,hw,EZ,no,kB,ae,Iq,w6,jK,uk,K9,zX,x9,RW,xs,FX,Ae,Bt,vR,Pn,hc,hA,fr,a0,NQ,fI,WZq,kK,pva,uw,cda,V2,D8,jY,ll,Uf,LfS,fTP,NP,Vh,r0,jz,SA,zV,nv,ee,XI,hs,yp,ug,DT,OB,Ra,N9,NW,HS,TG,ts,Kj,VU,Ya,XT,ic,VT,T4,TR,VD,Oh,zy,Nb,Fy,eU,ADW,Ri,kq,Ag,PW]}
\ 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 990b5f2c..11a25ac 100644
--- a/runtime/bin/vmservice/client/lib/observatory.dart
+++ b/runtime/bin/vmservice/client/lib/observatory.dart
@@ -11,3 +11,4 @@
 part 'src/observatory/isolate.dart';
 part 'src/observatory/isolate_manager.dart';
 part 'src/observatory/request_manager.dart';
+part 'src/observatory/script_source.dart';
diff --git a/runtime/bin/vmservice/client/lib/observatory_elements.dart b/runtime/bin/vmservice/client/lib/observatory_elements.dart
index ab3025a..6847736 100644
--- a/runtime/bin/vmservice/client/lib/observatory_elements.dart
+++ b/runtime/bin/vmservice/client/lib/observatory_elements.dart
@@ -12,4 +12,6 @@
 export
   'package:observatory/src/observatory_elements/observatory_application.dart';
 export 'package:observatory/src/observatory_elements/response_viewer.dart';
-export 'package:observatory/src/observatory_elements/stack_trace.dart';
\ No newline at end of file
+export 'package:observatory/src/observatory_elements/script_view.dart';
+export 'package:observatory/src/observatory_elements/source_view.dart';
+export 'package:observatory/src/observatory_elements/stack_trace.dart';
diff --git a/runtime/bin/vmservice/client/lib/observatory_elements.html b/runtime/bin/vmservice/client/lib/observatory_elements.html
index b8955fd..199998a 100644
--- a/runtime/bin/vmservice/client/lib/observatory_elements.html
+++ b/runtime/bin/vmservice/client/lib/observatory_elements.html
@@ -15,9 +15,11 @@
  <link rel="import" href="src/observatory_elements/navigation_bar.html">
  <link rel="import"
        href="src/observatory_elements/observatory_application.html">
-<link rel="import"
-      href="src/observatory_elements/observatory_element.html">
+ <link rel="import"
+       href="src/observatory_elements/observatory_element.html">
  <link rel="import" href="src/observatory_elements/response_viewer.html">
+ <link rel="import" href="src/observatory_elements/script_view.html">
+ <link rel="import" href="src/observatory_elements/source_view.html">
  <link rel="import" href="src/observatory_elements/stack_trace.html">
 </head>
 </html>
\ 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 b761b2f..c5423b9 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart
@@ -6,8 +6,10 @@
 
 /// State for a running isolate.
 class Isolate extends Observable {
-  @observable final int id;
-  @observable final String name;
+  @observable int id;
+  @observable String name;
+  @observable final Map<String, ScriptSource> scripts =
+      toObservable(new Map<String, ScriptSource>());
 
   Isolate(this.id, this.name);
 
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/isolate_manager.dart b/runtime/bin/vmservice/client/lib/src/observatory/isolate_manager.dart
index 93cba65..1471450 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/isolate_manager.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/isolate_manager.dart
@@ -24,6 +24,15 @@
     });
   }
 
+  Isolate getIsolate(int id) {
+    Isolate isolate = isolates[id];
+    if (isolate == null) {
+      isolate = new Isolate(id, '');
+      isolates[id] = isolate;
+    }
+    return isolate;
+  }
+
   void _updateIsolates(List<Map> members) {
     // Find dead isolates.
     var deadIsolates = [];
@@ -43,6 +52,8 @@
       if (isolates[id] == null) {
         var isolate = new Isolate(id, name);
         isolates[id] = isolate;
+      } else {
+        isolates[id].name = name;
       }
     });
   }
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart b/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart
index 97df456..b4f487c 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/location_manager.dart
@@ -16,7 +16,7 @@
   ObservatoryApplication get application => _application;
 
   @observable String currentHash = '';
-
+  @observable Uri currentHashUri;
   void init() {
     window.onHashChange.listen((event) {
       if (setDefaultHash()) {
@@ -48,6 +48,15 @@
     return currentIsolateAnchorPrefix() != null;
   }
 
+  bool get isScriptLink {
+    String type = currentHashUri.queryParameters['type'];
+    return type == 'Script';
+  }
+
+  String get scriptName {
+    return Uri.decodeQueryComponent(currentHashUri.queryParameters['name']);
+  }
+
   /// Extract the current isolate id as an integer. Returns [InvalidIsolateId]
   /// if none is present in window.location.
   int currentIsolateId() {
@@ -76,6 +85,7 @@
     currentHash = window.location.hash;
     // Chomp off the #
     String requestUrl = currentHash.substring(1);
+    currentHashUri = Uri.parse(requestUrl);
     application.requestManager.get(requestUrl);
   }
 
@@ -109,6 +119,16 @@
     return classLink(isolateId, cid);
   }
 
+  /// Create a request for the script [objectId] with script [name].
+  @observable
+  String currentIsolateScriptLink(int objectId, String name) {
+    var isolateId = currentIsolateId();
+    if (isolateId == LocationManager.InvalidIsolateId) {
+      return defaultHash;
+    }
+    return scriptLink(isolateId, objectId, name);
+  }
+
   /// Create a request for [l] on [isolateId].
   @observable
   String relativeLink(int isolateId, String l) {
@@ -126,4 +146,12 @@
   String classLink(int isolateId, int cid) {
     return '#/isolates/$isolateId/classes/$cid';
   }
+
+  @observable
+  /// Create a request for the script [objectId] with script [url].
+  String scriptLink(int isolateId, int objectId, String name) {
+    String encodedName = Uri.encodeQueryComponent(name);
+    return '#/isolates/$isolateId/objects/$objectId'
+           '?type=Script&name=$encodedName';
+  }
 }
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 328601d..9a26b54 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory/request_manager.dart
@@ -47,11 +47,47 @@
 
   /// Request [requestString] from the VM service. Updates [responses].
   /// Will trigger [interceptor] if one is set.
-  Future<Map> get(String requestString) {
-    request(requestString).then((responseString) {
-      parseResponses(responseString);
+  void get(String requestString) {
+    if (_application.locationManager.isScriptLink) {
+      // We cache script sources.
+      String scriptName = _application.locationManager.scriptName;
+      getScriptSource(scriptName, requestString).then((source) {
+        if (source != null) {
+          setResponses([{
+            'type': 'Script',
+            'source': source
+          }]);
+        } else {
+          setResponses([{
+            'type': 'RequestError',
+            'error': 'Source for $scriptName could not be loaded.'
+          }]);
+        }
+      });
+    } else {
+      request(requestString).then((responseString) {
+        parseResponses(responseString);
+      }).catchError((e) {
+        setResponseError(e.target);
+      });
+    }
+  }
+
+  Future<ScriptSource> getScriptSource(String name, String requestString) {
+    int isolateId = _application.locationManager.currentIsolateId();
+    Isolate isolate = _application.isolateManager.getIsolate(isolateId);
+    ScriptSource source = isolate.scripts[name];
+    if (source != null) {
+      return new Future.value(source);
+    }
+    return request(requestString).then((responseString) {
+      var r = JSON.decode(responseString);
+      ScriptSource scriptSource = new ScriptSource(r);
+      isolate.scripts[name] = scriptSource;
+      return scriptSource;
     }).catchError((e) {
       setResponseError(e.target);
+      return null;
     });
   }
 
diff --git a/runtime/bin/vmservice/client/lib/src/observatory/script_source.dart b/runtime/bin/vmservice/client/lib/src/observatory/script_source.dart
new file mode 100644
index 0000000..1c2acec
--- /dev/null
+++ b/runtime/bin/vmservice/client/lib/src/observatory/script_source.dart
@@ -0,0 +1,42 @@
+// 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 observatory;
+
+class ScriptSourceLine extends Observable {
+  final int line;
+  final int numDigits;
+  @observable final String src;
+  @observable String paddedLine;
+  ScriptSourceLine(this.line, this.numDigits, this.src) {
+    paddedLine = '$line';
+    for (int i = paddedLine.length; i < numDigits; i++) {
+      paddedLine = ' $paddedLine';
+    }
+  }
+}
+
+class ScriptSource extends Observable {
+  @observable String kind = '';
+  @observable String url = '';
+  @observable List<ScriptSourceLine> lines = toObservable([]);
+
+  ScriptSource(Map response) {
+    kind = response['kind'];
+    url = response['name'];
+    buildSourceLines(response['source']);
+  }
+
+  void buildSourceLines(String src) {
+    List<String> splitSrc = src.split('\n');
+    int numDigits = '${splitSrc.length+1}'.length;
+    for (int i = 0; i < splitSrc.length; i++) {
+      ScriptSourceLine sourceLine = new ScriptSourceLine(i+1, numDigits,
+                                                         splitSrc[i]);
+      lines.add(sourceLine);
+    }
+  }
+
+  String toString() => 'ScriptSource';
+}
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/error_view.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/error_view.dart
index 787dba1..33c4089 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/error_view.dart
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/error_view.dart
@@ -11,7 +11,7 @@
 @CustomTag('error-view')
 class ErrorViewElement extends ObservatoryElement {
   @published String error = '';
-  @published error_obj;
+  @published var error_obj;
 
   ErrorViewElement.created() : super.created();
 }
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/library_view.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/library_view.html
index aaa0667..93009fb 100644
--- a/runtime/bin/vmservice/client/lib/src/observatory_elements/library_view.html
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/library_view.html
@@ -4,13 +4,74 @@
 <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>
+  <table class="table table-hover">
+    <tbody>
+      <tr template repeat="{{ script in library['scripts']}}">
+        <td>
+          {{ script['kind'] }}
+        </td>
+        <td>
+          <a href="{{ app.locationManager.currentIsolateScriptLink(script['id'], script['name']) }}">{{ script['name'] }}</a>
+        </td>
+      </tr>
+    </tbody>
+  </table>
   <div class="alert alert-info">Imported Libraries</div>
   <table class="table table-hover">
     <tbody>
       <tr template repeat="{{ lib in library['libraries'] }}">
         <td>
           <a href="{{ app.locationManager.currentIsolateObjectLink(lib['id'])}}">
-            {{ lib['name'] }}
+            {{ lib['url'] }}
+          </a>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div class="alert alert-info">Variables</div>
+  <table class="table table-hover">
+    <tbody>
+      <tr template repeat="{{ variable in library['variables'] }}">
+        <td>
+          <template if="{{ variable['final'] }}">
+            final
+          </template>
+          <template if="{{ variable['const'] }}">
+            const
+          </template>
+          <template if="{{ (variable['declared_type']['name'] == 'dynamic' && !variable['final'] && !variable['const']) }}">
+            var
+          </template>
+          <template if="{{ (variable['declared_type']['name'] != 'dynamic') }}">
+            <a href="{{ app.locationManager.currentIsolateClassLink(variable['declared_type']['id']) }}">
+              {{ variable['declared_type']['user_name'] }}
+            </a>
+          </template>
+          <a href="{{ app.locationManager.currentIsolateObjectLink(variable['id'])}}">
+            {{ variable['user_name'] }}
+          </a>
+        </td>
+        <td>
+          <template if="{{ (variable['value']['type'] == 'null') }}">
+            {{ "null" }}
+          </template>
+          <template if="{{ (variable['value']['type'] != 'null') }}">
+            <a href="{{ app.locationManager.currentIsolateObjectLink(variable['value']['id'])}}">
+              {{ variable['value']['preview'] }}
+            </a>
+          </template>
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  <div class="alert alert-info">Functions</div>
+  <table class="table table-hover">
+    <tbody>
+      <tr template repeat="{{ func in library['functions'] }}">
+        <td>
+          <a href="{{ app.locationManager.currentIsolateObjectLink(func['id'])}}">
+            {{ func['user_name'] }}
           </a>
         </td>
       </tr>
@@ -39,6 +100,7 @@
       </tr>
     </tbody>
   </table>
+
   </template>
   <script type="application/dart" src="library_view.dart"></script>
 </polymer-element>
\ No newline at end of file
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 3ea91e3..6ed611e 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
@@ -7,6 +7,8 @@
   <link rel="import" href="isolate_list.html">
   <link rel="import" href="library_view.html">
   <link rel="import" href="observatory_element.html">
+  <link rel="import" href="script_view.html">
+  <link rel="import" href="source_view.html">
   <link rel="import" href="stack_trace.html">
 </head>
 <polymer-element name="message-viewer" extends="observatory-element">
@@ -42,6 +44,9 @@
     <template if="{{ messageType == 'Code' }}">
       <code-view app="{{ app }}" code="{{ message }}"></code-view>
     </template>
+    <template if="{{ messageType == 'Script' }}">
+      <script-view app="{{ app }}" script="{{ message }}"></script-view>
+    </template>
     <!-- Add new views and message types in the future here. -->
   </template>
   <script type="application/dart" src="message_viewer.dart"></script>
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.dart
new file mode 100644
index 0000000..2b8550e
--- /dev/null
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.dart
@@ -0,0 +1,16 @@
+// 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 script_view_element;
+
+import 'package:polymer/polymer.dart';
+import 'observatory_element.dart';
+
+/// Displays an Error response.
+@CustomTag('script-view')
+class ScriptViewElement extends ObservatoryElement {
+  @published Map script;
+
+  ScriptViewElement.created() : super.created();
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..0666dff
--- /dev/null
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/script_view.html
@@ -0,0 +1,10 @@
+<head>
+  <link rel="import" href="observatory_element.html">
+  <link rel="import" href="source_view.html">
+</head>
+<polymer-element name="script-view" extends="observatory-element">
+  <template>
+    <source-view app="{{ app }}" source="{{ script['source'] }}"></source-view>
+  </template>
+  <script type="application/dart" src="script_view.dart"></script>
+</polymer-element>
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/source_view.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/source_view.dart
new file mode 100644
index 0000000..4065aed
--- /dev/null
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/source_view.dart
@@ -0,0 +1,17 @@
+// 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 source_view_element;
+
+import 'package:polymer/polymer.dart';
+import 'package:observatory/observatory.dart';
+import 'observatory_element.dart';
+
+/// Displays an Error response.
+@CustomTag('source-view')
+class SourceViewElement extends ObservatoryElement {
+  @published ScriptSource source;
+
+  SourceViewElement.created() : super.created();
+}
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/source_view.html b/runtime/bin/vmservice/client/lib/src/observatory_elements/source_view.html
new file mode 100644
index 0000000..38f3160
--- /dev/null
+++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/source_view.html
@@ -0,0 +1,22 @@
+<head>
+  <link rel="import" href="observatory_element.html">
+</head>
+<polymer-element name="source-view" extends="observatory-element">
+  <template>
+  <div class="row">
+    <div class="col-md-8 col-md-offset-2">
+      <div class="panel-heading">{{ source.url }}</div>
+      <div class="panel-body">
+        <div class="row">
+          <div><strong>Source</strong></div>
+        </div>
+        <pre>
+        <template repeat="{{ line in source.lines }}">{{line.paddedLine}} {{line.src}}
+        </template>
+        </pre>
+      </div>
+    </div>
+  </div>
+  </template>
+  <script type="application/dart" src="source_view.dart"></script>
+</polymer-element>
\ No newline at end of file
diff --git a/runtime/bin/vmservice/client/web/index.html b/runtime/bin/vmservice/client/web/index.html
index 48a9cbd..b96cbdc 100644
--- a/runtime/bin/vmservice/client/web/index.html
+++ b/runtime/bin/vmservice/client/web/index.html
@@ -5,7 +5,7 @@
   <link type="text/css" rel="stylesheet" 
                         href="bootstrap_css/css/bootstrap.min.css" />
   <link rel="import" href="packages/observatory/observatory_elements.html">
-  <script type='application/dart'>export 'package:polymer/init.dart';</script>
+  <script type="application/dart">export 'package:polymer/init.dart';</script>
   <script src="packages/browser/dart.js"></script>
 </head>
 <body>
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 805737c..feb3819 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -409,6 +409,12 @@
  * This handle has the lifetime of the current isolate unless it is
  * explicitly deallocated by calling Dart_DeletePersistentHandle.
  *
+ * If the object becomes unreachable the callback is invoked with the weak
+ * persistent handle and the peer as arguments. This gives the native code the
+ * ability to cleanup data associated with the object and to delete the weak
+ * persistent handle. It is illegal to call into the VM from the callback,
+ * except to delete the weak persistent handle.
+ *
  * Requires there to be a current isolate.
  *
  * \param object An object.
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 405c129..d67d438 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -250,7 +250,7 @@
   const Array& args = Array::Handle(Array::New(6));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
   args.SetAt(1, type);
-  args.SetAt(2, String::Handle(cls.UserVisibleName()));
+  args.SetAt(2, String::Handle(cls.Name()));
   args.SetAt(3, Bool::Get(cls.NumTypeParameters() != 0));
   args.SetAt(4, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
   args.SetAt(5, owner_mirror);
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 2bda632..d52530b 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -406,10 +406,10 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, y, arguments->NativeArgAt(2));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, z, arguments->NativeArgAt(3));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, w, arguments->NativeArgAt(4));
-  int32_t _x = static_cast<int32_t>(x.AsInt64Value() & 0xFFFFFFFF);
-  int32_t _y = static_cast<int32_t>(y.AsInt64Value() & 0xFFFFFFFF);
-  int32_t _z = static_cast<int32_t>(z.AsInt64Value() & 0xFFFFFFFF);
-  int32_t _w = static_cast<int32_t>(w.AsInt64Value() & 0xFFFFFFFF);
+  int32_t _x = static_cast<int32_t>(x.AsTruncatedUint32Value());
+  int32_t _y = static_cast<int32_t>(y.AsTruncatedUint32Value());
+  int32_t _z = static_cast<int32_t>(z.AsTruncatedUint32Value());
+  int32_t _w = static_cast<int32_t>(w.AsTruncatedUint32Value());
   return Int32x4::New(_x, _y, _z, _w);
 }
 
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index fb3d65f..2a71553 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -317,14 +317,14 @@
   // Method(s) implementing the Collection interface.
   bool contains(element) => IterableMixinWorkaround.contains(this, element);
 
-  void forEach(void f(num element)) {
+  void forEach(void f(element)) {
     var len = this.length;
     for (var i = 0; i < len; i++) {
       f(this[i]);
     }
   }
 
-  Iterable map(f(num element)) {
+  Iterable map(f(element)) {
     return IterableMixinWorkaround.mapList(this, f);
   }
 
@@ -332,20 +332,20 @@
     return IterableMixinWorkaround.join(this, separator);
   }
 
-  num reduce(dynamic combine(num value, num element)) {
+  dynamic reduce(dynamic combine(value, element)) {
     return IterableMixinWorkaround.reduce(this, combine);
   }
 
   dynamic fold(dynamic initialValue,
-               dynamic combine(dynamic initialValue, num element)) {
+               dynamic combine(dynamic initialValue, element)) {
     return IterableMixinWorkaround.fold(this, initialValue, combine);
   }
 
-  Iterable where(bool f(num element)) {
+  Iterable where(bool f(element)) {
     return IterableMixinWorkaround.where(this, f);
   }
 
-  Iterable expand(Iterable f(num element)) {
+  Iterable expand(Iterable f(element)) {
     return IterableMixinWorkaround.expand(this, f);
   }
 
@@ -353,7 +353,7 @@
     return IterableMixinWorkaround.takeList(this, n);
   }
 
-  Iterable takeWhile(bool test(num element)) {
+  Iterable takeWhile(bool test(element)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
@@ -361,35 +361,35 @@
     return IterableMixinWorkaround.skipList(this, n);
   }
 
-  Iterable skipWhile(bool test(num element)) {
+  Iterable skipWhile(bool test(element)) {
     return IterableMixinWorkaround.skipWhile(this, test);
   }
 
-  bool every(bool f(num element)) {
+  bool every(bool f(element)) {
     return IterableMixinWorkaround.every(this, f);
   }
 
-  bool any(bool f(num element)) {
+  bool any(bool f(element)) {
     return IterableMixinWorkaround.any(this, f);
   }
 
-  num firstWhere(bool test(num element), {orElse()}) {
+  dynamic firstWhere(bool test(element), {orElse()}) {
     return IterableMixinWorkaround.firstWhere(this, test, orElse);
   }
 
-  num lastWhere(bool test(num element), {orElse()}) {
+  dynamic lastWhere(bool test(element), {orElse()}) {
     return IterableMixinWorkaround.lastWhereList(this, test, orElse);
   }
 
-  num singleWhere(bool test(num element)) {
+  dynamic singleWhere(bool test(element)) {
     return IterableMixinWorkaround.singleWhere(this, test);
   }
 
-  Iterable<num> get reversed {
+  Iterable<dynamic> get reversed {
     return IterableMixinWorkaround.reversedList(this);
   }
 
-  num elementAt(int index) {
+  dynamic elementAt(int index) {
     return this[index];
   }
 
@@ -426,7 +426,7 @@
         "Cannot insert into a non-extendable array");
   }
 
-  void sort([int compare(num a, num b)]) {
+  void sort([int compare(a, b)]) {
     IterableMixinWorkaround.sortList(this, compare);
   }
 
@@ -472,17 +472,17 @@
         "Cannot remove from a non-extendable array");
   }
 
-  num get first {
+  dynamic get first {
     if (length > 0) return this[0];
     throw new StateError("No elements");
   }
 
-  num get last {
+  dynamic get last {
     if (length > 0) return this[length - 1];
     throw new StateError("No elements");
   }
 
-  num get single {
+  dynamic get single {
     if (length == 1) return this[0];
     if (length == 0) throw new StateError("No elements");
     throw new StateError("More than one element");
@@ -506,7 +506,7 @@
     return new Set.from(this);
   }
 
-  Map<int, num> asMap() {
+  Map<int, dynamic> asMap() {
     return IterableMixinWorkaround.asMapList(this);
   }
 
@@ -534,7 +534,7 @@
     IterableMixinWorkaround.setAllList(this, index, iterable);
   }
 
-  void fillRange(int start, int end, [num fillValue]) {
+  void fillRange(int start, int end, [fillValue]) {
     IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
   }
 
diff --git a/runtime/platform/c99_support_win.h b/runtime/platform/c99_support_win.h
index 71ec127..b952ecd 100644
--- a/runtime/platform/c99_support_win.h
+++ b/runtime/platform/c99_support_win.h
@@ -5,8 +5,10 @@
 #ifndef PLATFORM_C99_SUPPORT_WIN_H_
 #define PLATFORM_C99_SUPPORT_WIN_H_
 
-// Visual C++ is missing a bunch of C99 math macros and
-// functions. Define them here.
+#if defined(_MSC_VER) && (_MSC_VER < 1800)
+
+// Before Visual Studio 2013 Visual C++ was missing a bunch of C99 math macros
+// and functions. Define them here.
 
 #include <float.h>
 #include <string.h>
@@ -70,5 +72,6 @@
 #define strtoll _strtoi64
 #endif
 
+#endif
 
 #endif  // PLATFORM_C99_SUPPORT_WIN_H_
diff --git a/runtime/platform/thread_win.cc b/runtime/platform/thread_win.cc
index d3712d2..f4494ae 100644
--- a/runtime/platform/thread_win.cc
+++ b/runtime/platform/thread_win.cc
@@ -293,6 +293,8 @@
         ASSERT(previous != NULL);
         previous->next_ = current->next_;
       }
+      // Clear next.
+      wait_data->next_ = NULL;
       break;
     }
     previous = current;
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index c77eb42..d036fde 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -693,6 +693,16 @@
 }
 
 
+uint32_t BigintOperations::TruncateToUint32(const Bigint& bigint) {
+  uint32_t value = 0;
+  for (intptr_t i = bigint.Length() - 1; i >= 0; i--) {
+    value <<= kDigitBitSize;
+    value += static_cast<uint32_t>(bigint.GetChunkAt(i));
+  }
+  return value;
+}
+
+
 bool BigintOperations::AbsFitsIntoUint64(const Bigint& bigint) {
   intptr_t b_length = bigint.Length();
   intptr_t num_bits = CountBits(bigint.GetChunkAt(b_length - 1));
diff --git a/runtime/vm/bigint_operations.h b/runtime/vm/bigint_operations.h
index b56eb83..70fe3a2 100644
--- a/runtime/vm/bigint_operations.h
+++ b/runtime/vm/bigint_operations.h
@@ -68,6 +68,7 @@
   static bool FitsIntoUint64(const Bigint& bigint);
   static bool AbsFitsIntoUint64(const Bigint& bigint);
   static uint64_t ToUint64(const Bigint& bigint);
+  static uint32_t TruncateToUint32(const Bigint& bigint);
   static uint64_t AbsToUint64(const Bigint& bigint);
 
   static RawDouble* ToDouble(const Bigint& bigint);
diff --git a/runtime/vm/block_scheduler.cc b/runtime/vm/block_scheduler.cc
index 37a9710..1591929 100644
--- a/runtime/vm/block_scheduler.cc
+++ b/runtime/vm/block_scheduler.cc
@@ -53,7 +53,8 @@
 
 void BlockScheduler::AssignEdgeWeights() const {
   const Code& unoptimized_code = Code::Handle(
-      flow_graph()->parsed_function().function().unoptimized_code());
+      flow_graph()->parsed_function().code());
+  ASSERT(!unoptimized_code.IsNull());
 
   intptr_t entry_count =
       ComputeEdgeCount(unoptimized_code,
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index 1b2786f..f78aeef 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -28,7 +28,7 @@
       "}\n";
 
   TestCase::LoadTestScript(kScriptChars, NULL);
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index b5216dc..64a2c87 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -104,10 +104,10 @@
 }
 
 
-// Type hierarchy finalization occurs:
+// Processing ObjectStore::pending_classes_ occurs:
 // a) when bootstrap process completes (VerifyBootstrapClasses).
 // b) after the user classes are loaded (dart_api).
-bool ClassFinalizer::FinalizeTypeHierarchy() {
+bool ClassFinalizer::ProcessPendingClasses() {
   bool retval = true;
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate != NULL);
@@ -227,7 +227,7 @@
 
   // Finalize type hierarchy for types that aren't pre-finalized
   // by Object::Init().
-  if (!FinalizeTypeHierarchy()) {
+  if (!ProcessPendingClasses()) {
     // TODO(srdjan): Exit like a real VM instead.
     const Error& err = Error::Handle(object_store->sticky_error());
     OS::PrintErr("Could not verify bootstrap classes : %s\n",
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 25d4861..91ec1ff 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -78,11 +78,11 @@
   // Return false if we still have classes pending to be finalized.
   static bool AllClassesFinalized();
 
-  // Return whether type hierarchy finalization failed.
-  // The function returns true if the finalization was successful.
-  // If finalization fails, an error message is set in the sticky error field
+  // Return whether processing pending classes (ObjectStore::pending_classes_)
+  // failed. The function returns true if the processing was successful.
+  // If processin fails, an error message is set in the sticky error field
   // in the object store.
-  static bool FinalizeTypeHierarchy();
+  static bool ProcessPendingClasses();
 
   // Finalize the types appearing in the declaration of class 'cls', i.e. its
   // type parameters and their upper bounds, its super type and interfaces.
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 1f55b0f..972eb6d 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -40,7 +40,7 @@
   pending_classes.Add(*classes_2[1]);
   classes_2.Add(&Class::ZoneHandle(CreateTestClass("Alfa")));
   pending_classes.Add(*classes_2[2]);
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   for (int i = 0; i < classes_1.length(); i++) {
     EXPECT(classes_1[i]->is_type_finalized());
   }
@@ -48,7 +48,7 @@
     EXPECT(classes_2[i]->is_type_finalized());
   }
   EXPECT(ClassFinalizer::AllClassesFinalized());
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
 
 
@@ -67,7 +67,7 @@
       Type::Handle(Type::NewNonParameterizedType(*classes[1])));
   classes[1]->set_super_type(
       Type::Handle(Type::NewNonParameterizedType(*classes[0])));
-  EXPECT(!ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(!ClassFinalizer::ProcessPendingClasses());
 }
 
 
@@ -99,7 +99,7 @@
       Type::New(Object::Handle(unresolved.raw()),
                 type_arguments,
                 Scanner::kDummyTokenIndex)));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
 
 }  // namespace dart
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 3d87602..0d007b2 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -219,7 +219,7 @@
       "}\n";
   // First setup the script and compile the script.
   TestCase::LoadTestScript(kScriptChars, native_resolver);
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 686ddd1..882f593 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1341,9 +1341,16 @@
     DartFrameIterator iterator;
     StackFrame* frame = iterator.NextFrame();
     ASSERT(frame != NULL);
-    const Function& function = Function::Handle(frame->LookupDartFunction());
+    const Code& code = Code::ZoneHandle(frame->LookupDartCode());
+    ASSERT(!code.IsNull());
+    const Function& function = Function::Handle(code.function());
     ASSERT(!function.IsNull());
-    if (!CanOptimizeFunction(function, isolate)) return;
+    // Since the code is referenced from the frame and the ZoneHandle,
+    // it cannot have been removed from the function.
+    ASSERT(function.HasCode());
+    if (!CanOptimizeFunction(function, isolate)) {
+      return;
+    }
     intptr_t osr_id =
         Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
     if (FLAG_trace_osr) {
@@ -1354,9 +1361,14 @@
     }
 
     const Code& original_code = Code::Handle(function.CurrentCode());
+    // Since the code is referenced from the frame and the ZoneHandle,
+    // it cannot have been removed from the function.
+    ASSERT(!original_code.IsNull());
     const Error& error =
         Error::Handle(Compiler::CompileOptimizedFunction(function, osr_id));
-    if (!error.IsNull()) Exceptions::PropagateError(error);
+    if (!error.IsNull()) {
+      Exceptions::PropagateError(error);
+    }
 
     const Code& optimized_code = Code::Handle(function.CurrentCode());
     // The current code will not be changed in the case that the compiler
@@ -1433,30 +1445,25 @@
   ASSERT(caller_code.is_optimized());
   const Function& target_function = Function::Handle(
       caller_code.GetStaticCallTargetFunctionAt(frame->pc()));
+  const Code& target_code = Code::Handle(
+      caller_code.GetStaticCallTargetCodeAt(frame->pc()));
+  ASSERT(!target_code.IsNull());
+  // Since there was a reference to the target_code in the caller_code, it is
+  // not possible for the target_function's code to be disconnected.
+  ASSERT(target_function.HasCode());
+  ASSERT(target_function.raw() == target_code.function());
 
-  // Check whether the code object has been detached from the target function.
-  // If it has been detached, reattach it.
-  Code& target_code = Code::Handle();
-  if (target_function.HasCode()) {
-    target_code ^= target_function.CurrentCode();
-    CodePatcher::PatchStaticCallAt(frame->pc(), caller_code,
-                                   target_code.EntryPoint());
-    caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code);
-  } else {
-    ASSERT(target_function.unoptimized_code() == Code::null());
-    target_code ^= caller_code.GetStaticCallTargetCodeAt(frame->pc());
-    ASSERT(!target_code.IsNull());
-    ASSERT(!target_code.is_optimized());
-    target_function.ReattachCode(target_code);
-  }
+  const Code& current_target_code = Code::Handle(target_function.CurrentCode());
+  CodePatcher::PatchStaticCallAt(frame->pc(), caller_code,
+                                 current_target_code.EntryPoint());
+  caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code);
   if (FLAG_trace_patching) {
     OS::PrintErr("FixCallersTarget: patching from %#" Px " to '%s' %#" Px "\n",
         frame->pc(),
-        Function::Handle(target_code.function()).ToFullyQualifiedCString(),
-        target_code.EntryPoint());
+        target_function.ToFullyQualifiedCString(),
+        current_target_code.EntryPoint());
   }
-  arguments.SetReturn(target_code);
-  ASSERT(target_function.HasCode());
+  arguments.SetReturn(current_target_code);
 }
 
 
@@ -1481,7 +1488,7 @@
   const Function& function = Function::Handle(optimized_code.function());
   const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
   ASSERT(!unoptimized_code.IsNull());
-  // The switch to unoptimized code may have already occured.
+  // The switch to unoptimized code may have already occurred.
   if (function.HasOptimizedCode()) {
     function.SwitchToUnoptimizedCode();
   }
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index c7e7cdb..42d1121 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -293,7 +293,7 @@
                                               RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::Handle(LookupClass(lib, "A"));
   EXPECT(!cls.IsNull());
 
@@ -340,7 +340,7 @@
                                               RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
   EXPECT(!cls.IsNull());
 
@@ -532,7 +532,7 @@
                                               RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::ZoneHandle(LookupClass(lib, "A"));
   EXPECT(!cls.IsNull());
 
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 9294e0e..c0f4799 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -42,7 +42,7 @@
   // Restore entry point with original code (i.e., before patching).
   static void RestoreEntry(const Code& code);
 
-  // Returns true if the code can be patched with a jump at beginnning (checks
+  // Returns true if the code can be patched with a jump at beginning (checks
   // that there are no conflicts with object pointers). Used in ASSERTs.
   static bool CodeIsPatchable(const Code& code);
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 87e85db..d8771dc 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -388,7 +388,11 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         // Do optimizations that depend on the propagated type information.
-        optimizer.Canonicalize();
+        if (optimizer.Canonicalize()) {
+          // Invoke Canonicalize twice in order to fully canonicalize patterns
+          // like "if (a & const == 0) { }".
+          optimizer.Canonicalize();
+        }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         BranchSimplifier::Simplify(flow_graph);
@@ -734,8 +738,10 @@
   LongJump* base = isolate->long_jump_base();
   LongJump jump;
   isolate->set_long_jump_base(&jump);
+  // Make sure unoptimized code is not collected while we are compiling.
+  const Code& unoptimized_code = Code::ZoneHandle(function.unoptimized_code());
   // Skips parsing if we need to only install unoptimized code.
-  if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) {
+  if (!optimized && !unoptimized_code.IsNull()) {
     InstallUnoptimizedCode(function);
     isolate->set_long_jump_base(base);
     return Error::null();
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index e7c4820..3e6ef9d 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -42,7 +42,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 7503dd0..2633f25 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -17,7 +17,6 @@
 #include "vm/object_id_ring.h"
 #include "vm/port.h"
 #include "vm/profiler.h"
-#include "vm/signal_handler.h"
 #include "vm/simulator.h"
 #include "vm/snapshot.h"
 #include "vm/stub_code.h"
@@ -173,7 +172,6 @@
   vm_isolate_ = NULL;
 #endif
 
-  ScopedSignalBlocker ssb;
   ProfilerManager::Shutdown();
   CodeObservers::DeleteAll();
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 19d01a2..8280f94 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -160,7 +160,7 @@
     // Class finalization is blocked for the isolate. Do nothing.
     return Api::Success();
   }
-  if (ClassFinalizer::FinalizeTypeHierarchy()) {
+  if (ClassFinalizer::ProcessPendingClasses()) {
     return Api::Success();
   }
   ASSERT(isolate->object_store()->sticky_error() != Object::null());
diff --git a/runtime/vm/dart_entry_test.cc b/runtime/vm/dart_entry_test.cc
index 576d6f3..301dd56 100644
--- a/runtime/vm/dart_entry_test.cc
+++ b/runtime/vm/dart_entry_test.cc
@@ -26,7 +26,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT_EQ(true, CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
@@ -54,7 +54,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT_EQ(true, CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
@@ -81,7 +81,7 @@
                                               RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT_EQ(true, CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New("A"))));
   EXPECT(!cls.IsNull());  // No ambiguity error expected.
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index ea2e147..6a1bad4 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -566,10 +566,8 @@
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    Function& function = Function::Handle(deopt_context->isolate());
-    function ^= deopt_context->ObjectAt(object_table_index_);
-    const Code& code =
-        Code::Handle(deopt_context->isolate(), function.unoptimized_code());
+    Code& code = Code::Handle(deopt_context->isolate());
+    code ^= deopt_context->ObjectAt(object_table_index_);
     ASSERT(!code.IsNull());
     uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
                                                 PcDescriptors::kDeopt);
@@ -789,16 +787,16 @@
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    Function& function = Function::Handle(deopt_context->isolate());
-    function ^= deopt_context->ObjectAt(object_table_index_);
-    if (function.IsNull()) {
+    Code& code = Code::Handle(deopt_context->isolate());
+    code ^= deopt_context->ObjectAt(object_table_index_);
+    if (code.IsNull()) {
       // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
       *dest_addr = 0;
       return;
     }
-    const Code& code =
-        Code::Handle(deopt_context->isolate(), function.unoptimized_code());
-    ASSERT(!code.IsNull());
+    const Function& function =
+        Function::Handle(deopt_context->isolate(), code.function());
+    ASSERT(function.HasCode());
     const intptr_t pc_marker =
         code.EntryPoint() + Assembler::kEntryPointToPcMarkerOffset;
     *dest_addr = pc_marker;
@@ -813,7 +811,9 @@
     // Clear invocation counter so that hopefully the function gets reoptimized
     // only after more feedback has been collected.
     function.set_usage_counter(0);
-    if (function.HasOptimizedCode()) function.SwitchToUnoptimizedCode();
+    if (function.HasOptimizedCode()) {
+      function.SwitchToUnoptimizedCode();
+    }
   }
 
  private:
@@ -841,10 +841,8 @@
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    Function& function = Function::Handle(deopt_context->isolate());
-    function ^= deopt_context->ObjectAt(object_table_index_);
-    const Code& code =
-        Code::Handle(deopt_context->isolate(), function.unoptimized_code());
+    Code& code = Code::Handle(deopt_context->isolate());
+    code ^= deopt_context->ObjectAt(object_table_index_);
     ASSERT(!code.IsNull());
     const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
     *dest_addr = pp;
@@ -1051,9 +1049,10 @@
   ASSERT(Isolate::IsDeoptAfter(ret_address_instr->deopt_id()));
   ASSERT(!object_table.IsNull());
   ASSERT(func != NULL);
-  *func ^= object_table.At(ret_address_instr->object_table_index());
-  const Code& code = Code::Handle(func->unoptimized_code());
+  Code& code = Code::Handle();
+  code ^= object_table.At(ret_address_instr->object_table_index());
   ASSERT(!code.IsNull());
+  *func ^= code.function();
   uword res = code.GetPcForDeoptId(ret_address_instr->deopt_id(),
                                    PcDescriptors::kDeopt);
   ASSERT(res != 0);
@@ -1161,36 +1160,32 @@
 }
 
 
-void DeoptInfoBuilder::AddReturnAddress(const Function& function,
+void DeoptInfoBuilder::AddReturnAddress(const Code& code,
                                         intptr_t deopt_id,
                                         intptr_t dest_index) {
   // Check that deopt_id exists.
   // TODO(vegorov): verify after deoptimization targets as well.
 #ifdef DEBUG
-  const Code& code = Code::Handle(function.unoptimized_code());
-  // The inlined function's code pointer may be null if there is a GC during
-  // compilation.
-  // TODO(zra): See if we can avoid this check by ensuring that code is not
-  //            removed during inlining.
-  ASSERT(code.IsNull() || Isolate::IsDeoptAfter(deopt_id) ||
-      (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0));
+  ASSERT(Isolate::IsDeoptAfter(deopt_id) ||
+         (code.GetPcForDeoptId(deopt_id, PcDescriptors::kDeopt) != 0));
 #endif
-  const intptr_t object_table_index = FindOrAddObjectInTable(function);
+  const intptr_t object_table_index = FindOrAddObjectInTable(code);
   ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptRetAddressInstr(object_table_index, deopt_id));
 }
 
 
-void DeoptInfoBuilder::AddPcMarker(const Function& function,
+void DeoptInfoBuilder::AddPcMarker(const Code& code,
                                    intptr_t dest_index) {
-  intptr_t object_table_index = FindOrAddObjectInTable(function);
+  intptr_t object_table_index = FindOrAddObjectInTable(code);
   ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptPcMarkerInstr(object_table_index));
 }
 
 
-void DeoptInfoBuilder::AddPp(const Function& function, intptr_t dest_index) {
-  intptr_t object_table_index = FindOrAddObjectInTable(function);
+void DeoptInfoBuilder::AddPp(const Code& code,
+                             intptr_t dest_index) {
+  intptr_t object_table_index = FindOrAddObjectInTable(code);
   ASSERT(dest_index == FrameSize());
   instructions_.Add(new DeoptPpInstr(object_table_index));
 }
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index f55c120..43a2bdc 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -282,14 +282,14 @@
   const GrowableObjectArray& object_table() { return object_table_; }
 
   // Return address before instruction.
-  void AddReturnAddress(const Function& function,
+  void AddReturnAddress(const Code& code,
                         intptr_t deopt_id,
                         intptr_t dest_index);
 
   // Copy from optimized frame to unoptimized.
   void AddCopy(Value* value, const Location& source_loc, intptr_t dest_index);
-  void AddPcMarker(const Function& function, intptr_t dest_index);
-  void AddPp(const Function& function, intptr_t dest_index);
+  void AddPcMarker(const Code& code, intptr_t dest_index);
+  void AddPp(const Code& code, intptr_t dest_index);
   void AddCallerFp(intptr_t dest_index);
   void AddCallerPp(intptr_t dest_index);
   void AddCallerPc(intptr_t dest_index);
diff --git a/runtime/vm/find_code_object_test.cc b/runtime/vm/find_code_object_test.cc
index 599b8c9..f67b684 100644
--- a/runtime/vm/find_code_object_test.cc
+++ b/runtime/vm/find_code_object_test.cc
@@ -22,6 +22,12 @@
   const int kScriptSize = 512 * KB;
   const int kNumFunctions = 1024;
   char scriptChars[kScriptSize];
+
+  // Get access to the code index table.
+  Isolate* isolate = Isolate::Current();
+  ASSERT(isolate != NULL);
+
+  StackZone zone(isolate);
   String& url = String::Handle(String::New("dart-test:FindCodeObject"));
   String& source = String::Handle();
   Script& script = Script::Handle();
@@ -32,10 +38,6 @@
   Function& function = Function::Handle();
   char buffer[256];
 
-  // Get access to the code index table.
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate != NULL);
-
   lib = Library::CoreLibrary();
 
   // Load up class A with 1024 functions.
@@ -55,13 +57,15 @@
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   clsA = lib.LookupClass(String::Handle(Symbols::New("A")));
   EXPECT(!clsA.IsNull());
-  ClassFinalizer::FinalizeTypeHierarchy();
+  ClassFinalizer::ProcessPendingClasses();
   for (int i = 0; i < kNumFunctions; i++) {
     OS::SNPrint(buffer, 256, "foo%d", i);
     function_name = String::New(buffer);
     function = clsA.LookupStaticFunction(function_name);
     EXPECT(!function.IsNull());
     EXPECT(CompilerTest::TestCompileFunction(function));
+    const Code& code = Code::ZoneHandle(function.CurrentCode());
+    EXPECT(!code.IsNull())
     EXPECT(function.HasCode());
   }
 
@@ -103,13 +107,15 @@
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   clsB = lib.LookupClass(String::Handle(Symbols::New("B")));
   EXPECT(!clsB.IsNull());
-  ClassFinalizer::FinalizeTypeHierarchy();
+  ClassFinalizer::ProcessPendingClasses();
   for (int i = 0; i < kNumFunctions; i++) {
     OS::SNPrint(buffer, 256, "moo%d", i);
     function_name = String::New(buffer);
     function = clsB.LookupStaticFunction(function_name);
     EXPECT(!function.IsNull());
     EXPECT(CompilerTest::TestCompileFunction(function));
+    const Code& code = Code::ZoneHandle(function.CurrentCode());
+    EXPECT(!code.IsNull());
     EXPECT(function.HasCode());
   }
 
@@ -142,19 +148,11 @@
   code = function.CurrentCode();
   EXPECT(code.Size() > 16);
   pc = code.EntryPoint() + 16;
-#if defined(TARGET_ARCH_MIPS)
-  // MIPS can only Branch +/- 128KB
-  EXPECT(code.Size() > ((PageSpace::kPageSizeInWords << kWordSizeLog2) / 2));
-  EXPECT(Code::LookupCode(pc) == code.raw());
-  pc = code.EntryPoint() + ((PageSpace::kPageSizeInWords << kWordSizeLog2) / 4);
-  EXPECT(Code::LookupCode(pc) == code.raw());
-#else
   EXPECT(code.Size() > (PageSpace::kPageSizeInWords << kWordSizeLog2));
   EXPECT(Code::LookupCode(pc) == code.raw());
   EXPECT(code.Size() > (1 * MB));
   pc = code.EntryPoint() + (1 * MB);
   EXPECT(Code::LookupCode(pc) == code.raw());
-#endif  // defined(TARGET_ARCH_MIPS)
 }
 
 }  // namespace dart
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index ff6be53..5f03f47 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -755,7 +755,7 @@
   Environment* deopt_env =
       Environment::From(*env,
                         num_non_copied_params_,
-                        parsed_function_.function());
+                        Code::Handle(parsed_function_.code()));
   instr->SetEnvironment(deopt_env);
   for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) {
     Value* use = it.CurrentValue();
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index a70becc..848a632 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -433,7 +433,8 @@
         new BranchInstr(new StrictCompareInstr(call_block->start_pos(),
                                                Token::kEQ_STRICT,
                                                new Value(true_const),
-                                               new Value(true_const)));
+                                               new Value(true_const),
+                                               false));  // No number check.
     branch->InheritDeoptTarget(call_);
     *branch->true_successor_address() = callee_entry;
     *branch->false_successor_address() = false_block;
@@ -833,8 +834,8 @@
       new StrictCompareInstr(condition_token_pos(),
                              Token::kEQ_STRICT,
                              value,
-                             constant_true);
-  comp->set_needs_number_check(false);
+                             constant_true,
+                             false);  // No number check.
   BranchInstr* branch = new BranchInstr(comp);
   AddInstruction(branch);
   CloseFragment();
@@ -856,7 +857,8 @@
         comp->token_pos(),
         (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
         comp->left(),
-        comp->right()));
+        comp->right(),
+        false));  // No number check.
   } else {
     branch = new BranchInstr(comp, FLAG_enable_type_checks);
   }
@@ -874,8 +876,8 @@
       new StrictCompareInstr(condition_token_pos(),
                              Token::kNE_STRICT,
                              neg->value(),
-                             constant_true);
-  comp->set_needs_number_check(false);
+                             constant_true,
+                             false);  // No number check.
   BranchInstr* branch = new BranchInstr(comp);
   AddInstruction(branch);
   CloseFragment();
@@ -1201,7 +1203,8 @@
         for_right.Bind(new StrictCompareInstr(node->token_pos(),
                                               Token::kEQ_STRICT,
                                               right_value,
-                                              constant_true));
+                                              constant_true,
+                                              false));  // No number check.
     for_right.Do(BuildStoreExprTemp(compare));
 
     if (node->kind() == Token::kAND) {
@@ -1536,7 +1539,8 @@
   StrictCompareInstr* comp = new StrictCompareInstr(token_pos,
                                                     kind,
                                                     for_left_value.value(),
-                                                    for_right_value.value());
+                                                    for_right_value.value(),
+                                                    true);  // Number check.
   return comp;
 }
 
@@ -3090,13 +3094,14 @@
             node->scope()->LookupVariable(Symbols::Other(),
                                           true);  // Test only.
         Value* other = Bind(new LoadLocalInstr(*other_var));
+        // Receiver is not a number because numbers override equality.
+        const bool kNoNumberCheck = false;
         StrictCompareInstr* compare =
             new StrictCompareInstr(node->token_pos(),
                                    Token::kEQ_STRICT,
                                    receiver,
-                                   other);
-        // Receiver is not a number because numbers override equality.
-        compare->set_needs_number_check(false);
+                                   other,
+                                   kNoNumberCheck);
         return ReturnDefinition(compare);
       }
       case MethodRecognizer::kStringBaseLength:
@@ -3124,7 +3129,8 @@
             new StrictCompareInstr(node->token_pos(),
                                    Token::kEQ_STRICT,
                                    load_val,
-                                   zero_val);
+                                   zero_val,
+                                   false);  // No number check.
         return ReturnDefinition(compare);
       }
       case MethodRecognizer::kGrowableArrayLength:
@@ -3994,7 +4000,9 @@
         new CheckStackOverflowInstr(function.token_pos(), 0);
     // If we are inlining don't actually attach the stack check. We must still
     // create the stack check in order to allocate a deopt id.
-    if (!IsInlining()) for_effect.AddInstruction(check);
+    if (!IsInlining()) {
+      for_effect.AddInstruction(check);
+    }
   }
   parsed_function()->node_sequence()->Visit(&for_effect);
   AppendFragment(normal_entry, for_effect);
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 3683838..bf9df1a 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -23,13 +23,6 @@
 class ParsedFunction;
 
 
-struct BranchLabels {
-  Label* true_label;
-  Label* false_label;
-  Label* fall_through;
-};
-
-
 class ParallelMoveResolver : public ValueObject {
  public:
   explicit ParallelMoveResolver(FlowGraphCompiler* compiler);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 737514f..19a75bb 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -61,12 +61,12 @@
   builder->MarkFrameStart();
 
   // Current PP, FP, and PC.
-  builder->AddPp(current->function(), slot_ix++);
+  builder->AddPp(current->code(), slot_ix++);
   builder->AddCallerFp(slot_ix++);
-  builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
+  builder->AddReturnAddress(current->code(), deopt_id(), slot_ix++);
 
   // Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
-  builder->AddPcMarker(Function::Handle(), slot_ix++);
+  builder->AddPcMarker(Code::Handle(), slot_ix++);
 
   // Emit all values that are needed for materialization as a part of the
   // expression stack for the bottom-most frame. This guarantees that GC
@@ -84,17 +84,17 @@
   current = current->outer();
   while (current != NULL) {
     // PP, FP, and PC.
-    builder->AddPp(current->function(), slot_ix++);
+    builder->AddPp(current->code(), slot_ix++);
     builder->AddCallerFp(slot_ix++);
 
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
-    builder->AddReturnAddress(current->function(),
+    builder->AddReturnAddress(current->code(),
                               Isolate::ToDeoptAfter(current->deopt_id()),
                               slot_ix++);
 
     // PC marker.
-    builder->AddPcMarker(previous->function(), slot_ix++);
+    builder->AddPcMarker(previous->code(), slot_ix++);
 
     // The values of outgoing arguments can be changed from the inlined call so
     // we must read them from the previous environment.
@@ -126,7 +126,7 @@
   builder->AddCallerPc(slot_ix++);
 
   // PC marker.
-  builder->AddPcMarker(previous->function(), slot_ix++);
+  builder->AddPcMarker(previous->code(), slot_ix++);
 
   // For the outermost environment, set the incoming arguments.
   for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
@@ -1359,7 +1359,11 @@
     Label is_compiled;
     __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
     __ b(&is_compiled, NE);
-    __ BranchLink(&StubCode::CompileFunctionRuntimeCallLabel());
+    __ BranchLinkPatchable(&StubCode::CompileFunctionRuntimeCallLabel());
+    AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
+                         Isolate::kNoDeoptId,
+                         token_pos);
+    RecordSafepoint(locs);
     // R0: target function.
     __ ldr(R1, FieldAddress(R0, Function::code_offset()));
     __ Bind(&is_compiled);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index ed47c72..81ae0aa 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -64,12 +64,12 @@
   // The real frame starts here.
   builder->MarkFrameStart();
 
-  // Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
-  builder->AddPcMarker(Function::Handle(), slot_ix++);
+  // Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
+  builder->AddPcMarker(Code::Handle(), slot_ix++);
 
   // Current FP and PC.
   builder->AddCallerFp(slot_ix++);
-  builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
+  builder->AddReturnAddress(current->code(), deopt_id(), slot_ix++);
 
   // Emit all values that are needed for materialization as a part of the
   // expression stack for the bottom-most frame. This guarantees that GC
@@ -84,7 +84,7 @@
   }
 
   // Current PC marker and caller FP.
-  builder->AddPcMarker(current->function(), slot_ix++);
+  builder->AddPcMarker(current->code(), slot_ix++);
   builder->AddCallerFp(slot_ix++);
 
   Environment* previous = current;
@@ -92,7 +92,7 @@
   while (current != NULL) {
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
-    builder->AddReturnAddress(current->function(),
+    builder->AddReturnAddress(current->code(),
                               Isolate::ToDeoptAfter(current->deopt_id()),
                               slot_ix++);
 
@@ -114,7 +114,7 @@
     }
 
     // PC marker and caller FP.
-    builder->AddPcMarker(current->function(), slot_ix++);
+    builder->AddPcMarker(current->code(), slot_ix++);
     builder->AddCallerFp(slot_ix++);
 
     // Iterate on the outer environment.
@@ -146,7 +146,9 @@
 #define __ assem->
   __ Comment("Deopt stub for id %" Pd "", deopt_id());
   __ Bind(entry_label());
-  if (FLAG_trap_on_deoptimization) __ int3();
+  if (FLAG_trap_on_deoptimization) {
+    __ int3();
+  }
 
   ASSERT(deopt_env() != NULL);
 
@@ -1406,6 +1408,10 @@
     __ cmpl(EBX, raw_null);
     __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
     __ call(&StubCode::CompileFunctionRuntimeCallLabel());
+    AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
+                         Isolate::kNoDeoptId,
+                         token_pos);
+    RecordSafepoint(locs);
     __ movl(EBX, FieldAddress(EAX, Function::code_offset()));
     __ Bind(&is_compiled);
   }
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 721597f..9c09757 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -61,12 +61,12 @@
   builder->MarkFrameStart();
 
   // Current PP, FP, and PC.
-  builder->AddPp(current->function(), slot_ix++);
+  builder->AddPp(current->code(), slot_ix++);
   builder->AddCallerFp(slot_ix++);
-  builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
+  builder->AddReturnAddress(current->code(), deopt_id(), slot_ix++);
 
-  // Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
-  builder->AddPcMarker(Function::Handle(), slot_ix++);
+  // Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
+  builder->AddPcMarker(Code::Handle(), slot_ix++);
 
   // Emit all values that are needed for materialization as a part of the
   // expression stack for the bottom-most frame. This guarantees that GC
@@ -84,17 +84,17 @@
   current = current->outer();
   while (current != NULL) {
     // PP, FP, and PC.
-    builder->AddPp(current->function(), slot_ix++);
+    builder->AddPp(current->code(), slot_ix++);
     builder->AddCallerFp(slot_ix++);
 
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
-    builder->AddReturnAddress(current->function(),
+    builder->AddReturnAddress(current->code(),
                               Isolate::ToDeoptAfter(current->deopt_id()),
                               slot_ix++);
 
     // PC marker.
-    builder->AddPcMarker(previous->function(), slot_ix++);
+    builder->AddPcMarker(previous->code(), slot_ix++);
 
     // The values of outgoing arguments can be changed from the inlined call so
     // we must read them from the previous environment.
@@ -126,7 +126,7 @@
   builder->AddCallerPc(slot_ix++);
 
   // PC marker.
-  builder->AddPcMarker(previous->function(), slot_ix++);
+  builder->AddPcMarker(previous->code(), slot_ix++);
 
   // For the outermost environment, set the incoming arguments.
   for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
@@ -1406,6 +1406,10 @@
     __ BranchNotEqual(T1, reinterpret_cast<int32_t>(Object::null()),
                       &is_compiled);
     __ BranchLink(&StubCode::CompileFunctionRuntimeCallLabel());
+    AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
+                         Isolate::kNoDeoptId,
+                         token_pos);
+    RecordSafepoint(locs);
     __ lw(T1, FieldAddress(T0, Function::code_offset()));
     __ Bind(&is_compiled);
   }
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 9257c35..c2b1561 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -62,10 +62,10 @@
   builder->MarkFrameStart();
 
   // Current PP, FP, and PC.
-  builder->AddPp(current->function(), slot_ix++);
-  builder->AddPcMarker(Function::Handle(), slot_ix++);
+  builder->AddPp(current->code(), slot_ix++);
+  builder->AddPcMarker(Code::Handle(), slot_ix++);
   builder->AddCallerFp(slot_ix++);
-  builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
+  builder->AddReturnAddress(current->code(), deopt_id(), slot_ix++);
 
   // Emit all values that are needed for materialization as a part of the
   // expression stack for the bottom-most frame. This guarantees that GC
@@ -83,13 +83,13 @@
   current = current->outer();
   while (current != NULL) {
     // PP, FP, and PC.
-    builder->AddPp(current->function(), slot_ix++);
-    builder->AddPcMarker(previous->function(), slot_ix++);
+    builder->AddPp(current->code(), slot_ix++);
+    builder->AddPcMarker(previous->code(), slot_ix++);
     builder->AddCallerFp(slot_ix++);
 
     // For any outer environment the deopt id is that of the call instruction
     // which is recorded in the outer environment.
-    builder->AddReturnAddress(current->function(),
+    builder->AddReturnAddress(current->code(),
                               Isolate::ToDeoptAfter(current->deopt_id()),
                               slot_ix++);
 
@@ -120,7 +120,7 @@
   // For the outermost environment, set caller PC, caller PP, and caller FP.
   builder->AddCallerPp(slot_ix++);
   // PC marker.
-  builder->AddPcMarker(previous->function(), slot_ix++);
+  builder->AddPcMarker(previous->code(), slot_ix++);
   builder->AddCallerFp(slot_ix++);
   builder->AddCallerPc(slot_ix++);
 
@@ -1441,6 +1441,10 @@
     __ cmpq(RBX, raw_null);
     __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
     __ call(&StubCode::CompileFunctionRuntimeCallLabel());
+    AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
+                         Isolate::kNoDeoptId,
+                         token_pos);
+    RecordSafepoint(locs);
     __ movq(RBX, FieldAddress(RAX, Function::code_offset()));
     __ Bind(&is_compiled);
   }
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index b6512b1..dd798b8 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -59,10 +59,12 @@
 
 
 // Test if a call is recursive by looking in the deoptimization environment.
-static bool IsCallRecursive(const Function& function, Definition* call) {
+static bool IsCallRecursive(const Code& code, Definition* call) {
   Environment* env = call->env();
   while (env != NULL) {
-    if (function.raw() == env->function().raw()) return true;
+    if (code.raw() == env->code().raw()) {
+      return true;
+    }
     env = env->outer();
   }
   return false;
@@ -434,6 +436,9 @@
       return false;
     }
 
+    // Make a handle for the unoptimized code so that it is not disconnected
+    // from the function while we are trying to inline it.
+    const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
     // Abort if the inlinable bit on the function is low.
     if (!function.IsInlineable()) {
       TRACE_INLINING(OS::Print("     Bailout: not inlinable\n"));
@@ -466,7 +471,7 @@
 
     // Abort if this is a recursive occurrence.
     Definition* call = call_data->call;
-    if (!FLAG_inline_recursive && IsCallRecursive(function, call)) {
+    if (!FLAG_inline_recursive && IsCallRecursive(unoptimized_code, call)) {
       function.set_is_inlinable(false);
       TRACE_INLINING(OS::Print("     Bailout: recursive function\n"));
       return false;
@@ -493,11 +498,11 @@
 
       // Load IC data for the callee.
       Array& ic_data_array = Array::Handle();
-      if (function.HasCode()) {
-        const Code& unoptimized_code =
-            Code::Handle(function.unoptimized_code());
-        ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
-      }
+
+      // IsInlineable above checked HasCode. Creating a Handle for the code
+      // should have kept GC from detaching, but let's assert just to make sure.
+      ASSERT(function.HasCode());
+      ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
 
       // Build the callee graph.
       InlineExitCollector* exit_collector =
@@ -620,7 +625,9 @@
       collected_call_sites_->FindCallSites(callee_graph, inlining_depth_);
 
       // Add the function to the cache.
-      if (!in_cache) function_cache_.Add(parsed_function);
+      if (!in_cache) {
+        function_cache_.Add(parsed_function);
+      }
 
       // Build succeeded so we restore the bailout jump.
       inlined_ = true;
@@ -639,6 +646,9 @@
                                       (*callee_graph->guarded_fields())[i]);
       }
 
+      // We allocate a ZoneHandle for the unoptimized code so that it cannot be
+      // disconnected from its function during the rest of compilation.
+      Code::ZoneHandle(unoptimized_code.raw());
       TRACE_INLINING(OS::Print("     Success\n"));
       return true;
     } else {
@@ -1280,7 +1290,8 @@
           new StrictCompareInstr(call_->instance_call()->token_pos(),
                                  Token::kEQ_STRICT,
                                  new Value(load_cid),
-                                 new Value(cid_constant));
+                                 new Value(cid_constant),
+                                 false);  // No number check.
       BranchInstr* branch = new BranchInstr(compare);
       branch->InheritDeoptTarget(call_);
       AppendInstruction(AppendInstruction(cursor, cid_constant), branch);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index a036153..3efaad4 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1456,10 +1456,12 @@
       ConstantInstr* left_const = left->AsConstant();
       if ((right_const != NULL && right_const->value().IsNull()) ||
           (left_const != NULL && left_const->value().IsNull())) {
-        StrictCompareInstr* comp = new StrictCompareInstr(call->token_pos(),
-                                                          Token::kEQ_STRICT,
-                                                          new Value(left),
-                                                          new Value(right));
+        StrictCompareInstr* comp =
+            new StrictCompareInstr(call->token_pos(),
+                                   Token::kEQ_STRICT,
+                                   new Value(left),
+                                   new Value(right),
+                                   false);  // No number check.
         ReplaceCall(call, comp);
         return true;
       }
@@ -6368,34 +6370,17 @@
 
 
 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) {
-  ASSERT(Token::IsEqualityOperator(instr->kind()));
-
-  const Object& left = instr->left()->definition()->constant_value();
-  const Object& right = instr->right()->definition()->constant_value();
-
-  if (IsNonConstant(left) || IsNonConstant(right)) {
-    // TODO(vegorov): incorporate nullability information into the lattice.
-    if ((left.IsNull() && instr->right()->Type()->HasDecidableNullability()) ||
-        (right.IsNull() && instr->left()->Type()->HasDecidableNullability())) {
-      bool result = left.IsNull() ? instr->right()->Type()->IsNull()
-                                  : instr->left()->Type()->IsNull();
-      if (instr->kind() == Token::kNE_STRICT ||
-          instr->kind() == Token::kNE) {
-        result = !result;
-      }
-      SetValue(instr, Smi::Handle(
-          Smi::New(result ? instr->if_true() : instr->if_false())));
-    } else {
-      SetValue(instr, non_constant_);
-    }
-  } else if (IsConstant(left) && IsConstant(right)) {
-    bool result = (left.raw() == right.raw());
-    if (instr->kind() == Token::kNE_STRICT ||
-        instr->kind() == Token::kNE) {
-      result = !result;
-    }
-    SetValue(instr, Smi::Handle(
-        Smi::New(result ? instr->if_true() : instr->if_false())));
+  instr->comparison()->Accept(this);
+  const Object& value = instr->comparison()->constant_value();
+  if (IsNonConstant(value)) {
+    SetValue(instr, non_constant_);
+  } else if (IsConstant(value)) {
+    ASSERT(!value.IsNull());
+    ASSERT(value.IsBool());
+    bool result = Bool::Cast(value).value();
+    SetValue(instr,
+             Smi::Handle(Smi::New(
+                 result ? instr->if_true() : instr->if_false())));
   }
 }
 
@@ -7466,37 +7451,11 @@
 
 
 BranchInstr* BranchSimplifier::CloneBranch(BranchInstr* branch,
-                                           Value* left,
-                                           Value* right) {
+                                           Value* new_left,
+                                           Value* new_right) {
   ComparisonInstr* comparison = branch->comparison();
-  ComparisonInstr* new_comparison = NULL;
-  if (comparison->IsStrictCompare()) {
-    new_comparison = new StrictCompareInstr(comparison->token_pos(),
-                                            comparison->kind(),
-                                            left,
-                                            right);
-  } else if (comparison->IsEqualityCompare()) {
-    EqualityCompareInstr* equality_compare = comparison->AsEqualityCompare();
-    EqualityCompareInstr* new_equality_compare =
-        new EqualityCompareInstr(equality_compare->token_pos(),
-                                 comparison->kind(),
-                                 left,
-                                 right,
-                                 equality_compare->operation_cid(),
-                                 equality_compare->deopt_id());
-    new_comparison = new_equality_compare;
-  } else {
-    ASSERT(comparison->IsRelationalOp());
-    RelationalOpInstr* relational_op = comparison->AsRelationalOp();
-    RelationalOpInstr* new_relational_op =
-        new RelationalOpInstr(relational_op->token_pos(),
-                              comparison->kind(),
-                              left,
-                              right,
-                              relational_op->operation_cid(),
-                              relational_op->deopt_id());
-    new_comparison = new_relational_op;
-  }
+  ComparisonInstr* new_comparison =
+      comparison->CopyWithNewOperands(new_left, new_right);
   return new BranchInstr(new_comparison, branch->is_checked());
 }
 
@@ -7708,10 +7667,11 @@
           Value* if_true = (pred1 == branch->true_successor()) ? v1 : v2;
           Value* if_false = (pred2 == branch->true_successor()) ? v1 : v2;
 
+          ComparisonInstr* new_comparison =
+              comparison->CopyWithNewOperands(comparison->left()->Copy(),
+                                              comparison->right()->Copy());
           IfThenElseInstr* if_then_else = new IfThenElseInstr(
-              comparison->kind(),
-              comparison->InputAt(0)->Copy(),
-              comparison->InputAt(1)->Copy(),
+              new_comparison,
               if_true->Copy(),
               if_false->Copy());
           flow_graph->InsertBefore(branch,
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 6137831..b1fd751 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -341,8 +341,8 @@
   // Duplicate a branch while replacing its comparison's left and right
   // inputs.
   static BranchInstr* CloneBranch(BranchInstr* branch,
-                                  Value* left,
-                                  Value* right);
+                                  Value* new_left,
+                                  Value* new_right);
 };
 
 
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index e19c5c2..47015a9 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -680,7 +680,6 @@
 
 
 CompileType IfThenElseInstr::ComputeType() const {
-  ASSERT(InputCount() == 2);
   return CompileType::FromCid(kSmiCid);
 }
 
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index c5b5dc8..4a9eabd 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -123,13 +123,15 @@
   MarkingVisitor(Isolate* isolate,
                  Heap* heap,
                  PageSpace* page_space,
-                 MarkingStack* marking_stack)
+                 MarkingStack* marking_stack,
+                 bool visit_function_code)
       : ObjectPointerVisitor(isolate),
         heap_(heap),
         vm_heap_(Dart::vm_isolate()->heap()),
         page_space_(page_space),
         marking_stack_(marking_stack),
-        visiting_old_object_(NULL) {
+        visiting_old_object_(NULL),
+        visit_function_code_(visit_function_code) {
     ASSERT(heap_ != vm_heap_);
   }
 
@@ -141,6 +143,12 @@
     }
   }
 
+  bool visit_function_code() const { return visit_function_code_; }
+
+  GrowableArray<RawFunction*>* skipped_code_functions() {
+    return &skipped_code_functions_;
+  }
+
   void DelayWeakProperty(RawWeakProperty* raw_weak) {
     RawObject* raw_key = raw_weak->ptr()->key_;
     DelaySet::iterator it = delay_set_.find(raw_key);
@@ -158,6 +166,9 @@
     for (; it != delay_set_.end(); ++it) {
       WeakProperty::Clear(it->second);
     }
+    if (!visit_function_code_) {
+      DetachCode();
+    }
   }
 
   void VisitingOldObject(RawObject* obj) {
@@ -195,10 +206,14 @@
 
   void MarkObject(RawObject* raw_obj, RawObject** p) {
     // Fast exit if the raw object is a Smi.
-    if (!raw_obj->IsHeapObject()) return;
+    if (!raw_obj->IsHeapObject()) {
+      return;
+    }
 
     // Fast exit if the raw object is marked.
-    if (raw_obj->IsMarked()) return;
+    if (raw_obj->IsMarked()) {
+      return;
+    }
 
     // Skip over new objects, but verify consistency of heap while at it.
     if (raw_obj->IsNewObject()) {
@@ -215,6 +230,31 @@
     MarkAndPush(raw_obj);
   }
 
+  void DetachCode() {
+    for (int i = 0; i < skipped_code_functions_.length(); i++) {
+      RawFunction* func = skipped_code_functions_[i];
+      RawCode* code = func->ptr()->code_;
+      if (!code->IsMarked()) {
+        // If the code wasn't strongly visited through other references
+        // after skipping the function's code pointer, then we disconnect the
+        // code from the function.
+        func->ptr()->code_ = Code::null();
+        func->ptr()->unoptimized_code_ = Code::null();
+        if (FLAG_log_code_drop) {
+          // NOTE: This code runs while GC is in progress and runs within
+          // a NoHandleScope block. Hence it is not okay to use a regular Zone
+          // or Scope handle. We use a direct stack handle so the raw pointer in
+          // this handle is not traversed. The use of a handle is mainly to
+          // be able to reuse the handle based code and avoid having to add
+          // helper functions to the raw object interface.
+          String name;
+          name = func->ptr()->name_;
+          OS::Print("Detaching code: %s\n", name.ToCString());
+        }
+      }
+    }
+  }
+
   Heap* heap_;
   Heap* vm_heap_;
   PageSpace* page_space_;
@@ -222,6 +262,8 @@
   RawObject* visiting_old_object_;
   typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
   DelaySet delay_set_;
+  const bool visit_function_code_;
+  GrowableArray<RawFunction*> skipped_code_functions_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor);
 };
@@ -429,10 +471,13 @@
 
 void GCMarker::MarkObjects(Isolate* isolate,
                            PageSpace* page_space,
-                           bool invoke_api_callbacks) {
+                           bool invoke_api_callbacks,
+                           bool collect_code) {
+  const bool visit_function_code = !collect_code;
   MarkingStack marking_stack;
   Prologue(isolate, invoke_api_callbacks);
-  MarkingVisitor mark(isolate, heap_, page_space, &marking_stack);
+  MarkingVisitor mark(
+      isolate, heap_, page_space, &marking_stack, visit_function_code);
   IterateRoots(isolate, &mark, !invoke_api_callbacks);
   DrainMarkingStack(isolate, &mark);
   IterateWeakReferences(isolate, &mark);
@@ -442,7 +487,6 @@
   ProcessWeakTables(page_space);
   ProcessObjectIdTable(isolate);
 
-
   Epilogue(isolate, invoke_api_callbacks);
 }
 
diff --git a/runtime/vm/gc_marker.h b/runtime/vm/gc_marker.h
index 422d062..4dae874 100644
--- a/runtime/vm/gc_marker.h
+++ b/runtime/vm/gc_marker.h
@@ -27,7 +27,8 @@
 
   void MarkObjects(Isolate* isolate,
                    PageSpace* page_space,
-                   bool invoke_api_callbacks);
+                   bool invoke_api_callbacks,
+                   bool collect_code);
 
  private:
   void Prologue(Isolate* isolate, bool invoke_api_callbacks);
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index ef2dde6..7af39e3 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -365,6 +365,9 @@
   left()->PrintTo(f);
   f->Print(", ");
   right()->PrintTo(f);
+  if (needs_number_check()) {
+    f->Print(", with number check");
+  }
 }
 
 
@@ -427,9 +430,7 @@
 
 
 void IfThenElseInstr::PrintOperandsTo(BufferFormatter* f) const {
-  left()->PrintTo(f);
-  f->Print(" %s ", Token::Str(kind_));
-  right()->PrintTo(f);
+  comparison()->PrintOperandsTo(f);
   f->Print(" ? %" Pd " : %" Pd,
            if_true_,
            if_false_);
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 8a8f06a..07604df 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -24,8 +24,6 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool, new_identity_spec, true,
-    "Use new identity check rules for numbers.");
 DEFINE_FLAG(bool, propagate_ic_data, true,
     "Propagate IC data from unoptimized to optimized IC calls.");
 DECLARE_FLAG(bool, enable_type_checks);
@@ -755,23 +753,6 @@
 }
 
 
-BranchInstr::BranchInstr(ComparisonInstr* comparison, bool is_checked)
-    : comparison_(comparison),
-      is_checked_(is_checked),
-      constrained_type_(NULL),
-      constant_target_(NULL) {
-  ASSERT(comparison->env() == NULL);
-  for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
-    comparison->InputAt(i)->set_instruction(this);
-  }
-}
-
-
-void BranchInstr::RawSetInputAt(intptr_t i, Value* value) {
-  comparison()->RawSetInputAt(i, value);
-}
-
-
 void BranchInstr::SetComparison(ComparisonInstr* new_comparison) {
   for (intptr_t i = new_comparison->InputCount() - 1; i >= 0; --i) {
     Value* input = new_comparison->InputAt(i);
@@ -1133,6 +1114,10 @@
       }
       return true;
     }
+    case Token::kMOD: {
+      Range* right_range = this->right()->definition()->range();
+      return (right_range == NULL) || right_range->Overlaps(0, 0);
+    }
     default:
       return overflow_;
   }
@@ -1922,9 +1907,10 @@
 StrictCompareInstr::StrictCompareInstr(intptr_t token_pos,
                                        Token::Kind kind,
                                        Value* left,
-                                       Value* right)
+                                       Value* right,
+                                       bool needs_number_check)
     : ComparisonInstr(token_pos, kind, left, right),
-      needs_number_check_(FLAG_new_identity_spec) {
+      needs_number_check_(needs_number_check) {
   ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
 }
 
@@ -2024,12 +2010,12 @@
 
 Environment* Environment::From(const GrowableArray<Definition*>& definitions,
                                intptr_t fixed_parameter_count,
-                               const Function& function) {
+                               const Code& code) {
   Environment* env =
       new Environment(definitions.length(),
                       fixed_parameter_count,
                       Isolate::kNoDeoptId,
-                      function,
+                      code,
                       NULL);
   for (intptr_t i = 0; i < definitions.length(); ++i) {
     env->values_.Add(new Value(definitions[i]));
@@ -2044,7 +2030,7 @@
       new Environment(length,
                       fixed_parameter_count_,
                       deopt_id_,
-                      function_,
+                      code_,
                       (outer_ == NULL) ? NULL : outer_->DeepCopy());
   if (locations_ != NULL) {
     Location* new_locations =
@@ -2475,21 +2461,60 @@
 }
 
 
+ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left,
+                                                           Value* new_right) {
+  return new EqualityCompareInstr(token_pos(),
+                                  kind(),
+                                  new_left,
+                                  new_right,
+                                  operation_cid(),
+                                  deopt_id());
+}
+
+
+ComparisonInstr* RelationalOpInstr::CopyWithNewOperands(Value* new_left,
+                                                        Value* new_right) {
+  return new RelationalOpInstr(token_pos(),
+                               kind(),
+                               new_left,
+                               new_right,
+                               operation_cid(),
+                               deopt_id());
+}
+
+
+ComparisonInstr* StrictCompareInstr::CopyWithNewOperands(Value* new_left,
+                                                         Value* new_right) {
+  return new StrictCompareInstr(token_pos(),
+                                kind(),
+                                new_left,
+                                new_right,
+                                needs_number_check());
+}
+
+
+
+ComparisonInstr* TestSmiInstr::CopyWithNewOperands(Value* new_left,
+                                                   Value* new_right) {
+  return new TestSmiInstr(token_pos(), kind(), new_left, new_right);
+}
+
+
 bool IfThenElseInstr::Supports(ComparisonInstr* comparison,
                                Value* v1,
                                Value* v2) {
-  if (!(comparison->IsStrictCompare() &&
-        !comparison->AsStrictCompare()->needs_number_check()) &&
-      !(comparison->IsEqualityCompare() &&
-        (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) {
+  bool is_smi_result = BindsToSmiConstant(v1) && BindsToSmiConstant(v2);
+  if (comparison->IsStrictCompare()) {
+    // Strict comparison with number checks calls a stub and is not supported
+    // by if-conversion.
+    return is_smi_result
+        && !comparison->AsStrictCompare()->needs_number_check();
+  }
+  if (comparison->operation_cid() != kSmiCid) {
+    // Non-smi comparisons are not supported by if-conversion.
     return false;
   }
-
-  if (!BindsToSmiConstant(v1) || !BindsToSmiConstant(v2)) {
-    return false;
-  }
-
-  return true;
+  return is_smi_result;
 }
 
 
@@ -2665,6 +2690,16 @@
 }
 
 
+bool Range::Overlaps(intptr_t min_int, intptr_t max_int) const {
+  const intptr_t this_min = min().LowerBound().value();
+  const intptr_t this_max = max().UpperBound().value();
+  if ((this_min <= min_int) && (min_int <= this_max)) return true;
+  if ((this_min <= max_int) && (max_int <= this_max)) return true;
+  if ((min_int < this_min) && (max_int > this_max)) return true;
+  return false;
+}
+
+
 bool Range::IsUnsatisfiable() const {
   // Constant case: For example [0, -1].
   if (Range::ConstantMin(this).value() > Range::ConstantMax(this).value()) {
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 3d85345..f5f4ac7 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -2152,6 +2152,7 @@
 
  private:
   friend class BranchInstr;
+  friend class IfThenElseInstr;
 
   virtual void RawSetInputAt(intptr_t i, Value* value) {
     inputs_[i] = value;
@@ -2161,6 +2162,13 @@
 };
 
 
+struct BranchLabels {
+  Label* true_label;
+  Label* false_label;
+  Label* fall_through;
+};
+
+
 class ComparisonInstr : public TemplateDefinition<2> {
  public:
   Value* left() const { return inputs_[0]; }
@@ -2171,9 +2179,14 @@
   intptr_t token_pos() const { return token_pos_; }
   Token::Kind kind() const { return kind_; }
 
+  virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
+
   virtual void EmitBranchCode(FlowGraphCompiler* compiler,
                               BranchInstr* branch) = 0;
 
+  virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
+                                       BranchLabels labels) = 0;
+
   void SetDeoptId(intptr_t deopt_id) {
     deopt_id_ = deopt_id;
   }
@@ -2207,7 +2220,16 @@
 
 class BranchInstr : public Instruction {
  public:
-  explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false);
+  explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false)
+      : comparison_(comparison),
+        is_checked_(is_checked),
+        constrained_type_(NULL),
+        constant_target_(NULL) {
+    ASSERT(comparison->env() == NULL);
+    for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
+      comparison->InputAt(i)->set_instruction(this);
+    }
+  }
 
   DECLARE_INSTRUCTION(Branch)
 
@@ -2243,6 +2265,8 @@
       LocationSummary* summary = comparison()->MakeLocationSummary();
       // Branches don't produce a result.
       summary->set_out(Location::NoLocation());
+      // The back-end expects the location summary to be stored in the
+      // comparison.
       comparison()->locs_ = summary;
     }
     return comparison()->locs_;
@@ -2296,7 +2320,9 @@
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
  private:
-  virtual void RawSetInputAt(intptr_t i, Value* value);
+  virtual void RawSetInputAt(intptr_t i, Value* value) {
+    comparison()->RawSetInputAt(i, value);
+  }
 
   TargetEntryInstr* true_successor_;
   TargetEntryInstr* false_successor_;
@@ -2513,6 +2539,9 @@
   // Inclusive.
   bool IsWithin(intptr_t min_int, intptr_t max_int) const;
 
+  // Inclusive.
+  bool Overlaps(intptr_t min_int, intptr_t max_int) const;
+
   bool IsUnsatisfiable() const;
 
  private:
@@ -2888,9 +2917,13 @@
   StrictCompareInstr(intptr_t token_pos,
                      Token::Kind kind,
                      Value* left,
-                     Value* right);
+                     Value* right,
+                     bool needs_number_check);
 
   DECLARE_INSTRUCTION(StrictCompare)
+
+  virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
+
   virtual CompileType ComputeType() const;
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -2907,6 +2940,9 @@
   virtual void EmitBranchCode(FlowGraphCompiler* compiler,
                               BranchInstr* branch);
 
+  virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
+                                       BranchLabels labels);
+
   bool needs_number_check() const { return needs_number_check_; }
   void set_needs_number_check(bool value) { needs_number_check_ = value; }
 
@@ -2936,6 +2972,9 @@
   }
 
   DECLARE_INSTRUCTION(TestSmi);
+
+  virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
+
   virtual CompileType ComputeType() const;
 
   virtual bool CanDeoptimize() const { return false; }
@@ -2960,6 +2999,9 @@
   virtual void EmitBranchCode(FlowGraphCompiler* compiler,
                               BranchInstr* branch);
 
+  virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
+                                       BranchLabels labels);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(TestSmiInstr);
 };
@@ -2980,6 +3022,9 @@
   }
 
   DECLARE_INSTRUCTION(EqualityCompare)
+
+  virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
+
   virtual CompileType ComputeType() const;
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -2994,6 +3039,9 @@
   virtual void EmitBranchCode(FlowGraphCompiler* compiler,
                               BranchInstr* branch);
 
+  virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
+                                       BranchLabels labels);
+
   virtual intptr_t DeoptimizationTarget() const {
     return GetDeoptId();
   }
@@ -3029,6 +3077,9 @@
   }
 
   DECLARE_INSTRUCTION(RelationalOp)
+
+  virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right);
+
   virtual CompileType ComputeType() const;
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -3043,6 +3094,8 @@
   virtual void EmitBranchCode(FlowGraphCompiler* compiler,
                               BranchInstr* branch);
 
+  virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
+                                       BranchLabels labels);
 
   virtual intptr_t DeoptimizationTarget() const {
     return GetDeoptId();
@@ -3068,19 +3121,19 @@
 
 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for
 // materialization of true and false constants.
-class IfThenElseInstr : public TemplateDefinition<2> {
+class IfThenElseInstr : public Definition {
  public:
-  IfThenElseInstr(Token::Kind kind,
-                  Value* left,
-                  Value* right,
+  IfThenElseInstr(ComparisonInstr* comparison,
                   Value* if_true,
                   Value* if_false)
-      : kind_(kind),
+      : comparison_(comparison),
         if_true_(Smi::Cast(if_true->BoundConstant()).Value()),
         if_false_(Smi::Cast(if_false->BoundConstant()).Value()) {
-    ASSERT(Token::IsEqualityOperator(kind));
-    SetInputAt(0, left);
-    SetInputAt(1, right);
+    // Adjust uses at the comparison.
+    ASSERT(comparison->env() == NULL);
+    for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) {
+      comparison->InputAt(i)->set_instruction(this);
+    }
   }
 
   // Returns true if this combination of comparison and values flowing on
@@ -3089,35 +3142,66 @@
 
   DECLARE_INSTRUCTION(IfThenElse)
 
+  intptr_t InputCount() const { return comparison()->InputCount(); }
+
+  Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
+
+  virtual bool CanDeoptimize() const {
+    return comparison()->CanDeoptimize();
+  }
+
+  virtual bool CanBecomeDeoptimizationTarget() const {
+    return comparison()->CanBecomeDeoptimizationTarget();
+  }
+
+  virtual LocationSummary* locs() {
+    if (comparison()->locs_ == NULL) {
+      LocationSummary* summary = MakeLocationSummary();
+      // The back-end expects the location summary to be stored in the
+      // comparison.
+      comparison()->locs_ = summary;
+    }
+    return comparison()->locs_;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    return comparison()->DeoptimizationTarget();
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t i) const {
+    return comparison()->RequiredInputRepresentation(i);
+  }
+
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
   virtual CompileType ComputeType() const;
 
   virtual void InferRange();
 
-  virtual bool CanDeoptimize() const { return false; }
-
-  Value* left() const { return inputs_[0]; }
-  Value* right() const { return inputs_[1]; }
+  ComparisonInstr* comparison() const { return comparison_; }
   intptr_t if_true() const { return if_true_; }
   intptr_t if_false() const { return if_false_; }
 
-  Token::Kind kind() const { return kind_; }
-
-  virtual bool AllowsCSE() const { return true; }
-  virtual EffectSet Effects() const { return EffectSet::None(); }
-  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AllowsCSE() const { return comparison()->AllowsCSE(); }
+  virtual EffectSet Effects() const { return comparison()->Effects(); }
+  virtual EffectSet Dependencies() const {
+    return comparison()->Dependencies();
+  }
   virtual bool AttributesEqual(Instruction* other) const {
     IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
-    return (kind_ == other_if_then_else->kind_) &&
+    return comparison()->AttributesEqual(other_if_then_else->comparison()) &&
            (if_true_ == other_if_then_else->if_true_) &&
            (if_false_ == other_if_then_else->if_false_);
   }
 
-  virtual bool MayThrow() const { return false; }
+  virtual bool MayThrow() const { return comparison()->MayThrow(); }
 
  private:
-  const Token::Kind kind_;
+  virtual void RawSetInputAt(intptr_t i, Value* value) {
+    comparison()->RawSetInputAt(i, value);
+  }
+
+  ComparisonInstr* comparison_;
   const intptr_t if_true_;
   const intptr_t if_false_;
 
@@ -6889,7 +6973,7 @@
   // Construct an environment by constructing uses from an array of definitions.
   static Environment* From(const GrowableArray<Definition*>& definitions,
                            intptr_t fixed_parameter_count,
-                           const Function& function);
+                           const Code& code);
 
   void set_locations(Location* locations) {
     ASSERT(locations_ == NULL);
@@ -6929,7 +7013,7 @@
     return fixed_parameter_count_;
   }
 
-  const Function& function() const { return function_; }
+  const Code& code() const { return code_; }
 
   Environment* DeepCopy() const { return DeepCopy(Length()); }
 
@@ -6944,13 +7028,13 @@
   Environment(intptr_t length,
               intptr_t fixed_parameter_count,
               intptr_t deopt_id,
-              const Function& function,
+              const Code& code,
               Environment* outer)
       : values_(length),
         locations_(NULL),
         fixed_parameter_count_(fixed_parameter_count),
         deopt_id_(deopt_id),
-        function_(function),
+        code_(code),
         outer_(outer) { }
 
   // Deep copy an environment.  The 'length' parameter may be less than the
@@ -6962,7 +7046,7 @@
   Location* locations_;
   const intptr_t fixed_parameter_count_;
   intptr_t deopt_id_;
-  const Function& function_;
+  const Code& code_;
   Environment* outer_;
 
   DISALLOW_COPY_AND_ASSIGN(Environment);
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 0377a24..c7854cd 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -136,24 +136,12 @@
 
 
 LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RegisterOrConstant(left()));
-  // Only one of the inputs can be a constant. Choose register if the first one
-  // is a constant.
-  locs->set_in(1, locs->in(0).IsConstant()
-                      ? Location::RequiresRegister()
-                      : Location::RegisterOrConstant(right()));
-  locs->set_out(Location::RequiresRegister());
-  return locs;
+  return comparison()->MakeLocationSummary();
 }
 
 
 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register result = locs()->out().reg();
-  ASSERT(Token::IsEqualityOperator(kind()));
 
   Location left = locs()->in(0);
   Location right = locs()->in(1);
@@ -162,19 +150,9 @@
   // Clear out register.
   __ eor(result, result, ShifterOperand(result));
 
-  // Compare left and right. For now only equality comparison is supported.
-  // TODO(vegorov): reuse code from the other comparison instructions instead of
-  // generating it inline here.
-  if (left.IsConstant()) {
-    __ CompareObject(right.reg(), left.constant());
-  } else if (right.IsConstant()) {
-    __ CompareObject(left.reg(), right.constant());
-  } else {
-    __ cmp(left.reg(), ShifterOperand(right.reg()));
-  }
-
-  Condition true_condition =
-      ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQ : NE;
+  // Emit comparison code. This must not overwrite the result register.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
@@ -495,31 +473,44 @@
 }
 
 
-static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
-                                   LocationSummary* locs) {
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+                                        LocationSummary* locs,
+                                        Token::Kind kind) {
   QRegister left = locs->in(0).fpu_reg();
   QRegister right = locs->in(1).fpu_reg();
   DRegister dleft = EvenDRegisterOf(left);
   DRegister dright = EvenDRegisterOf(right);
   __ vcmpd(dleft, dright);
   __ vmstat();
+  Condition true_condition = TokenKindToDoubleCondition(kind);
+  return true_condition;
+}
+
+
+Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                   BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, locs(), kind());
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, locs(), kind());
+  }
 }
 
 
 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
 
+  // The ARM code does not use true- and false-labels here.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+
+  Register result = locs()->out().reg();
   if (operation_cid() == kSmiCid) {
-    Condition true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
-    Register result = locs()->out().reg();
     __ LoadObject(result, Bool::True(), true_condition);
     __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
   } else {
     ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, locs());
-
-    Register result = locs()->out().reg();
-    Condition true_condition = TokenKindToDoubleCondition(kind());
     Label done;
     __ LoadObject(result, Bool::False());
     if (true_condition != NE) {
@@ -536,15 +527,9 @@
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
 
-  Condition true_condition = kNoCondition;
-  if (operation_cid() == kSmiCid) {
-    true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    true_condition = TokenKindToDoubleCondition(kind());
-    EmitDoubleComparisonOp(compiler, locs());
-
+  if (operation_cid() == kDoubleCid) {
     Label* nan_result = (true_condition == NE) ?
         labels.true_label : labels.false_label;
     __ b(nan_result, VS);
@@ -566,17 +551,8 @@
 }
 
 
-void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Never emitted outside of the BranchInstr.
-  UNREACHABLE();
-}
-
-
-void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                  BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
+Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                           BranchLabels labels) {
   Register left = locs()->in(0).reg();
   Location right = locs()->in(1);
   if (right.IsConstant()) {
@@ -587,6 +563,20 @@
   } else {
     __ tst(left, ShifterOperand(right.reg()));
   }
+  Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
+  return true_condition;
+}
+
+void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // Never emitted outside of the BranchInstr.
+  UNREACHABLE();
+}
+
+
+void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                  BranchInstr* branch) {
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
   EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
@@ -627,18 +617,28 @@
 }
 
 
-void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                BranchLabels labels) {
   if (operation_cid() == kSmiCid) {
-    Condition true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
-    Register result = locs()->out().reg();
+    return EmitSmiComparisonOp(compiler, locs(), kind());
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, locs(), kind());
+  }
+}
+
+
+void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // The ARM code does not use true- and false-labels here.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+
+  Register result = locs()->out().reg();
+  if (operation_cid() == kSmiCid) {
     __ LoadObject(result, Bool::True(), true_condition);
     __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
   } else {
     ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, locs());
-
-    Register result = locs()->out().reg();
-    Condition true_condition = TokenKindToDoubleCondition(kind());
     Label done;
     __ LoadObject(result, Bool::False());
     if (true_condition != NE) {
@@ -653,15 +653,9 @@
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
   BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
 
-  Condition true_condition = kNoCondition;
-  if (operation_cid() == kSmiCid) {
-    true_condition = EmitSmiComparisonOp(compiler, locs(), kind());
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    true_condition = TokenKindToDoubleCondition(kind());
-    EmitDoubleComparisonOp(compiler, locs());
-
+  if (operation_cid() == kDoubleCid) {
     Label* nan_result = (true_condition == NE) ?
         labels.true_label : labels.false_label;
     __ b(nan_result, VS);
@@ -2380,6 +2374,7 @@
   }
 
   Register right = locs()->in(1).reg();
+  Range* right_range = this->right()->definition()->range();
   switch (op_kind()) {
     case Token::kADD: {
       if (deopt == NULL) {
@@ -2427,9 +2422,11 @@
       break;
     }
     case Token::kTRUNCDIV: {
-      // Handle divide by zero in runtime.
-      __ cmp(right, ShifterOperand(0));
-      __ b(deopt, EQ);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ cmp(right, ShifterOperand(0));
+        __ b(deopt, EQ);
+      }
       Register temp = locs()->temp(0).reg();
       DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
       __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp.
@@ -2445,9 +2442,11 @@
       break;
     }
     case Token::kMOD: {
-      // Handle divide by zero in runtime.
-      __ cmp(right, ShifterOperand(0));
-      __ b(deopt, EQ);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ cmp(right, ShifterOperand(0));
+        __ b(deopt, EQ);
+      }
       Register temp = locs()->temp(0).reg();
       DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
       __ Asr(temp, left, kSmiTagSize);  // SmiUntag left into temp.
@@ -2484,7 +2483,6 @@
       __ Asr(IP, right, kSmiTagSize);  // SmiUntag right into IP.
       // sarl operation masks the count to 5 bits.
       const intptr_t kCountLimit = 0x1F;
-      Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
         __ CompareImmediate(IP, kCountLimit);
@@ -4094,9 +4092,12 @@
     Register left = locs()->in(0).reg();
     Register right = locs()->in(1).reg();
     Register result = locs()->out().reg();
-    // Handle divide by zero in runtime.
-    __ cmp(right, ShifterOperand(0));
-    __ b(deopt, EQ);
+    Range* right_range = InputAt(1)->definition()->range();
+    if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+      // Handle divide by zero in runtime.
+      __ cmp(right, ShifterOperand(0));
+      __ b(deopt, EQ);
+    }
     Register temp = locs()->temp(0).reg();
     DRegister dtemp = EvenDRegisterOf(locs()->temp(1).fpu_reg());
     Register result_div = locs()->temp(2).reg();
@@ -4504,41 +4505,40 @@
 }
 
 
-static void EmitStrictComparison(FlowGraphCompiler* compiler,
-                                 StrictCompareInstr* compare) {
-  LocationSummary* locs = compare->locs();
-  bool needs_number_check = compare->needs_number_check();
-  intptr_t token_pos = compare->token_pos();
-  Location left = locs->in(0);
-  Location right = locs->in(1);
+Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                 BranchLabels labels) {
+  Location left = locs()->in(0);
+  Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
   if (left.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(right.reg(),
                                           left.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else if (right.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(left.reg(),
                                           right.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else {
     compiler->EmitEqualityRegRegCompare(left.reg(),
                                        right.reg(),
-                                       needs_number_check,
-                                       token_pos);
+                                       needs_number_check(),
+                                       token_pos());
   }
+  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  return true_condition;
 }
 
 
-// Special code for numbers (compare values instead of references.)
 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
-  EmitStrictComparison(compiler, this);
+  // The ARM code does not use true- and false-labels here.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
 
   Register result = locs()->out().reg();
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
   __ LoadObject(result, Bool::True(), true_condition);
   __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
 }
@@ -4548,10 +4548,8 @@
                                         BranchInstr* branch) {
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
-  EmitStrictComparison(compiler, this);
-
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  Condition true_condition = EmitComparisonCode(compiler, labels);
   EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index b0e0f54..dc8a237 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -345,10 +345,10 @@
 }
 
 
-static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
-                                const LocationSummary& locs,
-                                Token::Kind kind,
-                                BranchLabels labels) {
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+                                     const LocationSummary& locs,
+                                     Token::Kind kind,
+                                     BranchLabels labels) {
   Location left = locs.in(0);
   Location right = locs.in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
@@ -365,7 +365,7 @@
   } else {
     __ cmpl(left.reg(), right.reg());
   }
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  return true_condition;
 }
 
 
@@ -410,10 +410,10 @@
 }
 
 
-static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
-                                      const LocationSummary& locs,
-                                      Token::Kind kind,
-                                      BranchLabels labels) {
+static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
+                                           const LocationSummary& locs,
+                                           Token::Kind kind,
+                                           BranchLabels labels) {
   ASSERT(Token::IsEqualityOperator(kind));
   XmmRegister left = locs.in(0).fpu_reg();
   XmmRegister right = locs.in(1).fpu_reg();
@@ -424,14 +424,14 @@
 
   Condition true_condition = TokenKindToMintCondition(kind);
   __ cmpl(temp, Immediate(-1));
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  return true_condition;
 }
 
 
-static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
-                                        const LocationSummary& locs,
-                                        Token::Kind kind,
-                                        BranchLabels labels) {
+static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
+                                             const LocationSummary& locs,
+                                             Token::Kind kind,
+                                             BranchLabels labels) {
   XmmRegister left = locs.in(0).fpu_reg();
   XmmRegister right = locs.in(1).fpu_reg();
   Register left_tmp = locs.temp(0).reg();
@@ -471,7 +471,7 @@
   __ pextrd(left_tmp, left, Immediate(0));
   __ pextrd(right_tmp, right, Immediate(0));
   __ cmpl(left_tmp, right_tmp);
-  EmitBranchOnCondition(compiler, lo_cond, labels);
+  return lo_cond;
 }
 
 
@@ -490,10 +490,10 @@
 }
 
 
-static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
-                                   const LocationSummary& locs,
-                                   Token::Kind kind,
-                                   BranchLabels labels) {
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+                                        const LocationSummary& locs,
+                                        Token::Kind kind,
+                                        BranchLabels labels) {
   XmmRegister left = locs.in(0).fpu_reg();
   XmmRegister right = locs.in(1).fpu_reg();
 
@@ -503,7 +503,20 @@
   Label* nan_result = (true_condition == NOT_EQUAL)
       ? labels.true_label : labels.false_label;
   __ j(PARITY_EVEN, nan_result);
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  return true_condition;
+}
+
+
+Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                   BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+  } else if (operation_cid() == kMintCid) {
+    return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+  }
 }
 
 
@@ -512,15 +525,9 @@
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler,  true_condition, labels);
 
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else if (operation_cid() == kMintCid) {
-    EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
   Register result = locs()->out().reg();
   Label done;
   __ Bind(&is_false);
@@ -537,15 +544,8 @@
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else if (operation_cid() == kMintCid) {
-    EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -562,17 +562,8 @@
 }
 
 
-void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Never emitted outside of the BranchInstr.
-  UNREACHABLE();
-}
-
-
-void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                  BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                           BranchLabels labels) {
   Register left = locs()->in(0).reg();
   Location right = locs()->in(1);
   if (right.IsConstant()) {
@@ -583,6 +574,21 @@
   } else {
     __ testl(left, right.reg());
   }
+  Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+  return true_condition;
+}
+
+
+void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // Never emitted outside of the BranchInstr.
+  UNREACHABLE();
+}
+
+
+void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                  BranchInstr* branch) {
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
   EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
@@ -623,18 +629,25 @@
 }
 
 
+Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+  } else if (operation_cid() == kMintCid) {
+    return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+  }
+}
+
+
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else if (operation_cid() == kMintCid) {
-    EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
   Register result = locs()->out().reg();
   Label done;
   __ Bind(&is_false);
@@ -649,15 +662,8 @@
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else if (operation_cid() == kMintCid) {
-    EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -2420,6 +2426,7 @@
 
   // if locs()->in(1).IsRegister.
   Register right = locs()->in(1).reg();
+  Range* right_range = this->right()->definition()->range();
   switch (op_kind()) {
     case Token::kADD: {
       __ addl(left, right);
@@ -2453,9 +2460,11 @@
       break;
     }
     case Token::kTRUNCDIV: {
-      // Handle divide by zero in runtime.
-      __ testl(right, right);
-      __ j(ZERO, deopt);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ testl(right, right);
+        __ j(ZERO, deopt);
+      }
       ASSERT(left == EAX);
       ASSERT((right != EDX) && (right != EAX));
       ASSERT(locs()->temp(0).reg() == EDX);
@@ -2472,9 +2481,11 @@
       break;
     }
     case Token::kMOD: {
-      // Handle divide by zero in runtime.
-      __ testl(right, right);
-      __ j(ZERO, deopt);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ testl(right, right);
+        __ j(ZERO, deopt);
+      }
       ASSERT(left == EDX);
       ASSERT((right != EDX) && (right != EAX));
       ASSERT(locs()->temp(0).reg() == EAX);
@@ -2492,16 +2503,26 @@
       //      res = res + right;
       //    }
       //  }
-      Label subtract, done;
+      Label done;
       __ cmpl(result, Immediate(0));
       __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
       // Result is negative, adjust it.
-      __ cmpl(right, Immediate(0));
-      __ j(LESS, &subtract, Assembler::kNearJump);
-      __ addl(result, right);
-      __ jmp(&done, Assembler::kNearJump);
-      __ Bind(&subtract);
-      __ subl(result, right);
+      if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+        // Right can be positive and negative.
+        Label subtract;
+        __ cmpl(right, Immediate(0));
+        __ j(LESS, &subtract, Assembler::kNearJump);
+        __ addl(result, right);
+        __ jmp(&done, Assembler::kNearJump);
+        __ Bind(&subtract);
+        __ subl(result, right);
+      } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+        // Right is positive.
+        __ addl(result, right);
+      } else {
+        // Right is negative.
+        __ subl(result, right);
+      }
       __ Bind(&done);
       __ SmiTag(result);
       break;
@@ -2514,7 +2535,6 @@
       __ SmiUntag(right);
       // sarl operation masks the count to 5 bits.
       const intptr_t kCountLimit = 0x1F;
-      Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
         __ cmpl(right, Immediate(kCountLimit));
@@ -4007,9 +4027,12 @@
     Register left = locs()->in(0).reg();
     Register right = locs()->in(1).reg();
     Register result = locs()->out().reg();
-    // Handle divide by zero in runtime.
-    __ testl(right, right);
-    __ j(ZERO, deopt);
+    Range* right_range = InputAt(1)->definition()->range();
+    if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+      // Handle divide by zero in runtime.
+      __ testl(right, right);
+      __ j(ZERO, deopt);
+    }
     ASSERT(left == EAX);
     ASSERT((right != EDX) && (right != EAX));
     ASSERT(locs()->temp(0).reg() == EDX);
@@ -4034,16 +4057,25 @@
     //      res = res + right;
     //    }
     //  }
-    Label subtract, done;
+    Label done;
     __ cmpl(EDX, Immediate(0));
     __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
     // Result is negative, adjust it.
-    __ cmpl(right, Immediate(0));
-    __ j(LESS, &subtract, Assembler::kNearJump);
-    __ addl(EDX, right);
-    __ jmp(&done, Assembler::kNearJump);
-    __ Bind(&subtract);
-    __ subl(EDX, right);
+    if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+      Label subtract;
+      __ cmpl(right, Immediate(0));
+      __ j(LESS, &subtract, Assembler::kNearJump);
+      __ addl(EDX, right);
+      __ jmp(&done, Assembler::kNearJump);
+      __ Bind(&subtract);
+      __ subl(EDX, right);
+    } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+      // Right is positive.
+      __ addl(EDX, right);
+    } else {
+      // Right is negative.
+      __ subl(EDX, right);
+    }
     __ Bind(&done);
 
     __ LoadObject(result, Array::ZoneHandle(Array::New(2, Heap::kOld)));
@@ -4709,45 +4741,39 @@
 }
 
 
-static void EmitStrictComparison(FlowGraphCompiler* compiler,
-                                 StrictCompareInstr* compare,
-                                 BranchLabels labels) {
-  LocationSummary* locs = compare->locs();
-  bool needs_number_check = compare->needs_number_check();
-  intptr_t token_pos = compare->token_pos();
-  Token::Kind kind = compare->kind();
-  Location left = locs->in(0);
-  Location right = locs->in(1);
+Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                 BranchLabels labels) {
+  Location left = locs()->in(0);
+  Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
   if (left.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(right.reg(),
                                           left.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else if (right.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(left.reg(),
                                           right.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else {
     compiler->EmitEqualityRegRegCompare(left.reg(),
                                         right.reg(),
-                                        needs_number_check,
-                                        token_pos);
+                                        needs_number_check(),
+                                        token_pos());
   }
-  Condition true_condition = (kind == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+  return true_condition;
 }
 
 
-// Special code for numbers (compare values instead of references.)
 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
-
-  EmitStrictComparison(compiler, this, labels);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
   Register result = locs()->out().reg();
   Label done;
@@ -4765,8 +4791,8 @@
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  EmitStrictComparison(compiler, this, labels);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -4778,16 +4804,7 @@
 
 
 LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RegisterOrConstant(left()));
-  // Only one of the inputs can be a constant. Choose register if the first one
-  // is a constant.
-  locs->set_in(1, locs->in(0).IsConstant()
-                      ? Location::RequiresRegister()
-                      : Location::RegisterOrConstant(right()));
+  LocationSummary* locs = comparison()->MakeLocationSummary();
   // TODO(vegorov): support byte register constraints in the register allocator.
   locs->set_out(Location::RegisterLocation(EDX));
   return locs;
@@ -4796,30 +4813,14 @@
 
 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->out().reg() == EDX);
-  ASSERT(Token::IsEqualityOperator(kind()));
-
-  Location left = locs()->in(0);
-  Location right = locs()->in(1);
-  ASSERT(!left.IsConstant() || !right.IsConstant());
 
   // Clear upper part of the out register. We are going to use setcc on it
   // which is a byte move.
   __ xorl(EDX, EDX);
 
-  // Compare left and right. For now only equality comparison is supported.
-  // TODO(vegorov): reuse code from the other comparison instructions instead of
-  // generating it inline here.
-  if (left.IsConstant()) {
-    __ CompareObject(right.reg(), left.constant());
-  } else if (right.IsConstant()) {
-    __ CompareObject(left.reg(), right.constant());
-  } else {
-    __ cmpl(left.reg(), right.reg());
-  }
-
-  Condition true_condition =
-      ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL
-                                                              : NOT_EQUAL;
+  // Emit comparison code. This must not overwrite the result register.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 1d31672..83d0b0c 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -135,24 +135,12 @@
 
 
 LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RegisterOrConstant(left()));
-  // Only one of the inputs can be a constant. Choose register if the first one
-  // is a constant.
-  locs->set_in(1, locs->in(0).IsConstant()
-                      ? Location::RequiresRegister()
-                      : Location::RegisterOrConstant(right()));
-  locs->set_out(Location::RequiresRegister());
-  return locs;
+  return comparison()->MakeLocationSummary();
 }
 
 
 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register result = locs()->out().reg();
-  ASSERT(Token::IsEqualityOperator(kind()));
 
   Location left = locs()->in(0);
   Location right = locs()->in(1);
@@ -161,20 +149,9 @@
   // Clear out register.
   __ mov(result, ZR);
 
-  // Compare left and right. For now only equality comparison is supported.
-  // TODO(vegorov): reuse code from the other comparison instructions instead of
-  // generating it inline here.
-  if (left.IsConstant()) {
-    __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant());
-  } else if (right.IsConstant()) {
-    __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant());
-  } else {
-    __ slt(CMPRES1, left.reg(), right.reg());
-    __ slt(CMPRES2, right.reg(), left.reg());
-  }
-
-  Condition true_condition =
-      ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQ : NE;
+  // Emit comparison code. This must not overwrite the result register.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
@@ -197,12 +174,29 @@
     }
   }
 
-  if (true_condition == EQ) {
-    __ xor_(result, CMPRES1, CMPRES2);
-    __ xori(result, result, Immediate(1));
-  } else {
-    ASSERT(true_condition == NE);
-    __ xor_(result, CMPRES1, CMPRES2);
+  switch (true_condition) {
+    case EQ:
+      __ xor_(result, CMPRES1, CMPRES2);
+      __ xori(result, result, Immediate(1));
+      break;
+    case NE:
+      __ xor_(result, CMPRES1, CMPRES2);
+      break;
+    case GT:
+      __ mov(result, CMPRES2);
+      break;
+    case GE:
+      __ xori(result, CMPRES1, Immediate(1));
+      break;
+    case LT:
+      __ mov(result, CMPRES1);
+      break;
+    case LE:
+      __ xori(result, CMPRES2, Immediate(1));
+      break;
+    default:
+      UNREACHABLE();
+      break;
   }
 
   if (is_power_of_two_kind) {
@@ -482,10 +476,10 @@
 }
 
 
-static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
-                                const LocationSummary& locs,
-                                Token::Kind kind,
-                                BranchLabels labels) {
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+                                     const LocationSummary& locs,
+                                     Token::Kind kind,
+                                     BranchLabels labels) {
   __ TraceSimMsg("EmitSmiComparisonOp");
   __ Comment("EmitSmiComparisonOp");
   Location left = locs.in(0);
@@ -503,7 +497,7 @@
     __ slt(CMPRES1, left.reg(), right.reg());
     __ slt(CMPRES2, right.reg(), left.reg());
   }
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  return true_condition;
 }
 
 
@@ -522,10 +516,10 @@
 }
 
 
-static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
-                                   const LocationSummary& locs,
-                                   Token::Kind kind,
-                                   BranchLabels labels) {
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+                                        const LocationSummary& locs,
+                                        Token::Kind kind,
+                                        BranchLabels labels) {
   DRegister left = locs.in(0).fpu_reg();
   DRegister right = locs.in(1).fpu_reg();
 
@@ -551,6 +545,7 @@
     }
   }
 
+  // Ordering is expected to be described by CMPRES1, CMPRES2.
   __ LoadImmediate(TMP, 1);
   if (true_condition == NE) {
     __ movf(CMPRES1, ZR);
@@ -560,9 +555,18 @@
     __ movt(CMPRES1, ZR);
   }
   __ mov(CMPRES2, ZR);
+  return EQ;
+}
 
-  // EmitBranchOnCondition expects ordering to be described by CMPRES1, CMPRES2.
-  EmitBranchOnCondition(compiler, EQ, labels);
+
+Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                   BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+  }
 }
 
 
@@ -572,13 +576,9 @@
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
   Register result = locs()->out().reg();
   Label done;
   __ Bind(&is_false);
@@ -597,13 +597,8 @@
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -620,17 +615,8 @@
 }
 
 
-void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Never emitted outside of the BranchInstr.
-  UNREACHABLE();
-}
-
-
-void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                  BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
+Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                           BranchLabels labels) {
   Register left = locs()->in(0).reg();
   Location right = locs()->in(1);
   if (right.IsConstant()) {
@@ -642,6 +628,21 @@
     __ and_(CMPRES1, left, right.reg());
   }
   __ mov(CMPRES2, ZR);
+  Condition true_condition = (kind() == Token::kNE) ? NE : EQ;
+  return true_condition;
+}
+
+
+void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // Never emitted outside of the BranchInstr.
+  UNREACHABLE();
+}
+
+
+void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                  BranchInstr* branch) {
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
   EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
@@ -682,18 +683,25 @@
 }
 
 
+Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+  }
+}
+
+
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ TraceSimMsg("RelationalOpInstr");
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
   Register result = locs()->out().reg();
   Label done;
   __ Bind(&is_false);
@@ -710,13 +718,8 @@
   __ TraceSimMsg("RelationalOpInstr");
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -2479,6 +2482,7 @@
   }
 
   Register right = locs()->in(1).reg();
+  Range* right_range = this->right()->definition()->range();
   switch (op_kind()) {
     case Token::kADD: {
       if (deopt == NULL) {
@@ -2528,8 +2532,10 @@
       break;
     }
     case Token::kTRUNCDIV: {
-      // Handle divide by zero in runtime.
-      __ beq(right, ZR, deopt);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ beq(right, ZR, deopt);
+      }
       Register temp = locs()->temp(0).reg();
       __ sra(temp, left, kSmiTagSize);  // SmiUntag left into temp.
       __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
@@ -2542,8 +2548,10 @@
       break;
     }
     case Token::kMOD: {
-      // Handle divide by zero in runtime.
-      __ beq(right, ZR, deopt);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ beq(right, ZR, deopt);
+      }
       Register temp = locs()->temp(0).reg();
       __ sra(temp, left, kSmiTagSize);  // SmiUntag left into temp.
       __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
@@ -2557,13 +2565,22 @@
       //      res = res + right;
       //    }
       //  }
-      Label done, subtract;
+      Label done;
       __ bgez(result, &done);
-      __ bltz(right, &subtract);
-      __ addu(result, result, TMP);
-      __ b(&done);
-      __ Bind(&subtract);
-      __ subu(result, result, TMP);
+      if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+        Label subtract;
+        __ bltz(right, &subtract);
+        __ addu(result, result, TMP);
+        __ b(&done);
+        __ Bind(&subtract);
+        __ subu(result, result, TMP);
+      } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+        // Right is positive.
+        __ addu(result, result, TMP);
+      } else {
+        // Right is negative.
+        __ subu(result, result, TMP);
+      }
       __ Bind(&done);
       __ SmiTag(result);
       break;
@@ -2576,7 +2593,6 @@
       __ sra(temp, right, kSmiTagSize);  // SmiUntag right into temp.
       // sra operation masks the count to 5 bits.
       const intptr_t kCountLimit = 0x1F;
-      Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
         Label ok;
@@ -3428,8 +3444,11 @@
     Register temp = locs()->temp(0).reg();
     Register result_div = locs()->temp(1).reg();
     Register result_mod = locs()->temp(2).reg();
-    // Handle divide by zero in runtime.
-    __ beq(right, ZR, deopt);
+    Range* right_range = InputAt(1)->definition()->range();
+    if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+      // Handle divide by zero in runtime.
+      __ beq(right, ZR, deopt);
+    }
     __ sra(temp, left, kSmiTagSize);  // SmiUntag left into temp.
     __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
     __ div(temp, TMP);
@@ -3446,13 +3465,22 @@
     //      res = res + right;
     //    }
     //  }
-    Label done, subtract;
+    Label done;
     __ bgez(result_mod, &done);
-    __ bltz(right, &subtract);
-    __ addu(result_mod, result_mod, TMP);
-    __ b(&done);
-    __ Bind(&subtract);
-    __ subu(result_mod, result_mod, TMP);
+    if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+      Label subtract;
+      __ bltz(right, &subtract);
+      __ addu(result_mod, result_mod, TMP);
+      __ b(&done);
+      __ Bind(&subtract);
+      __ subu(result_mod, result_mod, TMP);
+    } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+      // Right is positive.
+      __ addu(result_mod, result_mod, TMP);
+    } else {
+      // Right is negative.
+      __ subu(result_mod, result_mod, TMP);
+    }
     __ Bind(&done);
 
     __ SmiTag(result_div);
@@ -3831,37 +3859,32 @@
 }
 
 
-static void EmitStrictComparison(FlowGraphCompiler* compiler,
-                                 StrictCompareInstr* compare,
-                                 BranchLabels labels) {
-  LocationSummary* locs = compare->locs();
-  bool needs_number_check = compare->needs_number_check();
-  intptr_t token_pos = compare->token_pos();
-  Token::Kind kind = compare->kind();
-  Location left = locs->in(0);
-  Location right = locs->in(1);
+Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                 BranchLabels labels) {
+  Location left = locs()->in(0);
+  Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
   if (left.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(right.reg(),
                                           left.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else if (right.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(left.reg(),
                                           right.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else {
     compiler->EmitEqualityRegRegCompare(left.reg(),
                                        right.reg(),
-                                       needs_number_check,
-                                       token_pos);
+                                       needs_number_check(),
+                                       token_pos());
   }
-  Condition true_condition = (kind == Token::kEQ_STRICT) ? EQ : NE;
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  return true_condition;
 }
 
-// Special code for numbers (compare values instead of references.)
+
 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ TraceSimMsg("StrictCompareInstr");
   __ Comment("StrictCompareInstr");
@@ -3869,8 +3892,8 @@
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
-
-  EmitStrictComparison(compiler, this, labels);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
   Register result = locs()->out().reg();
   Label done;
@@ -3889,8 +3912,8 @@
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  EmitStrictComparison(compiler, this, labels);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
diff --git a/runtime/vm/intermediate_language_test.cc b/runtime/vm/intermediate_language_test.cc
index 4caaa86..ac57c55 100644
--- a/runtime/vm/intermediate_language_test.cc
+++ b/runtime/vm/intermediate_language_test.cc
@@ -39,4 +39,24 @@
   EXPECT(!c3->Equals(c1));
 }
 
+
+TEST_CASE(RangeTests) {
+  Range* zero = new Range(
+      RangeBoundary::FromConstant(0),
+      RangeBoundary::FromConstant(0));
+  Range* positive = new Range(
+      RangeBoundary::FromConstant(0),
+      RangeBoundary::FromConstant(100));
+  Range* negative = new Range(
+      RangeBoundary::FromConstant(-1),
+      RangeBoundary::FromConstant(-100));
+  Range* range_x = new Range(
+      RangeBoundary::FromConstant(-15),
+      RangeBoundary::FromConstant(100));
+  EXPECT(zero->Overlaps(0, 0));
+  EXPECT(positive->Overlaps(0, 0));
+  EXPECT(!negative->Overlaps(0, 0));
+  EXPECT(range_x->Overlaps(0, 0));
+}
+
 }  // namespace dart
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 055ba3c..9f61a2f 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -131,16 +131,7 @@
 
 
 LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
-  const intptr_t kNumInputs = 2;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs =
-      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RegisterOrConstant(left()));
-  // Only one of the inputs can be a constant. Choose register if the first one
-  // is a constant.
-  locs->set_in(1, locs->in(0).IsConstant()
-                      ? Location::RequiresRegister()
-                      : Location::RegisterOrConstant(right()));
+  LocationSummary* locs = comparison()->MakeLocationSummary();
   // TODO(vegorov): support byte register constraints in the register allocator.
   locs->set_out(Location::RegisterLocation(RDX));
   return locs;
@@ -149,30 +140,14 @@
 
 void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->out().reg() == RDX);
-  ASSERT(Token::IsEqualityOperator(kind()));
-
-  Location left = locs()->in(0);
-  Location right = locs()->in(1);
-  ASSERT(!left.IsConstant() || !right.IsConstant());
 
   // Clear upper part of the out register. We are going to use setcc on it
   // which is a byte move.
   __ xorq(RDX, RDX);
 
-  // Compare left and right. For now only equality comparison is supported.
-  // TODO(vegorov): reuse code from the other comparison instructions instead of
-  // generating it inline here.
-  if (left.IsConstant()) {
-    __ CompareObject(right.reg(), left.constant(), PP);
-  } else if (right.IsConstant()) {
-    __ CompareObject(left.reg(), right.constant(), PP);
-  } else {
-    __ cmpq(left.reg(), right.reg());
-  }
-
-  Condition true_condition =
-      ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL
-                                                              : NOT_EQUAL;
+  // Emit comparison code. This must not overwrite the result register.
+  BranchLabels labels = { NULL, NULL, NULL };
+  Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
 
   const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
 
@@ -420,10 +395,10 @@
 }
 
 
-static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
-                                const LocationSummary& locs,
-                                Token::Kind kind,
-                                BranchLabels labels) {
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+                                     const LocationSummary& locs,
+                                     Token::Kind kind,
+                                     BranchLabels labels) {
   Location left = locs.in(0);
   Location right = locs.in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
@@ -440,7 +415,7 @@
   } else {
     __ cmpq(left.reg(), right.reg());
   }
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  return true_condition;
 }
 
 
@@ -459,10 +434,10 @@
 }
 
 
-static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
-                                   const LocationSummary& locs,
-                                   Token::Kind kind,
-                                   BranchLabels labels) {
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+                                        const LocationSummary& locs,
+                                        Token::Kind kind,
+                                        BranchLabels labels) {
   XmmRegister left = locs.in(0).fpu_reg();
   XmmRegister right = locs.in(1).fpu_reg();
 
@@ -472,7 +447,18 @@
   Label* nan_result = (true_condition == NOT_EQUAL)
       ? labels.true_label : labels.false_label;
   __ j(PARITY_EVEN, nan_result);
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  return true_condition;
+}
+
+
+Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                   BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+  }
 }
 
 
@@ -481,13 +467,9 @@
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler,  true_condition, labels);
 
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
   Register result = locs()->out().reg();
   Label done;
   __ Bind(&is_false);
@@ -504,13 +486,8 @@
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else  {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -527,17 +504,8 @@
 }
 
 
-void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Never emitted outside of the BranchInstr.
-  UNREACHABLE();
-}
-
-
-void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
-                                  BranchInstr* branch) {
-  BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  Condition branch_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                           BranchLabels labels) {
   Register left_reg = locs()->in(0).reg();
   Location right = locs()->in(1);
   if (right.IsConstant()) {
@@ -548,7 +516,22 @@
   } else {
     __ testq(left_reg, right.reg());
   }
-  EmitBranchOnCondition(compiler, branch_condition, labels);
+  Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+  return true_condition;
+}
+
+
+void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // Never emitted outside of the BranchInstr.
+  UNREACHABLE();
+}
+
+
+void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+                                  BranchInstr* branch) {
+  BranchLabels labels = compiler->CreateBranchLabels(branch);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -577,16 +560,23 @@
 }
 
 
+Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                BranchLabels labels) {
+  if (operation_cid() == kSmiCid) {
+    return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+  } else {
+    ASSERT(operation_cid() == kDoubleCid);
+    return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+  }
+}
+
+
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
   Register result = locs()->out().reg();
   Label done;
   __ Bind(&is_false);
@@ -601,13 +591,8 @@
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  if (operation_cid() == kSmiCid) {
-    EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
-  } else {
-    ASSERT(operation_cid() == kDoubleCid);
-    EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
-  }
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
@@ -2391,6 +2376,7 @@
 
   // if locs()->in(1).IsRegister.
   Register right = locs()->in(1).reg();
+  Range* right_range = this->right()->definition()->range();
   switch (op_kind()) {
     case Token::kADD: {
       __ addq(left, right);
@@ -2431,11 +2417,11 @@
       ASSERT((right != RDX) && (right != RAX));
       ASSERT(temp == RDX);
       ASSERT(result == RAX);
-
-      // Handle divide by zero in runtime.
-      __ testq(right, right);
-      __ j(ZERO, deopt);
-
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ testq(right, right);
+        __ j(ZERO, deopt);
+      }
       // Check if both operands fit into 32bits as idiv with 64bit operands
       // requires twice as many cycles and has much higher latency.
       // We are checking this before untagging them to avoid corner case
@@ -2478,9 +2464,11 @@
       ASSERT((right != RDX) && (right != RAX));
       ASSERT(temp == RAX);
       ASSERT(result == RDX);
-      // Handle divide by zero in runtime.
-      __ testq(right, right);
-      __ j(ZERO, deopt);
+      if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+        // Handle divide by zero in runtime.
+        __ testq(right, right);
+        __ j(ZERO, deopt);
+      }
       // Check if both operands fit into 32bits as idiv with 64bit operands
       // requires twice as many cycles and has much higher latency.
       // We are checking this before untagging them to avoid corner case
@@ -2517,16 +2505,25 @@
       //      res = res + right;
       //    }
       //  }
-      Label subtract, all_done;
+      Label all_done;
       __ cmpq(result, Immediate(0));
       __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump);
       // Result is negative, adjust it.
-      __ cmpq(right, Immediate(0));
-      __ j(LESS, &subtract, Assembler::kNearJump);
-      __ addq(result, right);
-      __ jmp(&all_done, Assembler::kNearJump);
-      __ Bind(&subtract);
-      __ subq(result, right);
+      if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+        Label subtract;
+        __ cmpq(right, Immediate(0));
+        __ j(LESS, &subtract, Assembler::kNearJump);
+        __ addq(result, right);
+        __ jmp(&all_done, Assembler::kNearJump);
+        __ Bind(&subtract);
+        __ subq(result, right);
+      } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+        // Right is positive.
+        __ addq(result, right);
+      } else {
+        // Right is negative.
+        __ subq(result, right);
+      }
       __ Bind(&all_done);
       __ SmiTag(result);
       break;
@@ -2539,7 +2536,6 @@
       __ SmiUntag(right);
       // sarq operation masks the count to 6 bits.
       const intptr_t kCountLimit = 0x3F;
-      Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
         __ CompareImmediate(right, Immediate(kCountLimit), PP);
@@ -4076,9 +4072,13 @@
     ASSERT((right != RDX) && (right != RAX));
     ASSERT(temp == RDX);
     ASSERT((result != RDX) && (result != RAX));
-    // Handle divide by zero in runtime.
-    __ testq(right, right);
-    __ j(ZERO, deopt);
+
+    Range* right_range = InputAt(1)->definition()->range();
+    if ((right_range == NULL) || right_range->Overlaps(0, 0)) {
+      // Handle divide by zero in runtime.
+      __ testq(right, right);
+      __ j(ZERO, deopt);
+    }
     // Check if both operands fit into 32bits as idiv with 64bit operands
     // requires twice as many cycles and has much higher latency.
     // We are checking this before untagging them to avoid corner case
@@ -4121,16 +4121,25 @@
     //      res = res + right;
     //    }
     //  }
-    Label subtract, all_done;
+    Label all_done;
     __ cmpq(RDX, Immediate(0));
     __ j(GREATER_EQUAL, &all_done, Assembler::kNearJump);
     // Result is negative, adjust it.
-    __ cmpq(right, Immediate(0));
-    __ j(LESS, &subtract, Assembler::kNearJump);
-    __ addq(RDX, right);
-    __ jmp(&all_done, Assembler::kNearJump);
-    __ Bind(&subtract);
-    __ subq(RDX, right);
+    if ((right_range == NULL) || right_range->Overlaps(-1, 1)) {
+      Label subtract;
+      __ cmpq(right, Immediate(0));
+      __ j(LESS, &subtract, Assembler::kNearJump);
+      __ addq(RDX, right);
+      __ jmp(&all_done, Assembler::kNearJump);
+      __ Bind(&subtract);
+      __ subq(RDX, right);
+    } else if (right_range->IsWithin(0, RangeBoundary::kPlusInfinity)) {
+      // Right is positive.
+      __ addq(RDX, right);
+    } else {
+      // Right is negative.
+      __ subq(RDX, right);
+    }
     __ Bind(&all_done);
     __ SmiTag(result);
 
@@ -4519,46 +4528,41 @@
 }
 
 
-static void EmitStrictComparison(FlowGraphCompiler* compiler,
-                                 StrictCompareInstr* compare,
-                                 BranchLabels labels) {
-  LocationSummary* locs = compare->locs();
-  bool needs_number_check = compare->needs_number_check();
-  intptr_t token_pos = compare->token_pos();
-  Token::Kind kind = compare->kind();
-  Location left = locs->in(0);
-  Location right = locs->in(1);
+Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+                                                 BranchLabels labels) {
+  Location left = locs()->in(0);
+  Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
   if (left.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(right.reg(),
                                           left.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else if (right.IsConstant()) {
     compiler->EmitEqualityRegConstCompare(left.reg(),
                                           right.constant(),
-                                          needs_number_check,
-                                          token_pos);
+                                          needs_number_check(),
+                                          token_pos());
   } else {
     compiler->EmitEqualityRegRegCompare(left.reg(),
                                         right.reg(),
-                                        needs_number_check,
-                                        token_pos);
+                                        needs_number_check(),
+                                        token_pos());
   }
 
-  Condition true_condition = (kind == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
-  EmitBranchOnCondition(compiler, true_condition, labels);
+  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+  return true_condition;
 }
 
 
-// Special code for numbers (compare values instead of references.)
 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
   Label is_true, is_false;
   BranchLabels labels = { &is_true, &is_false, &is_false };
 
-  EmitStrictComparison(compiler, this, labels);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 
   Register result = locs()->out().reg();
   Label done;
@@ -4576,8 +4580,8 @@
   ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
 
   BranchLabels labels = compiler->CreateBranchLabels(branch);
-
-  EmitStrictComparison(compiler, this, labels);
+  Condition true_condition = EmitComparisonCode(compiler, labels);
+  EmitBranchOnCondition(compiler, true_condition, labels);
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index c3e92fa..1874127 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -25,7 +25,6 @@
 #include "vm/profiler.h"
 #include "vm/reusable_handles.h"
 #include "vm/service.h"
-#include "vm/signal_handler.h"
 #include "vm/simulator.h"
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
@@ -340,7 +339,6 @@
 }
 
 void Isolate::SetCurrent(Isolate* current) {
-  ScopedSignalBlocker ssb;
   Isolate* old_isolate = Current();
   if (old_isolate != NULL) {
     ProfilerManager::DescheduleIsolate(old_isolate);
@@ -371,6 +369,9 @@
   Isolate* result = new Isolate();
   ASSERT(result != NULL);
 
+  // Setup for profiling.
+  ProfilerManager::SetupIsolateForProfiling(result);
+
   // TODO(5411455): For now just set the recently created isolate as
   // the current isolate.
   SetCurrent(result);
@@ -409,8 +410,6 @@
     }
   }
 
-  // Setup for profiling.
-  ProfilerManager::SetupIsolateForProfiling(result);
 
   return result;
 }
@@ -529,7 +528,7 @@
     StartIsolateScope start_scope(isolate);
     StackZone zone(isolate);
     HandleScope handle_scope(isolate);
-    if (!ClassFinalizer::FinalizeTypeHierarchy()) {
+    if (!ClassFinalizer::ProcessPendingClasses()) {
       // Error is in sticky error already.
       return false;
     }
@@ -704,11 +703,6 @@
     StackZone stack_zone(this);
     HandleScope handle_scope(this);
 
-    ScopedSignalBlocker ssb;
-
-    ProfilerManager::DescheduleIsolate(this);
-
-
     if (FLAG_print_object_histogram) {
       heap()->CollectAllGarbage();
       object_histogram()->Print();
@@ -750,6 +744,7 @@
   // TODO(5411455): For now just make sure there are no current isolates
   // as we are shutting down the isolate.
   SetCurrent(NULL);
+  ProfilerManager::DescheduleIsolate(this);
   ProfilerManager::ShutdownIsolateForProfiling(this);
 }
 
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 91272a1..a392731 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -12,7 +12,8 @@
 namespace dart {
 
 MegamorphicCacheTable::MegamorphicCacheTable()
-    : miss_handler_(NULL),
+    : miss_handler_function_(NULL),
+      miss_handler_code_(NULL),
       capacity_(0),
       length_(0),
       table_(NULL) {
@@ -65,14 +66,16 @@
                                      false,  // Not external.
                                      cls,
                                      0));  // No token position.
+  miss_handler_code_ = code.raw();
+  miss_handler_function_ = function.raw();
   function.SetCode(code);
-  miss_handler_ = function.raw();
 }
 
 
 void MegamorphicCacheTable::VisitObjectPointers(ObjectPointerVisitor* v) {
   ASSERT(v != NULL);
-  v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_));
+  v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_code_));
+  v->VisitPointer(reinterpret_cast<RawObject**>(&miss_handler_function_));
   for (intptr_t i = 0; i < length_; ++i) {
     v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].name));
     v->VisitPointer(reinterpret_cast<RawObject**>(&table_[i].descriptor));
diff --git a/runtime/vm/megamorphic_cache_table.h b/runtime/vm/megamorphic_cache_table.h
index 1cfd8c2..eafb35b 100644
--- a/runtime/vm/megamorphic_cache_table.h
+++ b/runtime/vm/megamorphic_cache_table.h
@@ -14,6 +14,7 @@
 class ObjectPointerVisitor;
 class RawArray;
 class RawFunction;
+class RawCode;
 class RawMegamorphicCache;
 class RawString;
 class String;
@@ -23,7 +24,7 @@
   MegamorphicCacheTable();
   ~MegamorphicCacheTable();
 
-  RawFunction* miss_handler() const { return miss_handler_; }
+  RawFunction* miss_handler() const { return miss_handler_function_; }
   void InitMissHandler();
 
   RawMegamorphicCache* Lookup(const String& name, const Array& descriptor);
@@ -41,7 +42,8 @@
 
   static const int kCapacityIncrement = 128;
 
-  RawFunction* miss_handler_;
+  RawFunction* miss_handler_function_;
+  RawCode* miss_handler_code_;
   intptr_t capacity_;
   intptr_t length_;
   Entry* table_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c420682..a954661 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1578,7 +1578,7 @@
     case kExternalTypedDataFloat64ArrayCid:
       return Symbols::Float64List().raw();
     default:
-      if (!IsSignatureClass()) {
+      if (!IsCanonicalSignatureClass()) {
         const String& name = String::Handle(Name());
         return String::IdentifierPrettyName(name);
       } else {
@@ -4103,22 +4103,6 @@
 }
 
 
-void Function::DetachCode() const {
-  // Set unoptimized code as non-entrant, and set code and unoptimized code
-  // to null.
-  CodePatcher::PatchEntry(Code::Handle(unoptimized_code()));
-  StorePointer(&raw_ptr()->code_, Code::null());
-  StorePointer(&raw_ptr()->unoptimized_code_, Code::null());
-}
-
-
-void Function::ReattachCode(const Code& code) const {
-  StorePointer(&raw_ptr()->code_, code.raw());
-  StorePointer(&raw_ptr()->unoptimized_code_, code.raw());
-  CodePatcher::RestoreEntry(code);
-}
-
-
 void Function::SwitchToUnoptimizedCode() const {
   ASSERT(HasOptimizedCode());
 
@@ -5918,18 +5902,21 @@
   jsobj.AddProperty("id", id);
   jsobj.AddProperty("name", internal_field_name);
   jsobj.AddProperty("user_name", field_name);
-  if (ref) {
-    return;
+  if (is_static()) {
+    const Object& valueObj = Object::Handle(value());
+    jsobj.AddProperty("value", valueObj);
   }
   Class& cls = Class::Handle(owner());
-  jsobj.AddProperty("type", "Field");
-  jsobj.AddProperty("id", id);
-  jsobj.AddProperty("name", internal_field_name);
-  jsobj.AddProperty("user_name", field_name);
-  jsobj.AddProperty("class", cls);
+  jsobj.AddProperty("owner", cls);
+  AbstractType& declared_type = AbstractType::Handle(type());
+  cls = declared_type.type_class();
+  jsobj.AddProperty("declared_type", cls);
   jsobj.AddProperty("static", is_static());
   jsobj.AddProperty("final", is_final());
   jsobj.AddProperty("const", is_const());
+  if (ref) {
+    return;
+  }
   jsobj.AddProperty("guard_nullable", is_nullable());
   if (guarded_cid() == kIllegalCid) {
     jsobj.AddProperty("guard_class", "unknown");
@@ -6804,6 +6791,24 @@
 }
 
 
+const char* Script::GetKindAsCString() const {
+  switch (kind()) {
+    case RawScript::kScriptTag:
+      return "script";
+    case RawScript::kLibraryTag:
+      return "library";
+    case RawScript::kSourceTag:
+      return "source";
+    case RawScript::kPatchTag:
+      return "patch";
+    default:
+      UNIMPLEMENTED();
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
 void Script::set_url(const String& value) const {
   StorePointer(&raw_ptr()->url_, value.raw());
 }
@@ -7055,6 +7060,18 @@
 
 void Script::PrintToJSONStream(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  jsobj.AddProperty("type", JSONType(ref));
+  jsobj.AddProperty("id", id);
+  const String& name = String::Handle(url());
+  jsobj.AddProperty("name", name.ToCString());
+  jsobj.AddProperty("kind", GetKindAsCString());
+  if (ref) {
+    return;
+  }
+  const String& source = String::Handle(Source());
+  jsobj.AddProperty("source", source.ToCString());
 }
 
 
@@ -8123,15 +8140,18 @@
   jsobj.AddProperty("type", JSONType(ref));
   jsobj.AddProperty("id", id);
   jsobj.AddProperty("name", library_name);
-  if (ref) return;
   jsobj.AddProperty("url", library_url);
+  if (ref) return;
   {
     JSONArray jsarr(&jsobj, "classes");
     ClassDictionaryIterator class_iter(*this);
     Class& klass = Class::Handle();
     while (class_iter.HasNext()) {
       klass = class_iter.GetNextClass();
-      jsarr.AddValue(klass);
+      if (!klass.IsCanonicalSignatureClass() &&
+          !klass.IsAnonymousMixinApplication()) {
+        jsarr.AddValue(klass);
+      }
     }
   }
   {
@@ -8142,6 +8162,42 @@
       jsarr.AddValue(lib);
     }
   }
+  {
+    JSONArray jsarr(&jsobj, "variables");
+    DictionaryIterator entries(*this);
+    Object& entry = Object::Handle();
+    while (entries.HasNext()) {
+      entry = entries.GetNext();
+      if (entry.IsField()) {
+        jsarr.AddValue(entry);
+      }
+    }
+  }
+  {
+    JSONArray jsarr(&jsobj, "functions");
+    DictionaryIterator entries(*this);
+    Object& entry = Object::Handle();
+    while (entries.HasNext()) {
+      entry = entries.GetNext();
+      if (entry.IsFunction()) {
+        const Function& func = Function::Cast(entry);
+        if (func.kind() == RawFunction::kRegularFunction ||
+            func.kind() == RawFunction::kGetterFunction ||
+            func.kind() == RawFunction::kSetterFunction) {
+          jsarr.AddValue(func);
+        }
+      }
+    }
+  }
+  {
+    JSONArray jsarr(&jsobj, "scripts");
+    Array& scripts = Array::Handle(LoadedScripts());
+    Script& script = Script::Handle();
+    for (intptr_t i = 0; i < scripts.Length(); i++) {
+      script ^= scripts.At(i);
+      jsarr.AddValue(script);
+    }
+  }
 }
 
 
@@ -11342,7 +11398,23 @@
 
 
 void Instance::PrintToJSONStream(JSONStream* stream, bool ref) const {
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+
   JSONObject jsobj(stream);
+  jsobj.AddProperty("type", JSONType(ref));
+  jsobj.AddProperty("id", id);
+
+  // Set the "preview" property for this instance.
+  if (IsNull()) {
+    jsobj.AddProperty("preview", "null");
+  } else if (raw() == Object::sentinel().raw() ||
+             raw() == Object::transition_sentinel().raw()) {
+    jsobj.AddProperty("preview", "<uninitialized>");
+  } else {
+    // TODO(turnidge): Handle special characters?  Truncate?
+    jsobj.AddProperty("preview", ToCString());
+  }
 }
 
 
@@ -12677,7 +12749,7 @@
 
 
 void Number::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -12689,7 +12761,7 @@
 
 
 void Integer::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Number::PrintToJSONStream(stream, ref);
 }
 
 
@@ -12788,6 +12860,12 @@
 }
 
 
+uint32_t Integer::AsTruncatedUint32Value() const {
+  UNIMPLEMENTED();
+  return 0;
+}
+
+
 int Integer::CompareWith(const Integer& other) const {
   UNIMPLEMENTED();
   return 0;
@@ -13057,6 +13135,11 @@
 }
 
 
+uint32_t Smi::AsTruncatedUint32Value() const {
+  return this->Value() & 0xFFFFFFFF;
+}
+
+
 static bool FitsIntoSmi(const Integer& integer) {
   if (integer.IsSmi()) {
     return true;
@@ -13107,7 +13190,7 @@
 
 
 void Smi::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Number::PrintToJSONStream(stream, ref);
 }
 
 
@@ -13190,6 +13273,11 @@
 }
 
 
+uint32_t Mint::AsTruncatedUint32Value() const {
+  return this->value() & 0xFFFFFFFF;
+}
+
+
 int Mint::CompareWith(const Integer& other) const {
   ASSERT(!FitsIntoSmi(*this));
   if (other.IsMint() || other.IsSmi()) {
@@ -13226,7 +13314,7 @@
 
 
 void Mint::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Number::PrintToJSONStream(stream, ref);
 }
 
 
@@ -13332,7 +13420,7 @@
 
 
 void Double::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Number::PrintToJSONStream(stream, ref);
 }
 
 
@@ -13457,6 +13545,11 @@
 }
 
 
+uint32_t Bigint::AsTruncatedUint32Value() const {
+  return BigintOperations::TruncateToUint32(*this);
+}
+
+
 // For positive values: Smi < Mint < Bigint.
 int Bigint::CompareWith(const Integer& other) const {
   ASSERT(!FitsIntoSmi(*this));
@@ -13503,7 +13596,7 @@
 
 
 void Bigint::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Number::PrintToJSONStream(stream, ref);
 }
 
 
@@ -14126,7 +14219,7 @@
 
 
 void String::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -14884,7 +14977,7 @@
 
 
 void Bool::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -14970,7 +15063,7 @@
 
 
 void Array::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15183,7 +15276,7 @@
 
 void GrowableObjectArray::PrintToJSONStream(JSONStream* stream,
                                             bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15288,7 +15381,7 @@
 
 
 void Float32x4::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15393,7 +15486,7 @@
 
 
 void Int32x4::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15443,7 +15536,7 @@
 
 
 void TypedData::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15479,7 +15572,7 @@
 
 void ExternalTypedData::PrintToJSONStream(JSONStream* stream,
                                           bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15666,7 +15759,7 @@
 
 
 void Stacktrace::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15876,7 +15969,7 @@
 
 
 void JSRegExp::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
@@ -15896,7 +15989,7 @@
 
 
 void WeakProperty::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 RawAbstractType* MirrorReference::GetAbstractTypeReferent() const {
@@ -15958,7 +16051,7 @@
 
 
 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  JSONObject jsobj(stream);
+  Instance::PrintToJSONStream(stream, ref);
 }
 
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2334c28..99a9fb5 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1508,13 +1508,6 @@
   // Sets function's code and code's function.
   void SetCode(const Code& value) const;
 
-  // Detaches code from the function by setting the code to null, and patches
-  // the code to be non-entrant.
-  void DetachCode() const;
-
-  // Reattaches code to the function, and patches the code to be entrant.
-  void ReattachCode(const Code& code) const;
-
   // Disables optimized code and switches to unoptimized code.
   void SwitchToUnoptimizedCode() const;
 
@@ -2002,6 +1995,9 @@
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Function, Object);
   friend class Class;
+  // RawFunction::VisitFunctionPointers accesses the private constructor of
+  // Function.
+  friend class RawFunction;
 };
 
 
@@ -2365,6 +2361,7 @@
   RawScript::Kind kind() const {
     return static_cast<RawScript::Kind>(raw_ptr()->kind_);
   }
+  const char* GetKindAsCString() const;
   intptr_t line_offset() const { return raw_ptr()->line_offset_; }
   intptr_t col_offset() const { return raw_ptr()->col_offset_; }
 
@@ -3360,6 +3357,10 @@
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Code, Object);
   friend class Class;
+
+  // So that the RawFunction pointer visitor can determine whether code the
+  // function points to is optimized.
+  friend class RawFunction;
 };
 
 
@@ -4476,6 +4477,7 @@
 
   virtual double AsDoubleValue() const;
   virtual int64_t AsInt64Value() const;
+  virtual uint32_t AsTruncatedUint32Value() const;
 
   // Returns 0, -1 or 1.
   virtual int CompareWith(const Integer& other) const;
@@ -4518,6 +4520,7 @@
 
   virtual double AsDoubleValue() const;
   virtual int64_t AsInt64Value() const;
+  virtual uint32_t AsTruncatedUint32Value() const;
 
   virtual int CompareWith(const Integer& other) const;
 
@@ -4607,6 +4610,7 @@
 
   virtual double AsDoubleValue() const;
   virtual int64_t AsInt64Value() const;
+  virtual uint32_t AsTruncatedUint32Value() const;
 
   virtual int CompareWith(const Integer& other) const;
 
@@ -4644,6 +4648,7 @@
 
   virtual double AsDoubleValue() const;
   virtual int64_t AsInt64Value() const;
+  virtual uint32_t AsTruncatedUint32Value() const;
 
   virtual int CompareWith(const Integer& other) const;
 
@@ -5020,6 +5025,8 @@
   friend class TwoByteString;
   friend class ExternalOneByteString;
   friend class ExternalTwoByteString;
+  // So that the MarkingVisitor can print a debug string from a NoHandleScope.
+  friend class MarkingVisitor;
 };
 
 
diff --git a/runtime/vm/object_id_ring.cc b/runtime/vm/object_id_ring.cc
index 434463b..5bc056b 100644
--- a/runtime/vm/object_id_ring.cc
+++ b/runtime/vm/object_id_ring.cc
@@ -86,7 +86,7 @@
 
 
 int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
-  ASSERT(raw_obj->IsHeapObject());
+  // TODO(turnidge): Do not enter Smis into the ObjectIdRing.
   int32_t id = NextSerial();
   ASSERT(id != kInvalidId);
   int32_t cursor = IndexOfId(id);
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 921976a..a4a22a6 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3518,7 +3518,7 @@
       "  }\n"
       "}";
   TestCase::LoadTestScript(kScriptChars, NULL);
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index e5a96c5..be05e97 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -23,12 +23,14 @@
             "Print free list statistics before a GC");
 DEFINE_FLAG(bool, print_free_list_after_gc, false,
             "Print free list statistics after a GC");
-DEFINE_FLAG(bool, collect_code, false,
+DEFINE_FLAG(bool, collect_code, true,
             "Attempt to GC infrequently used code.");
 DEFINE_FLAG(int, code_collection_interval_in_us, 30000000,
             "Time between attempts to collect unused code.");
 DEFINE_FLAG(bool, log_code_drop, false,
             "Emit a log message when pointers to unused code are dropped.");
+DEFINE_FLAG(bool, always_drop_code, false,
+            "Always try to drop code if the function's usage counter is >= 0");
 
 HeapPage* HeapPage::Initialize(VirtualMemory* memory, PageType type) {
   ASSERT(memory->size() > VirtualMemory::PageSize());
@@ -385,61 +387,21 @@
 }
 
 
-class CodeDetacherVisitor : public ObjectVisitor {
- public:
-  explicit CodeDetacherVisitor(Isolate* isolate) : ObjectVisitor(isolate) { }
-
-  virtual void VisitObject(RawObject* obj);
-
- private:
-  static bool MayDetachCode(const Function& fn);
-  DISALLOW_COPY_AND_ASSIGN(CodeDetacherVisitor);
-};
-
-
-bool CodeDetacherVisitor::MayDetachCode(const Function& fn) {
-  return fn.HasCode() &&  // Not already detached.
-         !fn.HasOptimizedCode() &&
-         !fn.HasBreakpoint() &&
-         (fn.usage_counter() > 0);
-}
-
-
-void CodeDetacherVisitor::VisitObject(RawObject* raw_obj) {
-  Isolate* isolate = Isolate::Current();
-  HANDLESCOPE(isolate);
-  const Object& obj = Object::Handle(raw_obj);
-  if (obj.GetClassId() == kFunctionCid) {
-    const Function& fn = Function::Cast(obj);
-    if (CodeDetacherVisitor::MayDetachCode(fn)) {
-      fn.set_usage_counter(fn.usage_counter() / 2);
-      if (fn.usage_counter() == 0) {
-        if (FLAG_log_code_drop) {
-          const String& name = String::Handle(fn.name());
-          OS::Print("Detaching code for function %s\n", name.ToCString());
-        }
-        fn.DetachCode();
-      }
-    }
-  }
-}
-
-
-void PageSpace::TryDetachingCode() {
+bool PageSpace::ShouldCollectCode() {
   // Try to collect code if enough time has passed since the last attempt.
   const int64_t start = OS::GetCurrentTimeMicros();
   const int64_t last_code_collection_in_us =
       page_space_controller_.last_code_collection_in_us();
+
   if ((start - last_code_collection_in_us) >
-       FLAG_code_collection_interval_in_us) {
+      FLAG_code_collection_interval_in_us) {
     if (FLAG_log_code_drop) {
       OS::Print("Trying to detach code.\n");
     }
-    Isolate* isolate = Isolate::Current();
-    CodeDetacherVisitor code_detacher(isolate);
-    heap_->IterateObjects(&code_detacher);
     page_space_controller_.set_last_code_collection_in_us(start);
+    return true;
   }
+  return false;
 }
 
 
@@ -448,9 +410,6 @@
   ASSERT(!sweeping_);
   sweeping_ = true;
   Isolate* isolate = Isolate::Current();
-  if (FLAG_collect_code) {
-    TryDetachingCode();
-  }
 
   NoHandleScope no_handles(isolate);
 
@@ -470,8 +429,9 @@
   const int64_t start = OS::GetCurrentTimeMicros();
 
   // Mark all reachable old-gen objects.
+  bool collect_code = FLAG_collect_code && ShouldCollectCode();
   GCMarker marker(heap_);
-  marker.MarkObjects(isolate, this, invoke_api_callbacks);
+  marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code);
 
   int64_t mid1 = OS::GetCurrentTimeMicros();
 
diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h
index 71707a8..ad2e3b0 100644
--- a/runtime/vm/pages.h
+++ b/runtime/vm/pages.h
@@ -13,6 +13,7 @@
 
 DECLARE_FLAG(bool, collect_code);
 DECLARE_FLAG(bool, log_code_drop);
+DECLARE_FLAG(bool, always_drop_code);
 
 // Forward declarations.
 class Heap;
@@ -199,9 +200,9 @@
   RawObject* FindObject(FindObjectVisitor* visitor,
                         HeapPage::PageType type) const;
 
-  // Runs a visitor that attempts to drop references to code that has not
-  // been run in awhile.
-  void TryDetachingCode();
+  // Checks if enough time has elapsed since the last attempt to collect
+  // code.
+  bool ShouldCollectCode();
 
   // Collect the garbage in the page space using mark-sweep.
   void MarkSweep(bool invoke_api_callbacks);
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index d1f891e..fc9ddbe 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -40,6 +40,7 @@
  public:
   explicit ParsedFunction(const Function& function)
       : function_(function),
+        code_(Code::Handle(function.unoptimized_code())),
         node_sequence_(NULL),
         instantiator_(NULL),
         default_parameter_values_(Array::ZoneHandle()),
@@ -54,6 +55,7 @@
   }
 
   const Function& function() const { return function_; }
+  RawCode* code() const { return code_.raw(); }
 
   SequenceNode* node_sequence() const { return node_sequence_; }
   void SetNodeSequence(SequenceNode* node_sequence);
@@ -115,6 +117,7 @@
 
  private:
   const Function& function_;
+  Code& code_;
   SequenceNode* node_sequence_;
   AstNode* instantiator_;
   Array& default_parameter_values_;
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index 567ea81..3706489 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -123,7 +123,7 @@
   script.Tokenize(String::Handle(String::New("")));
 
   Parser::ParseCompilationUnit(lib, script);
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
   CheckField(lib, "A", "f1", false, false);
   CheckField(lib, "A", "f2", false, true);
   CheckField(lib, "A", "f3", false, true);
@@ -158,7 +158,7 @@
   script.Tokenize(String::Handle(String::New("")));
 
   Parser::ParseCompilationUnit(lib, script);
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
 
   DumpFunction(lib, "A", "foo");
   DumpFunction(lib, "A", "bar");
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 95601ba..8de6d12 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -12,6 +12,7 @@
 #include "vm/object.h"
 #include "vm/os.h"
 #include "vm/profiler.h"
+#include "vm/signal_handler.h"
 
 namespace dart {
 
@@ -54,9 +55,8 @@
 // mutex and the profile manager monitor. When an isolate running thread
 // (potential signal target) calls into an entry point which acquires
 // ProfileManager::monitor_ signal delivery must be blocked. An example is
-// Isolate::SetCurrent which blocks signal delivery while removing the old
-// current isolate from the scheduled list and adding the new current isolate
-// to the scheduled list.
+// ProfileManager::ScheduleIsolate which blocks signal delivery while removing
+// the scheduling the isolate.
 //
 
 // Notes on stack frame walking:
@@ -68,27 +68,51 @@
 // fail (sometimes leading to a crash).
 //
 
-
 DEFINE_FLAG(bool, profile, false, "Enable Sampling Profiler");
+DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
 
 bool ProfilerManager::initialized_ = false;
 bool ProfilerManager::shutdown_ = false;
+bool ProfilerManager::thread_running_ = false;
 Monitor* ProfilerManager::monitor_ = NULL;
+Monitor* ProfilerManager::start_stop_monitor_ = NULL;
 Isolate** ProfilerManager::isolates_ = NULL;
 intptr_t ProfilerManager::isolates_capacity_ = 0;
 intptr_t ProfilerManager::isolates_size_ = 0;
 
 
 void ProfilerManager::InitOnce() {
+#if defined(USING_SIMULATOR)
+  // Force disable of profiling on simulator.
+  FLAG_profile = false;
+#endif
+#if defined(TARGET_OS_WINDOWS)
+  // Force disable of profiling on Windows.
+  FLAG_profile = false;
+#endif
   if (!FLAG_profile) {
     return;
   }
   NativeSymbolResolver::InitOnce();
   ASSERT(!initialized_);
   monitor_ = new Monitor();
+  start_stop_monitor_ = new Monitor();
   initialized_ = true;
   ResizeIsolates(16);
-  Thread::Start(ThreadMain, 0);
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager starting up.\n");
+  }
+  {
+    ScopedMonitor startup_lock(start_stop_monitor_);
+    Thread::Start(ThreadMain, 0);
+    while (!thread_running_) {
+      // Wait until profiler thread has started up.
+      startup_lock.Wait();
+    }
+  }
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager running.\n");
+  }
 }
 
 
@@ -97,18 +121,33 @@
     return;
   }
   ASSERT(initialized_);
-  ScopedMonitor lock(monitor_);
-  shutdown_ = true;
-  for (intptr_t i = 0; i < isolates_size_; i++) {
-    Isolate* isolate = isolates_[i];
-    ASSERT(isolate != NULL);
-    FreeIsolateProfilingData(isolate);
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager shutting down.\n");
   }
-  isolates_size_ = 0;
-  free(isolates_);
-  isolates_ = NULL;
-  lock.Notify();
+  intptr_t size_at_shutdown = 0;
+  {
+    ScopedSignalBlocker ssb;
+    {
+      ScopedMonitor lock(monitor_);
+      shutdown_ = true;
+      size_at_shutdown = isolates_size_;
+      isolates_size_ = 0;
+      free(isolates_);
+      isolates_ = NULL;
+      lock.Notify();
+    }
+  }
   NativeSymbolResolver::ShutdownOnce();
+  {
+    ScopedMonitor shutdown_lock(start_stop_monitor_);
+    while (thread_running_) {
+      // Wait until profiler thread has exited.
+      shutdown_lock.Wait();
+    }
+  }
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager shut down (%" Pd ").\n", size_at_shutdown);
+  }
 }
 
 
@@ -117,12 +156,25 @@
     return;
   }
   ASSERT(isolate != NULL);
-  ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
-  SampleBuffer* sample_buffer = new SampleBuffer();
-  IsolateProfilerData* profiler_data =
-      new IsolateProfilerData(isolate, sample_buffer);
-  profiler_data->set_sample_interval_micros(1000);
-  isolate->set_profiler_data(profiler_data);
+  {
+    ScopedSignalBlocker ssb;
+    {
+      ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
+      SampleBuffer* sample_buffer = new SampleBuffer();
+      ASSERT(sample_buffer != NULL);
+      IsolateProfilerData* profiler_data =
+          new IsolateProfilerData(isolate, sample_buffer);
+      ASSERT(profiler_data != NULL);
+      profiler_data->set_sample_interval_micros(1000);
+      isolate->set_profiler_data(profiler_data);
+      if (FLAG_trace_profiled_isolates) {
+        OS::Print("ProfilerManager Setup Isolate %p %s %p\n",
+            isolate,
+            isolate->name(),
+            reinterpret_cast<void*>(Thread::GetCurrentThreadId()));
+      }
+    }
+  }
 }
 
 
@@ -136,8 +188,15 @@
   isolate->set_profiler_data(NULL);
   SampleBuffer* sample_buffer = profiler_data->sample_buffer();
   ASSERT(sample_buffer != NULL);
+  profiler_data->set_sample_buffer(NULL);
   delete sample_buffer;
   delete profiler_data;
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Shutdown Isolate %p %s %p\n",
+        isolate,
+        isolate->name(),
+        reinterpret_cast<void*>(Thread::GetCurrentThreadId()));
+  }
 }
 
 
@@ -146,26 +205,55 @@
   if (!FLAG_profile) {
     return;
   }
-  FreeIsolateProfilingData(isolate);
+  {
+    ScopedSignalBlocker ssb;
+    FreeIsolateProfilingData(isolate);
+  }
 }
 
 
-void ProfilerManager::ScheduleIsolate(Isolate* isolate) {
+void ProfilerManager::ScheduleIsolateHelper(Isolate* isolate) {
+  ScopedMonitor lock(monitor_);
+  {
+    if (shutdown_) {
+      // Shutdown.
+      return;
+    }
+    ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
+    IsolateProfilerData* profiler_data = isolate->profiler_data();
+    if (profiler_data == NULL) {
+      return;
+    }
+    profiler_data->Scheduled(OS::GetCurrentTimeMicros(),
+                             Thread::GetCurrentThreadId());
+  }
+  intptr_t i = FindIsolate(isolate);
+  if (i >= 0) {
+    // Already scheduled.
+    return;
+  }
+  AddIsolate(isolate);
+  lock.Notify();
+}
+
+
+void ProfilerManager::ScheduleIsolate(Isolate* isolate, bool inside_signal) {
   if (!FLAG_profile) {
     return;
   }
   ASSERT(initialized_);
   ASSERT(isolate != NULL);
-  ScopedMonitor lock(monitor_);
-  ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
+  if (!inside_signal) {
+    ScopedSignalBlocker ssb;
+    {
+      ScheduleIsolateHelper(isolate);
+    }
+  } else {
+    // Do not need a signal blocker inside a signal handler.
+    {
+      ScheduleIsolateHelper(isolate);
+    }
   }
-  profiler_data->Scheduled(OS::GetCurrentTimeMicros(),
-                           Thread::GetCurrentThreadId());
-  AddIsolate(isolate);
-  lock.Notify();
 }
 
 
@@ -175,20 +263,30 @@
   }
   ASSERT(initialized_);
   ASSERT(isolate != NULL);
-  ScopedMonitor lock(monitor_);
-  intptr_t i = FindIsolate(isolate);
-  if (i < 0) {
-    // Not scheduled.
-    return;
-  }
   {
-    ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
-    IsolateProfilerData* profiler_data = isolate->profiler_data();
-    ASSERT(profiler_data != NULL);
-    profiler_data->Descheduled();
+    ScopedSignalBlocker ssb;
+    {
+      ScopedMonitor lock(monitor_);
+      if (shutdown_) {
+        // Shutdown.
+        return;
+      }
+      intptr_t i = FindIsolate(isolate);
+      if (i < 0) {
+        // Not scheduled.
+        return;
+      }
+      {
+        ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
+        IsolateProfilerData* profiler_data = isolate->profiler_data();
+        if (profiler_data != NULL) {
+          profiler_data->Descheduled();
+        }
+      }
+      RemoveIsolate(i);
+      lock.Notify();
+    }
   }
-  RemoveIsolate(i);
-  lock.Notify();
 }
 
 
@@ -212,11 +310,11 @@
 
 
 void ProfilerManager::AddIsolate(Isolate* isolate) {
+  // Must be called with monitor_ locked.
   if (isolates_ == NULL) {
     // We are shutting down.
     return;
   }
-  // Must be called with monitor_ locked.
   if (isolates_size_ == isolates_capacity_) {
     ResizeIsolates(isolates_capacity_ == 0 ? 16 : isolates_capacity_ * 2);
   }
@@ -227,6 +325,10 @@
 
 intptr_t ProfilerManager::FindIsolate(Isolate* isolate) {
   // Must be called with monitor_ locked.
+  if (isolates_ == NULL) {
+    // We are shutting down.
+    return -1;
+  }
   for (intptr_t i = 0; i < isolates_size_; i++) {
     if (isolates_[i] == isolate) {
       return i;
@@ -238,6 +340,10 @@
 
 void ProfilerManager::RemoveIsolate(intptr_t i) {
   // Must be called with monitor_ locked.
+  if (isolates_ == NULL) {
+    // We are shutting down.
+    return;
+  }
   ASSERT(i < isolates_size_);
   intptr_t last = isolates_size_ - 1;
   if (i != last) {
@@ -280,139 +386,141 @@
 void ProfilerManager::WriteTracing(Isolate* isolate, const char* name,
                                    Dart_Port port) {
   ASSERT(isolate == Isolate::Current());
-  ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    return;
-  }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  ASSERT(sample_buffer != NULL);
-  JSONStream stream(10 * MB);
-  intptr_t tid = reinterpret_cast<intptr_t>(sample_buffer);
-  intptr_t pid = 1;
   {
-    JSONArray events(&stream);
+    ScopedSignalBlocker ssb;
     {
-      JSONObject thread_name(&events);
-      thread_name.AddProperty("name", "thread_name");
-      thread_name.AddProperty("ph", "M");
-      thread_name.AddProperty("tid", tid);
-      thread_name.AddProperty("pid", pid);
-      {
-        JSONObject args(&thread_name, "args");
-        args.AddProperty("name", name);
+      ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
+      IsolateProfilerData* profiler_data = isolate->profiler_data();
+      if (profiler_data == NULL) {
+        return;
       }
-    }
-    {
-      JSONObject process_name(&events);
-      process_name.AddProperty("name", "process_name");
-      process_name.AddProperty("ph", "M");
-      process_name.AddProperty("tid", tid);
-      process_name.AddProperty("pid", pid);
+      SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+      ASSERT(sample_buffer != NULL);
+      JSONStream stream(10 * MB);
+      intptr_t tid = reinterpret_cast<intptr_t>(sample_buffer);
+      intptr_t pid = 1;
       {
-        JSONObject args(&process_name, "args");
-        args.AddProperty("name", "Dart VM");
-      }
-    }
-    uint64_t last_time = 0;
-    for (Sample* i = sample_buffer->FirstSample();
-         i != sample_buffer->LastSample();
-         i = sample_buffer->NextSample(i)) {
-      if (last_time == 0) {
-        last_time = i->timestamp;
-      }
-      intptr_t delta = i->timestamp - last_time;
-      {
-        double percentage = static_cast<double>(i->cpu_usage) /
-                            static_cast<double>(delta) * 100.0;
-        if (percentage != percentage) {
-          percentage = 0.0;
-        }
-        percentage = percentage < 0.0 ? 0.0 : percentage;
-        percentage = percentage > 100.0 ? 100.0 : percentage;
+        JSONArray events(&stream);
         {
-          JSONObject cpu_usage(&events);
-          cpu_usage.AddProperty("name", "CPU Usage");
-          cpu_usage.AddProperty("ph", "C");
-          cpu_usage.AddProperty("tid", tid);
-          cpu_usage.AddProperty("pid", pid);
-          cpu_usage.AddProperty("ts", static_cast<double>(last_time));
+          JSONObject thread_name(&events);
+          thread_name.AddProperty("name", "thread_name");
+          thread_name.AddProperty("ph", "M");
+          thread_name.AddProperty("tid", tid);
+          thread_name.AddProperty("pid", pid);
           {
-            JSONObject args(&cpu_usage, "args");
-            args.AddProperty("CPU", percentage);
+            JSONObject args(&thread_name, "args");
+            args.AddProperty("name", name);
           }
         }
         {
-          JSONObject cpu_usage(&events);
-          cpu_usage.AddProperty("name", "CPU Usage");
-          cpu_usage.AddProperty("ph", "C");
-          cpu_usage.AddProperty("tid", tid);
-          cpu_usage.AddProperty("pid", pid);
-          cpu_usage.AddProperty("ts", static_cast<double>(i->timestamp));
+          JSONObject process_name(&events);
+          process_name.AddProperty("name", "process_name");
+          process_name.AddProperty("ph", "M");
+          process_name.AddProperty("tid", tid);
+          process_name.AddProperty("pid", pid);
           {
-            JSONObject args(&cpu_usage, "args");
-            args.AddProperty("CPU", percentage);
+            JSONObject args(&process_name, "args");
+            args.AddProperty("name", "Dart VM");
           }
         }
-      }
-      for (int j = 0; j < Sample::kNumStackFrames; j++) {
-        if (i->pcs[j] == 0) {
-          continue;
-        }
-        bool native_symbol = false;
-        char* symbol_name = FindSymbolName(i->pcs[j], &native_symbol);
-        {
-          JSONObject begin(&events);
-          begin.AddProperty("ph", "B");
-          begin.AddProperty("tid", tid);
-          begin.AddProperty("pid", pid);
-          begin.AddProperty("name", symbol_name);
-          begin.AddProperty("ts", static_cast<double>(last_time));
-        }
-        if (native_symbol) {
-          NativeSymbolResolver::FreeSymbolName(symbol_name);
+        uint64_t last_time = 0;
+        for (Sample* i = sample_buffer->FirstSample();
+             i != sample_buffer->LastSample();
+             i = sample_buffer->NextSample(i)) {
+          if (last_time == 0) {
+            last_time = i->timestamp;
+          }
+          intptr_t delta = i->timestamp - last_time;
+          {
+            double percentage = static_cast<double>(i->cpu_usage) /
+                                static_cast<double>(delta) * 100.0;
+            if (percentage != percentage) {
+              percentage = 0.0;
+            }
+            percentage = percentage < 0.0 ? 0.0 : percentage;
+            percentage = percentage > 100.0 ? 100.0 : percentage;
+            {
+              JSONObject cpu_usage(&events);
+              cpu_usage.AddProperty("name", "CPU Usage");
+              cpu_usage.AddProperty("ph", "C");
+              cpu_usage.AddProperty("tid", tid);
+              cpu_usage.AddProperty("pid", pid);
+              cpu_usage.AddProperty("ts", static_cast<double>(last_time));
+              {
+                JSONObject args(&cpu_usage, "args");
+                args.AddProperty("CPU", percentage);
+              }
+            }
+            {
+              JSONObject cpu_usage(&events);
+              cpu_usage.AddProperty("name", "CPU Usage");
+              cpu_usage.AddProperty("ph", "C");
+              cpu_usage.AddProperty("tid", tid);
+              cpu_usage.AddProperty("pid", pid);
+              cpu_usage.AddProperty("ts", static_cast<double>(i->timestamp));
+              {
+                JSONObject args(&cpu_usage, "args");
+                args.AddProperty("CPU", percentage);
+              }
+            }
+          }
+          for (int j = 0; j < Sample::kNumStackFrames; j++) {
+            if (i->pcs[j] == 0) {
+              continue;
+            }
+            bool native_symbol = false;
+            char* symbol_name = FindSymbolName(i->pcs[j], &native_symbol);
+            {
+              JSONObject begin(&events);
+              begin.AddProperty("ph", "B");
+              begin.AddProperty("tid", tid);
+              begin.AddProperty("pid", pid);
+              begin.AddProperty("name", symbol_name);
+              begin.AddProperty("ts", static_cast<double>(last_time));
+            }
+            if (native_symbol) {
+              NativeSymbolResolver::FreeSymbolName(symbol_name);
+            }
+          }
+          for (int j = Sample::kNumStackFrames-1; j >= 0; j--) {
+            if (i->pcs[j] == 0) {
+              continue;
+            }
+            bool native_symbol = false;
+            char* symbol_name = FindSymbolName(i->pcs[j], &native_symbol);
+            {
+              JSONObject end(&events);
+              end.AddProperty("ph", "E");
+              end.AddProperty("tid", tid);
+              end.AddProperty("pid", pid);
+              end.AddProperty("name", symbol_name);
+              end.AddProperty("ts", static_cast<double>(i->timestamp));
+            }
+            if (native_symbol) {
+              NativeSymbolResolver::FreeSymbolName(symbol_name);
+            }
+          }
+          last_time = i->timestamp;
         }
       }
-      for (int j = Sample::kNumStackFrames-1; j >= 0; j--) {
-        if (i->pcs[j] == 0) {
-          continue;
-        }
-        bool native_symbol = false;
-        char* symbol_name = FindSymbolName(i->pcs[j], &native_symbol);
-        {
-          JSONObject end(&events);
-          end.AddProperty("ph", "E");
-          end.AddProperty("tid", tid);
-          end.AddProperty("pid", pid);
-          end.AddProperty("name", symbol_name);
-          end.AddProperty("ts", static_cast<double>(i->timestamp));
-        }
-        if (native_symbol) {
-          NativeSymbolResolver::FreeSymbolName(symbol_name);
-        }
-      }
-      last_time = i->timestamp;
+      char fname[1024];
+    #if defined(TARGET_OS_WINDOWS)
+      snprintf(fname, sizeof(fname)-1, "c:\\tmp\\isolate-%d.prof",
+               static_cast<int>(port));
+    #else
+      snprintf(fname, sizeof(fname)-1, "/tmp/isolate-%d.prof",
+               static_cast<int>(port));
+    #endif
+      printf("%s\n", fname);
+      FILE* f = fopen(fname, "wb");
+      ASSERT(f != NULL);
+      fputs(stream.ToCString(), f);
+      fclose(f);
     }
   }
-  char fname[1024];
-#if defined(TARGET_OS_WINDOWS)
-  snprintf(fname, sizeof(fname)-1, "c:\\tmp\\isolate-%d.prof",
-           static_cast<int>(port));
-#else
-  snprintf(fname, sizeof(fname)-1, "/tmp/isolate-%d.prof",
-           static_cast<int>(port));
-#endif
-  printf("%s\n", fname);
-  FILE* f = fopen(fname, "wb");
-  ASSERT(f != NULL);
-  fputs(stream.ToCString(), f);
-  fclose(f);
 }
 
 
-
-
-
 IsolateProfilerData::IsolateProfilerData(Isolate* isolate,
                                          SampleBuffer* sample_buffer) {
   isolate_ = isolate;
@@ -434,8 +542,8 @@
 
 void IsolateProfilerData::Scheduled(int64_t current_time, ThreadId thread_id) {
   timer_expiration_micros_ = current_time + sample_interval_micros_;
-  Thread::GetThreadCpuUsage(thread_id, &cpu_usage_);
   thread_id_ = thread_id;
+  Thread::GetThreadCpuUsage(thread_id_, &cpu_usage_);
 }
 
 
@@ -445,7 +553,6 @@
   // isolate again.
   cpu_usage_ = kDescheduledCpuUsage;
   timer_expiration_micros_ = kNoExpirationTime;
-  thread_id_ = 0;
   Sample* sample = sample_buffer_->ReserveSample();
   ASSERT(sample != NULL);
   sample->timestamp = OS::GetCurrentTimeMicros();
@@ -480,16 +587,22 @@
   if (samples_ != NULL) {
     free(samples_);
     samples_ = NULL;
+    start_ = 0;
+    end_ = 0;
+    capacity_ = 0;
   }
 }
 
 
 Sample* SampleBuffer::ReserveSample() {
+  ASSERT(samples_ != NULL);
   intptr_t index = end_;
   end_ = WrapIncrement(end_);
   if (end_ == start_) {
     start_ = WrapIncrement(start_);
   }
+  ASSERT(index >= 0);
+  ASSERT(index < capacity_);
   // Reset.
   samples_[index] = Sample();
   return &samples_[index];
@@ -539,6 +652,7 @@
 
 int ProfilerSampleStackWalker::walk() {
   uword* pc = reinterpret_cast<uword*>(original_pc_);
+#if defined(WALK_STACK)
   uword* fp = reinterpret_cast<uword*>(original_fp_);
   uword* previous_fp = fp;
   if (original_sp_ < lower_bound_) {
@@ -563,6 +677,10 @@
     lower_bound_ = reinterpret_cast<uintptr_t>(fp);
   }
   return i;
+#else
+  sample_->pcs[0] = reinterpret_cast<uintptr_t>(pc);
+  return 0;
+#endif
 }
 
 
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index ba25c43..bec51e6 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -24,7 +24,7 @@
 
   static void SetupIsolateForProfiling(Isolate* isolate);
   static void ShutdownIsolateForProfiling(Isolate* isolate);
-  static void ScheduleIsolate(Isolate* isolate);
+  static void ScheduleIsolate(Isolate* isolate, bool inside_signal = false);
   static void DescheduleIsolate(Isolate* isolate);
 
   static void PrintToJSONStream(Isolate* isolate, JSONStream* stream);
@@ -35,12 +35,15 @@
   static const intptr_t kMaxProfiledIsolates = 4096;
   static bool initialized_;
   static bool shutdown_;
+  static bool thread_running_;
   static Monitor* monitor_;
+  static Monitor* start_stop_monitor_;
 
   static Isolate** isolates_;
   static intptr_t isolates_capacity_;
   static intptr_t isolates_size_;
 
+  static void ScheduleIsolateHelper(Isolate* isolate);
   static void ResizeIsolates(intptr_t new_capacity);
   static void AddIsolate(Isolate* isolate);
   static intptr_t FindIsolate(Isolate* isolate);
@@ -108,6 +111,10 @@
 
   SampleBuffer* sample_buffer() const { return sample_buffer_; }
 
+  void set_sample_buffer(SampleBuffer* sample_buffer) {
+    sample_buffer_ = sample_buffer;
+  }
+
  private:
   int64_t last_sampled_micros_;
   int64_t timer_expiration_micros_;
@@ -142,7 +149,7 @@
 // Ring buffer of samples. One per isolate.
 class SampleBuffer {
  public:
-  static const intptr_t kDefaultBufferCapacity = 1000000;
+  static const intptr_t kDefaultBufferCapacity = 120000;  // 2 minutes @ 1000hz.
 
   explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity);
   ~SampleBuffer();
diff --git a/runtime/vm/profiler_android.cc b/runtime/vm/profiler_android.cc
index d8d6747..f1d5704 100644
--- a/runtime/vm/profiler_android.cc
+++ b/runtime/vm/profiler_android.cc
@@ -13,7 +13,7 @@
 namespace dart {
 
 DECLARE_FLAG(bool, profile);
-
+DECLARE_FLAG(bool, trace_profiled_isolates);
 
 static void ProfileSignalAction(int signal, siginfo_t* info, void* context_) {
   if (signal != SIGPROF) {
@@ -28,14 +28,20 @@
     // Thread owns isolate profiler data mutex.
     ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
+    if ((profiler_data == NULL) || !profiler_data->CanExpire() ||
+        (profiler_data->sample_buffer() == NULL)) {
+      // Descheduled.
       return;
     }
+    if (profiler_data->thread_id() == Thread::GetCurrentThreadId()) {
+      // Still scheduled on this thread.
+      // TODO(johnmccutchan): Perform sample on Android.
+    }
   }
   // Thread owns no profiler locks at this point.
   // This call will acquire both ProfilerManager::monitor and the
   // isolate's profiler data mutex.
-  ProfilerManager::ScheduleIsolate(isolate);
+  ProfilerManager::ScheduleIsolate(isolate, true);
 }
 
 
@@ -50,6 +56,12 @@
     Isolate* isolate = isolates_[i];
     ScopedMutex isolate_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
+    if (profiler_data == NULL) {
+      // Isolate has been shutdown for profiling.
+      RemoveIsolate(i);
+      // Remove moves the last element into i, do not increment i.
+      continue;
+    }
     ASSERT(profiler_data != NULL);
     if (profiler_data->ShouldSample(current_time)) {
       pthread_kill(profiler_data->thread_id(), SIGPROF);
@@ -85,12 +97,30 @@
   ASSERT(initialized_);
   ASSERT(FLAG_profile);
   SignalHandler::Install(ProfileSignalAction);
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Android ready.\n");
+  }
+  {
+    // Signal to main thread we are ready.
+    ScopedMonitor startup_lock(start_stop_monitor_);
+    thread_running_ = true;
+    startup_lock.Notify();
+  }
   ScopedMonitor lock(monitor_);
   while (!shutdown_) {
     int64_t current_time = OS::GetCurrentTimeMicros();
     int64_t next_sample = SampleAndRescheduleIsolates(current_time);
     lock.WaitMicros(next_sample);
   }
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Android exiting.\n");
+  }
+  {
+    // Signal to main thread we are exiting.
+    ScopedMonitor shutdown_lock(start_stop_monitor_);
+    thread_running_ = false;
+    shutdown_lock.Notify();
+  }
 }
 
 
diff --git a/runtime/vm/profiler_linux.cc b/runtime/vm/profiler_linux.cc
index a58821d..6489a43 100644
--- a/runtime/vm/profiler_linux.cc
+++ b/runtime/vm/profiler_linux.cc
@@ -13,6 +13,7 @@
 namespace dart {
 
 DECLARE_FLAG(bool, profile);
+DECLARE_FLAG(bool, trace_profiled_isolates);
 
 static void CollectSample(IsolateProfilerData* profiler_data,
                           uintptr_t pc,
@@ -52,24 +53,28 @@
     // Thread owns isolate profiler data mutex.
     ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
+    if ((profiler_data == NULL) || !profiler_data->CanExpire() ||
+        (profiler_data->sample_buffer() == NULL)) {
+      // Descheduled.
       return;
     }
-
-    uintptr_t stack_lower = 0;
-    uintptr_t stack_upper = 0;
-    isolate->GetStackBounds(&stack_lower, &stack_upper);
-    uintptr_t PC = SignalHandler::GetProgramCounter(mcontext);
-    uintptr_t FP = SignalHandler::GetFramePointer(mcontext);
-    uintptr_t SP = SignalHandler::GetStackPointer(mcontext);
-    int64_t sample_time = OS::GetCurrentTimeMicros();
-    profiler_data->SampledAt(sample_time);
-    CollectSample(profiler_data, PC, FP, SP, stack_lower, stack_upper);
+    if (profiler_data->thread_id() == Thread::GetCurrentThreadId()) {
+      // Still scheduled on this thread.
+      uintptr_t stack_lower = 0;
+      uintptr_t stack_upper = 0;
+      isolate->GetStackBounds(&stack_lower, &stack_upper);
+      uintptr_t PC = SignalHandler::GetProgramCounter(mcontext);
+      uintptr_t FP = SignalHandler::GetFramePointer(mcontext);
+      uintptr_t SP = SignalHandler::GetStackPointer(mcontext);
+      int64_t sample_time = OS::GetCurrentTimeMicros();
+      profiler_data->SampledAt(sample_time);
+      CollectSample(profiler_data, PC, FP, SP, stack_lower, stack_upper);
+    }
   }
   // Thread owns no profiler locks at this point.
   // This call will acquire both ProfilerManager::monitor and the
   // isolate's profiler data mutex.
-  ProfilerManager::ScheduleIsolate(isolate);
+  ProfilerManager::ScheduleIsolate(isolate, true);
 }
 
 
@@ -84,6 +89,12 @@
     Isolate* isolate = isolates_[i];
     ScopedMutex isolate_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
+    if (profiler_data == NULL) {
+      // Isolate has been shutdown for profiling.
+      RemoveIsolate(i);
+      // Remove moves the last element into i, do not increment i.
+      continue;
+    }
     ASSERT(profiler_data != NULL);
     if (profiler_data->ShouldSample(current_time)) {
       pthread_kill(profiler_data->thread_id(), SIGPROF);
@@ -119,12 +130,30 @@
   ASSERT(initialized_);
   ASSERT(FLAG_profile);
   SignalHandler::Install(ProfileSignalAction);
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Linux ready.\n");
+  }
+  {
+    // Signal to main thread we are ready.
+    ScopedMonitor startup_lock(start_stop_monitor_);
+    thread_running_ = true;
+    startup_lock.Notify();
+  }
   ScopedMonitor lock(monitor_);
   while (!shutdown_) {
     int64_t current_time = OS::GetCurrentTimeMicros();
     int64_t next_sample = SampleAndRescheduleIsolates(current_time);
     lock.WaitMicros(next_sample);
   }
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Linux exiting.\n");
+  }
+  {
+    // Signal to main thread we are exiting.
+    ScopedMonitor shutdown_lock(start_stop_monitor_);
+    thread_running_ = false;
+    shutdown_lock.Notify();
+  }
 }
 
 
diff --git a/runtime/vm/profiler_macos.cc b/runtime/vm/profiler_macos.cc
index 2cb31c6..e1ae399 100644
--- a/runtime/vm/profiler_macos.cc
+++ b/runtime/vm/profiler_macos.cc
@@ -13,6 +13,7 @@
 namespace dart {
 
 DECLARE_FLAG(bool, profile);
+DECLARE_FLAG(bool, trace_profiled_isolates);
 
 static void CollectSample(IsolateProfilerData* profiler_data,
                           uintptr_t pc,
@@ -52,24 +53,28 @@
     // Thread owns isolate profiler data mutex.
     ScopedMutex profiler_data_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
-    if (profiler_data == NULL) {
+    if ((profiler_data == NULL) || !profiler_data->CanExpire() ||
+        (profiler_data->sample_buffer() == NULL)) {
+      // Descheduled.
       return;
     }
-
-    uintptr_t stack_lower = 0;
-    uintptr_t stack_upper = 0;
-    isolate->GetStackBounds(&stack_lower, &stack_upper);
-    uintptr_t PC = SignalHandler::GetProgramCounter(mcontext);
-    uintptr_t FP = SignalHandler::GetFramePointer(mcontext);
-    uintptr_t SP = SignalHandler::GetStackPointer(mcontext);
-    int64_t sample_time = OS::GetCurrentTimeMicros();
-    profiler_data->SampledAt(sample_time);
-    CollectSample(profiler_data, PC, FP, SP, stack_lower, stack_upper);
+    if (profiler_data->thread_id() == Thread::GetCurrentThreadId()) {
+      // Still scheduled on this thread.
+      uintptr_t stack_lower = 0;
+      uintptr_t stack_upper = 0;
+      isolate->GetStackBounds(&stack_lower, &stack_upper);
+      uintptr_t PC = SignalHandler::GetProgramCounter(mcontext);
+      uintptr_t FP = SignalHandler::GetFramePointer(mcontext);
+      uintptr_t SP = SignalHandler::GetStackPointer(mcontext);
+      int64_t sample_time = OS::GetCurrentTimeMicros();
+      profiler_data->SampledAt(sample_time);
+      CollectSample(profiler_data, PC, FP, SP, stack_lower, stack_upper);
+    }
   }
   // Thread owns no profiler locks at this point.
   // This call will acquire both ProfilerManager::monitor and the
   // isolate's profiler data mutex.
-  ProfilerManager::ScheduleIsolate(isolate);
+  ProfilerManager::ScheduleIsolate(isolate, true);
 }
 
 
@@ -84,6 +89,12 @@
     Isolate* isolate = isolates_[i];
     ScopedMutex isolate_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
+    if (profiler_data == NULL) {
+      // Isolate has been shutdown for profiling.
+      RemoveIsolate(i);
+      // Remove moves the last element into i, do not increment i.
+      continue;
+    }
     ASSERT(profiler_data != NULL);
     if (profiler_data->ShouldSample(current_time)) {
       pthread_kill(profiler_data->thread_id(), SIGPROF);
@@ -119,12 +130,30 @@
   ASSERT(initialized_);
   ASSERT(FLAG_profile);
   SignalHandler::Install(ProfileSignalAction);
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager MacOS ready.\n");
+  }
+  {
+    // Signal to main thread we are ready.
+    ScopedMonitor startup_lock(start_stop_monitor_);
+    thread_running_ = true;
+    startup_lock.Notify();
+  }
   ScopedMonitor lock(monitor_);
   while (!shutdown_) {
     int64_t current_time = OS::GetCurrentTimeMicros();
     int64_t next_sample = SampleAndRescheduleIsolates(current_time);
     lock.WaitMicros(next_sample);
   }
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager MacOS exiting.\n");
+  }
+  {
+    // Signal to main thread we are exiting.
+    ScopedMonitor shutdown_lock(start_stop_monitor_);
+    thread_running_ = false;
+    shutdown_lock.Notify();
+  }
 }
 
 
diff --git a/runtime/vm/profiler_win.cc b/runtime/vm/profiler_win.cc
index 61aa28b..3bc9e41 100644
--- a/runtime/vm/profiler_win.cc
+++ b/runtime/vm/profiler_win.cc
@@ -13,6 +13,7 @@
 #define kThreadError -1
 
 DECLARE_FLAG(bool, profile);
+DECLARE_FLAG(bool, trace_profiled_isolates);
 
 static void CollectSample(IsolateProfilerData* profiler_data,
                           uintptr_t pc,
@@ -20,7 +21,9 @@
                           uintptr_t stack_lower,
                           uintptr_t stack_upper) {
   uintptr_t sp = stack_lower;
+  ASSERT(profiler_data != NULL);
   SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+  ASSERT(sample_buffer != NULL);
   Sample* sample = sample_buffer->ReserveSample();
   ASSERT(sample != NULL);
   sample->timestamp = OS::GetCurrentTimeMicros();
@@ -101,7 +104,11 @@
     Isolate* isolate = isolates_[i];
     ScopedMutex isolate_lock(isolate->profiler_data_mutex());
     IsolateProfilerData* profiler_data = isolate->profiler_data();
-    ASSERT(profiler_data != NULL);
+    if ((profiler_data == NULL) || !profiler_data->CanExpire() ||
+        (profiler_data->sample_buffer() == NULL)) {
+      // Descheduled.
+      continue;
+    }
     if (profiler_data->ShouldSample(current_time)) {
       SuspendAndSample(isolate, profiler_data);
       Reschedule(profiler_data);
@@ -132,12 +139,30 @@
 void ProfilerManager::ThreadMain(uword parameters) {
   ASSERT(initialized_);
   ASSERT(FLAG_profile);
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Windows ready.\n");
+  }
+  {
+    // Signal to main thread we are ready.
+    ScopedMonitor startup_lock(start_stop_monitor_);
+    thread_running_ = true;
+    startup_lock.Notify();
+  }
   ScopedMonitor lock(monitor_);
   while (!shutdown_) {
     int64_t current_time = OS::GetCurrentTimeMicros();
     int64_t next_sample = SampleAndRescheduleIsolates(current_time);
     lock.WaitMicros(next_sample);
   }
+  if (FLAG_trace_profiled_isolates) {
+    OS::Print("ProfilerManager Windows exiting.\n");
+  }
+  {
+    // Signal to main thread we are exiting.
+    ScopedMonitor shutdown_lock(start_stop_monitor_);
+    thread_running_ = false;
+    shutdown_lock.Notify();
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 361006f..c425df7 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -366,9 +366,44 @@
 }
 
 
+bool RawFunction::SkipCode(RawFunction* raw_fun) {
+  // NOTE: This code runs while GC is in progress and runs within
+  // a NoHandleScope block. Hence it is not okay to use regular Zone or
+  // Scope handles. We use direct stack handles, and so the raw pointers in
+  // these handles are not traversed. The use of handles is mainly to
+  // be able to reuse the handle based code and avoid having to add
+  // helper functions to the raw object interface.
+  Function fn;
+  fn = raw_fun;
+
+  Code code;
+  code = fn.CurrentCode();
+
+  if (!code.IsNull() &&  // The function may not have code.
+      !code.is_optimized() &&
+      (fn.CurrentCode() == fn.unoptimized_code()) &&
+      !fn.HasBreakpoint() &&
+      (fn.usage_counter() >= 0)) {
+    fn.set_usage_counter(fn.usage_counter() / 2);
+    if (FLAG_always_drop_code || (fn.usage_counter() == 0)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
 intptr_t RawFunction::VisitFunctionPointers(RawFunction* raw_obj,
                                             ObjectPointerVisitor* visitor) {
-  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  if (visitor->visit_function_code() ||
+      !RawFunction::SkipCode(raw_obj)) {
+    visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  } else {
+    GrowableArray<RawFunction*>* sfga = visitor->skipped_code_functions();
+    ASSERT(sfga != NULL);
+    sfga->Add(raw_obj);
+    visitor->VisitPointers(raw_obj->from(), raw_obj->to_no_code());
+  }
   return Function::InstanceSize();
 }
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 89f4690..dce7cbf 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -610,8 +610,11 @@
   };
 
  private:
+  // So that the MarkingVisitor::DetachCode can null out the code fields.
+  friend class MarkingVisitor;
   friend class Class;
   RAW_HEAP_OBJECT_IMPLEMENTATION(Function);
+  static bool SkipCode(RawFunction* raw_fun);
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->name_); }
   RawString* name_;
@@ -620,10 +623,13 @@
   RawAbstractType* result_type_;
   RawArray* parameter_types_;
   RawArray* parameter_names_;
+  RawObject* data_;  // Additional data specific to the function kind.
   RawCode* code_;  // Compiled code for the function.
   RawCode* unoptimized_code_;  // Unoptimized code, keep it after optimization.
-  RawObject* data_;  // Additional data specific to the function kind.
   RawObject** to() {
+    return reinterpret_cast<RawObject**>(&ptr()->unoptimized_code_);
+  }
+  RawObject** to_no_code() {
     return reinterpret_cast<RawObject**>(&ptr()->data_);
   }
 
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index c2997a6..f06e42f 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -46,7 +46,7 @@
   Library& lib = Library::Handle(Library::New(lib_name));
   lib.Register();
   EXPECT(CompilerTest::TestCompileScript(lib, script));
-  EXPECT(ClassFinalizer::FinalizeTypeHierarchy());
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
 
 
diff --git a/runtime/vm/signal_handler_linux.cc b/runtime/vm/signal_handler_linux.cc
index d4021cf..4345dd4 100644
--- a/runtime/vm/signal_handler_linux.cc
+++ b/runtime/vm/signal_handler_linux.cc
@@ -20,6 +20,8 @@
   pc = static_cast<uintptr_t>(mcontext.gregs[REG_EIP]);
 #elif defined(TARGET_ARCH_ARM) && defined(USING_SIMULATOR)
   pc = static_cast<uintptr_t>(mcontext.gregs[REG_EIP]);
+#elif defined(TARGET_ARCH_ARM)
+  pc = static_cast<uintptr_t>(mcontext.arm_pc);
 #else
   UNIMPLEMENTED();
 #endif  // TARGET_ARCH_...
@@ -38,6 +40,8 @@
   fp = static_cast<uintptr_t>(mcontext.gregs[REG_EBP]);
 #elif defined(TARGET_ARCH_ARM) && defined(USING_SIMULATOR)
   fp = static_cast<uintptr_t>(mcontext.gregs[REG_EBP]);
+#elif defined(TARGET_ARCH_ARM)
+  fp = static_cast<uintptr_t>(mcontext.arm_fp);
 #else
   UNIMPLEMENTED();
 #endif  // TARGET_ARCH_...
@@ -57,6 +61,8 @@
   sp = static_cast<uintptr_t>(mcontext.gregs[REG_ESP]);
 #elif defined(TARGET_ARCH_ARM) && defined(USING_SIMULATOR)
   sp = static_cast<uintptr_t>(mcontext.gregs[REG_ESP]);
+#elif defined(TARGET_ARCH_ARM)
+  sp = static_cast<uintptr_t>(mcontext.arm_sp);
 #else
   UNIMPLEMENTED();
 #endif  // TARGET_ARCH_...
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 33c8238..76b4370 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -86,7 +86,7 @@
       // | spill slots | outgoing arguments | saved registers |
       // |XXXXXXXXXXXXX|--------------------|XXXXXXXXXXXXXXXXX|
       //
-      // The splill slots and any saved registers are described in the stack
+      // The spill slots and any saved registers are described in the stack
       // map.  The outgoing arguments are assumed to be tagged; the number
       // of outgoing arguments is not explicitly tracked.
       //
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index ff8b563..1305a1c 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -5,6 +5,7 @@
 #include "platform/assert.h"
 #include "vm/isolate.h"
 #include "vm/unit_test.h"
+#include "vm/signal_handler.h"
 #include "vm/thread.h"
 
 namespace dart {
@@ -42,6 +43,10 @@
   const int kNumAttempts = 5;
   int attempts = 0;
   while (attempts < kNumAttempts) {
+    // This test verifies that a monitor returns after the specified timeout. If
+    // a signal is delivered to this thread, the monitor may return early.
+    // Block signal delivery in this scope.
+    ScopedSignalBlocker ssb;
     MonitorLocker ml(monitor);
     int64_t start = OS::GetCurrentTimeMillis();
     int64_t wait_time = 2017;
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index 20b48b3..78de10f 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -6,6 +6,7 @@
 #define VM_VISITOR_H_
 
 #include "vm/globals.h"
+#include "vm/growable_array.h"
 
 namespace dart {
 
@@ -24,6 +25,11 @@
   // Range of pointers to visit 'first' <= pointer <= 'last'.
   virtual void VisitPointers(RawObject** first, RawObject** last) = 0;
 
+  virtual bool visit_function_code() const { return true; }
+  virtual GrowableArray<RawFunction*>* skipped_code_functions() {
+    return NULL;
+  }
+
   // len argument is the number of pointers to visit starting from 'p'.
   void VisitPointers(RawObject** p, intptr_t len) {
     VisitPointers(p, (p + len - 1));
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 3173ded..10f4950 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -254,6 +254,7 @@
     'object_id_ring.h',
     'object_id_ring_test.cc',
     'object_mips_test.cc',
+    'object_set.h',
     'object_store.cc',
     'object_store.h',
     'object_store_test.cc',
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index cc8be6e..f16cabe 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -57,8 +57,6 @@
             preserveComments: hasOption(options, '--preserve-comments'),
             verbose: hasOption(options, '--verbose'),
             sourceMapUri: extractSourceMapUri(options),
-            globalJsName: extractStringOption(
-                options, '--global-js-name=', r'$'),
             terseDiagnostics: hasOption(options, '--terse'),
             buildId: extractStringOption(
                 options, '--build-id=',
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 0cadcae..38c18ee 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -127,8 +127,9 @@
     superclass.ensureResolved(compiler);
     supertype = superclass.computeType(compiler);
     interfaces = const Link<DartType>();
-    allSupertypes = const Link<DartType>().prepend(supertype);
     thisType = rawType = new InterfaceType(this);
+    allSupertypesAndSelf =
+        superclass.allSupertypesAndSelf.extendClass(thisType);
   }
 
   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 4117c78..fd1163e 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -365,7 +365,7 @@
   }
 
   Constant visitLiteralString(LiteralString node) {
-    return constantSystem.createString(node.dartString, node);
+    return constantSystem.createString(node.dartString);
   }
 
   Constant visitStringJuxtaposition(StringJuxtaposition node) {
@@ -373,7 +373,7 @@
     StringConstant right = evaluate(node.second);
     if (left == null || right == null) return null;
     return constantSystem.createString(
-        new DartString.concat(left.value, right.value), node);
+        new DartString.concat(left.value, right.value));
   }
 
   Constant visitStringInterpolation(StringInterpolation node) {
@@ -399,14 +399,14 @@
       if (partString == null) return null;
       accumulator = new DartString.concat(accumulator, partString.value);
     };
-    return constantSystem.createString(accumulator, node);
+    return constantSystem.createString(accumulator);
   }
 
   Constant visitLiteralSymbol(LiteralSymbol node) {
     InterfaceType type = compiler.symbolClass.computeType(compiler);
     List<Constant> createArguments(_) {
       return [constantSystem.createString(
-        new DartString.literal(node.slowNameString), node)];
+        new DartString.literal(node.slowNameString))];
     }
     return makeConstructedConstant(
         node, type, compiler.symbolConstructor, createArguments);
@@ -711,7 +711,7 @@
         }
       } else {
         assert(constructor == compiler.stringEnvironment);
-        return constantSystem.createString(new DartString.literal(value), node);
+        return constantSystem.createString(new DartString.literal(value));
       }
     } else {
       return makeConstructedConstant(
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index ecfe995..1ded67e 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -254,6 +254,9 @@
   ClassElement get typeImplementation => compiler.typeClass;
   ClassElement get boolImplementation => compiler.boolClass;
   ClassElement get nullImplementation => compiler.nullClass;
+  ClassElement get uint32Implementation => compiler.intClass;
+  ClassElement get uint31Implementation => compiler.intClass;
+  ClassElement get positiveIntImplementation => compiler.intClass;
 
   ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass;
 
@@ -263,6 +266,8 @@
     return classElement == compiler.objectClass;
   }
 
+  bool isInterceptorClass(ClassElement element) => false;
+
   void registerStaticUse(Element element, Enqueuer enqueuer) {}
 
   Future onLibraryLoaded(LibraryElement library, Uri uri) {
@@ -394,12 +399,6 @@
    */
   final Uri sourceMapUri;
 
-  /**
-   * The name to use for the global JS object in JS output.  Default
-   * value is "$".
-   */
-  final String globalJsName;
-
   /// Emit terse diagnostics without howToFix.
   final bool terseDiagnostics;
 
@@ -504,31 +503,30 @@
     _currentElement = element;
     try {
       return f();
-    } on SpannableAssertionFailure catch (ex, s) {
+    } on SpannableAssertionFailure catch (ex) {
       if (!hasCrashed) {
         String message = (ex.message != null) ? tryToString(ex.message)
                                               : tryToString(ex);
         SourceSpan span = spanFromSpannable(ex.node);
         reportError(ex.node, MessageKind.GENERIC, {'text': message});
-        pleaseReportCrash(s, 'The compiler crashed: $message.');
+        pleaseReportCrash();
       }
       hasCrashed = true;
-      throw new CompilerCancelledException('The compiler crashed.');
+      rethrow;
     } on CompilerCancelledException catch (ex) {
       rethrow;
     } on StackOverflowError catch (ex) {
       // We cannot report anything useful in this case, because we
       // do not have enough stack space.
       rethrow;
-    } catch (ex, s) {
+    } catch (ex) {
       if (hasCrashed) rethrow;
-      String message = 'The compiler crashed: ${tryToString(ex)}.';
       try {
-        unhandledExceptionOnElement(element, s, message);
+        unhandledExceptionOnElement(element);
       } catch (doubleFault) {
         // Ignoring exceptions in exception handling.
       }
-      throw new CompilerCancelledException(message);
+      rethrow;
     } finally {
       _currentElement = old;
     }
@@ -544,6 +542,7 @@
   ResolverTask resolver;
   closureMapping.ClosureTask closureToClassMapper;
   TypeCheckerTask checker;
+  IrBuilderTask irBuilder;
   ti.TypesTask typesTask;
   Backend backend;
   ConstantHandler constantHandler;
@@ -622,7 +621,6 @@
             this.verbose: false,
             this.sourceMapUri: null,
             this.buildId: UNDETERMINED_BUILD_ID,
-            this.globalJsName: r'$',
             this.terseDiagnostics: false,
             outputProvider,
             List<String> strips: const []})
@@ -656,6 +654,7 @@
       resolver = new ResolverTask(this),
       closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer),
       checker = new TypeCheckerTask(this),
+      irBuilder = new IrBuilderTask(this),
       typesTask = new ti.TypesTask(this),
       constantHandler = new ConstantHandler(this, backend.constantSystem),
       deferredLoadTask = new DeferredLoadTask(this),
@@ -702,25 +701,17 @@
     internalError(message, element: element);
   }
 
-  void unhandledExceptionOnElement(Element element,
-                                   StackTrace stackTrace,
-                                   String message) {
+  void unhandledExceptionOnElement(Element element) {
     if (hasCrashed) return;
     hasCrashed = true;
     reportDiagnostic(spanFromElement(element),
                      MessageKind.COMPILER_CRASHED.error().toString(),
                      api.Diagnostic.CRASH);
-    pleaseReportCrash(stackTrace, message);
+    pleaseReportCrash();
   }
 
-  void pleaseReportCrash(StackTrace stackTrace, String message) {
+  void pleaseReportCrash() {
     print(MessageKind.PLEASE_REPORT_THE_CRASH.message({'buildId': buildId}));
-    if (message != null) {
-      print(message);
-    }
-    if (stackTrace != null) {
-      print(stackTrace);
-    }
   }
 
   void cancel(String reason, {Node node, Token token,
@@ -774,7 +765,7 @@
   Future<bool> run(Uri uri) {
     totalCompileTime.start();
 
-    return new Future.sync(() => runCompiler(uri)).catchError((error, trace) {
+    return new Future.sync(() => runCompiler(uri)).catchError((error) {
       if (error is CompilerCancelledException) {
         log('Error: $error');
         return false;
@@ -786,8 +777,7 @@
           reportDiagnostic(new SourceSpan(uri, 0, 0),
                            MessageKind.COMPILER_CRASHED.error().toString(),
                            api.Diagnostic.CRASH);
-          String message = 'The compiler crashed.';
-          pleaseReportCrash(trace, message);
+          pleaseReportCrash();
         }
       } catch (doubleFault) {
         // Ignoring exceptions in exception handling.
@@ -1111,6 +1101,9 @@
 
     deferredLoadTask.onResolutionComplete(main);
 
+    log('Building IR...');
+    irBuilder.buildNodes();
+
     log('Inferring types...');
     typesTask.onResolutionComplete(main);
 
diff --git a/sdk/lib/_internal/compiler/implementation/constant_system.dart b/sdk/lib/_internal/compiler/implementation/constant_system.dart
index b2688b5..b2e2b54 100644
--- a/sdk/lib/_internal/compiler/implementation/constant_system.dart
+++ b/sdk/lib/_internal/compiler/implementation/constant_system.dart
@@ -52,8 +52,7 @@
 
   Constant createInt(int i);
   Constant createDouble(double d);
-  // We need a diagnostic node to report errors in case the string is malformed.
-  Constant createString(DartString string, Node diagnosticNode);
+  Constant createString(DartString string);
   Constant createBool(bool value);
   Constant createNull();
 
diff --git a/sdk/lib/_internal/compiler/implementation/constant_system_dart.dart b/sdk/lib/_internal/compiler/implementation/constant_system_dart.dart
index 7be2ed3..a1067c3 100644
--- a/sdk/lib/_internal/compiler/implementation/constant_system_dart.dart
+++ b/sdk/lib/_internal/compiler/implementation/constant_system_dart.dart
@@ -363,8 +363,7 @@
 
   IntConstant createInt(int i) => new IntConstant(i);
   DoubleConstant createDouble(double d) => new DoubleConstant(d);
-  StringConstant createString(DartString string, Node diagnosticNode)
-      => new StringConstant(string, diagnosticNode);
+  StringConstant createString(DartString string) => new StringConstant(string);
   BoolConstant createBool(bool value) => new BoolConstant(value);
   NullConstant createNull() => new NullConstant();
 
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index c32a52e..3e15ab8 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -48,6 +48,8 @@
   // TODO(johnniwinther): Replace with a 'type' getter.
   DartType computeType(Compiler compiler);
 
+  ti.TypeMask computeMask(Compiler compiler);
+
   List<Constant> getDependencies();
 
   accept(ConstantVisitor visitor);
@@ -75,6 +77,10 @@
     return compiler.functionClass.computeType(compiler);
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.functionType;
+  }
+
   int get hashCode => (17 * element.hashCode) & 0x7fffffff;
 
   accept(ConstantVisitor visitor) => visitor.visitFunction(this);
@@ -113,6 +119,10 @@
     return compiler.nullClass.computeType(compiler);
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.nullType;
+  }
+
   void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) {
     buffer.write(JsNull);
   }
@@ -152,11 +162,21 @@
   }
   const IntConstant._internal(this.value);
   bool isInt() => true;
+  bool isUInt31() => value >= 0 && value < (1 << 31);
+  bool isUInt32() => value >= 0 && value < (1 << 32);
+  bool isPositive() => value >= 0;
 
   DartType computeType(Compiler compiler) {
     return compiler.intClass.computeType(compiler);
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    if (isUInt31()) return compiler.typesTask.uint31Type;
+    if (isUInt32()) return compiler.typesTask.uint32Type;
+    if (isPositive()) return compiler.typesTask.positiveIntType;
+    return compiler.typesTask.intType;
+  }
+
   // We have to override the equality operator so that ints and doubles are
   // treated as separate constants.
   // The is [:!IntConstant:] check at the beginning of the function makes sure
@@ -200,6 +220,10 @@
     return compiler.doubleClass.computeType(compiler);
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.doubleType;
+  }
+
   bool operator ==(var other) {
     if (other is !DoubleConstant) return false;
     DoubleConstant otherDouble = other;
@@ -230,6 +254,10 @@
     return compiler.boolClass.computeType(compiler);
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.boolType;
+  }
+
   BoolConstant negate();
 }
 
@@ -272,12 +300,11 @@
 class StringConstant extends PrimitiveConstant {
   final DartString value;
   final int hashCode;
-  final Node node;
 
   // TODO(floitsch): cache StringConstants.
   // TODO(floitsch): compute hashcode without calling toString() on the
   // DartString.
-  StringConstant(DartString value, this.node)
+  StringConstant(DartString value)
       : this.value = value,
         this.hashCode = value.slowToString().hashCode;
   bool isString() => true;
@@ -286,6 +313,10 @@
     return compiler.stringClass.computeType(compiler);
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.stringType;
+  }
+
   bool operator ==(var other) {
     if (other is !StringConstant) return false;
     StringConstant otherString = other;
@@ -323,6 +354,10 @@
     return other is TypeConstant && representedType == other.representedType;
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.typeType;
+  }
+
   int get hashCode => representedType.hashCode * 13;
 
   List<Constant> getDependencies() => const <Constant>[];
@@ -368,6 +403,10 @@
 
   int get length => entries.length;
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.constListType;
+  }
+
   accept(ConstantVisitor visitor) => visitor.visitList(this);
 
   String toString() {
@@ -424,6 +463,10 @@
     return hash;
   }
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.constMapType;
+  }
+
   bool operator ==(var other) {
     if (other is !MapConstant) return false;
     MapConstant otherMap = other;
@@ -489,6 +532,10 @@
 
   DartType computeType(Compiler compiler) => compiler.types.dynamicType;
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    return compiler.typesTask.nonNullType;
+  }
+
   String toString() {
     return 'InterceptorConstant(${Error.safeToString(dispatchedType)})';
   }
@@ -530,6 +577,13 @@
 
   List<Constant> getDependencies() => fields;
 
+  ti.TypeMask computeMask(Compiler compiler) {
+    if (compiler.backend.isInterceptorClass(type.element)) {
+      return compiler.typesTask.nonNullType;
+    }
+    return new ti.TypeMask.nonNullExact(type.element);
+  }
+
   accept(ConstantVisitor visitor) => visitor.visitConstructed(this);
 
   Map<Element, Constant> get fieldElements {
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 7869913..3138995 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -4,7 +4,8 @@
 
 library dart2js.cmdline;
 
-import 'dart:async';
+import 'dart:async'
+    show Future, EventSink;
 import 'dart:io'
     show exit, File, FileMode, Platform, RandomAccessFile;
 import 'dart:math' as math;
@@ -205,14 +206,6 @@
     passThrough('--categories=${categories.join(",")}');
   }
 
-  checkGlobalName(String argument) {
-    String globalName = extractParameter(argument);
-    if (!new RegExp(r'^\$[a-z]*$').hasMatch(globalName)) {
-      fail('Error: "$globalName" must match "\\\$[a-z]*"');
-    }
-    passThrough(argument);
-  }
-
   handleShortOptions(String argument) {
     var shortOptions = argument.substring(1).split("");
     for (var shortOption in shortOptions) {
@@ -278,7 +271,6 @@
     new OptionHandler('--analyze-signatures-only', passThrough),
     new OptionHandler('--disable-native-live-type-analysis', passThrough),
     new OptionHandler('--categories=.*', setCategories),
-    new OptionHandler('--global-js-name=.*', checkGlobalName),
     new OptionHandler('--disable-type-inference', passThrough),
     new OptionHandler('--terse', passThrough),
     new OptionHandler('--disallow-unsafe-eval',
@@ -418,9 +410,9 @@
     return new EventSinkWrapper(writeStringSync, onDone);
   }
 
-  return api.compile(uri, libraryRoot, packageRoot,
-              inputProvider, diagnosticHandler,
-              options, outputProvider, environment)
+  return compileFunc(uri, libraryRoot, packageRoot,
+                     inputProvider, diagnosticHandler,
+                     options, outputProvider, environment)
             .then(compilationDone);
 }
 
@@ -458,7 +450,7 @@
   } else {
     print(message);
   }
-  exit(1);
+  exitFunc(1);
 }
 
 Future compilerMain(List<String> arguments) {
@@ -570,11 +562,6 @@
     unsupported category, for example, --categories=help.  To enable
     all categories, use --categories=all.
 
-  --global-js-name=<name>
-    By default, dart2js generates JavaScript output that uses a global
-    variable named "$".  The name of this global can be overridden
-    with this option.  The name must match the regular expression "\$[a-z]*".
-
 '''.trim());
 }
 
@@ -592,7 +579,7 @@
       help();
     }
   }
-  exit(0);
+  exitFunc(0);
 }
 
 void helpAndFail(String message) {
@@ -602,11 +589,18 @@
 }
 
 void main(List<String> arguments) {
-  runZoned(() => compilerMain(arguments), onError: (exception, trace) {
+  internalMain(arguments);
+}
+
+var exitFunc = exit;
+var compileFunc = api.compile;
+
+Future internalMain(List<String> arguments) {
+  onError(exception, trace) {
     try {
-      print('Internal error: $exception');
+      print('The compiler crashed: $exception');
     } catch (ignored) {
-      print('Internal error: error while printing exception');
+      print('The compiler crashed: error while printing exception');
     }
 
     try {
@@ -614,7 +608,14 @@
         print(trace);
       }
     } finally {
-      exit(253); // 253 is recognized as a crash by our test scripts.
+      exitFunc(253); // 253 is recognized as a crash by our test scripts.
     }
-  });
+  }
+
+  try {
+    return compilerMain(arguments).catchError(onError);
+  } catch (exception, trace) {
+    onError(exception, trace);
+    return new Future.value();
+  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 6499365..ca186dc 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -23,6 +23,7 @@
 import 'scanner/scannerlib.dart';
 import 'ssa/ssa.dart';
 import 'tree/tree.dart';
+import 'ir/ir_builder.dart' show IrBuilderTask;
 import 'universe/universe.dart';
 import 'util/util.dart';
 import 'util/characters.dart' show $_;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index 56db7fa..cd9dff9 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -4,11 +4,14 @@
 
 library dart_types;
 
+import 'dart:math' show min;
+
 import 'dart2jslib.dart' show Compiler, invariant, Script, Message;
 import 'elements/modelx.dart'
     show VoidElementX, LibraryElementX, BaseClassElementX;
 import 'elements/elements.dart';
-import 'util/util.dart' show Link, LinkBuilder;
+import 'ordered_typeset.dart' show OrderedTypeSet;
+import 'util/util.dart' show Link, LinkBuilder, CURRENT_ELEMENT_SPANNABLE;
 
 class TypeKind {
   final String id;
@@ -1477,6 +1480,157 @@
   static List<DartType> sorted(Iterable<DartType> types) {
     return types.toList()..sort(compare);
   }
+
+  /// Computes the least upper bound of two interface types [a] and [b].
+  InterfaceType computeLeastUpperBoundInterfaces(InterfaceType a,
+                                                 InterfaceType b) {
+
+    /// Returns the set of supertypes of [type] at depth [depth].
+    Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) {
+      ClassElement cls = type.element;
+      OrderedTypeSet types = cls.allSupertypesAndSelf;
+      Link<DartType> typeVariables = cls.typeVariables;
+      Link<DartType> typeArguments = type.typeArguments;
+      Set<DartType> set = new Set<DartType>();
+      types.forEach(depth, (DartType type) {
+        set.add(type.subst(typeArguments, typeVariables));
+      });
+      return set;
+    }
+
+    ClassElement aClass = a.element;
+    ClassElement bClass = b.element;
+    int maxCommonDepth = min(aClass.hierarchyDepth, bClass.hierarchyDepth);
+    for (int depth = maxCommonDepth; depth >= 0; depth--) {
+      Set<DartType> aTypeSet = getSupertypesAtDepth(a, depth);
+      Set<DartType> bTypeSet = getSupertypesAtDepth(b, depth);
+      Set<DartType> intersection = aTypeSet..retainAll(bTypeSet);
+      if (intersection.length == 1) {
+        return intersection.first;
+      }
+    }
+    assert(invariant(CURRENT_ELEMENT_SPANNABLE, false,
+        message: 'No least upper bound computed for $a and $b.'));
+  }
+
+  /// Computes the least upper bound of the types in the longest prefix of [a]
+  /// and [b].
+  Link<DartType> computeLeastUpperBoundsTypes(Link<DartType> a,
+                                              Link<DartType> b) {
+    if (a.isEmpty || b.isEmpty) return const Link<DartType>();
+    LinkBuilder<DartType> types = new LinkBuilder<DartType>();
+    while (!a.isEmpty && !b.isEmpty) {
+      types.addLast(computeLeastUpperBound(a.head, b.head));
+      a = a.tail;
+      b = b.tail;
+    }
+    return types.toLink();
+  }
+
+  /// Computes the least upper bound of two function types [a] and [b].
+  ///
+  /// If the required parameter count of [a] and [b] does not match, `Function`
+  /// is returned.
+  ///
+  /// Otherwise, a function type is returned whose return type and
+  /// parameter types are the least upper bound of those of [a] and [b],
+  /// respectively. In addition, the optional parameters are the least upper
+  /// bound of the longest common prefix of the optional parameters of [a] and
+  /// [b], and the named parameters are the least upper bound of those common to
+  /// [a] and [b].
+  DartType computeLeastUpperBoundFunctionTypes(FunctionType a,
+                                               FunctionType b) {
+    if (a.parameterTypes.slowLength() != b.parameterTypes.slowLength()) {
+      return compiler.functionClass.rawType;
+    }
+    DartType returnType = computeLeastUpperBound(a.returnType, b.returnType);
+    Link<DartType> parameterTypes =
+        computeLeastUpperBoundsTypes(a.parameterTypes, b.parameterTypes);
+    Link<DartType> optionalParameterTypes =
+        computeLeastUpperBoundsTypes(a.optionalParameterTypes,
+                                     b.optionalParameterTypes);
+    LinkBuilder<String> namedParameters = new LinkBuilder<String>();
+    Link<String> aNamedParameters = a.namedParameters;
+    Link<String> bNamedParameters = b.namedParameters;
+    LinkBuilder<DartType> namedParameterTypes = new LinkBuilder<DartType>();
+    Link<DartType> aNamedParameterTypes = a.namedParameterTypes;
+    Link<DartType> bNamedParameterTypes = b.namedParameterTypes;
+    while (!aNamedParameters.isEmpty && !bNamedParameters.isEmpty) {
+      String aNamedParameter = aNamedParameters.head;
+      String bNamedParameter = bNamedParameters.head;
+      int result = aNamedParameter.compareTo(bNamedParameter);
+      if (result == 0) {
+        namedParameters.addLast(aNamedParameter);
+        namedParameterTypes.addLast(computeLeastUpperBound(
+            aNamedParameterTypes.head, bNamedParameterTypes.head));
+      }
+      if (result <= 0) {
+        aNamedParameters = aNamedParameters.tail;
+        aNamedParameterTypes = aNamedParameterTypes.tail;
+      }
+      if (result >= 0) {
+        bNamedParameters = bNamedParameters.tail;
+        bNamedParameterTypes = bNamedParameterTypes.tail;
+      }
+    }
+    return new FunctionType(compiler.functionClass,
+        returnType,
+        parameterTypes, optionalParameterTypes,
+        namedParameters.toLink(), namedParameterTypes.toLink());
+  }
+
+  /// Computes the least upper bound of two types of which at least one is a
+  /// type variable. The least upper bound of a type variable is defined in
+  /// terms of its bound, but to ensure reflexivity we need to check for common
+  /// bounds transitively.
+  DartType computeLeastUpperBoundTypeVariableTypes(DartType a,
+                                                   DartType b) {
+    Set<DartType> typeVariableBounds = new Set<DartType>();
+    while (a.kind == TypeKind.TYPE_VARIABLE) {
+      if (a == b) return a;
+      typeVariableBounds.add(a);
+      TypeVariableElement element = a.element;
+      a = element.bound;
+    }
+    while (b.kind == TypeKind.TYPE_VARIABLE) {
+      if (typeVariableBounds.contains(b)) return b;
+      TypeVariableElement element = b.element;
+      b = element.bound;
+    }
+    return computeLeastUpperBound(a, b);
+  }
+
+  /// Computes the least upper bound for [a] and [b].
+  DartType computeLeastUpperBound(DartType a, DartType b) {
+    if (a == b) return a;
+
+    if (a.kind == TypeKind.TYPE_VARIABLE ||
+           b.kind == TypeKind.TYPE_VARIABLE) {
+      return computeLeastUpperBoundTypeVariableTypes(a, b);
+    }
+
+    a = a.unalias(compiler);
+    b = b.unalias(compiler);
+
+    if (a.treatAsDynamic || b.treatAsDynamic) return dynamicType;
+    if (a.isVoid || b.isVoid) return voidType;
+
+    if (a.kind == TypeKind.FUNCTION && b.kind == TypeKind.FUNCTION) {
+      return computeLeastUpperBoundFunctionTypes(a, b);
+    }
+
+    if (a.kind == TypeKind.FUNCTION) {
+      a = compiler.functionClass.rawType;
+    }
+    if (b.kind == TypeKind.FUNCTION) {
+      b = compiler.functionClass.rawType;
+    }
+
+    if (a.kind == TypeKind.INTERFACE && b.kind == TypeKind.INTERFACE) {
+      return computeLeastUpperBoundInterfaces(a, b);
+    }
+    return dynamicType;
+  }
 }
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 6e9281c..52c6b30 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -28,6 +28,8 @@
                                          isUserDefinableOperator,
                                          isMinusOperator;
 
+import '../ordered_typeset.dart' show OrderedTypeSet;
+
 const int STATE_NOT_STARTED = 0;
 const int STATE_STARTED = 1;
 const int STATE_DONE = 2;
@@ -836,12 +838,16 @@
     implements ScopeContainerElement {
   int get id;
 
+  /// The length of the longest inheritance path from [:Object:].
+  int get hierarchyDepth;
+
   InterfaceType get rawType;
   InterfaceType get thisType;
 
   ClassElement get superclass;
 
   DartType get supertype;
+  OrderedTypeSet get allSupertypesAndSelf;
   Link<DartType> get allSupertypes;
   Link<DartType> get interfaces;
 
@@ -866,7 +872,6 @@
   // TODO(kasperl): These are bit fishy. Do we really need them?
   void set thisType(InterfaceType value);
   void set supertype(DartType value);
-  void set allSupertypes(Link<DartType> value);
   void set interfaces(Link<DartType> value);
   void set patch(ClassElement value);
   void set origin(ClassElement value);
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 8859321..b53316f 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -29,6 +29,7 @@
 
 import '../scanner/scannerlib.dart' show Token, EOF_TOKEN;
 
+import '../ordered_typeset.dart' show OrderedTypeSet;
 
 class ElementX implements Element {
   static int elementHashCode = 0;
@@ -1157,7 +1158,7 @@
 
   DartType computeType(Compiler compiler) {
     VariableDefinitions definitions = variables.parseNode(compiler);
-    if (definitions.type == null && !definitions.modifiers.isVar()) {
+    if (definitions.type == null) {
       return fieldElement.computeType(compiler);
     }
     return super.computeType(compiler);
@@ -1705,7 +1706,11 @@
   // compilation. They don't have any user-side counter-part.
   Link<Element> backendMembers = const Link<Element>();
 
-  Link<DartType> allSupertypes;
+  OrderedTypeSet allSupertypesAndSelf;
+
+  Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
+
+  int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
 
   BaseClassElementX(String name,
                     Element enclosing,
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
index 5663714..3b75903 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/container_tracer.dart
@@ -139,9 +139,9 @@
   // The list of found assignments to the container.
   final List<TypeInformation> assignments = <TypeInformation>[];
 
-  bool enableLengthTracking = true;
+  bool callsGrowableMethod = false;
   bool continueAnalyzing = true;
-
+  
   static const int MAX_ANALYSIS_COUNT = 16;
   final Setlet<Element> analyzedElements = new Setlet<Element>();
 
@@ -178,7 +178,7 @@
     }
 
     if (continueAnalyzing) {
-      if (enableLengthTracking && container.inferredLength == null) {
+      if (!callsGrowableMethod && container.inferredLength == null) {
         container.inferredLength = container.originalLength;
       }
       return assignments;
@@ -193,7 +193,7 @@
             'because: $reason');
     }
     continueAnalyzing = false;
-    enableLengthTracking = false;
+    callsGrowableMethod = true;
   }
 
   visitNarrowTypeInformation(NarrowTypeInformation info) {}
@@ -248,10 +248,10 @@
         }
       }
       if (!doNotChangeLengthSelectorsSet.contains(selectorName)) {
-        enableLengthTracking = false;
+        callsGrowableMethod = true;
       }
       if (selectorName == 'length' && selector.isSetter()) {
-        enableLengthTracking = false;
+        callsGrowableMethod = true;
         assignments.add(inferrer.types.nullType);
       }
     } else if (selector.isCall()
@@ -271,5 +271,8 @@
     if (isClosure(info.element)) {
       bailout('Returned from a closure');
     }
+    if (compiler.backend.isNeededForReflection(info.element)) {
+      bailout('Escape in reflection');
+    }
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
index 46170e4..6eb5bb5 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
@@ -10,6 +10,7 @@
 import '../tree/tree.dart';
 import '../universe/universe.dart';
 import '../util/util.dart';
+import '../types/types.dart' show TypeMask;
 
 /**
  * The interface [InferrerVisitor] will use when working on types.
@@ -18,6 +19,9 @@
   T get dynamicType;
   T get nullType;
   T get intType;
+  T get uint31Type;
+  T get uint32Type;
+  T get positiveIntType;
   T get doubleType;
   T get numType;
   T get boolType;
@@ -85,6 +89,11 @@
    * [receiverType].
    */
   T refineReceiver(Selector selector, T receiverType);
+
+  /**
+   * Returns the internal inferrer representation for [mask].
+   */
+  T getConcreteTypeFor(TypeMask mask);
 }
 
 /**
@@ -248,8 +257,8 @@
 
   bool hasNoArguments() => positional.isEmpty && named.isEmpty;
 
-  bool hasOnePositionalArgumentWithType(T type) {
-    return named.isEmpty && positional.length == 1 && positional[0] == type;
+  bool hasOnePositionalArgumentThatMatches(bool f(T type)) {
+    return named.isEmpty && positional.length == 1 && f(positional[0]);
   }
 
   void forEach(void f(T type)) {
@@ -652,22 +661,18 @@
 
   T visitLiteralDouble(LiteralDouble node) {
     ConstantSystem constantSystem = compiler.backend.constantSystem;
-    Constant constant = constantSystem.createDouble(node.value);
     // The JavaScript backend may turn this literal into an integer at
     // runtime.
-    return constantSystem.isDouble(constant)
-        ? types.doubleType
-        : types.intType;
+    return types.getConcreteTypeFor(
+        constantSystem.createDouble(node.value).computeMask(compiler));
   }
 
   T visitLiteralInt(LiteralInt node) {
     ConstantSystem constantSystem = compiler.backend.constantSystem;
-    Constant constant = constantSystem.createInt(node.value);
     // The JavaScript backend may turn this literal into a double at
     // runtime.
-    return constantSystem.isDouble(constant)
-        ? types.doubleType
-        : types.intType;
+    return types.getConcreteTypeFor(
+        constantSystem.createInt(node.value).computeMask(compiler));
   }
 
   T visitLiteralList(LiteralList node) {
@@ -692,9 +697,7 @@
   }
 
   T visitTypeReferenceSend(Send node) {
-    // If [node] is not a type literal is the class name of a static access,
-    // in which case we don't use the type mask.
-    return elements.isTypeLiteral(node) ? types.typeType : null;
+    return elements.isTypeLiteral(node) ? types.typeType : types.dynamicType;
   }
 
   bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart
new file mode 100644
index 0000000..5591f68
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/ir_type_inferrer.dart
@@ -0,0 +1,77 @@
+// 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 dart2js.ir_type_inferrer;
+
+import '../ir/ir_nodes.dart';
+import 'inferrer_visitor.dart' show TypeSystem;
+import 'simple_types_inferrer.dart' show InferrerEngine;
+import '../elements/elements.dart' show
+    Element, FunctionElement, FunctionSignature;
+import '../dart2jslib.dart' show Compiler, Constant, ConstantSystem;
+import 'type_graph_inferrer.dart' show TypeInformation;
+
+class IrTypeInferrerVisitor extends IrNodesVisitor {
+  final Compiler compiler;
+  final Element analyzedElement;
+  final TypeSystem<TypeInformation> types;
+  final InferrerEngine<TypeInformation, TypeSystem<TypeInformation>> inferrer;
+
+  IrTypeInferrerVisitor(this.compiler,
+                        this.analyzedElement,
+                        InferrerEngine<TypeInformation,
+                        TypeSystem<TypeInformation>> inferrer)
+    : inferrer = inferrer,
+      types = inferrer.types;
+
+  final Map<IrNode, TypeInformation> analyzed = <IrNode, TypeInformation>{};
+
+  TypeInformation returnType;
+
+  TypeInformation run() {
+    if (analyzedElement.isField()) {
+      // TODO(lry): handle fields.
+      throw "Type infer from IR for field $analyzedElement";
+    }
+    FunctionElement function = analyzedElement;
+    FunctionSignature signature = function.computeSignature(compiler);
+    IrFunction node = compiler.irBuilder.getIr(function);
+    // TODO(lry): handle parameters.
+
+    if (function.isNative()) {
+      // TODO(lry): handle native.
+      throw "Type infer from IR for native $analyzedElement";
+    }
+
+    if (analyzedElement.isGenerativeConstructor()) {
+      // TODO(lry): handle constructors.
+      throw "Type infer from IR for constructor $analyzedElement";
+    }
+
+    if (analyzedElement.isSynthesized) {
+      // TODO(lry): handle synthethics.
+      throw "Type infer from IR for synthetic $analyzedElement";
+    }
+
+    visitAll(node.statements);
+    return returnType;
+  }
+
+  TypeInformation typeOfConstant(Constant constant) {
+    return inferrer.types.getConcreteTypeFor(constant.computeMask(compiler));
+  }
+
+  void visitIrConstant(IrConstant node) {
+    analyzed[node] = typeOfConstant(node.value);
+  }
+
+  void visitIrReturn(IrReturn node) {
+    TypeInformation type = analyzed[node.value];
+    returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
+  }
+
+  void visitNode(IrNode 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 020c597c..2dbdc3b 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -74,6 +74,9 @@
   TypeMask get dynamicType => compiler.typesTask.dynamicType;
   TypeMask get nullType => compiler.typesTask.nullType;
   TypeMask get intType => compiler.typesTask.intType;
+  TypeMask get uint32Type => compiler.typesTask.uint32Type;
+  TypeMask get uint31Type => compiler.typesTask.uint31Type;
+  TypeMask get positiveIntType => compiler.typesTask.positiveIntType;
   TypeMask get doubleType => compiler.typesTask.doubleType;
   TypeMask get numType => compiler.typesTask.numType;
   TypeMask get boolType => compiler.typesTask.boolType;
@@ -123,6 +126,8 @@
     TypeMask newType = compiler.world.allFunctions.receiverType(selector);
     return receiverType.intersection(newType, compiler);
   }
+
+  TypeMask getConcreteTypeFor(TypeMask mask) => mask;
 }
 
 /**
@@ -680,7 +685,7 @@
     T indexType;
 
     if (isIncrementOrDecrement) {
-      rhsType = types.intType;
+      rhsType = types.uint31Type;
       if (node.isIndex) indexType = visit(node.arguments.head);
     } else if (node.isIndex) {
       indexType = visit(node.arguments.head);
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 833080c..0cd9be4 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -15,7 +15,8 @@
 import '../native_handler.dart' as native;
 import '../util/util.dart' show Spannable, Setlet;
 import 'simple_types_inferrer.dart';
-import '../dart2jslib.dart' show invariant;
+import 'ir_type_inferrer.dart';
+import '../dart2jslib.dart' show invariant, Constant;
 
 part 'type_graph_nodes.dart';
 part 'container_tracer.dart';
@@ -77,6 +78,25 @@
     return intTypeCache = getConcreteTypeFor(compiler.typesTask.intType);
   }
 
+  TypeInformation uint32TypeCache;
+  TypeInformation get uint32Type {
+    if (uint32TypeCache != null) return uint32TypeCache;
+    return uint32TypeCache = getConcreteTypeFor(compiler.typesTask.uint32Type);
+  }
+
+  TypeInformation uint31TypeCache;
+  TypeInformation get uint31Type {
+    if (uint31TypeCache != null) return uint31TypeCache;
+    return uint31TypeCache = getConcreteTypeFor(compiler.typesTask.uint31Type);
+  }
+
+  TypeInformation positiveIntTypeCache;
+  TypeInformation get positiveIntType {
+    if (positiveIntTypeCache != null) return positiveIntTypeCache;
+    return positiveIntTypeCache =
+        getConcreteTypeFor(compiler.typesTask.positiveIntType);
+  }
+
   TypeInformation doubleTypeCache;
   TypeInformation get doubleType {
     if (doubleTypeCache != null) return doubleTypeCache;
@@ -224,6 +244,7 @@
   }
 
   ConcreteTypeInformation getConcreteTypeFor(TypeMask mask) {
+    assert(mask != null);
     return concreteTypes.putIfAbsent(mask, () {
       return new ConcreteTypeInformation(mask);
     });
@@ -430,6 +451,10 @@
       if (newAssignments == null) return;
 
       info.elementType.inferred = true;
+      TypeMask fixedListType = compiler.typesTask.fixedListType;
+      if (info.originalContainerType.forwardTo == fixedListType) {
+        info.checksGrowable = tracer.callsGrowableMethod;
+      }
       newAssignments.forEach(info.elementType.addAssignment);
       workQueue.add(info);
       workQueue.add(info.elementType);
@@ -468,8 +493,12 @@
     if (analyzedElements.contains(element)) return;
     analyzedElements.add(element);
 
-    SimpleTypeInferrerVisitor visitor =
-        new SimpleTypeInferrerVisitor(element, compiler, this);
+      var visitor;
+      if (compiler.irBuilder.hasIr(element)) {
+        visitor = new IrTypeInferrerVisitor(compiler, element, this);
+      } else {
+        visitor = new SimpleTypeInferrerVisitor(element, compiler, this);
+      }
     TypeInformation type;
     compiler.withCurrentElement(element, () {
       type = visitor.run();
@@ -482,6 +511,15 @@
         // If [element] is final and has an initializer, we record
         // the inferred type.
         if (node.asSendSet() != null) {
+          if (type is! ContainerTypeInformation) {
+            // For non-container types, the constant handler does
+            // constant folding that could give more precise results.
+            Constant value =
+                compiler.constantHandler.getConstantForVariable(element);
+            if (value != null) {
+              type = types.getConcreteTypeFor(value.computeMask(compiler));
+            }
+          }
           recordType(element, type);
         } else if (!element.isInstanceMember()) {
           recordType(element, types.nullType);
@@ -680,6 +718,7 @@
   void recordReturnType(Element element, TypeInformation type) {
     TypeInformation info = types.getInferredTypeOf(element);
     if (element.name == '==') {
+      // Even if x.== doesn't return a bool, 'x == null' evaluates to 'false'.
       info.addAssignment(types.boolType);
     }
     // TODO(ngeoffray): Clean up. We do these checks because
@@ -875,6 +914,12 @@
     return inferrer.types.allocatedContainers[node].type;
   }
 
+  bool isFixedArrayCheckedForGrowable(Node node) {
+    if (compiler.disableTypeInference) return true;
+    ContainerTypeInformation info = inferrer.types.allocatedContainers[node];
+    return info.checksGrowable;
+  }
+
   TypeMask getTypeOfSelector(Selector selector) {
     if (compiler.disableTypeInference) return compiler.typesTask.dynamicType;
     // Bailout for closure calls. We're not tracking types of
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 b6a2cab..2598dd3 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -185,7 +185,7 @@
 
 /**
  * A node representing a resolved element of the program. The kind of
- * elements that need an [ElementTypeRepresentation] are:
+ * elements that need an [ElementTypeInformation] are:
  *
  * - Functions (including getters and setters)
  * - Constructors (factory or generative)
@@ -507,12 +507,6 @@
     }
   }
 
-  bool hasOnePositionalArgumentWithType(TypeMask type) {
-    return arguments.named.isEmpty
-        && arguments.positional.length == 1
-        && arguments.positional[0].type == type;
-  }
-
   /**
    * We optimize certain operations on the [int] class because we know
    * more about their return type than the actual Dart code. For
@@ -521,38 +515,72 @@
    */
   TypeInformation handleIntrisifiedSelector(Selector selector,
                                             TypeGraphInferrerEngine inferrer) {
-    if (!inferrer.compiler.backend.intImplementation.isResolved) return null;
-    TypeMask intType = inferrer.compiler.typesTask.intType;
-    TypeMask nullableIntType = intType.nullable();
+    Compiler compiler = inferrer.compiler;
+    if (!compiler.backend.intImplementation.isResolved) return null;
     TypeMask emptyType = const TypeMask.nonNullEmpty();
-    if (selector.mask != intType && selector.mask != nullableIntType) {
+    if (selector.mask == null) return null;
+    if (!selector.mask.containsOnlyInt(compiler)) {
       return null;
     }
     if (!selector.isCall() && !selector.isOperator()) return null;
     if (!arguments.named.isEmpty) return null;
     if (arguments.positional.length > 1) return null;
 
+    ClassElement uint31Implementation = compiler.backend.uint31Implementation;
+    bool isInt(info) => info.type.containsOnlyInt(compiler);
+    bool isEmpty(info) => info.type == emptyType;
+    bool isUInt31(info) {
+      return info.type.satisfies(uint31Implementation, compiler);
+    }
+    bool isPositiveInt(info) {
+      return info.type.satisfies(
+          compiler.backend.positiveIntImplementation, compiler);
+    }
+
     String name = selector.name;
-    if (name == '*' || name == '+' || name == '%' || name == 'remainder') {
-      if (hasOnePositionalArgumentWithType(intType)
-          || hasOnePositionalArgumentWithType(nullableIntType)) {
+    // We are optimizing for the cases that are not expressed in the
+    // Dart code, for example:
+    // int + int -> int
+    // uint31 | uint31 -> uint31
+    if (name == '*' || name == '+' || name == '%' || name == 'remainder'
+        || name == '~/') {
+      if (isPositiveInt(receiver)
+          && arguments.hasOnePositionalArgumentThatMatches(isPositiveInt)) {
+        return inferrer.types.positiveIntType;
+      } else if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
         return inferrer.types.intType;
-      } else if (hasOnePositionalArgumentWithType(emptyType)) {
+      } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
         return inferrer.types.nonNullEmptyType;
       } else {
         return null;
       }
+    } else if (name == '|' || name == '^') {
+      if (isUInt31(receiver)
+          && arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
+        return inferrer.types.uint31Type;
+      }
+    } else if (name == '>>') {
+      if (isUInt31(receiver)) {
+        return inferrer.types.uint31Type;
+      }
+    } else if (name == '&') {
+      if (isUInt31(receiver)
+          || arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
+        return inferrer.types.uint31Type;
+      }
+    } else if (name == 'unary-') {
+      // The receiver being an int, the return value will also be an
+      // int.
+      return inferrer.types.intType;
     } else if (name == '-') {
-      if (arguments.hasNoArguments()) return inferrer.types.intType;
-      if (hasOnePositionalArgumentWithType(intType)
-          || hasOnePositionalArgumentWithType(nullableIntType)) {
+      if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
         return inferrer.types.intType;
-      } else if (hasOnePositionalArgumentWithType(emptyType)) {
+      } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
         return inferrer.types.nonNullEmptyType;
       }
       return null;
     } else if (name == 'abs') {
-      return arguments.hasNoArguments() ? inferrer.types.intType : null;
+      return arguments.hasNoArguments() ? inferrer.types.positiveIntType : null;
     }
     return null;
   }
@@ -817,6 +845,12 @@
   /** The length after the container has been traced. */
   int inferredLength;
 
+  /**
+   * Whether this container goes through a growable check.
+   * We conservatively assume it does.
+   */
+  bool checksGrowable = true;
+
   ContainerTypeInformation(this.originalContainerType,
                            this.elementType,
                            this.originalLength) {
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
new file mode 100644
index 0000000..86cdabd
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
@@ -0,0 +1,335 @@
+// 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 dart2js.ir_builder;
+
+import 'ir_nodes.dart';
+import '../elements/elements.dart';
+import '../dart2jslib.dart';
+import '../source_file.dart';
+import '../tree/tree.dart';
+import '../scanner/scannerlib.dart' show Token;
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import 'ir_pickler.dart' show Unpickler;
+
+/**
+ * This task iterates through all resolved elements and builds [IrNode]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
+ * 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.
+ *
+ * The type inferrer works on either IR nodes or tree nodes. The IR nodes are
+ * then translated into the SSA form for optimizations and code generation.
+ * Long-term, once the IR supports the full language, the backend can be
+ * re-implemented to work directly on the IR.
+ */
+class IrBuilderTask extends CompilerTask {
+  final Map<Element, IrNode> nodes = new Map<Element, IrNode>();
+
+  IrBuilderTask(Compiler compiler) : super(compiler);
+
+  String get name => 'IR builder';
+
+  bool hasIr(Element element) => nodes.containsKey(element.implementation);
+
+  IrNode getIr(Element element) => nodes[element.implementation];
+
+  void buildNodes() {
+    if (!irEnabled()) return;
+    measure(() {
+      Map<Element, TreeElements> resolved =
+          compiler.enqueuer.resolution.resolvedElements;
+      resolved.forEach((Element element, TreeElements elementsMapping) {
+        if (canBuild(element)) {
+          element = element.implementation;
+
+          SourceFile sourceFile = elementSourceFile(element);
+          IrNodeBuilderVisitor visitor =
+              new IrNodeBuilderVisitor(elementsMapping, compiler, sourceFile);
+          IrNode irNode;
+          ElementKind kind = element.kind;
+          if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+            // TODO(lry): build ir for constructors.
+          } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
+              kind == ElementKind.FUNCTION ||
+              kind == ElementKind.GETTER ||
+              kind == ElementKind.SETTER) {
+            irNode = visitor.buildMethod(element);
+          } else if (kind == ElementKind.FIELD) {
+            // TODO(lry): build ir for lazy initializers of static fields.
+          } else {
+            compiler.internalErrorOnElement(element,
+                'unexpected element kind $kind');
+          }
+
+          if (irNode != null) {
+            assert(() {
+              // In host-checked mode, serialize and de-serialize the IrNode.
+              List<int> data = irNode.pickle();
+              irNode = new Unpickler(compiler).unpickle(data);
+              return true;
+            });
+            nodes[element] = irNode;
+            unlinkTreeAndToken(element);
+          }
+        }
+      });
+    });
+  }
+
+  bool irEnabled() {
+    // TODO(lry): support checked-mode checks.
+    if (compiler.enableTypeAssertions ||
+        compiler.backend is !JavaScriptBackend ||
+        compiler.enableConcreteTypeInference) {
+      return false;
+    }
+    return true;
+  }
+
+  bool canBuild(Element element) {
+    // TODO(lry): support lazy initializers.
+    FunctionElement function = element.asFunctionElement();
+    if (function == null) return false;
+
+    // TODO(lry): support functions with parameters.
+    FunctionSignature signature = function.computeSignature(compiler);
+    if (signature.parameterCount > 0) return false;
+
+    // TODO(lry): support intercepted methods. Then the dependency on
+    // JavaScriptBackend will go away.
+    JavaScriptBackend backend = compiler.backend;
+    if (backend.isInterceptedMethod(element)) return false;
+
+    // TODO(lry): support native functions (also in [visitReturn]).
+    if (function.isNative()) return false;
+
+    return true;
+  }
+
+  void unlinkTreeAndToken(element) {
+    element.beginToken.next = null;
+    element.cachedNode = null;
+  }
+
+  SourceFile elementSourceFile(Element element) {
+    if (element is FunctionElement) {
+      FunctionElement functionElement = element;
+      if (functionElement.patch != null) element = functionElement.patch;
+    }
+    return element.getCompilationUnit().script.file;
+  }
+}
+
+/**
+ * A tree visitor that builds [IrNodes]. The visit methods add statements using
+ * to the [builder] and return the last added statement for trees that represent
+ * an expression.
+ */
+class IrNodeBuilderVisitor extends ResolvedVisitor<IrNode> {
+  final SourceFile sourceFile;
+
+  IrNodeBuilderVisitor(
+      TreeElements elements,
+      Compiler compiler,
+      this.sourceFile)
+    : super(elements, compiler);
+
+  IrBuilder builder;
+
+  /**
+   * Builds the [IrFunction] 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) {
+    return nullIfGiveup(() => buildMethodInternal(functionElement));
+  }
+
+  IrFunction buildMethodInternal(FunctionElement functionElement) {
+    assert(invariant(functionElement, functionElement.isImplementation));
+    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>[]);
+    builder = new IrBuilder(this);
+    builder.enterBlock();
+    if (function.hasBody()) {
+      function.body.accept(this);
+      ensureReturn(function);
+      result.statements
+        ..addAll(builder.constants.values)
+        ..addAll(builder.block.statements);
+    }
+    builder.exitBlock();
+    return result;
+  }
+
+  ConstantSystem get constantSystem => compiler.backend.constantSystem;
+
+  /* int | PositionWithIdentifierName */ nodePosition(Node node) {
+    Token token = node.getBeginToken();
+    if (token.isIdentifier()) {
+      return new PositionWithIdentifierName(token.charOffset, token.value);
+    } else {
+      return token.charOffset;
+    }
+  }
+
+  bool get blockReturns => builder.block.hasReturn;
+
+  /**
+   * Add an explicit [:return null:] for functions that don't have a return
+   * statement on each branch. This includes functions with an empty body,
+   * such as [:foo(){ }:].
+   */
+  void ensureReturn(FunctionExpression node) {
+    if (blockReturns) return;
+    IrConstant nullValue =
+        builder.addConstant(constantSystem.createNull(), node);
+    builder.addStatement(new IrReturn(nodePosition(node), nullValue));
+  }
+
+  IrNode visitBlock(Block node) {
+    for (Node n in node.statements.nodes) {
+      n.accept(this);
+      if (blockReturns) return null;
+    }
+  }
+
+  IrNode visitReturn(Return node) {
+    assert(!blockReturns);
+    IrNode value;
+    // TODO(lry): support native returns.
+    if (node.beginToken.value == 'native') return giveup();
+    if (node.expression == null) {
+      value = builder.addConstant(constantSystem.createNull(), node);
+    } else {
+      value = node.expression.accept(this);
+    }
+    builder.addStatement(new IrReturn(nodePosition(node), value));
+    builder.block.hasReturn = true;
+  }
+
+  IrConstant visitLiteralBool(LiteralBool node) {
+    return builder.addConstant(constantSystem.createBool(node.value), node);
+  }
+
+  IrConstant visitLiteralDouble(LiteralDouble node) {
+    return builder.addConstant(constantSystem.createDouble(node.value), node);
+  }
+
+  IrConstant visitLiteralInt(LiteralInt node) {
+    return builder.addConstant(constantSystem.createInt(node.value), node);
+  }
+
+  IrConstant visitLiteralString(LiteralString node) {
+    Constant value = constantSystem.createString(node.dartString);
+    return builder.addConstant(value, node);
+  }
+
+  IrConstant visitLiteralNull(LiteralNull node) {
+    return builder.addConstant(constantSystem.createNull(), node);
+  }
+
+//  TODO(lry): other literals.
+//  IrNode visitLiteralList(LiteralList node) => visitExpression(node);
+//  IrNode visitLiteralMap(LiteralMap node) => visitExpression(node);
+//  IrNode visitLiteralMapEntry(LiteralMapEntry node) => visitNode(node);
+//  IrNode visitLiteralSymbol(LiteralSymbol node) => visitExpression(node);
+
+  IrNode visitAssert(Send node) {
+    return giveup();
+  }
+
+  IrNode visitClosureSend(Send node) {
+    return giveup();
+  }
+
+  IrNode visitDynamicSend(Send node) {
+    return giveup();
+  }
+
+  IrNode visitGetterSend(Send node) {
+    return giveup();
+  }
+
+  IrNode visitOperatorSend(Send node) {
+    return giveup();
+  }
+
+  IrNode visitStaticSend(Send node) {
+    return giveup();
+  }
+
+  IrNode visitSuperSend(Send node) {
+    return giveup();
+  }
+
+  IrNode visitTypeReferenceSend(Send node) {
+    return giveup();
+  }
+
+  static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
+
+  IrNode giveup() => throw ABORT_IRNODE_BUILDER;
+
+  IrNode nullIfGiveup(IrNode action()) {
+    try {
+      return action();
+    } catch(e) {
+      if (e == ABORT_IRNODE_BUILDER) return null;
+      rethrow;
+    }
+  }
+
+  void internalError(String reason, {Node node}) {
+    giveup();
+  }
+}
+
+class IrBuilder {
+  final IrNodeBuilderVisitor visitor;
+  IrBuilder(this.visitor);
+
+  List<BlockBuilder> blockBuilders = <BlockBuilder>[];
+
+  BlockBuilder get block => blockBuilders.last;
+
+  Map<Constant, IrConstant> constants = <Constant, IrConstant>{};
+
+  IrConstant addConstant(Constant value, Node node) {
+    return constants.putIfAbsent(
+      value, () => new IrConstant(visitor.nodePosition(node), value));
+  }
+
+  IrNode addStatement(IrNode statement) {
+    block.statements.add(statement);
+    return statement;
+  }
+
+  void enterBlock() {
+    blockBuilders.add(new BlockBuilder());
+  }
+
+  void exitBlock() {
+    blockBuilders.removeLast();
+  }
+}
+
+class BlockBuilder {
+  List<IrNode> statements = <IrNode>[];
+  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
new file mode 100644
index 0000000..5a0672c
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart
@@ -0,0 +1,80 @@
+// 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.
+
+// IrNodes are kept in a separate library to have precise control over their
+// dependencies on other parts of the system.
+library dart2js.ir_nodes;
+
+import '../dart2jslib.dart' show Constant;
+import 'ir_pickler.dart' show Pickler;
+
+/**
+ * A pair of source offset and an identifier name. Identifier names are used in
+ * the Javascript backend to generate source maps.
+ */
+class PositionWithIdentifierName {
+  final int offset;
+  final String sourceName;
+  PositionWithIdentifierName(this.offset, this.sourceName);
+}
+
+abstract class IrNode {
+  static int hashCount = 0;
+  final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff;
+
+  final /* int | PositionWithIdentifierName */ position;
+
+  const IrNode(this.position);
+
+  int get offset => (position is int) ? position : position.offset;
+
+  String get sourceName => (position is int) ? null : position.sourceName;
+
+  List<int> pickle() => new Pickler().pickle(this);
+
+  accept(IrNodesVisitor visitor);
+}
+
+class IrFunction extends IrNode {
+  final List<IrNode> statements;
+
+  final int endOffset;
+  final int namePosition;
+
+  IrFunction(position, this.endOffset, this.namePosition, this.statements)
+    : super(position);
+
+  accept(IrNodesVisitor visitor) => visitor.visitIrFunction(this);
+}
+
+class IrReturn extends IrNode {
+  final IrNode value;
+
+  IrReturn(position, this.value) : super(position);
+
+  accept(IrNodesVisitor visitor) => visitor.visitIrReturn(this);
+}
+
+class IrConstant extends IrNode {
+  final Constant value;
+
+  IrConstant(position, this.value) : super(position);
+
+  accept(IrNodesVisitor visitor) => visitor.visitIrConstant(this);
+}
+
+
+abstract class IrNodesVisitor<T> {
+  T visit(IrNode node) => node.accept(this);
+
+  void visitAll(List<IrNode> nodes) {
+    for (IrNode n in nodes) visit(n);
+  }
+
+  T visitNode(IrNode node);
+
+  T visitIrFunction(IrFunction node) => visitNode(node);
+  T visitIrReturn(IrReturn node) => visitNode(node);
+  T visitIrConstant(IrConstant node) => visitNode(node);
+}
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
new file mode 100644
index 0000000..ff43852
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_pickler.dart
@@ -0,0 +1,354 @@
+// 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 dart2js.ir_pickler;
+
+import 'ir_nodes.dart';
+import '../dart2jslib.dart' show
+    Constant, FalseConstant, TrueConstant, IntConstant, DoubleConstant,
+    StringConstant, NullConstant, ListConstant, MapConstant,
+    InterceptorConstant, FunctionConstant, TypeConstant, ConstructedConstant,
+    ConstantVisitor, ConstantSystem,
+    Compiler;
+import 'dart:typed_data' show ByteData, Endianness, Uint8List;
+import 'dart:convert' show UTF8;
+import '../tree/tree.dart' show
+    DartString, LiteralDartString, RawSourceDartString, EscapedSourceDartString,
+    ConsDartString;
+
+part 'ir_unpickler.dart';
+
+/* The elementCount only includes elements that might potentially be referred
+ * to in back reference, for example nodes.
+ *
+ * pickle     ::= int(elementCount) node(function)
+ *
+ * int        ::= see [writeInt] for number encoding
+ *
+ * string     ::= byte(STRING_ASCII) int(length) {byte(ascii)}
+ *              | byte(STRING_UTF8) int(length) {byte(utf8)}
+ *
+ * node       ::= byte(BACK_REFERENCE) int(index)
+ *              | byte(NODE_FUNCTION) position int(endSourceOffset)
+ *                    int(namePosition) int(statements) {node(statement)}
+ *              | byte(NODE_RETURN) position node(value)
+ *              | byte(NODE_CONST) position constant
+ *
+ * position   ::= byte(POSITION_WITH_ID) string(sourceName) int(sourceOffset)
+ *              | byte(POSITION_OFFSET) int(sourceOffset)
+ *
+ * constant   ::= byte(CONST_BOOL) byte(0 or 1)
+ *              | byte(CONST_DOUBLE) byte{8}
+ *              | byte(CONST_INT) int(value)
+ *              | byte(CONST_STRING_LITERAL) string
+ *              | byte(CONST_STRING_RAW) string int(length)
+ *              | byte(CONST_STRING_ESCAPED) string int(length)
+ *              | byte(CONST_STRING_CONS) constant(left) constant(right)
+ *              | byte(CONST_NULL)
+ */
+class Pickles {
+  static const int BACK_REFERENCE = 1;
+
+  static const int STRING_ASCII = BACK_REFERENCE + 1;
+  static const int STRING_UTF8  = STRING_ASCII + 1;
+
+  static const int BEGIN_NODE    = STRING_UTF8 + 1;
+  static const int NODE_FUNCTION = BEGIN_NODE;
+  static const int NODE_RETURN   = NODE_FUNCTION + 1;
+  static const int NODE_CONST    = NODE_RETURN + 1;
+  static const int END_NODE      = NODE_CONST;
+
+  static const int BEGIN_POSITION   = END_NODE + 1;
+  static const int POSITION_OFFSET  = BEGIN_POSITION;
+  static const int POSITION_WITH_ID = POSITION_OFFSET + 1;
+  static const int END_POSITION     = POSITION_WITH_ID;
+
+  static const int BEGIN_CONST          = END_POSITION + 1;
+  static const int CONST_BOOL           = BEGIN_CONST;
+  static const int CONST_INT            = CONST_BOOL + 1;
+  static const int CONST_DOUBLE         = CONST_INT + 1;
+  static const int CONST_STRING_LITERAL = CONST_DOUBLE + 1;
+  static const int CONST_STRING_RAW     = CONST_STRING_LITERAL + 1;
+  static const int CONST_STRING_ESCAPED = CONST_STRING_RAW + 1;
+  static const int CONST_STRING_CONS    = CONST_STRING_ESCAPED + 1;
+  static const int CONST_NULL           = CONST_STRING_CONS + 1;
+  static const int END_CONST            = CONST_NULL;
+
+  static const int END_TAG = END_CONST;
+}
+
+/**
+ * The [Pickler] serializes [IrNode]s to a byte array.
+ */
+class Pickler extends IrNodesVisitor {
+  ConstantPickler constantPickler;
+
+  Pickler() {
+    assert(Pickles.END_TAG <= 0xff);
+    constantPickler = new ConstantPickler(this);
+  }
+
+  static final int INITIAL_SIZE = 8;
+  static final int MAX_GROW_RATE = 4096;
+
+  List<int> data;
+
+  /** Offset of the next byte that will be written. */
+  int offset;
+
+  /** Stores the intex for emitted elements that might be back-referenced. */
+  Map<Object, int> emitted;
+
+  /** A counter for emitted elements. */
+  int index;
+
+  /**
+   * This buffer is used in [writeConstDouble] to obtain a byte representation
+   * for doubles.
+   */
+  ByteData doubleData = new ByteData(8);
+
+  List<int> pickle(IrNode node) {
+    data = new Uint8List(INITIAL_SIZE);
+    offset = 0;
+    emitted = <Object, int>{};
+    index = 0;
+    node.accept(this);
+
+    int sizeOffset = offset;
+    writeInt(emitted.length);
+    int sizeBytes = offset - sizeOffset;
+
+    // The array is longer than necessary, create a copy with the actual size.
+    Uint8List result = new Uint8List(offset);
+    // Emit the number or elements in the beginning.
+    for (int i = 0, j = sizeOffset; i < sizeBytes; i++, j++) {
+      result[i] = data[j];
+    }
+    for (int i = sizeBytes, j = 0; i < offset; i++, j++) {
+      result[i] = data[j];
+    }
+    return result;
+  }
+
+  void resize(int newSize) {
+    Uint8List newData = new Uint8List(newSize);
+    for (int i = 0; i < data.length; i++) {
+      newData[i] = data[i];
+    }
+    data = newData;
+  }
+
+  void ensureCapacity() {
+    // (offset == data.length-1) is still OK, the byte at [offset] has not yet
+    // been written.
+    int size = data.length;
+    if (offset < size) return;
+    if (size > MAX_GROW_RATE) {
+      size += MAX_GROW_RATE;
+    } else {
+      size *= 2;
+    }
+    resize(size);
+  }
+
+  static isByte(int byte) => 0 <= byte && byte <= 0xff;
+
+  void writeByte(int byte) {
+    assert(isByte(byte));
+    ensureCapacity();
+    data[offset++] = byte;
+  }
+
+  /**
+   * Writes integers to the buffer.
+   *
+   * The least significant bit of the serialized data encodes the sign. Each
+   * byte contains 7 bits of data and one bit indicating if it is the last byte
+   * of the number.
+   */
+  void writeInt(int n) {
+    bool isNegative = n < 0;
+    n = isNegative ? -n : n;
+    // Least significant bit is the sign.
+    int bits = (n << 1) | (isNegative ? 1 : 0);
+    do {
+      int next = bits & 0x7f;
+      bits >>= 7;
+      bool hasMore = bits != 0;
+      next = (next << 1) | (hasMore ? 1 : 0);
+      writeByte(next);
+    } while (bits != 0);
+  }
+
+  void writeString(String s) {
+    int startOffset = offset;
+    writeByte(Pickles.STRING_ASCII);
+    writeInt(s.length);
+    for (int i = 0; i < s.length; i++) {
+      int c = s.codeUnitAt(i);
+      if (c < 0x80) {
+        writeByte(c);
+      } else {
+        // Strings with non-ascii characters are encoded using UTF-8.
+        writeUtf8String(s, startOffset);
+        return;
+      }
+    }
+  }
+
+  void writeUtf8String(String s, int startOffset) {
+    offset = startOffset;
+    writeByte(Pickles.STRING_UTF8);
+    List<int> bytes = UTF8.encode(s);
+    writeInt(bytes.length);
+    for (int i = 0; i < bytes.length; i++) {
+      writeByte(bytes[i]);
+    }
+  }
+
+  /**
+   * If [element] has already been emitted, this function writes a back
+   * reference to the buffer and returns [:true:]. Otherwise, it registers the
+   * element in the [emitted] map and the [:false:].
+   */
+  bool writeBackrefIfEmitted(Object element) {
+    int elementIndex = emitted[element];
+    if (elementIndex != null) {
+      writeByte(Pickles.BACK_REFERENCE);
+      writeInt(elementIndex);
+      return true;
+    } else {
+      emitted[element] = index++;
+      return false;
+    }
+  }
+
+  void writePosition(/* int | PositionWithIdentifierName */ position) {
+    if (position is int) {
+      writeByte(Pickles.POSITION_OFFSET);
+      writeInt(position);
+    } else {
+      PositionWithIdentifierName namedPosition = position;
+      writeByte(Pickles.POSITION_WITH_ID);
+      writeString(namedPosition.sourceName);
+      writeInt(namedPosition.offset);
+    }
+  }
+
+  void writeConstBool(bool b) {
+    writeByte(Pickles.CONST_BOOL);
+    writeByte(b ? 1 : 0);
+  }
+
+  void writeConstInt(int n) {
+    writeByte(Pickles.CONST_INT);
+    writeInt(n);
+  }
+
+  void writeConstDouble(double d) {
+    writeByte(Pickles.CONST_DOUBLE);
+    doubleData.setFloat64(0, d, Endianness.BIG_ENDIAN);
+    for (int i = 0; i < 8; i++) {
+      writeByte(doubleData.getUint8(i));
+    }
+  }
+
+  void writeDartString(DartString s) {
+    if (s is LiteralDartString) {
+      writeByte(Pickles.CONST_STRING_LITERAL);
+      writeString(s.string);
+    } else if (s is RawSourceDartString) {
+      writeByte(Pickles.CONST_STRING_RAW);
+      writeString(s.source);
+      writeInt(s.length);
+    } else if (s is EscapedSourceDartString) {
+      writeByte(Pickles.CONST_STRING_ESCAPED);
+      writeString(s.source);
+      writeInt(s.length);
+    } else if (s is ConsDartString) {
+      writeByte(Pickles.CONST_STRING_CONS);
+      writeDartString(s.left);
+      writeDartString(s.right);
+    } else {
+      throw "Unexpected DartString: $s";
+    }
+  }
+
+  void writeConstNull() {
+    writeByte(Pickles.CONST_NULL);
+  }
+
+  void visitIrFunction(IrFunction node) {
+    if (writeBackrefIfEmitted(node)) return;
+    writeByte(Pickles.NODE_FUNCTION);
+    writePosition(node.position);
+    writeInt(node.endOffset);
+    writeInt(node.namePosition);
+    writeInt(node.statements.length);
+    for (int i = 0; i < node.statements.length; i++) {
+      node.statements[i].accept(this);
+    }
+  }
+
+  void visitIrReturn(IrReturn node) {
+    if (writeBackrefIfEmitted(node)) return;
+    writeByte(Pickles.NODE_RETURN);
+    writePosition(node.position);
+    node.value.accept(this);
+  }
+
+  void visitIrConstant(IrConstant node) {
+    if (writeBackrefIfEmitted(node)) return;
+    writeByte(Pickles.NODE_CONST);
+    writePosition(node.position);
+    node.value.accept(constantPickler);
+  }
+
+  void visitNode(IrNode node) {
+    throw "Unexpected $node in pickler.";
+  }
+}
+
+/**
+ * A visitor for constants which writes the constant values to its [Pickler].
+ */
+class ConstantPickler extends ConstantVisitor {
+
+  final Pickler pickler;
+  ConstantPickler(this.pickler);
+
+  void visitFalse(FalseConstant constant) {
+    pickler.writeConstBool(false);
+  }
+
+  void visitTrue(TrueConstant constant) {
+    pickler.writeConstBool(true);
+  }
+
+  void visitInt(IntConstant constant) {
+    pickler.writeConstInt(constant.value);
+  }
+
+  void visitDouble(DoubleConstant constant) {
+    pickler.writeConstDouble(constant.value);
+  }
+
+  void visitString(StringConstant constant) {
+    pickler.writeDartString(constant.value);
+  }
+
+  void visitNull(NullConstant constant) {
+    pickler.writeConstNull();
+  }
+
+  void visitList(ListConstant constant) => abort(constant);
+  void visitMap(MapConstant constant) => abort(constant);
+  void visitInterceptor(InterceptorConstant constant) => abort(constant);
+  void visitFunction(FunctionConstant constant) => abort(constant);
+  void visitType(TypeConstant constant) => abort(constant);
+  void visitConstructed(ConstructedConstant constant) => abort(constant);
+
+  void abort(Constant value) => throw "Can not pickle constant $value";
+}
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart
new file mode 100644
index 0000000..c1b9f21
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_unpickler.dart
@@ -0,0 +1,174 @@
+// 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.ir_pickler;
+
+class Unpickler {
+  final Compiler compiler;
+
+  Unpickler(this.compiler);
+
+  List<int> data;
+
+  int offset;
+
+  /** For each element index, the corresponding unpickled element. */
+  List<Object> unpickled;
+
+  /** Counter for elements in [unpickled]. */
+  int index;
+
+  /**
+   * This buffer is used in [readConstant] to reconstruct a double value from
+   * a sequence of bytes.
+   */
+  ByteData doubleData = new ByteData(8);
+
+  ConstantSystem get constantSystem => compiler.backend.constantSystem;
+
+  IrFunction unpickle(List<int> data) {
+    this.data = data;
+    offset = 0;
+    int numElements = readInt();
+    unpickled = new List<Object>(numElements);
+    index = 0;
+    return readElement();
+  }
+
+  int readByte() {
+    return data[offset++];
+  }
+
+  int readInt() {
+    int result = 0;
+    int next;
+    for (int i = 0; true; i += 7) {
+      next = readByte();
+      result |= (next >> 1) << i;
+      if ((next & 1) == 0) break;
+    }
+    bool isNegative = (result & 1) == 1;
+    result >>= 1;
+    return isNegative ? -result : result;
+  }
+
+  String readString() {
+    int tag = readByte();
+    int length = readInt();
+    List<int> bytes = new Uint8List(length);
+    for (int i = 0; i < length; i++) {
+      bytes[i] = readByte();
+    }
+    if (tag == Pickles.STRING_ASCII) {
+      return new String.fromCharCodes(bytes);
+    } else if (tag == Pickles.STRING_UTF8) {
+      return UTF8.decode(bytes);
+    } else {
+      compiler.internalError("Unexpected string tag: $tag");
+    }
+  }
+
+  /**
+   * Read an element that might be a back reference, or that might be used
+   * in a back reference.
+   */
+  Object readElement() {
+    // Obtain the index of the element before reading its content to ensure
+    // that elements are placed in consecutive order in [unpickled].
+    int elementIndex = index++;
+    int tag = readByte();
+    if (tag == Pickles.BACK_REFERENCE) {
+      int backIndex = readInt();
+      assert(unpickled[backIndex] != null);
+      return unpickled[backIndex];
+    }
+    Object result;
+    if (tag == Pickles.NODE_CONST) {
+      result = readConstantNode();
+    } else if (tag == Pickles.NODE_FUNCTION) {
+      result = readFunctionNode();
+    } else if (tag == Pickles.NODE_RETURN) {
+      result = readReturnNode();
+    } else {
+      compiler.internalError("Unexpected element tag: $tag");
+    }
+    unpickled[elementIndex] = result;
+    return result;
+  }
+
+  IrFunction readFunctionNode() {
+    var position = readPosition();
+    int endOffset = readInt();
+    int namePosition = readInt();
+    int numStatements = readInt();
+    List<IrNode> statements = new List<IrNode>(numStatements);
+    for (int i = 0; i < numStatements; i++) {
+      statements[i] = readElement();
+    }
+    return new IrFunction(position, endOffset, namePosition, statements);
+  }
+
+  IrConstant readConstantNode() {
+    var position = readPosition();
+    Constant constant = readConstant();
+    return new IrConstant(position, constant);
+  }
+
+  IrReturn readReturnNode() {
+    var position = readPosition();
+    IrNode value = readElement();
+    return new IrReturn(position, value);
+  }
+
+  /* int | PositionWithIdentifierName */ readPosition() {
+    if (readByte() == Pickles.POSITION_OFFSET) {
+      return readInt();
+    } else {
+      String sourceName = readString();
+      int offset = readInt();
+      return new PositionWithIdentifierName(offset, sourceName);
+    }
+  }
+
+  Constant readConstant() {
+    int tag = readByte();
+    switch(tag) {
+      case Pickles.CONST_BOOL:
+        return constantSystem.createBool(readByte() == 1);
+      case Pickles.CONST_INT:
+        return constantSystem.createInt(readInt());
+      case Pickles.CONST_DOUBLE:
+        for (int i = 0; i < 8; i++) {
+          doubleData.setUint8(i, readByte());
+        }
+        double value = doubleData.getFloat64(0, Endianness.BIG_ENDIAN);
+        return constantSystem.createDouble(value);
+      case Pickles.CONST_STRING_LITERAL:
+      case Pickles.CONST_STRING_RAW:
+      case Pickles.CONST_STRING_ESCAPED:
+      case Pickles.CONST_STRING_CONS:
+        return constantSystem.createString(readDartString(tag));
+      case Pickles.CONST_NULL:
+        return constantSystem.createNull();
+      default:
+        compiler.internalError("Unexpected constant tag: $tag");
+    }
+  }
+
+  DartString readDartString(int tag) {
+    switch(tag) {
+      case Pickles.CONST_STRING_LITERAL:
+        return new LiteralDartString(readString());
+      case Pickles.CONST_STRING_RAW:
+        return new RawSourceDartString(readString(), readInt());
+      case Pickles.CONST_STRING_ESCAPED:
+        return new EscapedSourceDartString(readString(), readInt());
+      case Pickles.CONST_STRING_CONS:
+        return new 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 02e78b7..17c53c0 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -163,6 +163,7 @@
 
 class JavaScriptBackend extends Backend {
   SsaBuilderTask builder;
+  SsaFromIrBuilderTask fromIrBuilder;
   SsaOptimizerTask optimizer;
   SsaCodeGeneratorTask generator;
   CodeEmitterTask emitter;
@@ -193,6 +194,9 @@
   ClassElement jsMutableArrayClass;
   ClassElement jsFixedArrayClass;
   ClassElement jsExtendableArrayClass;
+  ClassElement jsPositiveIntClass;
+  ClassElement jsUInt32Class;
+  ClassElement jsUInt31Class;
 
   Element jsIndexableLength;
   Element jsArrayTypedConstructor;
@@ -226,6 +230,9 @@
   TypeMask get stringType => compiler.typesTask.stringType;
   TypeMask get doubleType => compiler.typesTask.doubleType;
   TypeMask get intType => compiler.typesTask.intType;
+  TypeMask get uint32Type => compiler.typesTask.uint32Type;
+  TypeMask get uint31Type => compiler.typesTask.uint31Type;
+  TypeMask get positiveIntType => compiler.typesTask.positiveIntType;
   TypeMask get numType => compiler.typesTask.numType;
   TypeMask get boolType => compiler.typesTask.boolType;
   TypeMask get dynamicType => compiler.typesTask.dynamicType;
@@ -419,6 +426,7 @@
         super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) {
     emitter = new CodeEmitterTask(compiler, namer, generateSourceMap);
     builder = new SsaBuilderTask(this);
+    fromIrBuilder = new SsaFromIrBuilderTask(compiler);
     optimizer = new SsaOptimizerTask(this);
     generator = new SsaCodeGeneratorTask(this);
     typeVariableHandler = new TypeVariableHandler(this);
@@ -574,6 +582,9 @@
       // The int class must be before the double class, because the
       // emitter relies on this list for the order of type checks.
       jsIntClass = compiler.findInterceptor('JSInt'),
+      jsPositiveIntClass = compiler.findInterceptor('JSPositiveInt'),
+      jsUInt32Class = compiler.findInterceptor('JSUInt32'),
+      jsUInt31Class = compiler.findInterceptor('JSUInt31'),
       jsDoubleClass = compiler.findInterceptor('JSDouble'),
       jsNumberClass = compiler.findInterceptor('JSNumber'),
       jsNullClass = compiler.findInterceptor('JSNull'),
@@ -845,6 +856,9 @@
       addInterceptors(jsExtendableArrayClass, enqueuer, elements);
     } else if (cls == compiler.intClass || cls == jsIntClass) {
       addInterceptors(jsIntClass, enqueuer, elements);
+      addInterceptors(jsPositiveIntClass, enqueuer, elements);
+      addInterceptors(jsUInt32Class, enqueuer, elements);
+      addInterceptors(jsUInt31Class, enqueuer, elements);
       addInterceptors(jsNumberClass, enqueuer, elements);
     } else if (cls == compiler.doubleClass || cls == jsDoubleClass) {
       addInterceptors(jsDoubleClass, enqueuer, elements);
@@ -855,6 +869,9 @@
       addInterceptors(jsNullClass, enqueuer, elements);
     } else if (cls == compiler.numClass || cls == jsNumberClass) {
       addInterceptors(jsIntClass, enqueuer, elements);
+      addInterceptors(jsPositiveIntClass, enqueuer, elements);
+      addInterceptors(jsUInt32Class, enqueuer, elements);
+      addInterceptors(jsUInt31Class, enqueuer, elements);
       addInterceptors(jsDoubleClass, enqueuer, elements);
       addInterceptors(jsNumberClass, enqueuer, elements);
     } else if (cls == jsPlainJavaScriptObjectClass) {
@@ -1260,8 +1277,9 @@
         compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper());
       }
     }
-
-    HGraph graph = builder.build(work);
+    HGraph graph = compiler.irBuilder.hasIr(element)
+        ? fromIrBuilder.build(work)
+        : builder.build(work);
     optimizer.optimize(work, graph);
     jsAst.Expression code = generator.generateCode(work, graph);
     generatedCode[element] = code;
@@ -1412,7 +1430,9 @@
       return typeCast
           ? 'boolTypeCast'
           : 'boolTypeCheck';
-    } else if (element == jsIntClass || element == compiler.intClass) {
+    } else if (element == jsIntClass || element == compiler.intClass
+               || element == jsUInt32Class || element == jsUInt31Class
+               || element == jsPositiveIntClass) {
       if (nativeCheckOnly) return null;
       return typeCast
           ? 'intTypeCast'
@@ -1630,6 +1650,9 @@
   }
 
   ClassElement get intImplementation => jsIntClass;
+  ClassElement get uint32Implementation => jsUInt32Class;
+  ClassElement get uint31Implementation => jsUInt31Class;
+  ClassElement get positiveIntImplementation => jsPositiveIntClass;
   ClassElement get doubleImplementation => jsDoubleClass;
   ClassElement get numImplementation => jsNumberClass;
   ClassElement get stringImplementation => jsStringClass;
@@ -1647,6 +1670,7 @@
     if (element == disableTreeShakingMarker) {
       compiler.disableTypeInferenceForMirrors = true;
       isTreeShakingDisabled = true;
+      typeVariableHandler.onTreeShakingDisabled(enqueuer);
     } else if (element == preserveNamesMarker) {
       mustPreserveNames = true;
     } else if (element == preserveMetadataMarker) {
@@ -1872,13 +1896,6 @@
       metadataConstants.clear();
     }
 
-    if (isTreeShakingDisabled) {
-      if (enqueuer.isResolutionQueue) {
-        typeVariableHandler.onResolutionQueueEmpty(enqueuer);
-      } else {
-        typeVariableHandler.onCodegenQueueEmpty();
-      }
-    }
     customElementsAnalysis.onQueueEmpty(enqueuer);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart
index 8e94149..e966bc2 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_system_javascript.dart
@@ -217,8 +217,7 @@
   NumConstant createInt32(int i) => new IntConstant(i & BITS32);
   NumConstant createDouble(double d)
       => convertToJavaScriptConstant(new DoubleConstant(d));
-  StringConstant createString(DartString string, Node diagnosticNode)
-      => new StringConstant(string, diagnosticNode);
+  StringConstant createString(DartString string) => new StringConstant(string);
   BoolConstant createBool(bool value) => new BoolConstant(value);
   NullConstant createNull() => new NullConstant();
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 40209b2..d137184 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -177,6 +177,11 @@
       "Z",
   ];
 
+  static const reservedGlobalHelperFunctions = const <String>[
+      "init",
+      "Isolate",
+  ];
+
   static final userGlobalObjects = new List.from(reservedGlobalObjectNames)
       ..remove('C')
       ..remove('H')
@@ -207,13 +212,12 @@
       _jsVariableReserved.addAll(reservedGlobalObjectNames);
       // 26 letters in the alphabet, 25 not counting I.
       assert(reservedGlobalObjectNames.length == 25);
+      _jsVariableReserved.addAll(reservedGlobalHelperFunctions);
     }
     return _jsVariableReserved;
   }
 
-  final String CURRENT_ISOLATE;
-  String get GLOBAL_OBJECT => CURRENT_ISOLATE;
-
+  final String currentIsolate = r'$';
   final String getterPrefix = r'get$';
   final String setterPrefix = r'set$';
   final String metadataField = '@';
@@ -255,7 +259,6 @@
 
   Namer(Compiler compiler)
       : compiler = compiler,
-        CURRENT_ISOLATE = compiler.globalJsName,
         globals = new Map<Element, String>(),
         shortPrivateNameOwners = new Map<String, LibraryElement>(),
         usedGlobalNames = new Set<String>(),
@@ -828,8 +831,8 @@
   // TODO(ahe): Remove this method. Use get getNameOfMember instead.
   String getNameOfGlobalFunction(FunctionElement element) => getNameX(element);
 
-  /// Returns true if [element] is stored on CURRENT_ISOLATE ('$').  We intend
-  /// to store only mutable static state in [CURRENT_ISOLATE], constants are
+  /// Returns true if [element] is stored on current isolate ('$').  We intend
+  /// to store only mutable static state in [currentIsolate], constants are
   /// stored in 'C', and functions, accessors, classes, etc. are stored in one
   /// of the other objects in [reservedGlobalObjectNames].
   bool isPropertyOfCurrentIsolate(Element element) {
@@ -838,7 +841,7 @@
     return
         // TODO(ahe): Re-write these tests to be positive (so it only returns
         // true for static/top-level mutable fields). Right now, a number of
-        // other elements, such as bound closures also live in CURRENT_ISOLATE.
+        // other elements, such as bound closures also live in [currentIsolate].
         !element.isAccessor() &&
         !element.isClass() &&
         !element.isConstructor() &&
@@ -846,9 +849,9 @@
         !element.isLibrary();
   }
 
-  /// Returns [CURRENT_ISOLATE] or one of [reservedGlobalObjectNames].
+  /// Returns [currentIsolate] or one of [reservedGlobalObjectNames].
   String globalObjectFor(Element element) {
-    if (isPropertyOfCurrentIsolate(element)) return CURRENT_ISOLATE;
+    if (isPropertyOfCurrentIsolate(element)) return currentIsolate;
     LibraryElement library = element.getLibrary();
     if (library == compiler.interceptorsLibrary) return 'J';
     if (library.isInternalLibrary) return 'H';
@@ -956,11 +959,9 @@
 
   String signatureLocation(FunctionType type) {
     ClassElement classElement = Types.getClassContext(type);
-    if (classElement != null) {
-      return '${isolateAccess(classElement)}';
-    } else {
-      return '${GLOBAL_OBJECT}';
-    }
+    return (classElement != null)
+        ? '${isolateAccess(classElement)}'
+        : currentIsolate;
   }
 
   String signatureName(FunctionType type) {
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 7ffe862..cae5491 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
@@ -40,31 +40,15 @@
   Compiler get compiler => backend.compiler;
 
   void registerClassWithTypeVariables(ClassElement cls) {
-    typeVariableClasses.add(cls);
-  }
-
-  void onResolutionQueueEmpty(Enqueuer enqueuer) {
-    if (typeVariableConstructor == null) {
-      if (!typeVariableClass.constructors.isEmpty &&
-          !typeVariableClass.constructors.tail.isEmpty) {
-        compiler.reportInternalError(
-            typeVariableClass,
-            'Class $typeVariableClass should only have one constructor');
-      }
-      typeVariableConstructor = typeVariableClass.constructors.head;
-      backend.enqueueClass(
-          enqueuer, typeVariableClass, compiler.globalDependencies);
-      backend.enqueueInResolution(
-          typeVariableConstructor, compiler.globalDependencies);
+    if (!backend.isTreeShakingDisabled || typeVariableConstructor == null) {
+      typeVariableClasses.add(cls);
+    } else {
+      processTypeVariablesOf(cls);
     }
   }
 
-  void onCodegenQueueEmpty() {
-    evaluator = new CompileTimeConstantEvaluator(
-        compiler.constantHandler, compiler.globalDependencies, compiler);
-
-    for (ClassElement cls in typeVariableClasses) {
-      // TODO(zarah): Running through all the members is suboptimal. Change this
+  void processTypeVariablesOf(ClassElement cls) {
+      //TODO(zarah): Running through all the members is suboptimal. Change this
       // as part of marking elements for reflection.
       bool hasMemberNeededForReflection(ClassElement cls) {
         bool result = false;
@@ -75,10 +59,17 @@
       }
 
       if (!backend.isNeededForReflection(cls) &&
-          !hasMemberNeededForReflection(cls)) continue;
+          !hasMemberNeededForReflection(cls)) {
+        return;
+      }
 
       InterfaceType typeVariableType = typeVariableClass.computeType(compiler);
       List<int> constants = <int>[];
+      evaluator = new CompileTimeConstantEvaluator(
+          compiler.constantHandler, 
+          compiler.globalDependencies, 
+          compiler);
+      
       for (TypeVariableType currentTypeVariable in cls.typeVariables) {
         List<Constant> createArguments(FunctionElement constructor) {
         if (constructor != typeVariableConstructor) {
@@ -87,8 +78,7 @@
                 'Unexpected constructor $constructor');
           }
           Constant name = backend.constantSystem.createString(
-              new DartString.literal(currentTypeVariable.name),
-              null);
+              new DartString.literal(currentTypeVariable.name));
           Constant bound = backend.constantSystem.createInt(
               emitter.reifyType(currentTypeVariable.element.bound));
           Constant type = evaluator.makeTypeConstant(cls);
@@ -104,8 +94,26 @@
             reifyTypeVariableConstant(c, currentTypeVariable.element));
       }
       typeVariables[cls] = constants;
+  }
+
+  void onTreeShakingDisabled(Enqueuer enqueuer) {
+    if (!enqueuer.isResolutionQueue || typeVariableClasses == null) return;
+    backend.enqueueClass(
+          enqueuer, typeVariableClass, compiler.globalDependencies);
+    Link constructors = typeVariableClass.ensureResolved(compiler).constructors;
+    if (constructors.isEmpty && constructors.tail.isEmpty) {
+      compiler.reportInternalError(
+          typeVariableClass,
+          "Class '$typeVariableClass' should only have one constructor");
     }
-    typeVariableClasses.clear();
+    typeVariableConstructor = typeVariableClass.constructors.head;
+    backend.enqueueInResolution(typeVariableConstructor,
+        compiler.globalDependencies);
+    enqueuer.registerInstantiatedType(typeVariableClass.rawType,
+        compiler.globalDependencies);
+    List<ClassElement> worklist = typeVariableClasses;
+    typeVariableClasses = null;
+    worklist.forEach((cls) => processTypeVariablesOf(cls));
   }
 
   /**
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 156e0de..60db17c 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
@@ -116,7 +116,7 @@
   String get name => 'CodeEmitter';
 
   String get currentGenerateAccessorName
-      => '${namer.CURRENT_ISOLATE}.\$generateAccessor';
+      => '${namer.currentIsolate}.\$generateAccessor';
   String get generateAccessorHolder
       => '$isolatePropertiesName.\$generateAccessor';
   String get finishClassesProperty
@@ -539,7 +539,7 @@
   }
 
   List addLazyInitializerLogic() {
-    String isolate = namer.CURRENT_ISOLATE;
+    String isolate = namer.currentIsolate;
     String cyclicThrow = namer.isolateAccess(backend.getCyclicThrowHelper());
     var lazies = [];
     if (backend.rememberLazies) {
@@ -794,6 +794,14 @@
       }
     }
 
+    // These classes are just helpers for the backend's type system.
+    unneededClasses.add(backend.jsMutableArrayClass);
+    unneededClasses.add(backend.jsFixedArrayClass);
+    unneededClasses.add(backend.jsExtendableArrayClass);
+    unneededClasses.add(backend.jsUInt32Class);
+    unneededClasses.add(backend.jsUInt31Class);
+    unneededClasses.add(backend.jsPositiveIntClass);
+
     return (ClassElement cls) => !unneededClasses.contains(cls);
   }
 
@@ -1195,7 +1203,7 @@
       addComment(HOOKS_API_USAGE, mainBuffer);
 
       if (!areAnyElementsDeferred) {
-        mainBuffer.add('(function(${namer.CURRENT_ISOLATE})$_{$n');
+        mainBuffer.add('(function(${namer.currentIsolate})$_{$n');
       }
 
       for (String globalObject in Namer.reservedGlobalObjectNames) {
@@ -1211,8 +1219,8 @@
 
       mainBuffer.add('function ${namer.isolateName}()$_{}\n');
       mainBuffer.add('init()$N$n');
-      // Shorten the code by using [namer.CURRENT_ISOLATE] as temporary.
-      isolateProperties = namer.CURRENT_ISOLATE;
+      // Shorten the code by using [namer.currentIsolate] as temporary.
+      isolateProperties = namer.currentIsolate;
       mainBuffer.add(
           '$isolateProperties$_=$_$isolatePropertiesName$N');
 
@@ -1385,11 +1393,11 @@
       isolateProperties = isolatePropertiesName;
       // The following code should not use the short-hand for the
       // initialStatics.
-      mainBuffer.add('${namer.CURRENT_ISOLATE}$_=${_}null$N');
+      mainBuffer.add('${namer.currentIsolate}$_=${_}null$N');
 
       emitFinishIsolateConstructorInvocation(mainBuffer);
       mainBuffer.add(
-          '${namer.CURRENT_ISOLATE}$_=${_}new ${namer.isolateName}()$N');
+          '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N');
 
       emitConvertToFastObjectFunction();
       for (String globalObject in Namer.reservedGlobalObjectNames) {
@@ -1527,13 +1535,13 @@
 
     var buffer = new CodeBuffer()
         ..write(buildGeneratedBy())
-        ..write('var old${namer.CURRENT_ISOLATE}$_='
-                '$_${namer.CURRENT_ISOLATE}$N'
+        ..write('var old${namer.currentIsolate}$_='
+                '$_${namer.currentIsolate}$N'
                 // TODO(ahe): This defines a lot of properties on the
                 // Isolate.prototype object.  We know this will turn it into a
                 // slow object in V8, so instead we should do something similar
                 // to Isolate.$finishIsolateConstructor.
-                '${namer.CURRENT_ISOLATE}$_='
+                '${namer.currentIsolate}$_='
                 '$_${namer.isolateName}.prototype$N$n'
                 // The classesCollector object ($$).
                 '$classesCollector$_=$_{};$n')
@@ -1544,14 +1552,14 @@
 
     if (!deferredClasses.isEmpty) {
       buffer.write(
-          '$finishClassesName($classesCollector,$_${namer.CURRENT_ISOLATE},'
+          '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
           '$_$isolatePropertiesName)$N');
     }
 
     buffer.write(
         // Reset the classesCollector ($$).
         '$classesCollector$_=${_}null$N$n'
-        '${namer.CURRENT_ISOLATE}$_=${_}old${namer.CURRENT_ISOLATE}$N');
+        '${namer.currentIsolate}$_=${_}old${namer.currentIsolate}$N');
 
     classesCollector = oldClassesCollector;
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
index 373b65d..864f130 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
@@ -68,7 +68,7 @@
 '''init.typeInformation[previousProperty] = element;
         } else if (firstChar === "@") {
           property = property.substring(1);
-          ${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
+          ${namer.currentIsolate}[property][$metadataField] = element;
         } else if (firstChar === "*") {
           globalObject[previousProperty].$defaultValuesField = element;
           var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 4bb7c50..7dfd10c 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -1616,8 +1616,7 @@
 
   Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrors,
                                          String text)
-      : super(mirrors,
-              new StringConstant(new DartString.literal(text), null));
+      : super(mirrors, new StringConstant(new DartString.literal(text)));
 
   StringConstant get _constant => super._constant;
 
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
index a5d6d52..05ddb81 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors_used.dart
@@ -105,11 +105,11 @@
   void analyzeUsage(LibraryElement mainApp) {
     if (compiler.mirrorsLibrary == null) return;
     measure(analyzer.run);
-    List<String> symbols = analyzer.mergedMirrorUsage.symbols;
+    List /*<String|Element>*/ symbols = analyzer.mergedMirrorUsage.symbols;
     List<Element> targets = analyzer.mergedMirrorUsage.targets;
     List<Element> metaTargets = analyzer.mergedMirrorUsage.metaTargets;
     compiler.backend.registerMirrorUsage(
-        symbols == null ? null : new Set<String>.from(symbols),
+        symbols == null ? null : new Set/*<String|Element>*/.from(symbols),
         targets == null ? null : new Set<Element>.from(targets),
         metaTargets == null ? null : new Set<Element>.from(metaTargets));
     librariesWithUsage = analyzer.librariesWithUsage;
@@ -304,7 +304,7 @@
       return a;
     }
     // TODO(ahe): Test the following cases.
-    List<String> symbols = a.symbols;
+    List /*<String|Element>*/ symbols = a.symbols;
     if (symbols == null) {
       symbols = b.symbols;
     } else if (b.symbols != null) {
@@ -349,7 +349,7 @@
 
 /// Used to represent a resolved MirrorsUsed constant.
 class MirrorUsage {
-  final List<String> symbols;
+  final List /* <String|Element> */ symbols;
   final List<Element> targets;
   final List<Element> metaTargets;
   final List<Element> override;
diff --git a/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart b/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart
new file mode 100644
index 0000000..6a68357
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ordered_typeset.dart
@@ -0,0 +1,203 @@
+// 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 resolution.ordered_typeset_builder;

+

+import 'dart2jslib.dart' show Compiler, MessageKind;

+import 'dart_types.dart';

+import 'elements/elements.dart' show ClassElement;

+import 'util/util.dart' show Link, LinkBuilder;

+import 'util/util_implementation.dart' show LinkEntry;

+

+/**

+ * An ordered set of the supertypes of a class. The supertypes of a class are

+ * ordered by decreasing hierarchy depth and by the order they are extended,

+ * mixed in, or implemented.

+ *

+ * For these classes

+ *

+ *     class A {} // Depth = 1.

+ *     class B {} // Depth = 1.

+ *     class C extends B implements A {} // Depth 2.

+ *

+ * the ordered supertypes are

+ *

+ *     A: [A, Object]

+ *     B: [B, Object]

+ *     C: [C, B, A, Object]

+ */

+class OrderedTypeSet {

+  final List<Link<DartType>> _levels;

+  final Link<DartType> types;

+  final Link<DartType> _supertypes;

+

+  OrderedTypeSet._internal(List<Link<DartType>> this._levels,

+                           Link<DartType> this.types,

+                           Link<DartType> this._supertypes);

+

+  factory OrderedTypeSet.singleton(DartType type) {

+    Link<DartType> types =

+        new LinkEntry<DartType>(type, const Link<DartType>());

+    List<Link<DartType>> list = new List<Link<DartType>>(1);

+    list[0] = types;

+    return new OrderedTypeSet._internal(list, types, const Link<DartType>());

+  }

+

+  /// Creates a new [OrderedTypeSet] for [type] when it directly extends the

+  /// class which this set represents. This is for instance used to create the

+  /// type set for [ClosureClassElement] which extends [Closure].

+  OrderedTypeSet extendClass(InterfaceType type) {

+    assert(type.treatAsRaw);

+    Link<DartType> extendedTypes =

+        new LinkEntry<DartType>(type, types);

+    List<Link<DartType>> list = new List<Link<DartType>>(levels + 1);

+    for (int i = 0; i < levels; i++) {

+      list[i] = _levels[i];

+    }

+    list[levels] = extendedTypes;

+    return new OrderedTypeSet._internal(

+        list, extendedTypes, _supertypes.prepend(types.head));

+  }

+

+  Link<DartType> get supertypes => _supertypes;

+

+  int get levels => _levels.length;

+

+  int get maxDepth => levels - 1;

+

+  Link<DartType> operator [](int index) {

+    if (index < levels) {

+      return _levels[index];

+    }

+    return const Link<DartType>();

+  }

+

+  void forEach(int level, void f(DartType type)) {

+    if (level < levels) {

+      Link<DartType> pointer = _levels[level];

+      Link<DartType> end =

+          level > 0 ? _levels[level - 1] : const Link<DartType>();

+      while (!identical(pointer, end)) {

+        f(pointer.head);

+        pointer = pointer.tail;

+      }

+    }

+  }

+

+  String toString() => types.toString();

+}

+

+/**

+ * Builder for creation an ordered set of the supertypes of a class. The

+ * supertypes are ordered by decreasing hierarchy depth and by the order they

+ * are extended, mixed in, or implemented.

+ *

+ * For these classes

+ *

+ *     class A {} // Depth = 1.

+ *     class B {} // Depth = 1.

+ *     class C extends B implements A {} // Depth 2.

+ *

+ * the ordered supertypes are

+ *

+ *     A: [A, Object]

+ *     B: [B, Object]

+ *     C: [C, B, A, Object]

+ */

+class OrderedTypeSetBuilder {

+  Map<int, LinkEntry<DartType>> map = new Map<int, LinkEntry<DartType>>();

+  // TODO(15296): Avoid computing this order on the side when member

+  // lookup handles multiply inherited members correctly.

+  LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>();

+  int maxDepth = -1;

+

+  final ClassElement cls;

+

+  OrderedTypeSetBuilder(this.cls);

+

+  void add(Compiler compiler, InterfaceType type) {

+    if (type.element == cls) {

+      if (type.element != compiler.objectClass) {

+        allSupertypes.addLast(compiler.objectClass.computeType(compiler));

+      }

+      _addAtDepth(compiler, type, maxDepth + 1);

+    } else {

+      if (type.element != compiler.objectClass) {

+        allSupertypes.addLast(type);

+      }

+      _addAtDepth(compiler, type, type.element.hierarchyDepth);

+    }

+  }

+

+  void _addAtDepth(Compiler compiler, InterfaceType type, int depth) {

+    LinkEntry<DartType> prev = null;

+    LinkEntry<DartType> link = map[depth];

+    while (link != null) {

+      DartType existingType = link.head;

+      if (existingType == type) return;

+      if (existingType.element == type.element) {

+        compiler.reportError(cls,

+            MessageKind.MULTI_INHERITANCE,

+            {'thisType': cls.computeType(compiler),

+             'firstType': existingType,

+             'secondType': type});

+        return;

+      }

+      prev = link;

+      link = link.tail;

+    }

+    LinkEntry<DartType> next = new LinkEntry<DartType>(type);

+    next.tail = null;

+    if (prev == null) {

+      map[depth] = next;

+    } else {

+      prev.tail = next;

+    }

+    if (depth > maxDepth) {

+      maxDepth = depth;

+    }

+  }

+

+  OrderedTypeSet toTypeSet() {

+    List<Link<DartType>> levels = new List<Link<DartType>>(maxDepth + 1);

+    if (maxDepth < 0) {

+      return new OrderedTypeSet._internal(

+          levels, const Link<DartType>(), const Link<DartType>());

+    }

+    Link<DartType> next = const Link<DartType>();

+    for (int depth = 0; depth <= maxDepth; depth++) {

+      LinkEntry<DartType> first = map[depth];

+      if (first == null) {

+        levels[depth] = next;

+      } else {

+        levels[depth] = first;

+        LinkEntry<DartType> last = first;

+        while (last.tail != null) {

+          last = last.tail;

+        }

+        last.tail = next;

+        next = first;

+      }

+    }

+    return new OrderedTypeSet._internal(

+        levels, levels.last, allSupertypes.toLink());

+  }

+

+  String toString() {

+    StringBuffer sb = new StringBuffer();

+    for (int depth = 0; depth <= maxDepth; depth++) {

+      sb.write('$depth: ');

+      LinkEntry<DartType> first = map[depth];

+      if (first != null) {

+        sb.write('${first.head}');

+        while (first.tail != null) {

+          sb.write(', ${first.tail.head}');

+          first = first.tail;

+        }

+      }

+      sb.write('\n');

+    }

+    return sb.toString();

+  }

+}

diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index aa8b76a..3e04dc9 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -661,16 +661,19 @@
    * Warning: do not call this method directly. It should only be
    * called by [resolveClass] and [ClassSupertypeResolver].
    */
-  void loadSupertypes(ClassElement cls, Spannable from) {
+  void loadSupertypes(BaseClassElementX cls, Spannable from) {
     compiler.withCurrentElement(cls, () => measure(() {
       if (cls.supertypeLoadState == STATE_DONE) return;
       if (cls.supertypeLoadState == STATE_STARTED) {
         compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
                                  {'className': cls.name});
         cls.supertypeLoadState = STATE_DONE;
-        cls.allSupertypes = const Link<DartType>().prepend(
-            compiler.objectClass.computeType(compiler));
+        cls.allSupertypesAndSelf =
+            compiler.objectClass.allSupertypesAndSelf.extendClass(
+                cls.computeType(compiler));
         cls.supertype = cls.allSupertypes.head;
+        assert(invariant(from, cls.supertype != null,
+            message: 'Missing supertype on cyclic class $cls.'));
         return;
       }
       cls.supertypeLoadState = STATE_STARTED;
@@ -723,7 +726,8 @@
     }
   }
 
-  void resolveClassInternal(ClassElement element, TreeElementMapping mapping) {
+  void resolveClassInternal(BaseClassElementX element,
+                            TreeElementMapping mapping) {
     if (!element.isPatch) {
       compiler.withCurrentElement(element, () => measure(() {
         assert(element.resolutionState == STATE_NOT_STARTED);
@@ -750,7 +754,7 @@
       // Copy class hiearchy from origin.
       element.supertype = element.origin.supertype;
       element.interfaces = element.origin.interfaces;
-      element.allSupertypes = element.origin.allSupertypes;
+      element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
       // Stepwise assignment to ensure invariant.
       element.supertypeLoadState = STATE_STARTED;
       element.supertypeLoadState = STATE_DONE;
@@ -2588,7 +2592,7 @@
         // type variable expression.
         mapping.setType(node, compiler.typeClass.computeType(compiler));
         world.registerTypeLiteral(target, mapping);
-      } else if (target.impliesType() && !sendIsMemberAccess) {
+      } else if (target.impliesType() && (!sendIsMemberAccess || node.isCall)) {
         // Set the type of the node to [Type] to mark this send as a
         // type literal.
         mapping.setType(node, compiler.typeClass.computeType(compiler));
@@ -2656,6 +2660,14 @@
         // dynamic invocation, because we statically know what the target is.
       } else if (!selector.applies(target, compiler)) {
         warnArgumentMismatch(node, target);
+        if (node.isSuperCall) {
+          // Similar to what we do when we can't find super via selector
+          // in [resolveSend] above, we still need to register the invocation,
+          // because we might call [:super.noSuchMethod:] which calls
+          // [JSInvocationMirror._invokeOn].
+          world.registerDynamicInvocation(selector);
+          compiler.backend.registerSuperNoSuchMethod(mapping);
+        }
       }
 
       if (target != null && target.isForeign(compiler)) {
@@ -3940,7 +3952,7 @@
         target.name, target, enclosing, false);
   }
 
-  void doApplyMixinTo(MixinApplicationElement mixinApplication,
+  void doApplyMixinTo(MixinApplicationElementX mixinApplication,
                       DartType supertype,
                       DartType mixinType) {
     Node node = mixinApplication.parseNode(compiler);
@@ -3965,12 +3977,14 @@
     // The class that is the result of a mixin application implements
     // the interface of the class that was mixed in so always prepend
     // that to the interface list.
+
     interfaces = interfaces.prepend(mixinType);
     assert(mixinApplication.interfaces == null);
     mixinApplication.interfaces = interfaces;
 
+    ClassElement superclass = supertype.element;
     if (mixinType.kind != TypeKind.INTERFACE) {
-      mixinApplication.allSupertypes = const Link<DartType>();
+      mixinApplication.allSupertypesAndSelf = superclass.allSupertypesAndSelf;
       return;
     }
 
@@ -3979,7 +3993,6 @@
 
     // Create forwarding constructors for constructor defined in the superclass
     // because they are now hidden by the mixin application.
-    ClassElement superclass = supertype.element;
     superclass.forEachLocalMember((Element member) {
       if (!member.isGenerativeConstructor()) return;
       FunctionElement forwarder =
@@ -4095,54 +4108,40 @@
    * different type arguments, the type used in the most specific class comes
    * first.
    */
-  void calculateAllSupertypes(ClassElement cls) {
-    if (cls.allSupertypes != null) return;
+  void calculateAllSupertypes(BaseClassElementX cls) {
+    if (cls.allSupertypesAndSelf != null) return;
     final DartType supertype = cls.supertype;
     if (supertype != null) {
-      Map<Element, DartType> instantiations = new Map<Element, DartType>();
-      LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>();
-
-      void addSupertype(DartType type) {
-        DartType existing =
-            instantiations.putIfAbsent(type.element, () => type);
-        if (existing != null && existing != type) {
-          compiler.reportError(cls,
-              MessageKind.MULTI_INHERITANCE,
-              {'thisType': cls.computeType(compiler),
-               'firstType': existing,
-               'secondType': type});
-        }
-        if (type.element != compiler.objectClass) {
-          allSupertypes.addLast(type);
-        }
-      }
-
-      addSupertype(supertype);
-      for (Link<DartType> interfaces = cls.interfaces;
-          !interfaces.isEmpty;
-          interfaces = interfaces.tail) {
-        addSupertype(interfaces.head);
-      }
-      addAllSupertypes(addSupertype, supertype);
+      OrderedTypeSetBuilder allSupertypes = new OrderedTypeSetBuilder(cls);
+      // TODO(15296): Collapse these iterations to one when the order is not
+      // needed.
+      allSupertypes.add(compiler, supertype);
       for (Link<DartType> interfaces = cls.interfaces;
            !interfaces.isEmpty;
            interfaces = interfaces.tail) {
-        addAllSupertypes(addSupertype, interfaces.head);
+        allSupertypes.add(compiler, interfaces.head);
       }
 
-      allSupertypes.addLast(compiler.objectClass.rawType);
-      cls.allSupertypes = allSupertypes.toLink();
+      addAllSupertypes(allSupertypes, supertype);
+      for (Link<DartType> interfaces = cls.interfaces;
+           !interfaces.isEmpty;
+           interfaces = interfaces.tail) {
+        addAllSupertypes(allSupertypes, interfaces.head);
+      }
+      allSupertypes.add(compiler, cls.computeType(compiler));
+      cls.allSupertypesAndSelf = allSupertypes.toTypeSet();
     } else {
       assert(identical(cls, compiler.objectClass));
-      cls.allSupertypes = const Link<DartType>();
+      cls.allSupertypesAndSelf =
+          new OrderedTypeSet.singleton(cls.computeType(compiler));
     }
-  }
+ }
 
   /**
    * Adds [type] and all supertypes of [type] to [allSupertypes] while
    * substituting type variables.
    */
-  void addAllSupertypes(void addSupertype(DartType supertype),
+  void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
                         InterfaceType type) {
     Link<DartType> typeArguments = type.typeArguments;
     ClassElement classElement = type.element;
@@ -4153,10 +4152,8 @@
                  "during resolution of $element"));
     while (!supertypes.isEmpty) {
       DartType supertype = supertypes.head;
-      if (supertype.element != compiler.objectClass) {
-        DartType substituted = supertype.subst(typeArguments, typeVariables);
-        addSupertype(substituted);
-      }
+      allSupertypes.add(compiler,
+                        supertype.subst(typeArguments, typeVariables));
       supertypes = supertypes.tail;
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index 9240eb4..136a930 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -12,7 +12,8 @@
 import '../tree/tree.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart'
-    show FunctionElementX,
+    show BaseClassElementX,
+         FunctionElementX,
          ErroneousElementX,
          VariableElementX,
          FieldParameterElementX,
@@ -27,6 +28,7 @@
 import '../scanner/scannerlib.dart' show PartialMetadataAnnotation;
 
 import 'secret_tree_element.dart' show getTreeElement, setTreeElement;
+import '../ordered_typeset.dart' show OrderedTypeSet, OrderedTypeSetBuilder;
 
 part 'members.dart';
 part 'scope.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/source_map_builder.dart b/sdk/lib/_internal/compiler/implementation/source_map_builder.dart
index 1665d22..a4d2e4b 100644
--- a/sdk/lib/_internal/compiler/implementation/source_map_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_map_builder.dart
@@ -173,28 +173,50 @@
   SourceMapEntry(this.sourceLocation, this.targetOffset);
 }
 
-class SourceFileLocation {
+abstract class SourceFileLocation {
   SourceFile sourceFile;
-  Token token;
-  int line;
 
-  SourceFileLocation(this.sourceFile, this.token) {
+  SourceFileLocation(this.sourceFile) {
     assert(isValid());
   }
 
+  int line;
+
+  int get offset;
+
   String getSourceUrl() => sourceFile.filename;
 
   int getLine() {
-    if (line == null) line = sourceFile.getLine(token.charOffset);
+    if (line == null) line = sourceFile.getLine(offset);
     return line;
   }
 
-  int getColumn() => sourceFile.getColumn(getLine(), token.charOffset);
+  int getColumn() => sourceFile.getColumn(getLine(), offset);
+
+  String getSourceName();
+
+  bool isValid() => offset < sourceFile.length;
+}
+
+class TokenSourceFileLocation extends SourceFileLocation {
+  final Token token;
+
+  TokenSourceFileLocation(SourceFile sourceFile, this.token)
+    : super(sourceFile);
+
+  int get offset => token.charOffset;
 
   String getSourceName() {
     if (token.isIdentifier()) return token.value;
     return null;
   }
+}
 
-  bool isValid() => token.charOffset < sourceFile.length;
+class OffsetSourceFileLocation extends SourceFileLocation {
+  final int offset;
+  final String sourceName;
+  OffsetSourceFileLocation(SourceFile sourceFile, this.offset,
+      [this.sourceName]) : super(sourceFile);
+
+  String getSourceName() => sourceName;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 3635a62..f556147 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -885,29 +885,12 @@
   }
 }
 
-class SsaBuilder extends ResolvedVisitor implements Visitor {
-  final SsaBuilderTask builder;
-  final JavaScriptBackend backend;
-  final CodegenWorkItem work;
-  final ConstantSystem constantSystem;
-  HGraph graph;
-  LocalsHandler localsHandler;
-  HInstruction rethrowableException;
-  Map<Element, HInstruction> parameters;
-  final RuntimeTypes rti;
-  HParameterValue lastAddedParameter;
-
-  Map<TargetElement, JumpHandler> jumpTargets;
-
-  /**
-   * Variables stored in the current activation. These variables are
-   * being updated in try/catch blocks, and should be
-   * accessed indirectly through [HLocalGet] and [HLocalSet].
-   */
-  Map<Element, HLocalValue> activationVariables;
-
-  // We build the Ssa graph by simulating a stack machine.
-  List<HInstruction> stack;
+/**
+ * This mixin implements functionality that is shared between the [SsaBuilder]
+ * and the [SsaFromIrBuilder] classes.
+ */
+class SsaGraphBuilderMixin {
+  final HGraph graph = new HGraph();
 
   /**
    * The current block to add instructions to. Might be null, if we are
@@ -931,6 +914,88 @@
    */
   bool isReachable = true;
 
+  HBasicBlock get current => _current;
+  void set current(c) {
+    isReachable = c != null;
+    _current = c;
+  }
+
+  HBasicBlock addNewBlock() {
+    HBasicBlock block = graph.addNewBlock();
+    // If adding a new block during building of an expression, it is due to
+    // conditional expressions or short-circuit logical operators.
+    return block;
+  }
+
+  void open(HBasicBlock block) {
+    block.open();
+    current = block;
+    lastOpenedBlock = block;
+  }
+
+  HBasicBlock close(HControlFlow end) {
+    HBasicBlock result = current;
+    current.close(end);
+    current = null;
+    return result;
+  }
+
+  HBasicBlock closeAndGotoExit(HControlFlow end) {
+    HBasicBlock result = current;
+    current.close(end);
+    current = null;
+    result.addSuccessor(graph.exit);
+    return result;
+  }
+
+  void goto(HBasicBlock from, HBasicBlock to) {
+    from.close(new HGoto());
+    from.addSuccessor(to);
+  }
+
+  bool isAborted() {
+    return _current == null;
+  }
+
+  /**
+   * Creates a new block, transitions to it from any current block, and
+   * opens the new block.
+   */
+  HBasicBlock openNewBlock() {
+    HBasicBlock newBlock = addNewBlock();
+    if (!isAborted()) goto(current, newBlock);
+    open(newBlock);
+    return newBlock;
+  }
+
+  void add(HInstruction instruction) {
+    current.add(instruction);
+  }
+}
+
+class SsaBuilder extends ResolvedVisitor with SsaGraphBuilderMixin {
+  final SsaBuilderTask builder;
+  final JavaScriptBackend backend;
+  final CodegenWorkItem work;
+  final ConstantSystem constantSystem;
+  LocalsHandler localsHandler;
+  HInstruction rethrowableException;
+  Map<Element, HInstruction> parameters;
+  final RuntimeTypes rti;
+  HParameterValue lastAddedParameter;
+
+  Map<TargetElement, JumpHandler> jumpTargets;
+
+  /**
+   * Variables stored in the current activation. These variables are
+   * being updated in try/catch blocks, and should be
+   * accessed indirectly through [HLocalGet] and [HLocalSet].
+   */
+  Map<Element, HLocalValue> activationVariables;
+
+  // We build the Ssa graph by simulating a stack machine.
+  List<HInstruction> stack;
+
   /**
    * True if we are visiting the expression of a throw expression.
    */
@@ -971,7 +1036,6 @@
     : this.builder = builder,
       this.backend = builder.backend,
       this.work = work,
-      graph = new HGraph(),
       stack = new List<HInstruction>(),
       activationVariables = new Map<Element, HLocalValue>(),
       jumpTargets = new Map<TargetElement, JumpHandler>(),
@@ -991,12 +1055,6 @@
   bool inTryStatement = false;
   int loopNesting = 0;
 
-  HBasicBlock get current => _current;
-  void set current(c) {
-    isReachable = c != null;
-    _current = c;
-  }
-
   Constant getConstantForNode(Node node) {
     ConstantHandler handler = compiler.constantHandler;
     Constant constant = elements.getConstant(node);
@@ -1225,9 +1283,15 @@
         localsHandler, inTryStatement);
     inTryStatement = false;
     LocalsHandler newLocalsHandler = new LocalsHandler(this);
-    newLocalsHandler.closureData =
-        compiler.closureToClassMapper.computeClosureToClassMapping(
-            function, function.parseNode(compiler), elements);
+    if (compiler.irBuilder.hasIr(function)) {
+      // TODO(lry): handle ir functions with nested closure definitions.
+      newLocalsHandler.closureData =
+          new ClosureClassMap(null, null, null, new ThisElement(function));
+    } else {
+      newLocalsHandler.closureData =
+          compiler.closureToClassMapper.computeClosureToClassMapping(
+              function, function.parseNode(compiler), elements);
+    }
     int argumentIndex = 0;
     if (isInstanceMember) {
       newLocalsHandler.updateLocal(newLocalsHandler.closureData.thisElement,
@@ -1350,7 +1414,7 @@
       return true;
     }
 
-    bool heuristicSayGoodToGo(FunctionExpression functionExpression) {
+    bool heuristicSayGoodToGo(bool canBeInlined(int maxNodes, bool useMax)) {
       // Don't inline recursivly
       if (inliningStack.any((entry) => entry.function == function)) {
         return false;
@@ -1382,17 +1446,16 @@
                   (entry) => inferrer.isCalledOnce(entry.function)))) {
         useMaxInliningNodes = false;
       }
-      bool canBeInlined = InlineWeeder.canBeInlined(
-          functionExpression, maxInliningNodes, useMaxInliningNodes);
-      if (canBeInlined) {
+      bool canInline = canBeInlined(maxInliningNodes, useMaxInliningNodes);
+      if (canInline) {
         backend.inlineCache.markAsInlinable(element, insideLoop: insideLoop);
       } else {
         backend.inlineCache.markAsNonInlinable(element, insideLoop: insideLoop);
       }
-      return canBeInlined;
+      return canInline;
     }
 
-    void doInlining(FunctionExpression functionExpression) {
+    void doInlining(void visitBody()) {
       // Add an explicit null check on the receiver before doing the
       // inlining. We use [element] to get the same name in the
       // NoSuchMethodError message as if we had called it.
@@ -1418,7 +1481,7 @@
         if (element.isGenerativeConstructor()) {
           buildFactory(element);
         } else {
-          functionExpression.body.accept(this);
+          visitBody();
         }
         removeInlinedInstantiation(instantiatedType);
       });
@@ -1426,11 +1489,25 @@
     }
 
     if (meetsHardConstraints()) {
-      FunctionExpression functionExpression = function.parseNode(compiler);
-
-      if (heuristicSayGoodToGo(functionExpression)) {
-        doInlining(functionExpression);
-        return true;
+      if (compiler.irBuilder.hasIr(function)) {
+        IrFunction irFunction = compiler.irBuilder.getIr(function);
+        bool canInline(int n, bool b) {
+          return IrInlineWeeder.canBeInlined(irFunction, n, b);
+        }
+        if (heuristicSayGoodToGo(canInline)) {
+          SsaFromIrInliner irInliner = new SsaFromIrInliner(this);
+          doInlining(() => irInliner.visitAll(irFunction.statements));
+          return true;
+        }
+      } else {
+        FunctionExpression functionNode = function.parseNode(compiler);
+        bool canInline(int n, bool b) {
+          return InlineWeeder.canBeInlined(functionNode, n, b);
+        }
+        if (heuristicSayGoodToGo(canInline)) {
+          doInlining(() => functionNode.body.accept(this));
+          return true;
+        }
       }
     }
 
@@ -2040,8 +2117,7 @@
     HInstruction subtypeInstruction = analyzeTypeArgument(subtype);
     HInstruction supertypeInstruction = analyzeTypeArgument(supertype);
     HInstruction messageInstruction =
-        graph.addConstantString(new DartString.literal(message),
-                                node, compiler);
+        graph.addConstantString(new DartString.literal(message), compiler);
     Element element = backend.getAssertIsSubtype();
     var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction,
                                 messageInstruction];
@@ -2058,58 +2134,6 @@
     return graph;
   }
 
-  HBasicBlock addNewBlock() {
-    HBasicBlock block = graph.addNewBlock();
-    // If adding a new block during building of an expression, it is due to
-    // conditional expressions or short-circuit logical operators.
-    return block;
-  }
-
-  void open(HBasicBlock block) {
-    block.open();
-    current = block;
-    lastOpenedBlock = block;
-  }
-
-  HBasicBlock close(HControlFlow end) {
-    HBasicBlock result = current;
-    current.close(end);
-    current = null;
-    return result;
-  }
-
-  HBasicBlock closeAndGotoExit(HControlFlow end) {
-    HBasicBlock result = current;
-    current.close(end);
-    current = null;
-    result.addSuccessor(graph.exit);
-    return result;
-  }
-
-  void goto(HBasicBlock from, HBasicBlock to) {
-    from.close(new HGoto());
-    from.addSuccessor(to);
-  }
-
-  bool isAborted() {
-    return _current == null;
-  }
-
-  /**
-   * Creates a new block, transitions to it from any current block, and
-   * opens the new block.
-   */
-  HBasicBlock openNewBlock() {
-    HBasicBlock newBlock = addNewBlock();
-    if (!isAborted()) goto(current, newBlock);
-    open(newBlock);
-    return newBlock;
-  }
-
-  void add(HInstruction instruction) {
-    current.add(instruction);
-  }
-
   void addWithPosition(HInstruction instruction, Node node) {
     add(attachPosition(instruction, node));
   }
@@ -2166,7 +2190,8 @@
     }
     Script script = element.getCompilationUnit().script;
     SourceFile sourceFile = script.file;
-    SourceFileLocation location = new SourceFileLocation(sourceFile, token);
+    SourceFileLocation location =
+        new TokenSourceFileLocation(sourceFile, token);
     if (!location.isValid()) {
       throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
           {'offset': token.charOffset,
@@ -3066,7 +3091,7 @@
 
       HInstruction signatureName = graph.addConstantString(
           new DartString.literal(backend.namer.getFunctionTypeName(type)),
-          node, compiler);
+          compiler);
 
       HInstruction contextName;
       HInstruction context;
@@ -3075,7 +3100,7 @@
         ClassElement contextClass = Types.getClassContext(type);
         contextName = graph.addConstantString(
             new DartString.literal(backend.namer.getNameOfClass(contextClass)),
-            node, compiler);
+            compiler);
         if (!currentElement.enclosingElement.isClosure()
             && currentElement.isInstanceMember()) {
           context = localsHandler.readThis();
@@ -3114,9 +3139,9 @@
       add(representations);
       String operator =
           backend.namer.operatorIs(backend.getImplementationClass(element));
-      HInstruction isFieldName = addConstantString(node, operator);
+      HInstruction isFieldName = addConstantString(operator);
       HInstruction asFieldName = compiler.world.hasAnySubtype(element)
-          ? addConstantString(node, backend.namer.substitutionName(element))
+          ? addConstantString(backend.namer.substitutionName(element))
           : graph.addConstantNull(compiler);
       List<HInstruction> inputs = <HInstruction>[expression,
                                                  isFieldName,
@@ -3282,7 +3307,7 @@
     if (!compiler.hasIsolateSupport()) {
       // If the isolate library is not used, we just generate code
       // to fetch the current isolate.
-      String name = backend.namer.CURRENT_ISOLATE;
+      String name = backend.namer.currentIsolate;
       push(new HForeign(new js.LiteralString(name),
                         backend.dynamicType,
                         <HInstruction>[]));
@@ -3327,7 +3352,6 @@
     }
     stack.add(
         addConstantString(
-            argument,
             backend.namer.getNameForJsGetName(
                 argument, string.dartString.slowToString())));
   }
@@ -3421,7 +3445,7 @@
                       node: node.argumentsNode);
     }
     visit(node.arguments.head);
-    String isolateName = backend.namer.CURRENT_ISOLATE;
+    String isolateName = backend.namer.currentIsolate;
     SideEffects sideEffects = new SideEffects.empty();
     sideEffects.setAllSideEffects();
     push(new HForeign(js.js("$isolateName = #"),
@@ -3455,7 +3479,7 @@
     if (!node.arguments.isEmpty) {
       compiler.cancel('Too many arguments', node: node.argumentsNode);
     }
-    push(new HForeign(new js.LiteralString(backend.namer.CURRENT_ISOLATE),
+    push(new HForeign(new js.LiteralString(backend.namer.currentIsolate),
                       backend.dynamicType,
                       <HInstruction>[]));
   }
@@ -3478,46 +3502,44 @@
     } else if (name == 'JS_CREATE_ISOLATE') {
       handleForeignCreateIsolate(node);
     } else if (name == 'JS_OPERATOR_IS_PREFIX') {
-      stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
+      stack.add(addConstantString(backend.namer.operatorIsPrefix()));
     } else if (name == 'JS_OBJECT_CLASS_NAME') {
       String name = backend.namer.getRuntimeTypeName(compiler.objectClass);
-      stack.add(addConstantString(node, name));
+      stack.add(addConstantString(name));
     } else if (name == 'JS_NULL_CLASS_NAME') {
       String name = backend.namer.getRuntimeTypeName(compiler.nullClass);
-      stack.add(addConstantString(node, name));
+      stack.add(addConstantString(name));
     } else if (name == 'JS_FUNCTION_CLASS_NAME') {
       String name = backend.namer.getRuntimeTypeName(compiler.functionClass);
-      stack.add(addConstantString(node, name));
+      stack.add(addConstantString(name));
     } else if (name == 'JS_OPERATOR_AS_PREFIX') {
-      stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
+      stack.add(addConstantString(backend.namer.operatorAsPrefix()));
     } else if (name == 'JS_SIGNATURE_NAME') {
-      stack.add(addConstantString(node, backend.namer.operatorSignature()));
+      stack.add(addConstantString(backend.namer.operatorSignature()));
     } else if (name == 'JS_FUNCTION_TYPE_TAG') {
-      stack.add(addConstantString(node, backend.namer.functionTypeTag()));
+      stack.add(addConstantString(backend.namer.functionTypeTag()));
     } else if (name == 'JS_FUNCTION_TYPE_VOID_RETURN_TAG') {
-      stack.add(addConstantString(node,
-                                  backend.namer.functionTypeVoidReturnTag()));
+      stack.add(addConstantString(backend.namer.functionTypeVoidReturnTag()));
     } else if (name == 'JS_FUNCTION_TYPE_RETURN_TYPE_TAG') {
-      stack.add(addConstantString(node,
-                                  backend.namer.functionTypeReturnTypeTag()));
+      stack.add(addConstantString(backend.namer.functionTypeReturnTypeTag()));
     } else if (name ==
                'JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG') {
-      stack.add(addConstantString(node,
+      stack.add(addConstantString(
           backend.namer.functionTypeRequiredParametersTag()));
     } else if (name ==
                'JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG') {
-      stack.add(addConstantString(node,
+      stack.add(addConstantString(
           backend.namer.functionTypeOptionalParametersTag()));
     } else if (name ==
                'JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG') {
-      stack.add(addConstantString(node,
+      stack.add(addConstantString(
           backend.namer.functionTypeNamedParametersTag()));
     } else if (name == 'JS_DART_OBJECT_CONSTRUCTOR') {
       handleForeignDartObjectJsConstructorFunction(node);
     } else if (name == 'JS_IS_INDEXABLE_FIELD_NAME') {
       Element element = compiler.findHelper(
           'JavaScriptIndexingBehavior');
-      stack.add(addConstantString(node, backend.namer.operatorIs(element)));
+      stack.add(addConstantString(backend.namer.operatorIs(element)));
     } else if (name == 'JS_CURRENT_ISOLATE') {
       handleForeignJsCurrentIsolate(node);
     } else if (name == 'JS_GET_NAME') {
@@ -3550,11 +3572,11 @@
     if (selector.isSetter()) publicName += '=';
 
     Constant nameConstant = constantSystem.createString(
-        new DartString.literal(publicName), node);
+        new DartString.literal(publicName));
 
     String internalName = backend.namer.invocationName(selector);
     Constant internalNameConstant =
-        constantSystem.createString(new DartString.literal(internalName), node);
+        constantSystem.createString(new DartString.literal(internalName));
 
     Element createInvocationMirror = backend.getCreateInvocationMirror();
     var argumentsInstruction = buildLiteralList(arguments);
@@ -3563,8 +3585,7 @@
     var argumentNames = new List<HInstruction>();
     for (String argumentName in selector.namedArguments) {
       Constant argumentNameConstant =
-          constantSystem.createString(new DartString.literal(argumentName),
-                                      node);
+          constantSystem.createString(new DartString.literal(argumentName));
       argumentNames.add(graph.addConstant(argumentNameConstant, compiler));
     }
     var argumentNamesInstruction = buildLiteralList(argumentNames);
@@ -3662,7 +3683,7 @@
       // segmentation of '$'.
       String substitutionNameString = backend.namer.getNameForRti(cls);
       HInstruction substitutionName = graph.addConstantString(
-          new LiteralDartString(substitutionNameString), null, compiler);
+          new LiteralDartString(substitutionNameString), compiler);
       pushInvokeStatic(null,
                        backend.getGetRuntimeTypeArgument(),
                        [target, substitutionName, index],
@@ -3800,10 +3821,12 @@
   handleNewSend(NewExpression node) {
     Send send = node.send;
     bool isFixedList = false;
+    bool isFixedListConstructorCall =
+        Elements.isFixedListConstructorCall(elements[send], send, compiler);
 
     TypeMask computeType(element) {
       Element originalElement = elements[send];
-      if (Elements.isFixedListConstructorCall(originalElement, send, compiler)
+      if (isFixedListConstructorCall
           || Elements.isFilledListConstructorCall(
                   originalElement, send, compiler)) {
         isFixedList = true;
@@ -3878,31 +3901,66 @@
       return;
     }
 
-    ClassElement cls = constructor.getEnclosingClass();
-    if (cls.isAbstract && constructor.isGenerativeConstructor()) {
-      generateAbstractClassInstantiationError(send, cls.name);
-      return;
-    }
-    if (backend.classNeedsRti(cls)) {
-      Link<DartType> typeVariable = cls.typeVariables;
-      expectedType.typeArguments.forEach((DartType argument) {
-        inputs.add(analyzeTypeArgument(argument));
-        typeVariable = typeVariable.tail;
-      });
-      assert(typeVariable.isEmpty);
-    }
-
     if (constructor.isFactoryConstructor() &&
         !expectedType.typeArguments.isEmpty) {
       compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
     }
-    TypeMask elementType = computeType(constructor);
-    addInlinedInstantiation(expectedType);
-    pushInvokeStatic(node, constructor, inputs, elementType);
-    removeInlinedInstantiation(expectedType);
-    HInstruction newInstance = stack.last;
 
+    TypeMask elementType = computeType(constructor);
+    if (isFixedListConstructorCall) {
+      if (!inputs[0].isNumber(compiler)) {
+        HTypeConversion conversion = new HTypeConversion(
+          null, HTypeConversion.ARGUMENT_TYPE_CHECK, backend.numType,
+          inputs[0], null);
+        add(conversion);
+        inputs[0] = conversion;
+      }
+      js.Expression code = js.js.parseForeignJS('Array(#)');
+      var behavior = new native.NativeBehavior();
+      behavior.typesReturned.add(expectedType);
+      // The allocation can throw only if the given length is a double
+      // or negative.
+      bool canThrow = true;
+      if (inputs[0].isInteger(compiler) && inputs[0] is HConstant) {
+        var constant = inputs[0];
+        if (constant.constant.value >= 0) canThrow = false;
+      }
+      HForeign foreign = new HForeign(
+          code, elementType, inputs, nativeBehavior: behavior,
+          canThrow: canThrow);
+      push(foreign);
+      TypesInferrer inferrer = compiler.typesTask.typesInferrer;
+      if (inferrer.isFixedArrayCheckedForGrowable(send)) {
+        js.Expression code = js.js.parseForeignJS(r'#.fixed$length = init');
+        // We set the instruction as [canThrow] to avoid it being dead code.
+        // We need a finer grained side effect.
+        add(new HForeign(
+              code, backend.nullType, [stack.last], canThrow: true));
+      }
+    } else {
+      ClassElement cls = constructor.getEnclosingClass();
+      if (cls.isAbstract && constructor.isGenerativeConstructor()) {
+        generateAbstractClassInstantiationError(send, cls.name);
+        return;
+      }
+      if (backend.classNeedsRti(cls)) {
+        Link<DartType> typeVariable = cls.typeVariables;
+        expectedType.typeArguments.forEach((DartType argument) {
+          inputs.add(analyzeTypeArgument(argument));
+          typeVariable = typeVariable.tail;
+        });
+        assert(typeVariable.isEmpty);
+      }
+
+      addInlinedInstantiation(expectedType);
+      pushInvokeStatic(node, constructor, inputs, elementType);
+      removeInlinedInstantiation(expectedType);
+    }
+    HInstruction newInstance = stack.last;
     if (isFixedList) {
+      // Overwrite the element type, in case the allocation site has
+      // been inlined.
+      newInstance.instructionType = elementType;
       JavaScriptItemCompilationContext context = work.compilationContext;
       context.allocatedFixedLists.add(newInstance);
     }
@@ -3911,7 +3969,7 @@
     // not know about the type argument. Therefore we special case
     // this constructor to have the setRuntimeTypeInfo called where
     // the 'new' is done.
-    if (isJSArrayTypedConstructor &&
+    if ((isFixedListConstructorCall || isJSArrayTypedConstructor) &&
         backend.classNeedsRti(compiler.listClass)) {
       handleListConstructor(type, send, newInstance);
     }
@@ -4034,9 +4092,9 @@
     }
   }
 
-  HConstant addConstantString(Node node, String string) {
+  HConstant addConstantString(String string) {
     DartString dartString = new DartString.literal(string);
-    Constant constant = constantSystem.createString(dartString, node);
+    Constant constant = constantSystem.createString(dartString);
     return graph.addConstant(constant, compiler);
   }
 
@@ -4088,7 +4146,7 @@
   }
 
   void generateError(Node node, String message, Element helper) {
-    HInstruction errorMessage = addConstantString(node, message);
+    HInstruction errorMessage = addConstantString(message);
     pushInvokeStatic(node, helper, [errorMessage]);
   }
 
@@ -4113,11 +4171,10 @@
                                   List<String> existingArguments}) {
     Element helper = backend.getThrowNoSuchMethod();
     Constant receiverConstant =
-        constantSystem.createString(new DartString.empty(), diagnosticNode);
+        constantSystem.createString(new DartString.empty());
     HInstruction receiver = graph.addConstant(receiverConstant, compiler);
     DartString dartString = new DartString.literal(methodName);
-    Constant nameConstant =
-        constantSystem.createString(dartString, diagnosticNode);
+    Constant nameConstant = constantSystem.createString(dartString);
     HInstruction name = graph.addConstant(nameConstant, compiler);
     if (argumentValues == null) {
       argumentValues = <HInstruction>[];
@@ -4134,8 +4191,7 @@
       List<HInstruction> existingNames = <HInstruction>[];
       for (String name in existingArguments) {
         HInstruction nameConstant =
-            graph.addConstantString(new DartString.literal(name),
-                                    diagnosticNode, compiler);
+            graph.addConstantString(new DartString.literal(name), compiler);
         existingNames.add(nameConstant);
       }
       existingNamesList = buildLiteralList(existingNames);
@@ -4501,7 +4557,7 @@
   }
 
   void visitLiteralString(LiteralString node) {
-    stack.add(graph.addConstantString(node.dartString, node, compiler));
+    stack.add(graph.addConstantString(node.dartString, compiler));
   }
 
   void visitLiteralSymbol(LiteralSymbol node) {
@@ -4513,7 +4569,7 @@
   void visitStringJuxtaposition(StringJuxtaposition node) {
     if (!node.isInterpolation) {
       // This is a simple string with no interpolations.
-      stack.add(graph.addConstantString(node.dartString, node, compiler));
+      stack.add(graph.addConstantString(node.dartString, compiler));
       return;
     }
     StringBuilderVisitor stringBuilder = new StringBuilderVisitor(this, node);
@@ -5156,7 +5212,6 @@
     HBasicBlock expressionEnd = close(switchInstruction);
     LocalsHandler savedLocals = localsHandler;
 
-    List<List<Constant>> matchExpressions = <List<Constant>>[];
     List<HStatementInformation> statements = <HStatementInformation>[];
     bool hasDefault = false;
     Element getFallThroughErrorElement = backend.getFallThroughError();
@@ -5164,16 +5219,13 @@
         new HasNextIterator<Node>(switchCases.iterator);
     while (caseIterator.hasNext) {
       SwitchCase switchCase = caseIterator.next();
-      List<Constant> caseConstants = <Constant>[];
       HBasicBlock block = graph.addNewBlock();
       for (Constant constant in getConstants(switchCase)) {
-        caseConstants.add(constant);
         HConstant hConstant = graph.addConstant(constant, compiler);
         switchInstruction.inputs.add(hConstant);
         hConstant.usedBy.add(switchInstruction);
         expressionEnd.addSuccessor(block);
       }
-      matchExpressions.add(caseConstants);
 
       if (isDefaultCase(switchCase)) {
         // An HSwitch has n inputs and n+1 successors, the last being the
@@ -5231,7 +5283,6 @@
       close(new HGoto());
       defaultCase.addSuccessor(joinBlock);
       caseHandlers.add(savedLocals);
-      matchExpressions.add(<Constant>[]);
       statements.add(new HSubGraphBlockInformation(new SubGraph(
           defaultCase, defaultCase)));
     }
@@ -5254,7 +5305,6 @@
                                                              expressionEnd));
     expressionStart.setBlockFlow(
         new HSwitchBlockInformation(expressionInfo,
-                                    matchExpressions,
                                     statements,
                                     jumpHandler.target,
                                     jumpHandler.labels()),
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 68646d9..1af7f49 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -19,23 +19,33 @@
     // TODO(sra): Attaching positions might be cleaner if the source position
     // was on a wrapping node.
     SourceFile sourceFile = sourceFileOfElement(element);
-    Node expression = element.implementation.parseNode(backend.compiler);
-    Token beginToken;
-    Token endToken;
-    if (expression == null) {
-      // Synthesized node. Use the enclosing element for the location.
-      beginToken = endToken = element.position();
+    if (compiler.irBuilder.hasIr(element)) {
+      IrFunction function = compiler.irBuilder.getIr(element);
+      node.sourcePosition = new OffsetSourceFileLocation(
+          sourceFile, function.offset, function.sourceName);
+      node.endSourcePosition = new OffsetSourceFileLocation(
+          sourceFile, function.endOffset);
     } else {
-      beginToken = expression.getBeginToken();
-      endToken = expression.getEndToken();
-    }
-    // TODO(podivilov): find the right sourceFile here and remove offset checks
-    // below.
-    if (beginToken.charOffset < sourceFile.length) {
-      node.sourcePosition = new SourceFileLocation(sourceFile, beginToken);
-    }
-    if (endToken.charOffset < sourceFile.length) {
-      node.endSourcePosition = new SourceFileLocation(sourceFile, endToken);
+      Node expression = element.implementation.parseNode(backend.compiler);
+      Token beginToken;
+      Token endToken;
+      if (expression == null) {
+        // Synthesized node. Use the enclosing element for the location.
+        beginToken = endToken = element.position();
+      } else {
+        beginToken = expression.getBeginToken();
+        endToken = expression.getEndToken();
+      }
+      // TODO(podivilov): find the right sourceFile here and remove offset
+      // checks below.
+      if (beginToken.charOffset < sourceFile.length) {
+        node.sourcePosition =
+            new TokenSourceFileLocation(sourceFile, beginToken);
+      }
+      if (endToken.charOffset < sourceFile.length) {
+        node.endSourcePosition =
+            new TokenSourceFileLocation(sourceFile, endToken);
+      }
     }
     return node;
   }
@@ -179,18 +189,6 @@
     return generateAtUseSite.contains(instruction);
   }
 
-  bool isNonNegativeInt32Constant(HInstruction instruction) {
-    if (instruction.isConstantInteger()) {
-      HConstant constantInstruction = instruction;
-      PrimitiveConstant primitiveConstant = constantInstruction.constant;
-      int value = primitiveConstant.value;
-      if (value >= 0 && value < (1 << 31)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   bool hasNonBitOpUser(HInstruction instruction, Set<HPhi> phiSet) {
     for (HInstruction user in instruction.usedBy) {
       if (user is HPhi) {
@@ -205,19 +203,10 @@
     return false;
   }
 
-  // We want the outcome of bit-operations to be positive. However, if
-  // the result of a bit-operation is only used by other bit
-  // operations we do not have to convert to an unsigned
-  // integer. Also, if we are using & with a positive constant we know
-  // that the result is positive already and need no conversion.
-  bool requiresUintConversion(HInstruction instruction) {
-    if (instruction is HBitAnd) {
-      HBitAnd bitAnd = instruction;
-      if (isNonNegativeInt32Constant(bitAnd.left) ||
-          isNonNegativeInt32Constant(bitAnd.right)) {
-        return false;
-      }
-    }
+  bool requiresUintConversion(instruction) {
+    if (instruction.isUInt31(compiler)) return false;
+    // If the result of a bit-operation is only used by other bit
+    // operations, we do not have to convert to an unsigned integer.
     return hasNonBitOpUser(instruction, new Set<HPhi>());
   }
 
@@ -675,20 +664,30 @@
     }
     js.Expression key = pop();
     List<js.SwitchClause> cases = <js.SwitchClause>[];
+    HSwitch switchInstruction = info.expression.end.last;
+    List<HInstruction> inputs = switchInstruction.inputs;
+    List<HBasicBlock> successors = switchInstruction.block.successors;
 
     js.Block oldContainer = currentContainer;
-    for (int i = 0; i < info.matchExpressions.length; i++) {
-      for (Constant constant in info.matchExpressions[i]) {
-        generateConstant(constant);
+    for (int inputIndex = 1, statementIndex = 0;
+         inputIndex < inputs.length;
+         statementIndex++) {
+      HBasicBlock successor = successors[inputIndex - 1];
+      do {
+        visit(inputs[inputIndex]);
         currentContainer = new js.Block.empty();
         cases.add(new js.Case(pop(), currentContainer));
-      }
-      if (i == info.matchExpressions.length - 1) {
-        currentContainer = new js.Block.empty();
-        cases.add(new js.Default(currentContainer));
-      }
-      generateStatements(info.statements[i]);
+        inputIndex++;
+      } while ((successors[inputIndex - 1] == successor)
+               && (inputIndex < inputs.length));
+
+      generateStatements(info.statements[statementIndex]);
     }
+
+    currentContainer = new js.Block.empty();
+    cases.add(new js.Default(currentContainer));
+    generateStatements(info.statements.last);
+
     currentContainer = oldContainer;
 
     js.Statement result = new js.Switch(key, cases);
@@ -1198,7 +1197,7 @@
   // shift operator to achieve this.
   visitBitInvokeBinary(HBinaryBitOp node, String op) {
     visitInvokeBinary(node, op);
-    if (requiresUintConversion(node)) {
+    if (op != '>>>' && requiresUintConversion(node)) {
       push(new js.Binary(">>>", pop(), new js.LiteralNumber("0")), node);
     }
   }
@@ -1257,6 +1256,7 @@
   visitBitOr(HBitOr node)           => visitBitInvokeBinary(node, '|');
   visitBitXor(HBitXor node)         => visitBitInvokeBinary(node, '^');
   visitShiftLeft(HShiftLeft node)   => visitBitInvokeBinary(node, '<<');
+  visitShiftRight(HShiftRight node) => visitBitInvokeBinary(node, '>>>');
 
   visitNegate(HNegate node)         => visitInvokeUnary(node, '-');
 
@@ -1983,10 +1983,14 @@
     }
     js.Call value = new js.Call(jsHelper, arguments);
     attachLocation(value, location);
-    // BUG(4906): Using throw here adds to the size of the generated code
+    // BUG(4906): Using throw/return here adds to the size of the generated code
     // but it has the advantage of explicitly telling the JS engine that
     // this code path will terminate abruptly. Needs more work.
-    pushStatement(new js.Throw(value));
+    if (helperName == 'wrapException') {
+      pushStatement(new js.Throw(value));
+    } else {
+      pushStatement(new js.Return(value));
+    }
   }
 
   visitThrowExpression(HThrowExpression node) {
@@ -2509,7 +2513,7 @@
         String methodName =
             backend.namer.invocationName(node.receiverTypeCheckSelector);
         js.Expression call = jsPropertyCall(pop(), methodName, []);
-        pushStatement(new js.Throw(call));
+        pushStatement(new js.Return(call));
       }
       currentContainer = oldContainer;
       body = unwrapStatement(body);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
new file mode 100644
index 0000000..4d97830
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_builder.dart
@@ -0,0 +1,128 @@
+// 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 ssa;
+
+class SsaFromIrBuilderTask extends CompilerTask {
+  SsaFromIrBuilderTask(Compiler compiler) : super(compiler);
+
+  HGraph build(CodegenWorkItem work) {
+    return measure(() {
+      Element element = work.element.implementation;
+      return compiler.withCurrentElement(element, () {
+        HInstruction.idCounter = 0;
+        SsaFromIrBuilder builder = new SsaFromIrBuilder(compiler, element);
+
+        HGraph graph;
+        ElementKind kind = element.kind;
+        if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+          throw "Build HGraph for constructor from IR";
+//          graph = compileConstructor(builder, work);
+        } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY ||
+                   kind == ElementKind.FUNCTION ||
+                   kind == ElementKind.GETTER ||
+                   kind == ElementKind.SETTER) {
+          graph = builder.buildMethod();
+        } else if (kind == ElementKind.FIELD) {
+          throw "Build HGraph for field from IR";
+//          assert(!element.isInstanceMember());
+//          graph = builder.buildLazyInitializer(element);
+        } else {
+          compiler.internalErrorOnElement(element,
+                                          'unexpected element kind $kind');
+        }
+        assert(graph.isValid());
+        // TODO(lry): for default arguments, register constants in backend.
+        // TODO(lry): tracing (factor out code in SsaBuilderTask).
+        return graph;
+      });
+    });
+  }
+}
+
+/**
+ * This builder generates SSA nodes for elements that have an IR representation.
+ * It mixes in [SsaGraphBuilderMixin] to share functionality with the
+ * [SsaBuilder] that creates SSA nodes from trees.
+ */
+class SsaFromIrBuilder
+    extends IrNodesVisitor<HInstruction> with SsaGraphBuilderMixin {
+  final Compiler compiler;
+
+  final Element sourceElement;
+
+  SsaFromIrBuilder(this.compiler, this.sourceElement);
+
+  /**
+   * Maps IR nodes ot the generated [HInstruction]. Because the IR is itself
+   * in an SSA form, the arguments of an [IrNode] have already been visited
+   * prior to the node. This map is used to obtain the corresponding generated
+   * SSA node.
+   */
+  final Map<IrNode, HInstruction> generated = new Map<IrNode, HInstruction>();
+
+  HInstruction recordGenerated(IrNode irNode, HInstruction ssaNode) {
+    return generated[irNode] = ssaNode;
+  }
+
+  HInstruction attachPosition(HInstruction target, IrNode node) {
+    target.sourcePosition = sourceFileLocation(node);
+    return target;
+  }
+
+  SourceFileLocation sourceFileLocation(IrNode node) {
+    Element element = sourceElement;
+    // TODO(johnniwinther): remove the 'element.patch' hack.
+    if (element is FunctionElement) {
+      FunctionElement functionElement = element;
+      if (functionElement.patch != null) element = functionElement.patch;
+    }
+    Script script = element.getCompilationUnit().script;
+    SourceFile sourceFile = script.file;
+    SourceFileLocation location =
+        new OffsetSourceFileLocation(sourceFile, node.offset, node.sourceName);
+    if (!location.isValid()) {
+      throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
+          {'offset': node.offset,
+           'fileName': sourceFile.filename,
+           'length': sourceFile.length});
+    }
+    return location;
+  }
+
+  HGraph buildMethod() {
+    graph.calledInLoop = compiler.world.isCalledInLoop(sourceElement);
+
+    open(graph.entry);
+    HBasicBlock block = graph.addNewBlock();
+    close(new HGoto()).addSuccessor(block);
+    open(block);
+
+    IrFunction function = compiler.irBuilder.getIr(sourceElement);
+    visitAll(function.statements);
+    if (!isAborted()) closeAndGotoExit(new HGoto());
+    graph.finalize();
+    return graph;
+  }
+
+  HInstruction visitIrConstant(IrConstant node) {
+    return recordGenerated(node, graph.addConstant(node.value, compiler));
+  }
+
+  HInstruction visitIrReturn(IrReturn node) {
+    assert(isReachable);
+    HInstruction value = generated[node.value];
+    // TODO(lry): add code for dynamic type check.
+    // value = potentiallyCheckType(value, returnType);
+    closeAndGotoExit(attachPosition(new HReturn(value), node));
+  }
+
+  HInstruction visitNode(IrNode node) {
+    abort(node);
+  }
+
+  void abort(IrNode node) {
+    throw 'Cannot build SSA from IR for $node';
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart
new file mode 100644
index 0000000..9a67f39
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ssa/from_ir_inliner.dart
@@ -0,0 +1,76 @@
+// 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 ssa;
+
+class SsaFromIrInliner extends IrNodesVisitor {
+
+  final SsaBuilder builder;
+
+  SsaFromIrInliner(this.builder);
+
+  final Map<IrNode, HInstruction> emitted = new Map<IrNode, HInstruction>();
+
+  Compiler get compiler => builder.compiler;
+
+  void visitIrReturn(IrReturn node) {
+    HInstruction hValue = emitted[node.value];
+    builder.localsHandler.updateLocal(builder.returnElement, hValue);
+  }
+
+  void visitIrConstant(IrConstant node) {
+    emitted[node] = builder.graph.addConstant(node.value, compiler);
+  }
+
+  void visitNode(IrNode node) {
+    compiler.internalError('Unexpected IrNode $node');
+  }
+}
+
+class IrInlineWeeder extends IrNodesVisitor {
+  static bool canBeInlined(IrFunction irFunction,
+                           int maxInliningNodes,
+                           bool useMaxInliningNodes) {
+    IrInlineWeeder weeder =
+        new IrInlineWeeder(maxInliningNodes, useMaxInliningNodes);
+    weeder.visitAll(irFunction.statements);
+    return !weeder.tooDifficult;
+  }
+
+  final int maxInliningNodes;
+  final bool useMaxInliningNodes;
+
+  IrInlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes);
+
+  bool seenReturn = false;
+  bool tooDifficult = false;
+  int nodeCount = 0;
+
+  bool registerNode() {
+    if (!useMaxInliningNodes) return true;
+    if (nodeCount++ > maxInliningNodes) {
+      tooDifficult = true;
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  void visitNode(IrNode node) {
+    if (!registerNode()) return;
+    if (seenReturn) {
+      tooDifficult = true;
+    }
+  }
+
+  void visitIrReturn(IrReturn node) {
+    visitNode(node);
+    seenReturn = true;
+  }
+
+  void visitIrFunction(IrFunction 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 b193fa2..e4a4ad8 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -268,7 +268,7 @@
           node.element,
           <HInstruction>[constant, node.inputs[1]],
           node.instructionType);
-    } else if (node.selector.isSetter()) {
+    } else if (selector.isSetter()) {
       instruction = new HInvokeDynamicSetter(
           selector,
           node.element,
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
index 87088e8..54827a9 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
@@ -135,7 +135,7 @@
     // integer or throw an error.
     JavaScriptBackend backend = compiler.backend;
     if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
-      return backend.intType;
+      return backend.uint32Type;
     }
     return super.computeTypeFromInputTypes(instruction, compiler);
   }
@@ -145,7 +145,8 @@
     JavaScriptBackend backend = compiler.backend;
     HInstruction input = instruction.inputs[1];
     if (input.isNumber(compiler)) {
-      return new HBitNot(input, instruction.selector, backend.intType);
+      return new HBitNot(input, instruction.selector,
+                         computeTypeFromInputTypes(instruction, compiler));
     }
     return null;
   }
@@ -208,12 +209,24 @@
       // Even if there is no builtin equivalent instruction, we know
       // the instruction does not have any side effect, and that it
       // can be GVN'ed.
-      instruction.sideEffects.clearAllSideEffects();
-      instruction.sideEffects.clearAllDependencies();
-      instruction.setUseGvn();
+      clearAllSideEffects(instruction);
     }
     return null;
   }
+  
+  void clearAllSideEffects(HInstruction instruction) {
+    instruction.sideEffects.clearAllSideEffects();
+    instruction.sideEffects.clearAllDependencies();
+    instruction.setUseGvn();
+  }
+
+  bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    JavaScriptBackend backend = compiler.backend;
+    return left.isPositiveIntegerOrNull(compiler)
+        && right.isPositiveIntegerOrNull(compiler);
+  }
 
   HInstruction newBuiltinVariant(HInvokeDynamic instruction, Compiler compiler);
 }
@@ -221,6 +234,15 @@
 class AddSpecializer extends BinaryArithmeticSpecializer {
   const AddSpecializer();
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    if (inputsArePositiveIntegers(instruction, compiler)) {
+      JavaScriptBackend backend = compiler.backend;
+      return backend.positiveIntType;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   BinaryOperation operation(ConstantSystem constantSystem) {
     return constantSystem.add;
   }
@@ -262,6 +284,15 @@
 class ModuloSpecializer extends BinaryArithmeticSpecializer {
   const ModuloSpecializer();
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    if (inputsArePositiveIntegers(instruction, compiler)) {
+      JavaScriptBackend backend = compiler.backend;
+      return backend.positiveIntType;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   BinaryOperation operation(ConstantSystem constantSystem) {
     return constantSystem.modulo;
   }
@@ -280,6 +311,15 @@
     return constantSystem.multiply;
   }
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    if (inputsArePositiveIntegers(instruction, compiler)) {
+      JavaScriptBackend backend = compiler.backend;
+      return backend.positiveIntType;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
     return new HMultiply(
@@ -310,6 +350,15 @@
     return constantSystem.truncatingDivide;
   }
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    if (inputsArePositiveIntegers(instruction, compiler)) {
+      JavaScriptBackend backend = compiler.backend;
+      return backend.positiveIntType;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
     // Truncating divide does not have a JS equivalent.    
@@ -327,10 +376,24 @@
     HInstruction left = instruction.inputs[1];
     JavaScriptBackend backend = compiler.backend;
     if (left.isPrimitiveOrNull(compiler)) {
-      return backend.intType;
+      return backend.uint32Type;
     }
     return super.computeTypeFromInputTypes(instruction, compiler);
   }
+
+  bool argumentLessThan32(HInstruction instruction) {
+    if (!instruction.isConstantInteger()) return false;
+    HConstant rightConstant = instruction;
+    IntConstant intConstant = rightConstant.constant;
+    int count = intConstant.value;
+    return count >= 0 && count <= 31;
+  }
+
+  bool isPositive(HInstruction instruction, Compiler compiler) {
+    // TODO: We should use the value range analysis. Currently, ranges
+    // are discarded just after the analysis.
+    return instruction.isPositiveInteger(compiler);
+  }
 }
 
 class ShiftLeftSpecializer extends BinaryBitOpSpecializer {
@@ -344,9 +407,14 @@
                                    Compiler compiler) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
-    if (!left.isNumber(compiler)) return null;
-    if (argumentLessThan32(right)) {
-      return newBuiltinVariant(instruction, compiler);
+    if (left.isNumber(compiler)) {
+      if (argumentLessThan32(right)) {
+        return newBuiltinVariant(instruction, compiler);
+      }
+      // Even if there is no builtin equivalent instruction, we know
+      // the instruction does not have any side effect, and that it
+      // can be GVN'ed.
+      clearAllSideEffects(instruction);
     }
     return null;
   }
@@ -356,25 +424,44 @@
     JavaScriptBackend backend = compiler.backend;
     return new HShiftLeft(
         instruction.inputs[1], instruction.inputs[2],
-        instruction.selector, backend.intType);
-  }
-
-  bool argumentLessThan32(HInstruction instruction) {
-    if (!instruction.isConstantInteger()) return false;
-    HConstant rightConstant = instruction;
-    IntConstant intConstant = rightConstant.constant;
-    int count = intConstant.value;
-    return count >= 0 && count <= 31;
+        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
   }
 }
 
 class ShiftRightSpecializer extends BinaryBitOpSpecializer {
   const ShiftRightSpecializer();
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    JavaScriptBackend backend = compiler.backend;
+    if (left.isUInt32(compiler)) return left.instructionType;
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
+  HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
+                                   Compiler compiler) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    if (left.isNumber(compiler)) {
+      if (argumentLessThan32(right) && isPositive(left, compiler)) {
+        return newBuiltinVariant(instruction, compiler);
+      }
+      // Even if there is no builtin equivalent instruction, we know
+      // the instruction does not have any side effect, and that it
+      // can be GVN'ed.
+      clearAllSideEffects(instruction);
+    }
+    return null;
+  }
+
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
-    // Shift right cannot be mapped to the native operator easily.    
-    return null;
+    JavaScriptBackend backend = compiler.backend;
+    return new HShiftRight(
+        instruction.inputs[1], instruction.inputs[2],
+        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
   }
 
   BinaryOperation operation(ConstantSystem constantSystem) {
@@ -389,12 +476,23 @@
     return constantSystem.bitOr;
   }
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    JavaScriptBackend backend = compiler.backend;
+    if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
+      return backend.uint31Type;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     return new HBitOr(
         instruction.inputs[1], instruction.inputs[2],
-        instruction.selector, backend.intType);
+        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
   }
 }
 
@@ -405,12 +503,23 @@
     return constantSystem.bitAnd;
   }
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    JavaScriptBackend backend = compiler.backend;
+    if (left.isUInt31(compiler) || right.isUInt31(compiler)) {
+      return backend.uint31Type;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     return new HBitAnd(
         instruction.inputs[1], instruction.inputs[2],
-        instruction.selector, backend.intType);
+        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
   }
 }
 
@@ -421,12 +530,23 @@
     return constantSystem.bitXor;
   }
 
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    HInstruction left = instruction.inputs[1];
+    HInstruction right = instruction.inputs[2];
+    JavaScriptBackend backend = compiler.backend;
+    if (left.isUInt31(compiler) && right.isUInt31(compiler)) {
+      return backend.uint31Type;
+    }
+    return super.computeTypeFromInputTypes(instruction, compiler);
+  }
+
   HInstruction newBuiltinVariant(HInvokeDynamic instruction,
                                  Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     return new HBitXor(
         instruction.inputs[1], instruction.inputs[2],
-        instruction.selector, backend.intType);
+        instruction.selector, computeTypeFromInputTypes(instruction, compiler));
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index c319986..9af57d7 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -55,6 +55,7 @@
   R visitRangeConversion(HRangeConversion node);
   R visitReturn(HReturn node);
   R visitShiftLeft(HShiftLeft node);
+  R visitShiftRight(HShiftRight node);
   R visitStatic(HStatic node);
   R visitStaticStore(HStaticStore node);
   R visitStringConcat(HStringConcat node);
@@ -161,30 +162,10 @@
     return result;
   }
 
-  static TypeMask mapConstantTypeToSsaType(Constant constant,
-                                           Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    if (constant.isNull()) return backend.nullType;
-    if (constant.isBool()) return backend.boolType;
-    if (constant.isInt()) return backend.intType;
-    if (constant.isDouble()) return backend.doubleType;
-    if (constant.isString()) return backend.stringType;
-    if (constant.isList()) return backend.readableArrayType;
-    if (constant.isFunction()) return backend.nonNullType;
-    if (constant.isSentinel()) return backend.nonNullType;
-    // TODO(sra): What is the type of the prototype of an interceptor?
-    if (constant.isInterceptor()) return backend.nonNullType;
-    ObjectConstant objectConstant = constant;
-    if (backend.isInterceptorClass(objectConstant.type.element)) {
-      return backend.nonNullType;
-    }
-    return new TypeMask.nonNullExact(objectConstant.type.element);
-  }
-
   HConstant addConstant(Constant constant, Compiler compiler) {
     HConstant result = constants[constant];
     if (result == null) {
-      TypeMask type = mapConstantTypeToSsaType(constant, compiler);
+      TypeMask type = constant.computeMask(compiler);
       result = new HConstant.internal(constant, type);
       entry.addAtExit(result);
       constants[constant] = result;
@@ -205,10 +186,9 @@
   }
 
   HConstant addConstantString(DartString str,
-                              Node diagnosticNode,
                               Compiler compiler) {
     return addConstant(
-        compiler.backend.constantSystem.createString(str, diagnosticNode),
+        compiler.backend.constantSystem.createString(str),
         compiler);
   }
 
@@ -336,6 +316,7 @@
   visitRangeConversion(HRangeConversion node) => visitCheck(node);
   visitReturn(HReturn node) => visitControlFlow(node);
   visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node);
+  visitShiftRight(HShiftRight node) => visitBinaryBitOp(node);
   visitSubtract(HSubtract node) => visitBinaryArithmetic(node);
   visitSwitch(HSwitch node) => visitControlFlow(node);
   visitStatic(HStatic node) => visitInstruction(node);
@@ -801,6 +782,7 @@
   static const int INDEX_TYPECODE = 27;
   static const int IS_TYPECODE = 28;
   static const int INVOKE_DYNAMIC_TYPECODE = 29;
+  static const int SHIFT_RIGHT_TYPECODE = 30;
 
   HInstruction(this.inputs, this.instructionType)
       : id = idCounter++, usedBy = <HInstruction>[] {
@@ -918,6 +900,29 @@
         && !instructionType.isNullable;
   }
 
+  bool isUInt32(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return !instructionType.isNullable
+        && instructionType.satisfies(backend.jsUInt32Class, compiler);
+  }
+
+  bool isUInt31(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return !instructionType.isNullable
+        && instructionType.satisfies(backend.jsUInt31Class, compiler);
+  }
+
+  bool isPositiveInteger(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return !instructionType.isNullable
+        && instructionType.satisfies(backend.jsPositiveIntClass, compiler);
+  }
+
+  bool isPositiveIntegerOrNull(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.satisfies(backend.jsPositiveIntClass, compiler);
+  }
+
   bool isIntegerOrNull(Compiler compiler) {
     return instructionType.containsOnlyInt(compiler);
   }
@@ -1571,6 +1576,7 @@
 class HForeign extends HInstruction {
   final js.Node codeAst;
   final bool isStatement;
+  final bool _canThrow;
   final native.NativeBehavior nativeBehavior;
 
   HForeign(this.codeAst,
@@ -1578,8 +1584,11 @@
            List<HInstruction> inputs,
            {this.isStatement: false,
             SideEffects effects,
-            native.NativeBehavior nativeBehavior})
-      : this.nativeBehavior = nativeBehavior, super(inputs, type) {
+            native.NativeBehavior nativeBehavior,
+            canThrow: false})
+      : this.nativeBehavior = nativeBehavior,
+        this._canThrow = canThrow,
+        super(inputs, type) {
     if (effects == null && nativeBehavior != null) {
       effects = nativeBehavior.sideEffects;
     }
@@ -1597,7 +1606,9 @@
 
   bool isJsStatement() => isStatement;
   bool canThrow() {
-    return sideEffects.hasSideEffects() || sideEffects.dependsOnSomething();
+    return _canThrow
+        || sideEffects.hasSideEffects()
+        || sideEffects.dependsOnSomething();
   }
 }
 
@@ -1721,6 +1732,17 @@
   bool dataEquals(HInstruction other) => true;
 }
 
+class HShiftRight extends HBinaryBitOp {
+  HShiftRight(left, right, selector, type) : super(left, right, selector, type);
+  accept(HVisitor visitor) => visitor.visitShiftRight(this);
+
+  BinaryOperation operation(ConstantSystem constantSystem)
+      => constantSystem.shiftRight;
+  int typeCode() => HInstruction.SHIFT_RIGHT_TYPECODE;
+  bool typeEquals(other) => other is HShiftRight;
+  bool dataEquals(HInstruction other) => true;
+}
+
 class HBitOr extends HBinaryBitOp {
   HBitOr(left, right, selector, type) : super(left, right, selector, type);
   accept(HVisitor visitor) => visitor.visitBitOr(this);
@@ -2806,13 +2828,11 @@
 
 class HSwitchBlockInformation implements HStatementInformation {
   final HExpressionInformation expression;
-  final List<List<Constant>> matchExpressions;
   final List<HStatementInformation> statements;
   final TargetElement target;
   final List<LabelElement> labels;
 
   HSwitchBlockInformation(this.expression,
-                          this.matchExpressions,
                           this.statements,
                           this.target,
                           this.labels);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 364fdc5..89ec2e7 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -214,7 +214,7 @@
       Element element = backend.jsIndexableLength;
       bool isFixed = isFixedLength(actualReceiver.instructionType, compiler);
       HFieldGet result = new HFieldGet(
-          element, actualReceiver, backend.intType,
+          element, actualReceiver, backend.positiveIntType,
           isAssignable: !isFixed);
       return result;
     } else if (actualReceiver.isConstantMap()) {
@@ -776,8 +776,7 @@
 
     HInstruction folded = graph.addConstant(
         constantSystem.createString(
-            new DartString.concat(leftString.value, rightString.value),
-            node.node),
+            new DartString.concat(leftString.value, rightString.value)),
         compiler);
     if (prefix == null) return folded;
     return new HStringConcat(prefix, folded, node.node, backend.stringType);
@@ -791,7 +790,7 @@
       if (!constant.constant.isPrimitive()) return node;
       PrimitiveConstant primitive = constant.constant;
       return graph.addConstant(constantSystem.createString(
-          primitive.toDartString(), node.node), compiler);
+          primitive.toDartString()), compiler);
     }
     return node;
   }
@@ -831,12 +830,15 @@
                                  HInstruction indexArgument) {
     Compiler compiler = backend.compiler;
     HFieldGet length = new HFieldGet(
-        backend.jsIndexableLength, array, backend.intType,
+        backend.jsIndexableLength, array, backend.positiveIntType,
         isAssignable: !isFixedLength(array.instructionType, compiler));
     indexNode.block.addBefore(indexNode, length);
 
+    TypeMask type = indexArgument.isPositiveInteger(compiler)
+        ? indexArgument.instructionType
+        : backend.positiveIntType;
     HBoundsCheck check = new HBoundsCheck(
-        indexArgument, length, array, backend.intType);
+        indexArgument, length, array, type);
     indexNode.block.addBefore(indexNode, check);
     // If the index input to the bounds check was not known to be an integer
     // then we replace its uses with the bounds check, which is known to be an
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index 5b0cc17..64c9200 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -16,6 +16,7 @@
 import '../js_backend/js_backend.dart';
 import '../native_handler.dart' as native;
 import '../tree/tree.dart';
+import '../ir/ir_nodes.dart';
 import '../types/types.dart';
 import '../universe/universe.dart';
 import '../util/util.dart';
@@ -30,6 +31,8 @@
 import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
 
 part 'builder.dart';
+part 'from_ir_builder.dart';
+part 'from_ir_inliner.dart';
 part 'codegen.dart';
 part 'codegen_helpers.dart';
 part 'interceptor_simplifier.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index 3a86a9d..b56cd35 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -426,6 +426,7 @@
   String visitReturn(HReturn node) => "Return ${temporaryId(node.inputs[0])}";
 
   String visitShiftLeft(HShiftLeft node) => handleInvokeBinary(node, '<<');
+  String visitShiftRight(HShiftRight node) => handleInvokeBinary(node, '>>');
 
   String visitStatic(HStatic node)
       => "Static ${node.element.name}";
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 9ff28dc..82b32ba 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -107,6 +107,24 @@
     return backend.numType;
   }
 
+  TypeMask checkPositiveInteger(HBinaryArithmetic instruction) {
+    HInstruction left = instruction.left;
+    HInstruction right = instruction.right;
+    JavaScriptBackend backend = compiler.backend;    
+    if (left.isPositiveInteger(compiler) && right.isPositiveInteger(compiler)) {
+      return backend.positiveIntType;
+    }
+    return visitBinaryArithmetic(instruction);
+  }
+
+  TypeMask visitMultiply(HMultiply instruction) {
+    return checkPositiveInteger(instruction);
+  }
+
+  TypeMask visitAdd(HAdd instruction) {
+    return checkPositiveInteger(instruction);
+  }
+
   TypeMask visitNegate(HNegate instruction) {
     return instruction.operand.instructionType;
   }
@@ -249,7 +267,7 @@
       if (right.isNumber(compiler)) return false;
       JavaScriptBackend backend = compiler.backend;    
       TypeMask type = right.isIntegerOrNull(compiler)
-          ? backend.intType
+          ? right.instructionType.nonNullable()
           : backend.numType;
       // TODO(ngeoffray): Some number operations don't have a builtin
       // variant and will do the check in their method anyway. We
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
index e36bec1..1e43997 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
@@ -24,8 +24,8 @@
     return new InstructionValue(instruction, this);
   }
 
-  Value newLengthValue(HInstruction instruction) {
-    return new LengthValue(instruction, this);
+  Value newPositiveValue(HInstruction instruction) {
+    return new PositiveValue(instruction, this);
   }
 
   Value newAddValue(Value left, Value right) {
@@ -291,14 +291,11 @@
 }
 
 /**
- * Special value for instructions that represent the length of an
- * array. The difference with an [InstructionValue] is that we know
- * the value is positive.
+ * Special value for instructions whose type is a positive integer.
  */
-class LengthValue extends InstructionValue {
-  LengthValue(HInstruction instruction, info) : super(instruction, info);
+class PositiveValue extends InstructionValue {
+  PositiveValue(HInstruction instruction, info) : super(instruction, info);
   bool get isPositive => true;
-  String toString() => 'Length: $instruction';
 }
 
 /**
@@ -637,13 +634,15 @@
   }
 
   Range visitInstruction(HInstruction instruction) {
-    return info.newUnboundRange();
-  }
-
-  Range visitParameterValue(HParameterValue parameter) {
-    if (!parameter.isInteger(compiler)) return info.newUnboundRange();
-    Value value = info.newInstructionValue(parameter);
-    return info.newNormalizedRange(value, value);
+    if (instruction.isPositiveInteger(compiler)) {
+      return info.newNormalizedRange(
+          info.intZero, info.newPositiveValue(instruction));
+    } else if (instruction.isInteger(compiler)) {
+      InstructionValue value = info.newInstructionValue(instruction);
+      return info.newNormalizedRange(value, value);
+    } else {
+      return info.newUnboundRange();
+    }
   }
 
   Range visitPhi(HPhi phi) {
@@ -682,7 +681,7 @@
     }
     JavaScriptBackend backend = compiler.backend;
     assert(fieldGet.element == backend.jsIndexableLength);
-    LengthValue value = info.newLengthValue(fieldGet);
+    PositiveValue value = info.newPositiveValue(fieldGet);
     // We know this range is above zero. To simplify the analysis, we
     // put the zero value as the lower bound of this range. This
     // allows to easily remove the second bound check in the following
@@ -825,7 +824,7 @@
 
   Range visitCheck(HCheck instruction) {
     if (ranges[instruction.checkedInput] == null) {
-      return info.newUnboundRange();
+      return visitInstruction(instruction);
     }
     return ranges[instruction.checkedInput];
   }
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index d060765..f5eccfd 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -185,7 +185,7 @@
   }
 
   String toString() {
-    return 'Promote ${variable} to ${type}';
+    return 'Promote ${variable} to ${type}${isValid ? '' : ' (invalid)'}';
   }
 }
 
@@ -410,16 +410,18 @@
     }
   }
 
-  void reshowTypePromotions(Node node, Node receiver, Node argument) {
-    for (TypePromotion typePromotion in  getShownTypePromotionsFor(receiver)) {
+  /// Show type promotions from [left] and [right] in [node] given that the
+  /// promoted variables are not potentially mutated in [right].
+  void reshowTypePromotions(Node node, Node left, Node right) {
+    for (TypePromotion typePromotion in  getShownTypePromotionsFor(left)) {
       typePromotion = typePromotion.copy();
-      checkTypePromotion(argument, typePromotion);
+      checkTypePromotion(right, typePromotion);
       showTypePromotion(node, typePromotion);
     }
 
-    for (TypePromotion typePromotion in getShownTypePromotionsFor(argument)) {
+    for (TypePromotion typePromotion in getShownTypePromotionsFor(right)) {
       typePromotion = typePromotion.copy();
-      checkTypePromotion(argument, typePromotion);
+      checkTypePromotion(right, typePromotion);
       showTypePromotion(node, typePromotion);
     }
   }
@@ -931,6 +933,17 @@
       analyze(node.receiver);
       if (!node.isIsNotCheck) {
         Element variable = elements[node.receiver];
+        if (variable == null) {
+          // Look for the variable element within parenthesized expressions.
+          ParenthesizedExpression parentheses =
+              node.receiver.asParenthesizedExpression();
+          while (parentheses != null) {
+            variable = elements[parentheses.expression];
+            if (variable != null) break;
+            parentheses = parentheses.expression.asParenthesizedExpression();
+          }
+        }
+
         if (variable != null &&
             (variable.isVariable() || variable.isParameter())) {
           DartType knownType = getKnownType(variable);
@@ -1410,7 +1423,12 @@
   }
 
   DartType visitParenthesizedExpression(ParenthesizedExpression node) {
-    return analyze(node.expression);
+    Expression expression = node.expression;
+    DartType type = analyze(expression);
+    for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) {
+      showTypePromotion(node, typePromotion);
+    }
+    return type;
   }
 
   DartType visitConditional(Conditional node) {
@@ -1422,13 +1440,7 @@
     DartType thenType = analyzeInPromotedContext(condition, thenExpression);
 
     DartType elseType = analyzeNonVoid(node.elseExpression);
-    if (types.isSubtype(thenType, elseType)) {
-      return thenType;
-    } else if (types.isSubtype(elseType, thenType)) {
-      return elseType;
-    } else {
-      return objectType;
-    }
+    return compiler.types.computeLeastUpperBound(thenType, elseType);
   }
 
   visitStringInterpolation(StringInterpolation node) {
@@ -1496,6 +1508,7 @@
     ClassElement cls = type.element;
     if (cls == compiler.doubleClass) return true;
     if (cls == compiler.intClass || cls == compiler.stringClass) return false;
+    if (cls == compiler.typeClass) return true;
     Element equals = cls.lookupMember('==');
     return equals.getEnclosingClass() != compiler.objectClass;
   }
@@ -1550,7 +1563,8 @@
     if (firstCaseType != null &&
         invalidSwitchExpressionType(firstCase, firstCaseType)) {
       compiler.reportError(firstCase.expression,
-          MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS);
+          MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
+          {'type': firstCaseType});
     }
     return StatementType.NOT_RETURNING;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index d22f263..5a2b13f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -1083,6 +1083,10 @@
     throw new UnsupportedError("");
   }
 
+  bool isFixedArrayCheckedForGrowable(Node node) {
+    throw new UnsupportedError("");
+  }
+
   // --- analysis ---
 
   /**
diff --git a/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
index c2e7ada..b013f68 100644
--- a/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
@@ -92,14 +92,16 @@
     return allocationNode == other.allocationNode
         && isNullable == other.isNullable
         && elementType == other.elementType
-        && length == other.length;
+        && length == other.length
+        && forwardTo == other.forwardTo;
   }
 
   int get hashCode {
-    return computeHashCode(allocationNode, isNullable, elementType, length);
+    return computeHashCode(
+        allocationNode, isNullable, elementType, length, forwardTo);
   }
 
   String toString() {
-    return 'Container mask: $elementType $length';
+    return 'Container mask: $elementType length: $length type: $forwardTo';
   }
 }
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 7be08f1..2e99ab4 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -96,7 +96,11 @@
       return cls == compiler.boolClass || cls == backend.boolImplementation;
     }
     if (containsOnlyInt(compiler)) {
-      return cls == compiler.intClass || cls == backend.intImplementation;
+      return cls == compiler.intClass
+          || cls == backend.intImplementation
+          || cls == backend.positiveIntImplementation
+          || cls == backend.uint32Implementation
+          || cls == backend.uint31Implementation;
     }
     if (containsOnlyDouble(compiler)) {
       return cls == compiler.doubleClass
@@ -132,7 +136,10 @@
 
   bool containsOnlyInt(Compiler compiler) {
     return base == compiler.intClass
-        || base == compiler.backend.intImplementation;
+        || base == compiler.backend.intImplementation
+        || base == compiler.backend.positiveIntImplementation
+        || base == compiler.backend.uint31Implementation
+        || base == compiler.backend.uint32Implementation;
   }
 
   bool containsOnlyDouble(Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 1d3ac5c..d1ab26c 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -32,6 +32,7 @@
   void clear();
   Iterable<Element> getCallersOf(Element element);
   bool isCalledOnce(Element element);
+  bool isFixedArrayCheckedForGrowable(Node node);
 }
 
 /**
@@ -52,8 +53,12 @@
   }
 
   TypeMask dynamicTypeCache;
+  TypeMask nonNullTypeCache;
   TypeMask nullTypeCache;
   TypeMask intTypeCache;
+  TypeMask uint32TypeCache;
+  TypeMask uint31TypeCache;
+  TypeMask positiveIntTypeCache;
   TypeMask doubleTypeCache;
   TypeMask numTypeCache;
   TypeMask boolTypeCache;
@@ -74,14 +79,45 @@
     return dynamicTypeCache;
   }
 
+  TypeMask get nonNullType {
+    if (nonNullTypeCache == null) {
+      nonNullTypeCache = new TypeMask.nonNullSubclass(compiler.objectClass);
+    }
+    return nonNullTypeCache;
+  }
+
   TypeMask get intType {
     if (intTypeCache == null) {
-      intTypeCache = new TypeMask.nonNullExact(
+      intTypeCache = new TypeMask.nonNullSubclass(
           compiler.backend.intImplementation);
     }
     return intTypeCache;
   }
 
+  TypeMask get uint32Type {
+    if (uint32TypeCache == null) {
+      uint32TypeCache = new TypeMask.nonNullSubclass(
+          compiler.backend.uint32Implementation);
+    }
+    return uint32TypeCache;
+  }
+
+  TypeMask get uint31Type {
+    if (uint31TypeCache == null) {
+      uint31TypeCache = new TypeMask.nonNullExact(
+          compiler.backend.uint31Implementation);
+    }
+    return uint31TypeCache;
+  }
+
+  TypeMask get positiveIntType {
+    if (positiveIntTypeCache == null) {
+      positiveIntTypeCache = new TypeMask.nonNullSubclass(
+          compiler.backend.positiveIntImplementation);
+    }
+    return positiveIntTypeCache;
+  }
+
   TypeMask get doubleType {
     if (doubleTypeCache == null) {
       doubleTypeCache = new TypeMask.nonNullExact(
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index dee467d..e1d1406 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -37,7 +37,7 @@
   final String message;
   SpannableAssertionFailure(this.node, this.message);
 
-  String toString() => 'Compiler crashed: $message';
+  String toString() => 'Assertion failure: $message';
 }
 
 /**
@@ -284,9 +284,10 @@
   buffer.write(string);
 }
 
-int computeHashCode(part1, [part2, part3, part4]) {
+int computeHashCode(part1, [part2, part3, part4, part5]) {
   return (part1.hashCode
           ^ part2.hashCode
           ^ part3.hashCode
-          ^ part4.hashCode) & 0x3fffffff;
+          ^ part4.hashCode
+          ^ part5.hashCode) & 0x3fffffff;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 6fe713d..62dcce4 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -537,7 +537,7 @@
   m(T t) => const C<T>();
 }
 
-void main() => new C().m(null);  
+void main() => new C().m(null);
 """
 ]);
 
@@ -567,7 +567,7 @@
 
   static const MessageKind SWITCH_CASE_VALUE_OVERRIDES_EQUALS =
       const MessageKind(
-          "Error: 'case' expression type overrides 'operator=='.");
+          "Error: 'case' expression type '#{type}' overrides 'operator =='.");
 
   static const MessageKind INVALID_ARGUMENT_AFTER_NAMED = const MessageKind(
       "Error: Unnamed argument after named argument.");
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index 3eb0459..474d6af 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -102,10 +102,10 @@
 // TODO(eub, sigmund): move the "manager" to be entirely in JS.
 // Running any Dart code outside the context of an isolate gives it
 // the chance to break the isolate abstraction.
-_Manager get _globalState => JS("_Manager", r"$globalState");
+_Manager get _globalState => JS("_Manager", "init.globalState");
 
 set _globalState(_Manager val) {
-  JS("void", r"$globalState = #", val);
+  JS("void", "init.globalState = #", val);
 }
 
 /** State associated with the current manager. See [globalState]. */
diff --git a/sdk/lib/_internal/lib/js_array.dart b/sdk/lib/_internal/lib/js_array.dart
index ec5aef9..9ce29f9 100644
--- a/sdk/lib/_internal/lib/js_array.dart
+++ b/sdk/lib/_internal/lib/js_array.dart
@@ -342,7 +342,7 @@
 
   int get hashCode => Primitives.objectHashCode(this);
 
-  int get length => JS('int', r'#.length', this);
+  int get length => JS('JSUInt32', r'#.length', this);
 
   void set length(int newLength) {
     if (newLength is !int) throw new ArgumentError(newLength);
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 002865d..c62ffd2 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -278,9 +278,12 @@
     var result = new Map();
     for (String className in _classes) {
       var cls = reflectClassByMangledName(className);
-      if (cls is JsClassMirror) {
-        result[cls.simpleName] = cls;
-        cls._owner = this;
+      if (cls is ClassMirror) {
+        cls = cls.originalDeclaration;
+        if (cls is JsClassMirror) {
+          result[cls.simpleName] = cls;
+          cls._owner = this;
+        }
       }
     }
     return _cachedClasses =
@@ -479,6 +482,7 @@
 
 TypeMirror reflectClassByMangledName(String mangledName) {
   String unmangledName = mangledGlobalNames[mangledName];
+  if (mangledName == 'dynamic') return JsMirrorSystem._dynamicType;
   if (unmangledName == null) unmangledName = mangledName;
   return reflectClassByName(s(unmangledName), mangledName);
 }
@@ -492,8 +496,8 @@
   disableTreeShaking();
   int typeArgIndex = mangledName.indexOf("<");
   if (typeArgIndex != -1) {
-    mirror = new JsTypeBoundClassMirror(
-        reflectClassByMangledName(mangledName.substring(0, typeArgIndex)),
+    mirror = new JsTypeBoundClassMirror(reflectClassByMangledName(
+        mangledName.substring(0, typeArgIndex)).originalDeclaration,
         // Remove the angle brackets enclosing the type arguments.
         mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
     JsCache.update(classMirrors, mangledName, mirror);
@@ -539,8 +543,19 @@
   if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) {
     mirror = reflectMixinApplication(mixins, mangledName);
   } else {
-    mirror = new JsClassMirror(
+    ClassMirror classMirror = new JsClassMirror(
         symbol, mangledName, constructorOrInterceptor, fields, fieldsMetadata);
+    List typeVariables =
+        JS('JSExtendableArray|Null', '#.prototype["<>"]', constructor);
+    if (typeVariables == null || typeVariables.length == 0) {
+      mirror = classMirror;
+    } else {
+      String typeArguments = 'dynamic';
+      for (int i = 1; i < typeVariables.length; i++) {
+        typeArguments += ',dynamic';
+      }
+      mirror = new JsTypeBoundClassMirror(classMirror, typeArguments);
+    }
   }
 
   JsCache.update(classMirrors, mangledName, mirror);
diff --git a/sdk/lib/_internal/lib/js_number.dart b/sdk/lib/_internal/lib/js_number.dart
index 1e3955c..b40aa4b 100644
--- a/sdk/lib/_internal/lib/js_number.dart
+++ b/sdk/lib/_internal/lib/js_number.dart
@@ -224,7 +224,7 @@
     // JavaScript only looks at the last 5 bits of the shift-amount. Shifting
     // by 33 is hence equivalent to a shift by 1.
     if (JS('bool', r'# > 31', other)) return 0;
-    return JS('int', r'(# << #) >>> 0', this, other);
+    return JS('JSUInt32', r'(# << #) >>> 0', this, other);
   }
 
   num operator >>(num other) {
@@ -238,28 +238,28 @@
       // Given that 'a' is positive we must not use '>>'. Otherwise a number
       // that has the 31st bit set would be treated as negative and shift in
       // ones.
-      return JS('int', r'# >>> #', this, other);
+      return JS('JSUInt32', r'# >>> #', this, other);
     }
     // For negative numbers we just clamp the shift-by amount. 'a' could be
     // negative but not have its 31st bit set. The ">>" would then shift in
     // 0s instead of 1s. Therefore we cannot simply return 0xFFFFFFFF.
     if (JS('num', '#', other) > 31) other = 31;
-    return JS('int', r'(# >> #) >>> 0', this, other);
+    return JS('JSUInt32', r'(# >> #) >>> 0', this, other);
   }
 
   num operator &(num other) {
     if (other is !num) throw new ArgumentError(other);
-    return JS('int', r'(# & #) >>> 0', this, other);
+    return JS('JSUInt32', r'(# & #) >>> 0', this, other);
   }
 
   num operator |(num other) {
     if (other is !num) throw new ArgumentError(other);
-    return JS('int', r'(# | #) >>> 0', this, other);
+    return JS('JSUInt32', r'(# | #) >>> 0', this, other);
   }
 
   num operator ^(num other) {
     if (other is !num) throw new ArgumentError(other);
-    return JS('int', r'(# ^ #) >>> 0', this, other);
+    return JS('JSUInt32', r'(# ^ #) >>> 0', this, other);
   }
 
   bool operator <(num other) {
@@ -358,10 +358,14 @@
 
   Type get runtimeType => int;
 
-  int operator ~() => JS('int', r'(~#) >>> 0', this);
+  int operator ~() => JS('JSUInt32', r'(~#) >>> 0', this);
 }
 
 class JSDouble extends JSNumber implements double {
   const JSDouble();
   Type get runtimeType => double;
 }
+
+class JSPositiveInt extends JSInt {}
+class JSUInt32 extends JSPositiveInt {}
+class JSUInt31 extends JSUInt32 {}
diff --git a/sdk/lib/_internal/lib/js_rti.dart b/sdk/lib/_internal/lib/js_rti.dart
index d8feff5..d090dea 100644
--- a/sdk/lib/_internal/lib/js_rti.dart
+++ b/sdk/lib/_internal/lib/js_rti.dart
@@ -675,11 +675,11 @@
         return false;
       }
     }
-    sPos = 0;
-    // Check the optional parameters of [t] with the remaing optional parameters
-    // of [s]:
+    tPos = 0;
+    // Check the optional parameters of [t] with the remaining optional
+    // parameters of [s]:
     for (; tPos < tOptionalParametersLen ; sPos++, tPos++) {
-      if (!isAssignable(getIndex(tOptionalParameterTypes, sPos),
+      if (!isAssignable(getIndex(sOptionalParameterTypes, sPos),
                         getIndex(tOptionalParameterTypes, tPos))) {
         return false;
       }
diff --git a/sdk/lib/_internal/lib/native_helper.dart b/sdk/lib/_internal/lib/native_helper.dart
index 799960e..bc77c48 100644
--- a/sdk/lib/_internal/lib/native_helper.dart
+++ b/sdk/lib/_internal/lib/native_helper.dart
@@ -389,6 +389,8 @@
   hooks = applyHooksTransformer(_operaHooksTransformer, hooks);
   hooks = applyHooksTransformer(_safariHooksTransformer, hooks);
 
+  hooks = applyHooksTransformer(_fixDocumentHooksTransformer, hooks);
+
   // TODO(sra): Update ShadowDOM polyfil to use
   // [dartNativeDispatchHooksTransformer] and remove this hook.
   hooks = applyHooksTransformer(_dartExperimentalFixupGetTagHooksTransformer,
@@ -484,14 +486,9 @@
  */
 const _constructorNameFallback = const JS_CONST(r'''
 function getTagFallback(o) {
-  if (o == null) return "Null";
   var constructor = o.constructor;
   if (typeof constructor == "function") {
-    var name = constructor.builtin$cls;
-    if (typeof name == "string") return name;
-    // The constructor is not null or undefined at this point. Try
-    // to grab hold of its name.
-    name = constructor.name;
+    var name = constructor.name;
     // If the name is a non-empty string, we use that as the type name of this
     // object. On Firefox, we often get "Object" as the constructor name even
     // for more specialized objects so we have to fall through to the toString()
@@ -515,11 +512,15 @@
     // TODO(sra): Recognize jsshell.
     if (typeof navigator != "object") return hooks;
 
-    var userAgent = navigator.userAgent;
+    var ua = navigator.userAgent;
     // TODO(antonm): remove a reference to DumpRenderTree.
-    if (userAgent.indexOf("Chrome") >= 0 ||
-        userAgent.indexOf("DumpRenderTree") >= 0) {
-      return hooks;
+    if (ua.indexOf("DumpRenderTree") >= 0) return hooks;
+    if (ua.indexOf("Chrome") >= 0) {
+      // Confirm constructor name is usable for dispatch.
+      function confirm(p) {
+        return typeof window == "object" && window[p] && window[p].name == p;
+      }
+      if (confirm("Window") && confirm("HTMLElement")) return hooks;
     }
 
     hooks.getTag = getTagFallback;
@@ -547,14 +548,6 @@
     var tag = getTag(o);
     var newTag = quickMap[tag];
     if (newTag) return newTag;
-    if (tag == "Document") {
-      // IE calls both HTML and XML documents "Document", so we check for the
-      // xmlVersion property, which is the empty string on HTML documents.
-      // Since both dart:html classes Document and HtmlDocument share the same
-      // type, we must patch the instances and not the prototype.
-      if (!!o.xmlVersion) return "!Document";
-      return "!HTMLDocument";
-    }
     // Patches for types which report themselves as Objects.
     if (tag == "Object") {
       if (window.DataView && (o instanceof window.DataView)) return "DataView";
@@ -563,7 +556,6 @@
   }
 
   function prototypeForTagIE(tag) {
-    if (tag == "Document") return null;  // Do not pre-patch Document.
     var constructor = window[tag];
     if (constructor == null) return null;
     return constructor.prototype;
@@ -573,6 +565,32 @@
   hooks.prototypeForTag = prototypeForTagIE;
 }''');
 
+const _fixDocumentHooksTransformer = const JS_CONST(r'''
+function(hooks) {
+  var getTag = hooks.getTag;
+  var prototypeForTag = hooks.prototypeForTag;
+  function getTagFixed(o) {
+    var tag = getTag(o);
+    if (tag == "Document") {
+      // Some browsers and the polymer polyfill call both HTML and XML documents
+      // "Document", so we check for the xmlVersion property, which is the empty
+      // string on HTML documents. Since both dart:html classes Document and
+      // HtmlDocument share the same type, we must patch the instances and not
+      // the prototype.
+      if (!!o.xmlVersion) return "!Document";
+      return "!HTMLDocument";
+    }
+    return tag;
+  }
+
+  function prototypeForTagFixed(tag) {
+    if (tag == "Document") return null;  // Do not pre-patch Document.
+    return prototypeForTag(tag);
+  }
+
+  hooks.getTag = getTagFixed;
+  hooks.prototypeForTag = prototypeForTagFixed;
+}''');
 
 const _firefoxHooksTransformer = const JS_CONST(r'''
 function(hooks) {
@@ -586,7 +604,7 @@
     "DataTransfer": "Clipboard",
     "GeoGeolocation": "Geolocation",
     "WorkerMessageEvent": "MessageEvent",
-    "XMLDocument": "Document"};
+    "XMLDocument": "!Document"};
 
   function getTagFirefox(o) {
     var tag = getTag(o);
diff --git a/sdk/lib/_internal/pub/bin/pub.dart b/sdk/lib/_internal/pub/bin/pub.dart
index e19d9a0..06be67a 100644
--- a/sdk/lib/_internal/pub/bin/pub.dart
+++ b/sdk/lib/_internal/pub/bin/pub.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.
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:io';
 import 'dart:math' as math;
 
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 35a4ac2..604a881 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -4,7 +4,7 @@
 
 library pub.dart2js_transformer;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:io';
 
 import 'package:analyzer/analyzer.dart';
diff --git a/sdk/lib/_internal/pub/lib/src/barback/sources.dart b/sdk/lib/_internal/pub/lib/src/barback/sources.dart
index ece690b..8d2a79a 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/sources.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/sources.dart
@@ -4,7 +4,7 @@
 
 library pub.barback.sources;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:barback/barback.dart';
 import 'package:path/path.dart' as path;
diff --git a/sdk/lib/_internal/pub/lib/src/command.dart b/sdk/lib/_internal/pub/lib/src/command.dart
index 221bc45..ffd7fff 100644
--- a/sdk/lib/_internal/pub/lib/src/command.dart
+++ b/sdk/lib/_internal/pub/lib/src/command.dart
@@ -5,7 +5,7 @@
 library pub.command;
 
 import 'dart:io';
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
diff --git a/sdk/lib/_internal/pub/lib/src/command/build.dart b/sdk/lib/_internal/pub/lib/src/command/build.dart
index 1c9e37e..ef2e80b 100644
--- a/sdk/lib/_internal/pub/lib/src/command/build.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/build.dart
@@ -4,7 +4,7 @@
 
 library pub.command.build;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:barback/barback.dart';
 import 'package:path/path.dart' as path;
diff --git a/sdk/lib/_internal/pub/lib/src/command/cache.dart b/sdk/lib/_internal/pub/lib/src/command/cache.dart
index 97e5dbe..6479781 100644
--- a/sdk/lib/_internal/pub/lib/src/command/cache.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/cache.dart
@@ -4,7 +4,7 @@
 
 library pub.command.cache;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:convert';
 
 import '../command.dart';
diff --git a/sdk/lib/_internal/pub/lib/src/command/help.dart b/sdk/lib/_internal/pub/lib/src/command/help.dart
index f02841f..9467721 100644
--- a/sdk/lib/_internal/pub/lib/src/command/help.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/help.dart
@@ -4,7 +4,7 @@
 
 library pub.command.help;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import '../command.dart';
 import '../exit_codes.dart' as exit_codes;
diff --git a/sdk/lib/_internal/pub/lib/src/command/lish.dart b/sdk/lib/_internal/pub/lib/src/command/lish.dart
index 1cc95ac..6a8b744 100644
--- a/sdk/lib/_internal/pub/lib/src/command/lish.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/lish.dart
@@ -4,7 +4,7 @@
 
 library pub.command.lish;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:http/http.dart' as http;
 
diff --git a/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart b/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
index 31c6916..15fb4da 100644
--- a/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/list_package_dirs.dart
@@ -4,7 +4,7 @@
 
 library pub.command.list_package_dirs;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:convert';
 
 import 'package:path/path.dart' as path;
diff --git a/sdk/lib/_internal/pub/lib/src/command/serve.dart b/sdk/lib/_internal/pub/lib/src/command/serve.dart
index f6df4ce..0d07f7b 100644
--- a/sdk/lib/_internal/pub/lib/src/command/serve.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/serve.dart
@@ -4,7 +4,7 @@
 
 library pub.command.serve;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:barback/barback.dart';
 
diff --git a/sdk/lib/_internal/pub/lib/src/command/uploader.dart b/sdk/lib/_internal/pub/lib/src/command/uploader.dart
index 330efcc..d02472b 100644
--- a/sdk/lib/_internal/pub/lib/src/command/uploader.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/uploader.dart
@@ -4,7 +4,7 @@
 
 library pub.command.uploader;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index 7e1fe28..fcd27b15 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -5,7 +5,7 @@
 /// A library for compiling Dart code and manipulating analyzer parse trees.
 library pub.dart;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:isolate';
 
 import 'package:analyzer/analyzer.dart';
@@ -107,7 +107,7 @@
       'uri': path.toUri(dartPath).toString(),
       'message': message
     }).then((_) => port.first).then((response) {
-      if (response['type'] == 'success') return;
+      if (response['type'] == 'success') return null;
       assert(response['type'] == 'error');
       return new Future.error(
           new CrossIsolateException.deserialize(response['error']));
diff --git a/sdk/lib/_internal/pub/lib/src/entrypoint.dart b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
index b4ef32b..65cecc3 100644
--- a/sdk/lib/_internal/pub/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
@@ -4,7 +4,7 @@
 
 library pub.entrypoint;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/error_group.dart b/sdk/lib/_internal/pub/lib/src/error_group.dart
index ea924e8..ae0410f 100644
--- a/sdk/lib/_internal/pub/lib/src/error_group.dart
+++ b/sdk/lib/_internal/pub/lib/src/error_group.dart
@@ -194,6 +194,11 @@
     return _completer.future.whenComplete(action);
   }
 
+  Future timeout(Duration timeLimit, [void onTimeout()]) {
+    _hasListeners = true;
+    return _completer.future.timeout(timeLimit, onTimeout);
+  }
+
   Stream asStream() {
     _hasListeners = true;
     return _completer.future.asStream();
diff --git a/sdk/lib/_internal/pub/lib/src/git.dart b/sdk/lib/_internal/pub/lib/src/git.dart
index e94e493..e692a47 100644
--- a/sdk/lib/_internal/pub/lib/src/git.dart
+++ b/sdk/lib/_internal/pub/lib/src/git.dart
@@ -5,7 +5,7 @@
 /// Helper functionality for invoking Git.
 library pub.git;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'io.dart';
 import 'log.dart' as log;
 
diff --git a/sdk/lib/_internal/pub/lib/src/http.dart b/sdk/lib/_internal/pub/lib/src/http.dart
index 017b387..969042f 100644
--- a/sdk/lib/_internal/pub/lib/src/http.dart
+++ b/sdk/lib/_internal/pub/lib/src/http.dart
@@ -5,7 +5,7 @@
 /// Helpers for dealing with HTTP.
 library pub.http;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 89179eb..90b06f9 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -5,7 +5,7 @@
 /// Helper functionality to make working with IO easier.
 library pub.io;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:collection';
 import 'dart:convert';
 import 'dart:io';
diff --git a/sdk/lib/_internal/pub/lib/src/log.dart b/sdk/lib/_internal/pub/lib/src/log.dart
index 10f220d..83e5edc 100644
--- a/sdk/lib/_internal/pub/lib/src/log.dart
+++ b/sdk/lib/_internal/pub/lib/src/log.dart
@@ -6,7 +6,7 @@
 library pub.log;
 
 import 'dart:io';
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'io.dart';
 import 'utils.dart';
diff --git a/sdk/lib/_internal/pub/lib/src/oauth2.dart b/sdk/lib/_internal/pub/lib/src/oauth2.dart
index 7146817..1bc1d9f 100644
--- a/sdk/lib/_internal/pub/lib/src/oauth2.dart
+++ b/sdk/lib/_internal/pub/lib/src/oauth2.dart
@@ -4,7 +4,7 @@
 
 library pub.oauth2;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:io';
 
 import 'package:oauth2/oauth2.dart';
diff --git a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
index e88ee93..f45741f 100644
--- a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
+++ b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
@@ -31,8 +31,9 @@
       : super(server),
         _inner = server;
 
-  Future close() => _inner.close();
+  Future close({bool force: false}) => _inner.close(force: force);
 
+  InternetAddress get address => _inner.address;
   int get port => _inner.port;
 
   set sessionTimeout(int timeout) {
@@ -149,6 +150,7 @@
   Future<HttpResponse> addStream(Stream<List<int>> stream) =>
     _inner.addStream(stream);
   Future close() => _inner.close();
+  Future flush() => _inner.flush();
   void write(Object obj) => _inner.write(obj);
   void writeAll(Iterable objects, [String separator = ""]) =>
     _inner.writeAll(objects, separator);
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 4300909..c38295c 100644
--- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
+++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
@@ -44,6 +44,8 @@
 import '../source_registry.dart';
 import '../utils.dart';
 import '../version.dart';
+import 'dependency_queue.dart';
+import 'version_queue.dart';
 import 'version_solver.dart';
 
 /// The top-level solver. Keeps track of the current potential solution, and
@@ -71,8 +73,8 @@
   /// are valid. This keeps track of which versions have been selected so far
   /// and which remain to be tried.
   ///
-  /// Each entry in the list is an ordered [Queue] of versions to try for a
-  /// single package. The first item in the queue is the currently selected
+  /// Each entry in the list is a [VersionQueue], which is an ordered queue of
+  /// versions to try for a single package. It maintains the currently selected
   /// version for that package. When a new dependency is encountered, a queue
   /// of versions of that dependency is pushed onto the end of the list. A
   /// queue is removed from the list once it's empty, indicating that none of
@@ -83,7 +85,7 @@
   /// on an already-selected package, and that constraint doesn't match the
   /// selected version, that will cause the current solution to fail and
   /// trigger backtracking.
-  final _selected = <Queue<PackageId>>[];
+  final _selected = <VersionQueue>[];
 
   /// The number of solutions the solver has tried so far.
   int get attemptedSolutions => _attemptedSolutions;
@@ -154,10 +156,10 @@
   /// in the list will be the currently selected version of that package.
   /// Subsequent items will be tried if it the current selection fails. Returns
   /// the first selected version.
-  PackageId select(Iterable<PackageId> versions) {
-    _selected.add(new Queue<PackageId>.from(versions));
+  PackageId select(VersionQueue versions) {
+    _selected.add(versions);
     logSolve();
-    return versions.first;
+    return versions.current;
   }
 
   /// Returns the the currently selected id for the package [name] or `null` if
@@ -168,7 +170,7 @@
 
     // Look through the current selections.
     for (var i = _selected.length - 1; i >= 0; i--) {
-      if (_selected[i].first.name == name) return _selected[i].first;
+      if (_selected[i].current.name == name) return _selected[i].current;
     }
 
     return null;
@@ -188,13 +190,15 @@
     return new Traverser(this).traverse().catchError((error) {
       if (error is! SolveFailure) throw error;
 
-      if (_backtrack(error)) {
-        _attemptedSolutions++;
-        return _traverseSolution();
-      }
+      return _backtrack(error).then((canTry) {
+        if (canTry) {
+          _attemptedSolutions++;
+          return _traverseSolution();
+        }
 
-      // All out of solutions, so fail.
-      throw error;
+        // All out of solutions, so fail.
+        throw error;
+      });
     });
   });
 
@@ -204,40 +208,47 @@
   /// the next possible solution.
   ///
   /// Returns `true` if there is a new solution to try.
-  bool _backtrack(SolveFailure failure) {
-    var dependers = failure.dependencies.map((dep) => dep.depender).toSet();
+  Future<bool> _backtrack(SolveFailure failure) {
+    // Bail if there is nothing to backtrack to.
+    if (_selected.isEmpty) return new Future.value(false);
 
-    while (!_selected.isEmpty) {
-      _backjump(failure);
+    // Get the set of packages that may have led to this failure.
+    var dependers = _getTransitiveDependers(failure.package);
 
-      // Advance past the current version of the leaf-most package.
-      var previous = _selected.last.removeFirst();
-      if (!_selected.last.isEmpty) {
-        logSolve();
-        return true;
-      }
+    // Advance past the current version of the leaf-most package.
+    advanceVersion() {
+      _backjump(failure, dependers);
+      var previous = _selected.last.current;
+      return _selected.last.advance().then((success) {
+        if (success) {
+          logSolve();
+          return true;
+        }
 
-      logSolve('$previous is last version, backtracking');
+        logSolve('$previous is last version, backtracking');
 
-      // That package has no more versions, so pop it and try the next one.
-      _selected.removeLast();
+        // That package has no more versions, so pop it and try the next one.
+        _selected.removeLast();
+        if (_selected.isEmpty) return false;
+
+        // If we got here, the leafmost package was discarded so we need to
+        // advance the next one.
+        return advanceVersion();
+      });
     }
 
-    return false;
+    return advanceVersion();
   }
 
   /// Walks the selected packages from most to least recent to determine which
   /// ones can be ignored and jumped over by the backtracker. The only packages
-  /// we need to backtrack to are ones that have other versions to try and that
-  /// led (possibly indirectly) to the failure. Everything else can be skipped.
-  void _backjump(SolveFailure failure) {
+  /// we need to backtrack to are ones that led (possibly indirectly) to the
+  /// failure. Everything else can be skipped.
+  void _backjump(SolveFailure failure, Set<String> dependers) {
     for (var i = _selected.length - 1; i >= 0; i--) {
       // Each queue will never be empty since it gets discarded by _backtrack()
       // when that happens.
-      var selected = _selected[i].first;
-
-      // If the package has no more versions, we can jump over it.
-      if (_selected[i].length == 1) continue;
+      var selected = _selected[i].current;
 
       // If we get to the package that failed, backtrack to here.
       if (selected.name == failure.package) {
@@ -248,10 +259,9 @@
 
       // If we get to a package that depends on the failing package, backtrack
       // to here.
-      var path = _getDependencyPath(selected, failure.package);
-      if (path != null) {
+      if (dependers.contains(selected.name)) {
         logSolve('backjump to ${selected.name} because it depends on '
-                 '${failure.package} along $path');
+                 '${failure.package}');
         _selected.removeRange(i + 1, _selected.length);
         return;
       }
@@ -264,40 +274,54 @@
     _selected.removeRange(1, _selected.length);
   }
 
-  /// Determines if [depender] has a direct or indirect dependency on
-  /// [dependent] based on the currently selected versions of all packages.
-  /// Returns a string describing the dependency chain if it does, or `null` if
-  /// there is no dependency.
-  String _getDependencyPath(PackageId depender, String dependent) {
-    // TODO(rnystrom): This is O(n^2) where n is the number of selected
-    // packages. Could store the reverse dependency graph to address that. If
-    // we do that, we need to make sure it gets correctly rolled back when
-    // backtracking occurs.
-    var visited = new Set<String>();
-
-    walkDeps(PackageId package, String currentPath) {
-      if (visited.contains(package.name)) return null;
-      visited.add(package.name);
-
-      var pubspec = cache.getCachedPubspec(package);
-      if (pubspec == null) return null;
+  /// Gets the set of currently selected packages that depend on [dependency]
+  /// either directly or indirectly.
+  ///
+  /// When backtracking, it's only useful to consider changing the version of
+  /// packages who have a dependency on the failed package that triggered
+  /// backtracking. This is used to determine those packages.
+  ///
+  /// We calculate the full set up front before backtracking because during
+  /// backtracking, we will unselect packages and start to lose this
+  /// information in the middle of the process.
+  ///
+  /// For example, consider dependencies A -> B -> C. We've selected A and B
+  /// then encounter a problem with C. We start backtracking. B has no more
+  /// versions so we discard it and keep backtracking to A. When we get there,
+  /// since we've unselected B, we no longer realize that A had a transitive
+  /// dependency on C. We would end up backjumping over A and failing.
+  ///
+  /// Calculating the dependency set up front before we start backtracking
+  /// solves that.
+  Set<String> _getTransitiveDependers(String dependency) {
+    // Generate a reverse dependency graph. For each package, create edges to
+    // each package that depends on it.
+    var dependers = new Map<String, Set<String>>();
+    for (var i = 0; i < _selected.length; i++) {
+      var id = _selected[i].current;
+      var pubspec = cache.getCachedPubspec(id);
+      if (pubspec == null) continue;
+      dependers.putIfAbsent(id.name, () => new Set<String>());
 
       for (var dep in pubspec.dependencies) {
-        if (dep.name == dependent) return currentPath;
-
-        var selected = getSelected(dep.name);
-        // Ignore unselected dependencies. We haven't traversed into them yet,
-        // so they can't affect backjumping.
-        if (selected == null) continue;
-
-        var depPath = walkDeps(selected, '$currentPath -> ${dep.name}');
-        if (depPath != null) return depPath;
+        var depender = dependers.putIfAbsent(dep.name,
+            () => new Set<String>());
+        depender.add(id.name);
       }
-
-      return null;
     }
 
-    return walkDeps(depender, depender.name);
+    // Now walk the depending graph to see which packages transitively depend
+    // on [dependency].
+    var visited = new Set<String>();
+    walk(String package) {
+      // Don't get stuck in cycles.
+      if (visited.contains(package)) return;
+      visited.add(package);
+      var depender = dependers[package].forEach(walk);
+    }
+
+    walk(dependency);
+    return visited;
   }
 
   /// Logs the initial parameters to the solver.
@@ -324,8 +348,7 @@
       if (_selected.isEmpty) {
         message = "* start at root";
       } else {
-        var count = _selected.last.length;
-        message = "* select ${_selected.last.first} ($count versions)";
+        message = "* select ${_selected.last.current}";
       }
     } else {
       // Otherwise, indent it under the current selected package.
@@ -424,79 +447,79 @@
         }
       }
 
-      // Given a package dep, returns a future that completes to a pair of the
-      // dep and the number of versions available for it.
-      getNumVersions(PackageDep dep) {
-        // There is only ever one version of the root package.
-        if (dep.isRoot) {
-          return new Future.value(new Pair<PackageDep, int>(dep, 1));
-        }
-
-        return _solver.cache.getVersions(dep.toRef()).then((versions) {
-          return new Pair<PackageDep, int>(dep, versions.length);
-        }).catchError((error, trace) {
-          // If it fails for any reason, just treat that as no versions. This
-          // will sort this reference higher so that we can traverse into it
-          // and report the error more properly.
-          log.solver("Could not get versions for $dep:\n$error\n\n$trace");
-          return new Pair<PackageDep, int>(dep, 0);
-        });
-      }
-
-      return Future.wait(deps.map(getNumVersions)).then((pairs) {
-        // Future.wait() returns an immutable list, so make a copy.
-        pairs = pairs.toList();
-
-        // Sort in best-first order to minimize backtracking.
-        pairs.sort((a, b) {
-          // Traverse into packages we've already selected first.
-          var aIsSelected = _solver.getSelected(a.first.name) != null;
-          var bIsSelected = _solver.getSelected(b.first.name) != null;
-          if (aIsSelected && !bIsSelected) return -1;
-          if (!aIsSelected && bIsSelected) return 1;
-
-          // Traverse into packages with fewer versions since they will lead to
-          // less backtracking.
-          if (a.last != b.last) return a.last.compareTo(b.last);
-
-          // Otherwise, just sort by name so that it's deterministic.
-          return a.first.name.compareTo(b.first.name);
-        });
-
-        var queue = new Queue<PackageDep>.from(pairs.map((pair) => pair.first));
-        return _traverseDeps(id.name, queue);
-      });
+      return _traverseDeps(id.name, new DependencyQueue(_solver, deps));
     });
   }
 
   /// Traverses the references that [depender] depends on, stored in [deps].
+  ///
   /// Desctructively modifies [deps]. Completes to a list of packages if the
   /// traversal is complete. Completes it to an error if a failure occurred.
   /// Otherwise, recurses.
-  Future<List<PackageId>> _traverseDeps(String depender,
-      Queue<PackageDep> deps) {
+  Future<List<PackageId>> _traverseDeps(String depender, DependencyQueue deps) {
     // Move onto the next package if we've traversed all of these references.
     if (deps.isEmpty) return _traversePackage();
 
     return resetStack(() {
-      var dep = deps.removeFirst();
+      return deps.advance().then((dep) {
+        _validateDependency(dep, depender);
 
-      _validateDependency(dep, depender);
-      var constraint = _addConstraint(dep, depender);
+        // Add the dependency.
+        var dependencies = _getDependencies(dep.name);
+        dependencies.add(new Dependency(depender, dep));
 
-      var selected = _validateSelected(dep, constraint);
-      if (selected != null) {
-        // The selected package version is good, so enqueue it to traverse into
-        // it.
-        _packages.add(selected);
-        return _traverseDeps(depender, deps);
+        var constraint = _getConstraint(dep.name);
+
+        // See if it's possible for a package to match that constraint.
+        if (constraint.isEmpty) {
+          _solver.logSolve('disjoint constraints on ${dep.name}}');
+          throw new DisjointConstraintException(depender, dependencies);
+        }
+
+        var selected = _validateSelected(dep, constraint);
+        if (selected != null) {
+          // The selected package version is good, so enqueue it to traverse
+          // into it.
+          _packages.add(selected);
+          return _traverseDeps(depender, deps);
+        }
+
+        // We haven't selected a version. Try all of the versions that match
+        // the constraints we currently have for this package.
+        var locked = _getValidLocked(dep.name);
+
+        return VersionQueue.create(locked,
+            () => _getAllowedVersions(dep)).then((versions) {
+          _packages.add(_solver.select(versions));
+        });
+      }).then((_) => _traverseDeps(depender, deps));
+    });
+  }
+
+  /// Gets all versions of [dep] that match the current constraints placed on
+  /// it.
+  Future<Iterable<PackageId>> _getAllowedVersions(PackageDep dep) {
+    var constraint = _getConstraint(dep.name);
+    return _solver.cache.getVersions(dep.toRef()).then((versions) {
+      var allowed = versions.where((id) => constraint.allows(id.version));
+
+      if (allowed.isEmpty) {
+        _solver.logSolve('no versions for ${dep.name} match $constraint');
+        throw new NoVersionException(dep.name, constraint,
+            _getDependencies(dep.name));
       }
 
-      // We haven't selected a version. Get all of the versions that match the
-      // constraints we currently have for this package and add them to the
-      // set of solutions to try.
-      return _selectPackage(dep, constraint).then(
-          (_) => _traverseDeps(depender, deps));
+      // If we're doing an upgrade on this package, only allow the latest
+      // version.
+      if (_solver._forceLatest.contains(dep.name)) allowed = [allowed.first];
+
+      // Remove the locked version, if any, since that was already handled.
+      var locked = _getValidLocked(dep.name);
+      if (locked != null) {
+        allowed = allowed.where((dep) => dep.version != locked.version);
+      }
+
+      return allowed;
     });
   }
 
@@ -527,31 +550,6 @@
     }
   }
 
-  /// Adds the version constraint that [depender] places on [dep] to the
-  /// overall constraint that all shared dependencies place on [dep]. Throws a
-  /// [SolveFailure] if that results in an unsolvable constraints.
-  ///
-  /// Returns the combined [VersionConstraint] that all dependers place on the
-  /// package.
-  VersionConstraint _addConstraint(PackageDep dep, String depender) {
-    // Add the dependency.
-    var dependencies = _getDependencies(dep.name);
-    dependencies.add(new Dependency(depender, dep));
-
-    // Determine the overall version constraint.
-    var constraint = dependencies
-        .map((dep) => dep.dep.constraint)
-        .fold(VersionConstraint.any, (a, b) => a.intersect(b));
-
-    // See if it's possible for a package to match that constraint.
-    if (constraint.isEmpty) {
-      _solver.logSolve('disjoint constraints on ${dep.name}');
-      throw new DisjointConstraintException(depender, dependencies);
-    }
-
-    return constraint;
-  }
-
   /// Validates the currently selected package against the new dependency that
   /// [dep] and [constraint] place on it. Returns `null` if there is no
   /// currently selected package, throws a [SolveFailure] if the new reference
@@ -571,42 +569,6 @@
     return selected;
   }
 
-  /// Tries to select a package that matches [dep] and [constraint]. Updates
-  /// the solver state so that we can backtrack from this decision if it turns
-  /// out wrong, but continues traversing with the new selection.
-  ///
-  /// Returns a future that completes with a [SolveFailure] if a version
-  /// could not be selected or that completes successfully if a package was
-  /// selected and traversing should continue.
-  Future _selectPackage(PackageDep dep, VersionConstraint constraint) {
-    return _solver.cache.getVersions(dep.toRef()).then((versions) {
-      var allowed = versions.where((id) => constraint.allows(id.version));
-
-      // See if it's in the lockfile. If so, try that version first. If the
-      // locked version doesn't match our constraint, just ignore it.
-      var locked = _getValidLocked(dep.name, constraint);
-      if (locked != null) {
-        allowed = allowed.where((dep) => dep.version != locked.version)
-            .toList();
-        allowed.insert(0, locked);
-      }
-
-      if (allowed.isEmpty) {
-        _solver.logSolve('no versions for ${dep.name} match $constraint');
-        throw new NoVersionException(dep.name, constraint,
-                                     _getDependencies(dep.name));
-      }
-
-      // If we're doing an upgrade on this package, only allow the latest
-      // version.
-      if (_solver._forceLatest.contains(dep.name)) allowed = [allowed.first];
-
-      // Try the first package in the allowed set and keep track of the list of
-      // other possible versions in case that fails.
-      _packages.add(_solver.select(allowed));
-    });
-  }
-
   /// Gets the list of dependencies for package [name]. Will create an empty
   /// list if needed.
   List<Dependency> _getDependencies(String name) {
@@ -629,13 +591,22 @@
         .firstWhere((dep) => !dep.dep.isRoot, orElse: () => null);
   }
 
+  /// Gets the combined [VersionConstraint] currently being placed on package
+  /// [name].
+  VersionConstraint _getConstraint(String name) {
+    return _getDependencies(name)
+        .map((dep) => dep.dep.constraint)
+        .fold(VersionConstraint.any, (a, b) => a.intersect(b));
+  }
+
   /// Gets the package [name] that's currently contained in the lockfile if it
   /// meets [constraint] and has the same source and description as other
   /// references to that package. Returns `null` otherwise.
-  PackageId _getValidLocked(String name, VersionConstraint constraint) {
+  PackageId _getValidLocked(String name) {
     var package = _solver.getLocked(name);
     if (package == null) return null;
 
+    var constraint = _getConstraint(name);
     if (!constraint.allows(package.version)) {
       _solver.logSolve('$package is locked but does not match $constraint');
       return null;
diff --git a/sdk/lib/_internal/pub/lib/src/solver/dependency_queue.dart b/sdk/lib/_internal/pub/lib/src/solver/dependency_queue.dart
new file mode 100644
index 0000000..3c64e53
--- /dev/null
+++ b/sdk/lib/_internal/pub/lib/src/solver/dependency_queue.dart
@@ -0,0 +1,138 @@
+// 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 pub.solver.dependency_queue;
+
+import 'dart:async';
+import 'dart:collection' show Queue;
+
+import '../log.dart' as log;
+import '../package.dart';
+import 'backtracking_solver.dart';
+
+/// A queue of one package's dependencies, ordered by how the solver should
+/// traverse them.
+///
+/// It prefers locked versions so that they stay locked if possible. Then it
+/// prefers a currently selected package so that it only has to consider a
+/// single version.
+///
+/// After that, it orders the remaining packages by the number of versions they
+/// have so that packages with fewer versions are solved first. (If two
+/// packages have the same number of versions, they are sorted alphabetically
+/// just to be deterministic.)
+///
+/// Critically, this queue will *not* sort the dependencies by number of
+/// versions until actually needed. This ensures we don't do any network
+/// requests until we actually need to. In particular, it means that solving
+/// a package graph with an already up-to-date lockfile will do no network
+/// requests.
+class DependencyQueue {
+  final BacktrackingSolver _solver;
+
+  /// The dependencies for packages that have already been selected.
+  final Queue<PackageDep> _presorted;
+
+  /// The dependencies on the remaining packages.
+  ///
+  /// This is lazily sorted right before the first item is requested.
+  final List<PackageDep> _remaining;
+
+  bool _isSorted = false;
+
+  /// Gets whether there are any dependencies left to iterate over.
+  bool get isEmpty => _presorted.isEmpty && _remaining.isEmpty;
+
+  /// The pending [Future] while the remaining dependencies are being sorted.
+  ///
+  /// This will only be non-null while a sort is in progress.
+  Future _sortFuture;
+
+  factory DependencyQueue(BacktrackingSolver solver,
+      Iterable<PackageDep> deps) {
+    // Separate out the presorted ones.
+    var presorted = <PackageDep>[];
+    var remaining = <PackageDep>[];
+
+    for (var dep in deps) {
+      // Selected or locked packages come first.
+      if (solver.getSelected(dep.name) != null ||
+          solver.getLocked(dep.name) != null) {
+        presorted.add(dep);
+      } else {
+        remaining.add(dep);
+      }
+    }
+
+    return new DependencyQueue._(solver, new Queue<PackageDep>.from(presorted),
+        remaining);
+  }
+
+  DependencyQueue._(this._solver, this._presorted, this._remaining);
+
+  /// Emits the next dependency in priority order.
+  ///
+  /// It is an error to call this if [isEmpty] returns `true`. Note that this
+  /// function is *not* re-entrant. You should only advance after the previous
+  /// advance has completed.
+  Future<PackageDep> advance() {
+    // Emit the sorted ones first.
+    if (_presorted.isNotEmpty) {
+      return new Future.value(_presorted.removeFirst());
+    }
+
+    // Sort the remaining packages when we need the first one.
+    if (!_isSorted) return _sort().then((_) => _remaining.removeAt(0));
+
+    return new Future.value(_remaining.removeAt(0));
+  }
+
+  /// Sorts the unselected packages by number of versions and name.
+  Future _sort() {
+    // Sorting is not re-entrant.
+    assert(_sortFuture == null);
+
+    _sortFuture = Future.wait(_remaining.map(_getNumVersions)).then((versions) {
+      _sortFuture = null;
+
+      // Map deps to the number of versions they have.
+      var versionMap = new Map.fromIterables(_remaining, versions);
+
+      // Sort in best-first order to minimize backtracking.
+      _remaining.sort((a, b) {
+        // Traverse into packages with fewer versions since they will lead to
+        // less backtracking.
+        if (versionMap[a] != versionMap[b]) {
+          return versionMap[a].compareTo(versionMap[b]);
+        }
+
+        // Otherwise, just sort by name so that it's deterministic.
+        return a.name.compareTo(b.name);
+      });
+
+      _isSorted = true;
+    });
+
+    return _sortFuture;
+  }
+
+  /// Given a dependency, returns a future that completes to the number of
+  /// versions available for it.
+  Future<int> _getNumVersions(PackageDep dep) {
+    // There is only ever one version of the root package.
+    if (dep.isRoot) {
+      return new Future.value(1);
+    }
+
+    return _solver.cache.getVersions(dep.toRef()).then((versions) {
+      return versions.length;
+    }).catchError((error, trace) {
+      // If it fails for any reason, just treat that as no versions. This
+      // will sort this reference higher so that we can traverse into it
+      // and report the error more properly.
+      log.solver("Could not get versions for $dep:\n$error\n\n$trace");
+      return 0;
+    });
+  }
+}
diff --git a/sdk/lib/_internal/pub/lib/src/solver/version_queue.dart b/sdk/lib/_internal/pub/lib/src/solver/version_queue.dart
new file mode 100644
index 0000000..529cf74
--- /dev/null
+++ b/sdk/lib/_internal/pub/lib/src/solver/version_queue.dart
@@ -0,0 +1,92 @@
+// 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 pub.solver.version_queue;
+
+import 'dart:async';
+import 'dart:collection' show Queue;
+
+import '../package.dart';
+import 'backtracking_solver.dart';
+
+/// A function that asynchronously returns a sequence of package IDs.
+typedef Future<Iterable<PackageId>> PackageIdGenerator();
+
+/// A prioritized, asynchronous queue of the possible versions that can be
+/// selected for one package.
+///
+/// If there is a locked version, that comes first, followed by other versions
+/// in descending order. This avoids requesting the list of versions until
+/// needed (i.e. after any locked version has been consumed) to avoid unneeded
+/// network requests.
+class VersionQueue {
+  /// The set of allowed versions that match [_constraint].
+  ///
+  /// If [_locked] is not `null`, this will initially be `null` until we
+  /// advance past the locked version.
+  Queue<PackageId> _allowed;
+
+  /// The callback that will generate the sequence of packages. This will be
+  /// called as lazily as possible.
+  final PackageIdGenerator _allowedGenerator;
+
+  /// The currently locked version of the package, or `null` if there is none,
+  /// or we have advanced past it.
+  PackageId _locked;
+
+  /// Gets the currently selected version.
+  PackageId get current {
+    if (_locked != null) return _locked;
+    return _allowed.first;
+  }
+
+  /// Creates a new [VersionQueue] queue for starting with the optional
+  /// [locked] package followed by the results of calling [allowedGenerator].
+  ///
+  /// This is asynchronous so that [current] can always be accessed
+  /// synchronously. If there is no locked version, we need to get the list of
+  /// versions asynchronously before we can determine what the first one is.
+  static Future<VersionQueue> create(PackageId locked,
+      PackageIdGenerator allowedGenerator) {
+    var versions = new VersionQueue._(locked, allowedGenerator);
+
+    // If there is a locked version, it's the current one so it's synchronously
+    // available now.
+    if (locked != null) return new Future.value(versions);
+
+    // Otherwise, the current version needs to be calculated before we can
+    // return.
+    return versions._calculateAllowed().then((_) => versions);
+  }
+
+  VersionQueue._(this._locked, this._allowedGenerator);
+
+  /// Tries to advance to the next possible version.
+  ///
+  /// Returns `true` if it moved to a new version (which can be accessed from
+  /// [current]. Returns `false` if there are no more versions.
+  Future<bool> advance() {
+    // If we have a locked version, consume it first.
+    if (_locked != null) {
+      // Advancing past the locked version, so need to load the others now
+      // so that [current] is available.
+      return _calculateAllowed().then((_) {
+        _locked = null;
+        return _allowed.isNotEmpty;
+      });
+    }
+
+    // Move to the next allowed version.
+    _allowed.removeFirst();
+    return new Future.value(_allowed.isNotEmpty);
+  }
+
+  /// Determines the list of allowed versions matching its constraint and places
+  /// them in [_allowed].
+  Future _calculateAllowed() {
+    return _allowedGenerator().then((allowed) {
+      _allowed = new Queue<PackageId>.from(allowed);
+    });
+  }
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/lib/src/source.dart b/sdk/lib/_internal/pub/lib/src/source.dart
index 676e1a6..78b4450 100644
--- a/sdk/lib/_internal/pub/lib/src/source.dart
+++ b/sdk/lib/_internal/pub/lib/src/source.dart
@@ -4,7 +4,7 @@
 
 library pub.source;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/source/git.dart b/sdk/lib/_internal/pub/lib/src/source/git.dart
index 42e6856..7caf1dae 100644
--- a/sdk/lib/_internal/pub/lib/src/source/git.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/git.dart
@@ -4,7 +4,7 @@
 
 library pub.source.git;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
@@ -48,11 +48,11 @@
       return _ensureRepoCache(id);
     }).then((_) => systemCacheDirectory(id)).then((path) {
       revisionCachePath = path;
-      if (entryExists(revisionCachePath)) return;
+      if (entryExists(revisionCachePath)) return null;
       return _clone(_repoCachePath(id), revisionCachePath, mirror: false);
     }).then((_) {
       var ref = _getEffectiveRef(id);
-      if (ref == 'HEAD') return;
+      if (ref == 'HEAD') return null;
       return _checkOut(revisionCachePath, ref);
     }).then((_) {
       return new Package.load(id.name, revisionCachePath, systemCache.sources);
diff --git a/sdk/lib/_internal/pub/lib/src/source/hosted.dart b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
index 265c844..295d2a5 100644
--- a/sdk/lib/_internal/pub/lib/src/source/hosted.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
@@ -4,7 +4,7 @@
 
 library pub.source.hosted;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:io' as io;
 import "dart:convert";
 
@@ -75,7 +75,7 @@
           expectedName: id.name, location: url);
     }).catchError((ex, stackTrace) {
       var parsed = _parseDescription(id.description);
-      _throwFriendlyError(ex, stackTrace, id, parsed.last);
+      _throwFriendlyError(ex, stackTrace, id.name, parsed.last);
     });
   }
 
diff --git a/sdk/lib/_internal/pub/lib/src/source/path.dart b/sdk/lib/_internal/pub/lib/src/source/path.dart
index af752d6..4d57069 100644
--- a/sdk/lib/_internal/pub/lib/src/source/path.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/path.dart
@@ -4,7 +4,7 @@
 
 library pub.source.path;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/system_cache.dart b/sdk/lib/_internal/pub/lib/src/system_cache.dart
index bfc6cea..fe28502 100644
--- a/sdk/lib/_internal/pub/lib/src/system_cache.dart
+++ b/sdk/lib/_internal/pub/lib/src/system_cache.dart
@@ -4,7 +4,7 @@
 
 library pub.system_cache;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/compiled_dartdoc.dart b/sdk/lib/_internal/pub/lib/src/validator/compiled_dartdoc.dart
index d6abf6d..ab98a18 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/compiled_dartdoc.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/compiled_dartdoc.dart
@@ -4,7 +4,7 @@
 
 library pub.validator.compiled_dartdoc;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/directory.dart b/sdk/lib/_internal/pub/lib/src/validator/directory.dart
index 6039fc5..01ddf91 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/directory.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/directory.dart
@@ -4,7 +4,7 @@
 
 library pub.validator.directory;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/lib.dart b/sdk/lib/_internal/pub/lib/src/validator/lib.dart
index 98bed28..622ee03 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/lib.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/lib.dart
@@ -4,7 +4,7 @@
 
 library pub.validator.lib;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/license.dart b/sdk/lib/_internal/pub/lib/src/validator/license.dart
index 222d693..0948860 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/license.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/license.dart
@@ -4,7 +4,7 @@
 
 library pub.validator.license;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/name.dart b/sdk/lib/_internal/pub/lib/src/validator/name.dart
index 1285fb1..d62325d 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/name.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/name.dart
@@ -4,7 +4,7 @@
 
 library pub.validator.name;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 
diff --git a/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart b/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart
index 9f30d65..d14e674 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/utf8_readme.dart
@@ -4,7 +4,7 @@
 
 library pub.validator.utf8_readme;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:convert';
 
 import '../entrypoint.dart';
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index fd1e29c..bf04ee6 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -6,6 +6,8 @@
 
 test/hosted/version_negotiation_test: Pass, Timeout # Issue 14346
 
+test/upgrade/hosted/upgrade_removed_constraints_test: Pass, Fail # Issue 15349
+
 [ $runtime == vm && $system == windows ]
 test/serve/watch_removed_file_test: Pass, Fail # Issue 13026
 
diff --git a/sdk/lib/_internal/pub/test/descriptor/tar.dart b/sdk/lib/_internal/pub/test/descriptor/tar.dart
index 2a04a03..f297abb 100644
--- a/sdk/lib/_internal/pub/test/descriptor/tar.dart
+++ b/sdk/lib/_internal/pub/test/descriptor/tar.dart
@@ -4,7 +4,7 @@
 
 library descriptor.tar;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 
 import 'package:path/path.dart' as path;
 import 'package:scheduled_test/scheduled_test.dart';
diff --git a/sdk/lib/_internal/pub/test/get/hosted/avoid_network_requests_test.dart b/sdk/lib/_internal/pub/test/get/hosted/avoid_network_requests_test.dart
new file mode 100644
index 0000000..cd66d84
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/get/hosted/avoid_network_requests_test.dart
@@ -0,0 +1,63 @@
+// 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 pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+
+  integration('only requests versions that are needed during solving', () {
+    servePackages([
+      packageMap("foo", "1.0.0"),
+      packageMap("foo", "1.1.0"),
+      packageMap("foo", "1.2.0"),
+      packageMap("bar", "1.0.0"),
+      packageMap("bar", "1.1.0"),
+      packageMap("bar", "1.2.0")
+    ]);
+
+    d.appDir({
+      "foo": "any"
+    }).create();
+
+    // Get once so it gets cached.
+    pubGet();
+
+    // Clear the cache. We don't care about anything that was served during
+    // the initial get.
+    getRequestedPaths();
+
+    // Add "bar" to the dependencies.
+    d.appDir({
+      "foo": "any",
+      "bar": "any"
+    }).create();
+
+    // Run the solver again.
+    pubGet();
+
+    d.packagesDir({
+      "foo": "1.2.0",
+      "bar": "1.2.0"
+    }).validate();
+
+    // The get should not have done any network requests since the lock file is
+    // up to date.
+    getRequestedPaths().then((paths) {
+      expect(paths, unorderedEquals([
+        // Bar should be requested because it's new, but not foo.
+        "api/packages/bar",
+        // Should only request the most recent version.
+        "api/packages/bar/versions/1.2.0",
+        // Need to download it.
+        "packages/bar/versions/1.2.0.tar.gz"
+      ]));
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/get/hosted/does_no_network_requests_when_possible_test.dart b/sdk/lib/_internal/pub/test/get/hosted/does_no_network_requests_when_possible_test.dart
new file mode 100644
index 0000000..44532fd
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/get/hosted/does_no_network_requests_when_possible_test.dart
@@ -0,0 +1,45 @@
+// 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 pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+
+main() {
+  initConfig();
+
+  integration('does not request versions if the lockfile is up to date', () {
+    servePackages([
+      packageMap("foo", "1.0.0"),
+      packageMap("foo", "1.1.0"),
+      packageMap("foo", "1.2.0")
+    ]);
+
+    d.appDir({
+      "foo": "any"
+    }).create();
+
+    // Get once so it gets cached.
+    pubGet();
+
+    // Clear the cache. We don't care about anything that was served during
+    // the initial get.
+    getRequestedPaths();
+
+    // Run the solver again now that it's cached.
+    pubGet();
+
+    d.cacheDir({"foo": "1.2.0"}).validate();
+    d.packagesDir({"foo": "1.2.0"}).validate();
+
+    // The get should not have done any network requests since the lock file is
+    // up to date.
+    getRequestedPaths().then((paths) {
+      expect(paths, isEmpty);
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/io_test.dart b/sdk/lib/_internal/pub/test/io_test.dart
index bc8d708..c4f5151 100644
--- a/sdk/lib/_internal/pub/test/io_test.dart
+++ b/sdk/lib/_internal/pub/test/io_test.dart
@@ -4,7 +4,7 @@
 
 library io_test;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:io';
 
 import 'package:path/path.dart' as path;
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index 59be37c..f398887 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -8,7 +8,7 @@
 /// tests like that.
 library test_pub;
 
-import 'dart:async';
+import 'dart:async' hide TimeoutException;
 import 'dart:convert';
 import 'dart:io';
 import 'dart:math';
@@ -88,7 +88,7 @@
     var paths = _requestedPaths.toList();
     _requestedPaths.clear();
     return paths;
-  });
+  }, "get previous network requests");
 }
 
 /// Creates an HTTP server to serve [contents] as static files. This server will
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 593a775..db26cee 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -408,6 +408,33 @@
    * its subscribers. The stream closes after the completion value.
    */
   Stream<T> asStream();
+
+  /**
+   * Time-out the future computation after [timeLimit] has passed.
+   *
+   * Returns a new future that completes with the same value as this future,
+   * if this future completes in time.
+   *
+   * If this future does not complete before `timeLimit` has passed,
+   * the [onTimeout] action is executed instead, and its result (whether it
+   * returns or throws) is used as the result of the returned future.
+   *
+   * If `onTimeout` is omitted, a timeout will cause the returned future to
+   * complete with a [TimeoutException].
+   */
+  Future timeout(Duration timeLimit, [void onTimeout()]);
+}
+
+/**
+ * Thrown when a scheduled timeout happens while waiting for an async result.
+ */
+class TimeoutException implements Exception {
+  /** The duration that was exceeded without a result. */
+  final Duration duration;
+
+  TimeoutException(this.duration);
+
+  String toString() => "Timeout after $duration";
 }
 
 /**
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 90e9df2..fb1280c 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -537,4 +537,37 @@
       source = listener;
     }
   }
+
+  Future timeout(Duration timeLimit, [void onTimeout()]) {
+    if (_isComplete) return new _Future.immediate(this);
+    _Future result = new _Future();
+    Timer timer;
+    if (onTimeout == null) {
+      timer = new Timer(timeLimit, () {
+        result._completeError(new TimeoutException(timeLimit));
+      });
+    } else {
+      Zone zone = Zone.current;
+      onTimeout = zone.registerCallback(onTimeout);
+      timer = new Timer(timeLimit, () {
+        try {
+          result._complete(zone.run(onTimeout));
+        } catch (e, s) {
+          result._completeError(e, s);
+        }
+      });
+    }
+    this.then((T v) {
+      if (timer.isActive) {
+        timer.cancel();
+        result._complete(v);
+      }
+    }, onError: (e, s) {
+      if (timer.isActive) {
+        timer.cancel();
+        result._completeError(e, s);
+      }
+    });
+    return result;
+  }
 }
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index 0fb0cea..8b2b115 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -60,7 +60,7 @@
    * canceled with the [cancel] function.
    */
   factory Timer.periodic(Duration duration,
-                                  void callback(Timer timer)) {
+                         void callback(Timer timer)) {
     if (Zone.current == Zone.ROOT) {
       // No need to bind the callback. We know that the root's timer will
       // be invoked in the root zone.
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 471a7d3..88b3054 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -359,7 +359,7 @@
       f(arg1, arg2), { bool runGuarded: true });
 
   /**
-   * Runs [f] asynchronously.
+   * Runs [f] asynchronously in this zone.
    */
   void scheduleMicrotask(void f());
 
@@ -732,20 +732,29 @@
 }
 
 void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) {
+  if (Zone.ROOT != zone) {
+    f = zone.bindCallback(f);
+  }
   _scheduleAsyncCallback(f);
 }
 
 Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone,
                        Duration duration, void callback()) {
+  if (Zone.ROOT != zone) {
+    callback = zone.bindCallback(callback);
+  }
   return _createTimer(duration, callback);
 }
 
 Timer _rootCreatePeriodicTimer(
     Zone self, ZoneDelegate parent, Zone zone,
     Duration duration, void callback(Timer timer)) {
+  if (Zone.ROOT != zone) {
+    callback = zone.bindUnaryCallback(callback);
+  }
   return _createPeriodicTimer(duration, callback);
-
 }
+
 void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) {
   printToConsole(line);
 }
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 4c901a3..ca2b39e 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -12,6 +12,15 @@
  *
  * All operations are defined in terms of `length`, `operator[]`,
  * `operator[]=` and `length=`, which need to be implemented.
+ *
+ * *NOTICE*: Forwarding just these four operations to a normal growable [List]
+ * (as created by `new List()`) will give very bad performance for `add` and
+ * `addAll` operations of `ListBase`. These operations are implemented by
+ * increasing the length of the list by one for each `add` operation, and
+ * repeatedly increasing the length of a growable list is not efficient.
+ * To avoid this, either override 'add' and 'addAll' to also forward directly
+ * to the growable list, or, preferably, use `DelegatingList` from
+ * "package:collection_helpers/wrappers.dart" instead.
  */
 abstract class ListBase<E> = Object with ListMixin<E>;
 
@@ -23,6 +32,15 @@
  * This implements all read operations using only the `length` and
  * `operator[]` members. It implements write operations using those and
  * `length=` and `operator[]=`
+ *
+ * *NOTICE*: Forwarding just these four operations to a normal growable [List]
+ * (as created by `new List()`) will give very bad performance for `add` and
+ * `addAll` operations of `ListBase`. These operations are implemented by
+ * increasing the length of the list by one for each `add` operation, and
+ * repeatedly increasing the length of a growable list is not efficient.
+ * To avoid this, either override 'add' and 'addAll' to also forward directly
+ * to the growable list, or, if possible, use `DelegatingList` from
+ * "package:collection_helpers/wrappers.dart" instead.
  */
 abstract class ListMixin<E> implements List<E> {
 
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index c06a3ee..6ca2718 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -246,8 +246,9 @@
    * first the decimal digits 0..9, and then the letters 'a'..'z'.
    * Accepts capital letters as well.
    *
-   * If no [radix] is given then it defaults to 16 if the string starts
-   * with "0x", "-0x" or "+0x" and 10 otherwise.
+   * If no [radix] is given then it defaults to 10, unless the string starts
+   * with "0x", "-0x" or "+0x", in which case the radix is set to 16 and the
+   * "0x" is ignored.
    *
    * The [source] must be a non-empty sequence of base-[radix] digits,
    * optionally prefixed with a minus or plus sign ('-' or '+').
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 674ab2a..c6bb4f8 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -359,4 +359,33 @@
    *
    */
   String toString();
+
+  /**
+   * Parses a string containing a number literal into a number.
+   *
+   * The method first tries to read the [input] as integer (similar to
+   * [int.parse] without a radix).
+   * If that fails, it tries to parse the [input] as a double (similar to
+   * [double.parse]).
+   * If that fails, too, it invokes [onError] with [input].
+   *
+   * If no [onError] is supplied, it defaults to a function that throws a
+   * [FormatException].
+   *
+   * For any number `n`, this function satisfies
+   * `identical(n, num.parse(n.toString()))`.
+   */
+  static num parse(String input, [num onError(String input)]) {
+    String source = input.trim();
+    // TODO(lrn): Optimize to detect format and result type in one check.
+    num result = int.parse(source, onError: _returnNull);
+    if (result != null) return result;
+    result = double.parse(source, _returnNull);
+    if (result != null) return result;
+    if (onError == null) throw new FormatException(input);
+    return onError(input);
+  }
+
+  /** Helper function for [parse]. */
+  static _returnNull(_) => null;
 }
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 6ff1c32..18735d0 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -36896,6 +36896,11 @@
 
   static String addTrailingDot(String str) => '${str}.';
 
+  static String demangle(String str) {
+    var atPos = str.indexOf('@');
+    return atPos == -1 ? str : str.substring(0, atPos);
+  }
+
   static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;
 
   static bool _isBuiltinType(ClassMirror cls) {
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 8a7ce39..cb1efe3 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -257,8 +257,9 @@
   FileStat statSync() => FileStat.statSync(path);
 
   Future<File> create({bool recursive: false}) {
-    return (recursive ? parent.create(recursive: true)
-                      : new Future.value(null))
+    var result = recursive ? parent.create(recursive: true)
+                           : new Future.value(null);
+    return result
       .then((_) => _IOService.dispatch(_FILE_CREATE, [path]))
       .then((response) {
         if (_isErrorResponse(response)) {
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index 81d406d..896ef26 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -353,8 +353,6 @@
    *     as expected.
    *   * `Mac OS`: Uses `FSEvents`. The implementation supports watching both
    *     files and directories. Recursive watching is supported.
-   *     Note: events happened slightly before calling [watch], may be part of
-   *     the returned stream, on Mac OS.
    *
    * The system will start listening for events once the returned [Stream] is
    * being listened to, not when the call to [watch] is issued.
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index e4960fa..756db60 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1749,13 +1749,13 @@
       bool callback(X509Certificate certificate) =>
           currentBadCertificateCallback == null ? false :
           currentBadCertificateCallback(certificate, uriHost, uriPort);
-      return (isSecure && proxy.isDirect
-                  ? SecureSocket.connect(host,
-                                         port,
-                                         sendClientCertificate: true,
-                                         onBadCertificate: callback)
-                  : Socket.connect(host, port))
-        .then((socket) {
+      Future socketFuture = (isSecure && proxy.isDirect
+          ? SecureSocket.connect(host,
+                                 port,
+                                 sendClientCertificate: true,
+                                 onBadCertificate: callback)
+          : Socket.connect(host, port));
+      return socketFuture.then((socket) {
           socket.setOption(SocketOption.TCP_NODELAY, true);
           var connection = new _HttpClientConnection(key, socket, this);
           if (isSecure && !proxy.isDirect) {
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index 99bc7c7..de55780 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -842,7 +842,7 @@
     return byte > 31 && byte < 128 && !_Const.SEPARATOR_MAP[byte];
   }
 
-  List<String> _tokenizeFieldValue(String headerValue) {
+  static List<String> _tokenizeFieldValue(String headerValue) {
     List<String> tokens = new List<String>();
     int start = 0;
     int index = 0;
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 7f07234..0ffcf0e 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -166,8 +166,9 @@
     if (Platform.operatingSystem == 'windows') {
       target = _makeWindowsLinkTarget(target);
     }
-    return (recursive ? parent.create(recursive: true)
-                      : new Future.value(null))
+    var result = recursive ? parent.create(recursive: true)
+                           : new Future.value(null);
+    return result
       .then((_) => _IOService.dispatch(_FILE_CREATE_LINK, [path, target]))
       .then((response) {
         if (_isErrorResponse(response)) {
diff --git a/sdk/lib/io/websocket.dart b/sdk/lib/io/websocket.dart
index a3f2b25..1e2d0fa 100644
--- a/sdk/lib/io/websocket.dart
+++ b/sdk/lib/io/websocket.dart
@@ -53,7 +53,18 @@
  */
 abstract class WebSocketTransformer
     implements StreamTransformer<HttpRequest, WebSocket> {
-  factory WebSocketTransformer() => new _WebSocketTransformerImpl();
+
+  /**
+   * Create a new [WebSocketTransformer].
+   *
+   * If [protocolSelector] is provided, [protocolSelector] will be called to
+   * select what protocol to use, if any were provided by the client.
+   * [protocolSelector] is should return either a [String] or a [Future]
+   * completing with a [String]. The [String] must exist in the list of
+   * protocols.
+   */
+  factory WebSocketTransformer({protocolSelector(List<String> protocols)})
+      => new _WebSocketTransformerImpl(protocolSelector);
 
   /**
    * Upgrades a [HttpRequest] to a [WebSocket] connection. If the
@@ -61,9 +72,16 @@
    * with status code 500 will be returned. Otherwise the returned
    * future will complete with the [WebSocket] when the upgrade pocess
    * is complete.
+   *
+   * If [protocolSelector] is provided, [protocolSelector] will be called to
+   * select what protocol to use, if any were provided by the client.
+   * [protocolSelector] is should return either a [String] or a [Future]
+   * completing with a [String]. The [String] must exist in the list of
+   * protocols.
    */
-  static Future<WebSocket> upgrade(HttpRequest request) {
-    return _WebSocketTransformerImpl._upgrade(request);
+  static Future<WebSocket> upgrade(HttpRequest request,
+                                   {protocolSelector(List<String> protocols)}) {
+    return _WebSocketTransformerImpl._upgrade(request, protocolSelector);
   }
 
   /**
@@ -78,7 +96,7 @@
 /**
  * A two-way HTTP communication object for client or server applications.
  *
- * The stream exposes the messages received. A text message will be of type 
+ * The stream exposes the messages received. A text message will be of type
  * [:String:] and a binary message will be of type [:List<int>:].
  */
 abstract class WebSocket implements Stream, StreamSink {
@@ -92,11 +110,11 @@
 
   /**
    * Create a new web socket connection. The URL supplied in [url]
-   * must use the scheme [:ws:] or [:wss:]. The [protocols] argument is either
-   * a [:String:] or [:List<String>:] specifying the subprotocols the
-   * client is willing to speak.
+   * must use the scheme [:ws:] or [:wss:]. The [protocols] argument is
+   * specifying the subprotocols the client is willing to speak.
    */
-  static Future<WebSocket> connect(String url, [protocols]) =>
+  static Future<WebSocket> connect(String url,
+                                   {List<String> protocols: const []}) =>
       _WebSocketImpl.connect(url, protocols);
 
   /**
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index 6a62609..556de41 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -393,10 +393,13 @@
 class _WebSocketTransformerImpl implements WebSocketTransformer {
   final StreamController<WebSocket> _controller =
       new StreamController<WebSocket>(sync: true);
+  final Function _protocolSelector;
+
+  _WebSocketTransformerImpl(this._protocolSelector);
 
   Stream<WebSocket> bind(Stream<HttpRequest> stream) {
     stream.listen((request) {
-        _upgrade(request)
+        _upgrade(request, _protocolSelector)
             .then((WebSocket webSocket) => _controller.add(webSocket))
             .catchError(_controller.addError);
     });
@@ -404,31 +407,58 @@
     return _controller.stream;
   }
 
-  static Future<WebSocket> _upgrade(HttpRequest request) {
+  static Future<WebSocket> _upgrade(HttpRequest request, _protocolSelector) {
     var response = request.response;
     if (!_isUpgradeRequest(request)) {
-      // Send error response and drain the request.
-      request.listen((_) {}, onDone: () {
-        response.statusCode = HttpStatus.BAD_REQUEST;
-        response.contentLength = 0;
-        response.close();
-      });
+      // Send error response.
+      response.statusCode = HttpStatus.BAD_REQUEST;
+      response.close();
       return new Future.error(
           new WebSocketException("Invalid WebSocket upgrade request"));
     }
 
-    // Send the upgrade response.
-    response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
-    response.headers.add(HttpHeaders.CONNECTION, "Upgrade");
-    response.headers.add(HttpHeaders.UPGRADE, "websocket");
-    String key = request.headers.value("Sec-WebSocket-Key");
-    _SHA1 sha1 = new _SHA1();
-    sha1.add("$key$_webSocketGUID".codeUnits);
-    String accept = _CryptoUtils.bytesToBase64(sha1.close());
-    response.headers.add("Sec-WebSocket-Accept", accept);
-    response.headers.contentLength = 0;
-    return response.detachSocket()
-        .then((socket) => new _WebSocketImpl._fromSocket(socket, true));
+    Future upgrade(String protocol) {
+      // Send the upgrade response.
+      response.statusCode = HttpStatus.SWITCHING_PROTOCOLS;
+      response.headers.add(HttpHeaders.CONNECTION, "Upgrade");
+      response.headers.add(HttpHeaders.UPGRADE, "websocket");
+      String key = request.headers.value("Sec-WebSocket-Key");
+      _SHA1 sha1 = new _SHA1();
+      sha1.add("$key$_webSocketGUID".codeUnits);
+      String accept = _CryptoUtils.bytesToBase64(sha1.close());
+      response.headers.add("Sec-WebSocket-Accept", accept);
+      if (protocol != null && protocol.isNotEmpty) {
+        response.headers.add("Sec-WebSocket-Protocol", protocol);
+      }
+      response.headers.contentLength = 0;
+      return response.detachSocket()
+          .then((socket) => new _WebSocketImpl._fromSocket(
+                socket, protocol, true));
+    }
+
+    var protocols = request.headers['Sec-WebSocket-Protocol'];
+    if (protocols != null && _protocolSelector != null) {
+      // The suggested protocols can be spread over multiple lines, each
+      // consisting of multiple protocols. To unify all of them, first join
+      // the lists with ', ' and then tokenize.
+      protocols = _HttpParser._tokenizeFieldValue(protocols.join(', '));
+      return new Future(() => _protocolSelector(protocols))
+        .then((protocol) {
+          if (protocols.indexOf(protocol) < 0) {
+            throw new WebSocketException(
+                "Selected protocol is not in the list of available protocols");
+          }
+          return protocol;
+        })
+        .catchError((error) {
+          response.statusCode = HttpStatus.INTERNAL_SERVER_ERROR;
+          response.close();
+          throw error;
+        })
+        .then(upgrade);
+    } else {
+      return upgrade(null);
+    }
   }
 
   static bool _isUpgradeRequest(HttpRequest request) {
@@ -724,6 +754,8 @@
 
 
 class _WebSocketImpl extends Stream implements WebSocket {
+  final String protocol;
+
   StreamController _controller;
   StreamSubscription _subscription;
   StreamSink _sink;
@@ -743,7 +775,7 @@
 
   static final HttpClient _httpClient = new HttpClient();
 
-  static Future<WebSocket> connect(String url, [protocols]) {
+  static Future<WebSocket> connect(String url, List<String> protocols) {
     Uri uri = Uri.parse(url);
     if (uri.scheme != "ws" && uri.scheme != "wss") {
       throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'");
@@ -774,6 +806,9 @@
         request.headers.set(HttpHeaders.UPGRADE, "websocket");
         request.headers.set("Sec-WebSocket-Key", nonce);
         request.headers.set("Sec-WebSocket-Version", "13");
+        if (protocols.isNotEmpty) {
+          request.headers.add("Sec-WebSocket-Protocol", protocols);
+        }
         return request.close();
       })
       .then((response) {
@@ -808,12 +843,14 @@
             error("Bad response 'Sec-WebSocket-Accept' header");
           }
         }
+        var protocol = response.headers.value('Sec-WebSocket-Protocol');
         return response.detachSocket()
-            .then((socket) => new _WebSocketImpl._fromSocket(socket));
+            .then((socket) => new _WebSocketImpl._fromSocket(socket, protocol));
       });
   }
 
   _WebSocketImpl._fromSocket(Socket this._socket,
+                             String this.protocol,
                              [bool this._serverSide = false]) {
     _consumer = new _WebSocketConsumer(this, _socket);
     _sink = new _StreamSinkImpl(_consumer);
@@ -893,7 +930,6 @@
   int get readyState => _readyState;
 
   String get extensions => null;
-  String get protocol => null;
   int get closeCode => _closeCode;
   String get closeReason => _closeReason;
 
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index c6b9253..efc6ca2 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -208,7 +208,7 @@
   void close();
 
   /**
-   * Returns a [SendPort] that sends to this receive port.
+   * Returns a [SendPort] that sends to this raw receive port.
    */
   SendPort get sendPort;
 }
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 027b197..ce9c8e7 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -538,7 +538,8 @@
    * If the invocation returns a result *r*, this method returns
    * the result of calling [reflect](*r*).
    * If the invocation causes a compilation error
-   * this method throws a [MirrorError].
+   * the effect is the same as if a non-reflective compilation error
+   * had been encountered.
    * If the invocation throws an exception *e* (that it does not catch)
    * this method throws *e*.
    */
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index 6bcb22e..6a4e0f1 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -10,7 +10,7 @@
 
 import 'dart:collection';
 import 'dart:_collection-dev';
-import 'dart:_interceptors' show JSIndexable;
+import 'dart:_interceptors' show JSIndexable, JSUInt32, JSUInt31;
 import 'dart:_js_helper'
     show Creates, JavaScriptIndexingBehavior, JSName, Null, Returns;
 import 'dart:_foreign_helper' show JS, JS_CONST;
@@ -259,7 +259,7 @@
       _getUint16(byteOffset, endian._littleEndian);
 
   @JSName('getUint16')
-  @Returns('int')
+  @Returns('JSUInt31')
   int _getUint16(int byteOffset, [bool littleEndian]) native;
 
   /**
@@ -268,12 +268,14 @@
    * form.
    * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
    *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
    */
   int getUint32(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]) =>
       _getUint32(byteOffset, endian._littleEndian);
 
   @JSName('getUint32')
-  @Returns('int')
+  @Returns('JSUInt32')
   int _getUint32(int byteOffset, [bool littleEndian]) native;
 
   /**
@@ -500,7 +502,7 @@
 
   static const int BYTES_PER_ELEMENT = 4;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   num operator[](int index) {
     _checkIndex(index, length);
@@ -575,7 +577,7 @@
 
   static const int BYTES_PER_ELEMENT = 8;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   num operator[](int index) {
     _checkIndex(index, length);
@@ -651,7 +653,7 @@
 
   static const int BYTES_PER_ELEMENT = 2;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
@@ -724,7 +726,7 @@
 
   static const int BYTES_PER_ELEMENT = 4;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
@@ -794,7 +796,7 @@
 
   static const int BYTES_PER_ELEMENT = 1;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
@@ -868,11 +870,11 @@
 
   static const int BYTES_PER_ELEMENT = 2;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
-    return JS("int", "#[#]", this, index);
+    return JS("JSUInt31", "#[#]", this, index);
   }
 
   void operator[]=(int index, int value) {
@@ -942,11 +944,11 @@
 
   static const int BYTES_PER_ELEMENT = 4;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
-    return JS("int", "#[#]", this, index);
+    return JS("JSUInt32", "#[#]", this, index);
   }
 
   void operator[]=(int index, int value) {
@@ -1013,11 +1015,11 @@
 
   static const int BYTES_PER_ELEMENT = 1;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
-    return JS("int", "#[#]", this, index);
+    return JS("JSUInt31", "#[#]", this, index);
   }
 
   void operator[]=(int index, int value) {
@@ -1089,11 +1091,11 @@
 
   static const int BYTES_PER_ELEMENT = 1;
 
-  int get length => JS("int", '#.length', this);
+  int get length => JS("JSUInt32", '#.length', this);
 
   int operator[](int index) {
     _checkIndex(index, length);
-    return JS("int", "#[#]", this, index);
+    return JS("JSUInt31", "#[#]", this, index);
   }
 
   void operator[]=(int index, int value) {
@@ -1362,7 +1364,8 @@
   }
 
   void _checkIndex(int index, int length) {
-    if (JS('bool', '(# >>> 0 != #)', index, index) || index >= length) {
+    if (JS('bool', '(# >>> 0 != #)', index, index)
+        || JS('bool', '# >= #', index, length)) {
       _invalidIndex(index, length);
     }
   }
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 4464fea..9d37eb6 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -229,6 +229,8 @@
    * form.
    * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
    *
+   * Throws [RangeError] if [byteOffset] is negative, or
+   * `byteOffset + 4` is greater than the length of this object.
    */
   int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]);
 
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index c35487e..3212583 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -15,18 +15,18 @@
 LibTest/core/Stopwatch/start_A01_t02: PASS, FAIL, OK # co19 issue 657
 LibTest/core/Stopwatch/elapsedTicks_A01_t01: PASS, FAIL, OK # co19 issue 657
 
-LibTest/isolate/Isolate/spawnUri_A01_t01: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A01_t02: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A01_t03: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A01_t04: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A01_t05: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnFunction_A02_t01: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnFunction_A03_t01: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnFunction_A04_t01: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnFunction_A04_t02: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnFunction_A04_t03: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A02_t02: Fail # co19-roll r667: Please triage this failure
-LibTest/isolate/Isolate/spawnUri_A02_t03: Fail # co19-roll r667: Please triage this failure
+LibTest/isolate/Isolate/spawnUri_A01_t01: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnUri_A01_t02: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnUri_A01_t03: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnUri_A01_t04: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnUri_A01_t05: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnFunction_A02_t01: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnFunction_A03_t01: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnFunction_A04_t01: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnFunction_A04_t02: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnFunction_A04_t03: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnUri_A02_t02: Fail, OK # co19 issue 639
+LibTest/isolate/Isolate/spawnUri_A02_t03: Fail, OK # co19 issue 639
 
 
 [ $runtime == vm || $runtime == dartium || $compiler == dart2dart || $compiler == dart2js ]
@@ -38,7 +38,8 @@
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
 
-LibTest/collection/LinkedList/forEach_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/collection/LinkedList/forEach_A02_t01: RuntimeError, OK # co19 issue 662
+
 LibTest/core/Invocation/namedArguments_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Set/intersection_A02_t01: Fail, OK # Issue 659
@@ -46,14 +47,15 @@
 Language/07_Classes/07_Classes_A13_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
 Language/07_Classes/07_Classes_A13_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
 Language/07_Classes/07_Classes_A13_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-LibTest/collection/HashSet/HashSet_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
-LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
-LibTest/core/Set/IterableBase_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
+
+LibTest/collection/HashSet/HashSet_class_A01_t01: RuntimeError, OK # co19 issue 663
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: RuntimeError, OK # co19 issue 663
+LibTest/core/Set/IterableBase_A01_t01: RuntimeError, OK # co19 issue 663
 
 LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
 
-LibTest/collection/ListBase/ListBase_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
-LibTest/collection/ListMixin/ListMixin_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
+LibTest/collection/ListBase/ListBase_class_A01_t01: Skip, OK # co19 issue 661
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip, OK # co19 issue 661
 
 [ $runtime == vm || $runtime == dartium || $compiler == dart2js ]
 LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
@@ -61,6 +63,7 @@
 LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
 
 LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
 
 LibTest/core/double/ceil_A01_t03: FAIL, OK # co19 issue 389
 LibTest/core/double/ceil_A01_t04: FAIL, OK # co19 issue 389
@@ -83,7 +86,6 @@
 
 LibTest/math/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/sin_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
 
 LibTest/async/Stream/Stream.periodic_A03_t01: PASS, FAIL, OK # co19 issue 538
 LibTest/async/Timer/run_A01_t01: PASS, FAIL, OK # co19 issue 538
@@ -137,7 +139,6 @@
 Language/13_Statements/09_Switch_A09_t01: PASS, FAIL, OK # co19 issue 633
 LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
-LibTest/typed_data/Float32x4List/reduce_A01_t01: Fail # co19-roll r623: Please triage this failure
 
 [ ($runtime == vm || $compiler == dart2js) && $checked]
 Language/14_Libraries_and_Scripts/1_Imports_A03_t46: PASS, FAIL, OK # co19 issue 560
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index bcc9b79..ce36919 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -27,7 +27,6 @@
 Language/05_Variables/05_Variables_A11_t01: fail
 LibTest/core/double/INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
-LibTest/core/List/List_A03_t01: RuntimeError # TODO(kasperl): Please triage this failure.
 
 LibTest/typed_data/ByteData/getFloat32_A02_t02: fail # co19-roll r569: Please triage this failure
 LibTest/typed_data/ByteData/getFloat64_A02_t02: fail # co19-roll r569: Please triage this failure
@@ -115,7 +114,7 @@
 Language/15_Types/2_Dynamic_Type_System_A01_t02: RuntimeError # co19-roll r607: Please triage this failure
 Language/15_Types/8_Parameterized_Types_A03_t07: RuntimeError # co19-roll r607: Please triage this failure
 Language/15_Types/1_Static_Types_A03_t01: RuntimeError # co19-roll r623: Please triage this failure
-
+LibTest/typed_data/Float32x4List/reduce_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 
 [ $compiler == dart2js ]
 LibTest/core/int/operator_GT_A01_t01: RuntimeError, OK # co19 issue 200
@@ -152,6 +151,52 @@
 
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError, OK # co19 issue 212
 
+[ $compiler == dart2js || $compiler == dart2dart ]
+
+Language/12_Expressions/05_Strings_A02_t02: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t03: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t04: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t05: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t06: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t07: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t08: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t09: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t10: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t11: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t12: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t13: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t14: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t15: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t16: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t17: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t18: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t19: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t20: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t21: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t22: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t23: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t24: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t25: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t28: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t29: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t32: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t32: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t33: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t34: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t36: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t38: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t40: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t42: Crash # Issue 15237
+Language/12_Expressions/05_Strings_A02_t44: Crash # Issue 15237
+
+
+Language/13_Statements/05_If_A01_t04: Crash # Issue 15237
+Language/13_Statements/07_While_A01_t01: Crash # Issue 15237
+Language/13_Statements/08_Do_A01_t03: Crash # Issue 15237
+Language/13_Statements/09_Switch_A01_t04: Crash # Issue 15237
+Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A15_t06: Crash # Issue 15237
+Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A22_t06: Crash # Issue 15237
+Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A29_t06: Crash # Issue 15237
 
 #
 # Issues with co19 test suite.
@@ -439,7 +484,6 @@
 LibTest/core/DateTime/DateTime_A01_t03: fail # co19-roll r546: Please triage this failure
 LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/Duration/operator_div_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/Match/pattern_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/core/RegExp/allMatches_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
@@ -486,7 +530,6 @@
 LibTest/typed_data/Uint8List/Uint8List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8List/Uint8List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
 Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: CompileTimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js && $checked ]
 Language/12_Expressions/03_Numbers_A05_t02: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index b9241e7..df0e9c9 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -84,27 +84,6 @@
 LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # co19-roll r576: Please triage this failure
 
 [ $compiler == none && $checked && ($runtime == vm || $runtime == dartium) ]
-LibTest/typed_data/Float32x4List/elementAt_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/fillRange_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/first_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/first_A03_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/firstWhere_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/firstWhere_A02_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/getRange_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/getRange_A02_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/last_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/lastWhere_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/map_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/map_A02_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/map_A03_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/operator_subscript_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/operator_subscripted_assignment_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/reversed_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/single_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/singleWhere_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/skip_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/take_A01_t01: Fail # Dart issue 12861
-LibTest/typed_data/Float32x4List/take_A02_t01: Fail # Dart issue 12861
 Language/15_Types/1_Static_Types_A03_t01: RuntimeError # co19-roll r667: Please triage this failure
 
 [ $compiler == none && $runtime == vm && $system == windows && $mode == debug ]
diff --git a/tests/co19/test_config.dart b/tests/co19/test_config.dart
index d37b5fa..b21a49c 100644
--- a/tests/co19/test_config.dart
+++ b/tests/co19/test_config.dart
@@ -4,7 +4,6 @@
 
 library co19_test_config;
 
-import 'dart:io';
 import '../../tools/testing/dart/test_suite.dart';
 import '../../tools/testing/dart/utils.dart' show Path;
 
diff --git a/tests/compiler/dart2js/array_tracing_mirror_test.dart b/tests/compiler/dart2js/array_tracing_mirror_test.dart
new file mode 100644
index 0000000..fe5324c
--- /dev/null
+++ b/tests/compiler/dart2js/array_tracing_mirror_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// Make sure that limiting mirrors through @MirrorsUsed does not
+// affect optimizations done on arrays.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_compiler.dart';
+
+const MEMORY_SOURCE_FILES = const {
+  'main.dart': '''
+
+@MirrorsUsed(targets: 'main')
+import 'dart:mirrors';
+class A {
+  var field;
+}
+
+main() {
+  var a = new A();
+  var mirror = reflect(a);
+  var array = [42, 42];
+  a.field = array;
+  var field = mirror.getField(#field);
+  field.invoke(#clear, []);
+  return array.length;
+}
+''',
+};
+
+main() {
+  var compiler = compilerFor(MEMORY_SOURCE_FILES);  
+  asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    var element = compiler.mainApp.findExported('main');
+    var code = compiler.backend.assembleCode(element);
+    Expect.isTrue(code.contains('return 2'));
+  }));
+}
+
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 04e6b13..6d56f4f 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -225,7 +225,8 @@
       var inferrer = compiler.typesTask.typesInferrer;
       signature.forEachParameter((Element element) {
         Expect.equals(expectedTypes[index++],
-            inferrer.getTypeOfElement(element).simplify(compiler));
+            inferrer.getTypeOfElement(element).simplify(compiler),
+            test);
       });
       Expect.equals(index, expectedTypes.length);
   });
@@ -242,7 +243,7 @@
 
 void test() {
   runTest(TEST_1, (compiler) => [compiler.typesTask.stringType]);
-  runTest(TEST_2, (compiler) => [compiler.typesTask.intType]);
+  runTest(TEST_2, (compiler) => [compiler.typesTask.uint31Type]);
   runTest(TEST_3, (compiler) => [compiler.typesTask.intType]);
   runTest(TEST_4, (compiler) => [compiler.typesTask.numType]);
   runTest(TEST_5, (compiler) => [compiler.typesTask.numType]);
@@ -251,32 +252,32 @@
   runTest(TEST_7b,
       (compiler) => [compiler.typesTask.dynamicType.nonNullable()]);
 
-  runTest(TEST_8, (compiler) => [compiler.typesTask.intType,
+  runTest(TEST_8, (compiler) => [compiler.typesTask.uint31Type,
                                  subclassOfInterceptor(compiler),
                                  compiler.typesTask.dynamicType.nonNullable()]);
-  runTest(TEST_9, (compiler) => [compiler.typesTask.intType,
-                                 compiler.typesTask.intType]);
-  runTest(TEST_10, (compiler) => [compiler.typesTask.intType,
-                                 compiler.typesTask.intType]);
+  runTest(TEST_9, (compiler) => [compiler.typesTask.uint31Type,
+                                 compiler.typesTask.uint31Type]);
+  runTest(TEST_10, (compiler) => [compiler.typesTask.uint31Type,
+                                 compiler.typesTask.uint31Type]);
   runTest(TEST_11, (compiler) => [subclassOfInterceptor(compiler),
                                   subclassOfInterceptor(compiler)]);
 
   runTest(TEST_12, (compiler) => [compiler.typesTask.stringType,
-                                  compiler.typesTask.intType]);
+                                  compiler.typesTask.uint31Type]);
 
   runTest(TEST_13, (compiler) => [compiler.typesTask.numType]);
 
-  runTest(TEST_14, (compiler) => [compiler.typesTask.intType,
+  runTest(TEST_14, (compiler) => [compiler.typesTask.uint31Type,
                                   compiler.typesTask.stringType]);
 
   runTest(TEST_15, (compiler) => [compiler.typesTask.stringType,
                                   compiler.typesTask.boolType]);
 
-  runTest(TEST_16, (compiler) => [compiler.typesTask.intType,
-                                  compiler.typesTask.intType,
+  runTest(TEST_16, (compiler) => [compiler.typesTask.uint31Type,
+                                  compiler.typesTask.uint31Type,
                                   compiler.typesTask.stringType]);
 
-  runTest(TEST_17, (compiler) => [compiler.typesTask.intType,
+  runTest(TEST_17, (compiler) => [compiler.typesTask.uint31Type,
                                   compiler.typesTask.boolType,
                                   compiler.typesTask.doubleType]);
 
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index b01868b..746a502 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -63,7 +63,7 @@
   });
   checkPrintType('1', (compiler, type) {
     var inferrer = compiler.typesTask.typesInferrer;
-    Expect.identical(compiler.typesTask.intType, type);
+    Expect.identical(compiler.typesTask.uint31Type, type);
   });
   checkPrintType('[]', (compiler, type) {
     var inferrer = compiler.typesTask.typesInferrer;
@@ -94,7 +94,7 @@
         var typesTask = compiler.typesTask;
         var inferrer = typesTask.typesInferrer;
         Expect.identical(
-            typesTask.intType,
+            typesTask.uint31Type,
             typesTask.getGuaranteedTypeOfElement(firstParameter));
         Expect.identical(
             typesTask.nullType,
diff --git a/tests/compiler/dart2js/constant_folding_test.dart b/tests/compiler/dart2js/constant_folding_test.dart
index 44f2e06..cdf4c1d 100644
--- a/tests/compiler/dart2js/constant_folding_test.dart
+++ b/tests/compiler/dart2js/constant_folding_test.dart
@@ -81,11 +81,11 @@
       LIST_INDEX_FOLDING, 'foo', new RegExp(r"return 1"));
 
   compileAndDoNotMatch(
-      LIST_INDEX_FOLDING, 'foo', new RegExp(r"throw"));
+      LIST_INDEX_FOLDING, 'foo', new RegExp(r"ioore"));
 
   compileAndMatch(
       STRING_LENGTH_FOLDING, 'foo', new RegExp(r"return 3"));
 
   compileAndMatch(
-      RANGE_ERROR_INDEX_FOLDING, 'foo', new RegExp(r"throw"));
+      RANGE_ERROR_INDEX_FOLDING, 'foo', new RegExp(r"ioore"));
 }
diff --git a/tests/compiler/dart2js/container_mask_equal_test.dart b/tests/compiler/dart2js/container_mask_equal_test.dart
new file mode 100644
index 0000000..f082bef
--- /dev/null
+++ b/tests/compiler/dart2js/container_mask_equal_test.dart
@@ -0,0 +1,49 @@
+// 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 dart2js that used to have a bogus
+// implementation of var.== and
+// var.hashCode. 
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_compiler.dart';
+
+const MEMORY_SOURCE_FILES = const {
+  'main.dart': '''
+
+import 'dart:typed_data';
+
+a() => [0];
+b() => [1, 2];
+c() => new Uint8List(1);
+d() => new Uint8List(2);
+
+main() {
+  print(a); print(b); print(c); print(d);
+}
+''',
+};
+
+main() {
+  var compiler = compilerFor(MEMORY_SOURCE_FILES);  
+  asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    var typesInferrer = compiler.typesTask.typesInferrer;
+
+    var element = compiler.mainApp.find('a');
+    var mask1 = typesInferrer.getReturnTypeOfElement(element);
+
+    element = compiler.mainApp.find('b');
+    var mask2 = typesInferrer.getReturnTypeOfElement(element);
+
+    element = compiler.mainApp.find('c');
+    var mask3 = typesInferrer.getReturnTypeOfElement(element);
+
+    element = compiler.mainApp.find('d');
+    var mask4 = typesInferrer.getReturnTypeOfElement(element);
+
+    Expect.notEquals(mask1.union(mask2, compiler),
+                     mask3.union(mask4, compiler));
+  }));
+}
diff --git a/tests/compiler/dart2js/exit_code_helper.dart b/tests/compiler/dart2js/exit_code_helper.dart
new file mode 100644
index 0000000..d3c6121
--- /dev/null
+++ b/tests/compiler/dart2js/exit_code_helper.dart
@@ -0,0 +1,3 @@
+void main() {

+

+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
new file mode 100644
index 0000000..68cfa76
--- /dev/null
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -0,0 +1,232 @@
+// 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 the exit code of dart2js in case of exceptions, fatal errors, errors,

+// warnings, etc.

+

+

+import 'dart:async';

+import 'dart:io' show Platform;

+

+import 'package:async_helper/async_helper.dart';

+import 'package:expect/expect.dart';

+

+import '../../../sdk/lib/_internal/compiler/compiler.dart' as api;

+import '../../../sdk/lib/_internal/compiler/implementation/dart2js.dart' as entry;

+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/apiimpl.dart' as apiimpl;

+import '../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/util/util.dart';

+

+class TestCompiler extends apiimpl.Compiler {

+  final String testMarker;

+  final String testType;

+  final Function onTest;

+

+  TestCompiler(api.CompilerInputProvider inputProvider,

+                api.CompilerOutputProvider outputProvider,

+                api.DiagnosticHandler handler,

+                Uri libraryRoot,

+                Uri packageRoot,

+                List<String> options,

+                Map<String, dynamic> environment,

+                String this.testMarker,

+                String this.testType,

+                Function this.onTest)

+      : super(inputProvider, outputProvider, handler, libraryRoot,

+              packageRoot, options, environment) {

+    scanner = new TestScanner(this);

+    test('Compiler');

+  }

+

+  Future<bool> run(Uri uri) {

+    test('Compiler.run');

+    return super.run(uri);

+  }

+

+  TreeElements analyzeElement(Element element) {

+    test('Compiler.analyzeElement');

+    return super.analyzeElement(element);

+  }

+

+  void codegen(CodegenWorkItem work, CodegenEnqueuer world) {

+    test('Compiler.codegen');

+    super.codegen(work, world);

+  }

+

+  withCurrentElement(Element element, f()) {

+    return super.withCurrentElement(element, () {

+      test('Compiler.withCurrentElement');

+      return f();

+    });

+  }

+

+  test(String marker) {

+    if (marker == testMarker) {

+      switch (testType) {

+      case 'assert':

+        onTest(testMarker, testType);

+        assert(false);

+        break;

+      case 'invariant':

+        onTest(testMarker, testType);

+        invariant(CURRENT_ELEMENT_SPANNABLE, false, message: marker);

+        break;

+      case 'warning':

+        onTest(testMarker, testType);

+        reportWarningCode(CURRENT_ELEMENT_SPANNABLE,

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

+        break;

+      case 'error':

+        onTest(testMarker, testType);

+        reportError(CURRENT_ELEMENT_SPANNABLE,

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

+        break;

+      case 'fatalError':

+        onTest(testMarker, testType);

+        reportFatalError(CURRENT_ELEMENT_SPANNABLE,

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

+        break;

+      case 'NoSuchMethodError':

+        onTest(testMarker, testType);

+        null.foo;

+        break;

+      case '':

+        onTest(testMarker, testType);

+        break;

+      }

+    }

+  }

+}

+

+class TestScanner extends ScannerTask {

+  TestScanner(TestCompiler compiler) : super(compiler);

+

+  TestCompiler get compiler => super.compiler;

+

+  void scanElements(CompilationUnitElement compilationUnit) {

+    compiler.test('ScannerTask.scanElements');

+    super.scanElements(compilationUnit);

+  }

+}

+

+int checkedResults = 0;

+

+Future testExitCode(String marker, String type, int expectedExitCode) {

+  bool testOccurred = false;

+

+  void onTest(String testMarker, String testType) {

+    if (testMarker == marker && testType == type) {

+      testOccurred = true;

+    }

+  }

+  return new Future(() {

+    Future<String> compile(Uri script,

+                           Uri libraryRoot,

+                           Uri packageRoot,

+                           api.CompilerInputProvider inputProvider,

+                           api.DiagnosticHandler handler,

+                           [List<String> options = const [],

+                            api.CompilerOutputProvider outputProvider,

+                            Map<String, dynamic> environment = const {}]) {

+      libraryRoot = Platform.script.resolve('../../../sdk/');

+      outputProvider = NullSink.outputProvider;

+      handler = (uri, begin, end, message, kind) {};

+      Compiler compiler = new TestCompiler(inputProvider,

+                                           outputProvider,

+                                           handler,

+                                           libraryRoot,

+                                           packageRoot,

+                                           options,

+                                           environment,

+                                           marker,

+                                           type,

+                                           onTest);

+      return compiler.run(script).then((_) {

+        String code = compiler.assembledCode;

+        if (code != null && outputProvider != null) {

+          String outputType = 'js';

+          if (options.contains('--output-type=dart')) {

+            outputType = 'dart';

+          }

+          outputProvider('', outputType)

+              ..add(code)

+              ..close();

+          code = ''; // Non-null signals success.

+        }

+        return code;

+      });

+    }

+

+    int foundExitCode;

+

+    checkResult() {

+      Expect.isTrue(testOccurred, 'testExitCode($marker, $type) did not occur');

+      if (foundExitCode == null) foundExitCode = 0;

+      print('testExitCode($marker, $type) '

+            'exitCode=$foundExitCode expected=$expectedExitCode');

+      Expect.equals(expectedExitCode, foundExitCode,

+          'testExitCode($marker, $type) '

+          'exitCode=$foundExitCode expected=${expectedExitCode}');

+      checkedResults++;

+    }

+

+    void exit(exitCode) {

+      if (foundExitCode == null) {

+        foundExitCode = exitCode;

+      }

+    };

+

+    entry.exitFunc = exit;

+    entry.compileFunc = compile;

+

+    Future result = entry.internalMain(

+        ["tests/compiler/dart2js/exit_code_helper.dart"]);

+    return result.whenComplete(checkResult);

+  });

+}

+

+Future testExitCodes(String marker, Map<String,int> expectedExitCodes) {

+  return Future.forEach(expectedExitCodes.keys, (String type) {

+    return testExitCode(marker, type, expectedExitCodes[type]);

+  });

+}

+

+void main() {

+  const beforeRun = const {

+    '': 0,

+    'NoSuchMethodError': 253,

+    'assert': 253,

+    'invariant': 253

+  };

+

+  const duringRun = const {

+    '': 0,

+    'NoSuchMethodError': 253,

+    'assert': 253,

+    'invariant': 253,

+    'warning': 0,

+    'error': 1,

+    'fatalError': 1,

+  };

+

+  const tests = const {

+    'Compiler': beforeRun,

+    'Compiler.run': beforeRun,

+    'ScannerTask.scanElements': duringRun,

+    'Compiler.withCurrentElement': duringRun,

+    'Compiler.analyzeElement': duringRun,

+    'Compiler.codegen': duringRun,

+  };

+

+  asyncStart();

+  Future.forEach(tests.keys, (marker) {

+    return testExitCodes(marker, tests[marker]);

+  }).then((_) {

+    Expect.equals(beforeRun.length * 2 + duringRun.length * 4,

+                  checkedResults);

+    asyncEnd();

+  });

+}

diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index d6dd1f6..b7181c4 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -484,11 +484,11 @@
       name,
       disableInlining,
       (compiler, field) {
-        TypeMask type = f(compiler);
+        TypeMask type = f(compiler.typesTask);
         var inferrer = compiler.typesTask.typesInferrer;
         TypeMask inferredType =
             inferrer.getTypeOfElement(field).simplify(inferrer.compiler);
-        Expect.equals(type, inferredType, name);
+        Expect.equals(type, inferredType, test);
     });
   });
 }
@@ -499,16 +499,16 @@
 }
 
 void test() {
-  subclassOfInterceptor(compiler) =>
-      findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
+  subclassOfInterceptor(types) =>
+      findTypeMask(types.compiler, 'Interceptor', 'nonNullSubclass');
 
-  runTest(TEST_1, {'f': (compiler) => compiler.typesTask.nullType});
-  runTest(TEST_2, {'f1': (compiler) => compiler.typesTask.nullType,
-                   'f2': (compiler) => compiler.typesTask.intType});
-  runTest(TEST_3, {'f1': (compiler) => compiler.typesTask.intType,
-                   'f2': (compiler) => compiler.typesTask.intType.nullable()});
+  runTest(TEST_1, {'f': (types) => types.nullType});
+  runTest(TEST_2, {'f1': (types) => types.nullType,
+                   'f2': (types) => types.uint31Type});
+  runTest(TEST_3, {'f1': (types) => types.uint31Type,
+                   'f2': (types) => types.uint31Type.nullable()});
   runTest(TEST_4, {'f1': subclassOfInterceptor,
-                   'f2': (compiler) => compiler.typesTask.stringType.nullable()});
+                   'f2': (types) => types.stringType.nullable()});
 
   // TODO(ngeoffray): We should try to infer that the initialization
   // code at the declaration site of the fields does not matter.
@@ -519,53 +519,53 @@
   runTest(TEST_7, {'f1': subclassOfInterceptor,
                    'f2': subclassOfInterceptor});
 
-  runTest(TEST_8, {'f': (compiler) => compiler.typesTask.stringType.nullable()});
-  runTest(TEST_9, {'f': (compiler) => compiler.typesTask.stringType.nullable()});
-  runTest(TEST_10, {'f': (compiler) => compiler.typesTask.intType});
-  runTest(TEST_11, {'fs': (compiler) => compiler.typesTask.intType});
+  runTest(TEST_8, {'f': (types) => types.stringType.nullable()});
+  runTest(TEST_9, {'f': (types) => types.stringType.nullable()});
+  runTest(TEST_10, {'f': (types) => types.uint31Type});
+  runTest(TEST_11, {'fs': (types) => types.uint31Type});
 
   // TODO(ngeoffray): We should try to infer that the initialization
   // code at the declaration site of the fields does not matter.
   runTest(TEST_12, {'fs': subclassOfInterceptor});
 
-  runTest(TEST_13, {'fs': (compiler) => compiler.typesTask.intType});
-  runTest(TEST_14, {'f': (compiler) => compiler.typesTask.intType});
-  runTest(TEST_15, {'f': (compiler) {
+  runTest(TEST_13, {'fs': (types) => types.uint31Type});
+  runTest(TEST_14, {'f': (types) => types.uint31Type});
+  runTest(TEST_15, {'f': (types) {
                             ClassElement cls =
-                                compiler.typesTask.compiler.backend.jsIndexableClass;
+                                types.compiler.backend.jsIndexableClass;
                             return new TypeMask.nonNullSubtype(cls);
                          }});
   runTest(TEST_16, {'f': subclassOfInterceptor});
-  runTest(TEST_17, {'f': (compiler) => compiler.typesTask.intType.nullable()});
-  runTest(TEST_18, {'f1': (compiler) => compiler.typesTask.intType,
-                    'f2': (compiler) => compiler.typesTask.stringType,
-                    'f3': (compiler) => compiler.typesTask.dynamicType});
-  runTest(TEST_19, {'f1': (compiler) => compiler.typesTask.intType,
-                    'f2': (compiler) => compiler.typesTask.stringType,
-                    'f3': (compiler) => compiler.typesTask.dynamicType});
-  runTest(TEST_20, {'f': (compiler) => compiler.typesTask.intType.nullable()});
-  runTest(TEST_21, {'f': (compiler) => compiler.typesTask.intType.nullable()});
+  runTest(TEST_17, {'f': (types) => types.uint31Type.nullable()});
+  runTest(TEST_18, {'f1': (types) => types.uint31Type,
+                    'f2': (types) => types.stringType,
+                    'f3': (types) => types.dynamicType});
+  runTest(TEST_19, {'f1': (types) => types.uint31Type,
+                    'f2': (types) => types.stringType,
+                    'f3': (types) => types.dynamicType});
+  runTest(TEST_20, {'f': (types) => types.uint31Type.nullable()});
+  runTest(TEST_21, {'f': (types) => types.uint31Type.nullable()});
 
-  runTest(TEST_22, {'f1': (compiler) => compiler.typesTask.intType,
-                    'f2': (compiler) => compiler.typesTask.intType,
-                    'f3': (compiler) => compiler.typesTask.stringType.nullable()});
+  runTest(TEST_22, {'f1': (types) => types.uint31Type,
+                    'f2': (types) => types.uint31Type,
+                    'f3': (types) => types.stringType.nullable()});
 
-  runTest(TEST_23, {'f1': (compiler) => compiler.typesTask.intType.nullable(),
-                    'f2': (compiler) => compiler.typesTask.intType.nullable(),
-                    'f3': (compiler) => compiler.typesTask.intType.nullable(),
-                    'f4': (compiler) => compiler.typesTask.intType.nullable()});
+  runTest(TEST_23, {'f1': (types) => types.uint31Type.nullable(),
+                    'f2': (types) => types.uint31Type.nullable(),
+                    'f3': (types) => types.uint31Type.nullable(),
+                    'f4': (types) => types.uint31Type.nullable()});
 
-  runTest(TEST_24, {'f1': (compiler) => compiler.typesTask.intType,
-                    'f2': (compiler) => compiler.typesTask.intType,
-                    'f3': (compiler) => compiler.typesTask.intType,
-                    'f4': (compiler) => compiler.typesTask.intType,
-                    'f5': (compiler) => compiler.typesTask.numType.nullable(),
-                    'f6': (compiler) => compiler.typesTask.stringType.nullable()});
+  runTest(TEST_24, {'f1': (types) => types.positiveIntType,
+                    'f2': (types) => types.positiveIntType,
+                    'f3': (types) => types.uint31Type,
+                    'f4': (types) => types.uint31Type,
+                    'f5': (types) => types.numType.nullable(),
+                    'f6': (types) => types.stringType.nullable()});
 
-  runTest(TEST_25, {'f1': (compiler) => compiler.typesTask.intType });
-  runTest(TEST_26, {'f1': (compiler) => compiler.typesTask.intType });
-  runTest(TEST_27, {'f1': (compiler) => compiler.typesTask.intType,
-                    'f2': (compiler) => compiler.typesTask.intType.nullable()});
+  runTest(TEST_25, {'f1': (types) => types.uint31Type });
+  runTest(TEST_26, {'f1': (types) => types.positiveIntType });
+  runTest(TEST_27, {'f1': (types) => types.uint31Type,
+                    'f2': (types) => types.uint31Type.nullable()});
 }
 
 void main() {
diff --git a/tests/compiler/dart2js/issue13354_test.dart b/tests/compiler/dart2js/issue13354_test.dart
index d9342b6..7cc2f55 100644
--- a/tests/compiler/dart2js/issue13354_test.dart
+++ b/tests/compiler/dart2js/issue13354_test.dart
@@ -47,10 +47,10 @@
           typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
     }
 
-    checkReturn('bar', typesTask.intType);
+    checkReturn('bar', typesTask.uint31Type);
     checkReturn('baz', typesTask.functionType);
 
-    checkReturnInClass('A', 'foo', typesTask.intType);
+    checkReturnInClass('A', 'foo', typesTask.uint31Type);
     checkReturnInClass('B', 'foo', typesTask.functionType);
   }));
 }
diff --git a/tests/compiler/dart2js/least_upper_bound_language_test.dart b/tests/compiler/dart2js/least_upper_bound_language_test.dart
new file mode 100644
index 0000000..f75c32c
--- /dev/null
+++ b/tests/compiler/dart2js/least_upper_bound_language_test.dart
@@ -0,0 +1,22 @@
+// 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 dart2js produces the expected static type warnings for least upper

+// bound language tests. This ensures that the analyzer and dart2js agrees

+// on these tests.

+

+import 'warnings_checker.dart';

+

+/// Map from test files to a map of their expected status. If the status map is

+/// `null` no warnings must be missing or unexpected, otherwise the status map

+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

+/// the warnings of each category.

+const Map<String, dynamic> TESTS = const {

+    'language/least_upper_bound_test.dart': null,

+    'language/least_upper_bound_expansive_test.dart': null,

+};

+

+void main() {

+  checkWarnings(TESTS);

+}

diff --git a/tests/compiler/dart2js/least_upper_bound_test.dart b/tests/compiler/dart2js/least_upper_bound_test.dart
new file mode 100644
index 0000000..f263f3b
--- /dev/null
+++ b/tests/compiler/dart2js/least_upper_bound_test.dart
@@ -0,0 +1,853 @@
+// 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 subtype_test;

+

+import 'package:expect/expect.dart';

+import 'package:async_helper/async_helper.dart';

+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;

+import '../../../sdk/lib/_internal/compiler/implementation/util/util.dart'

+       show Link;

+

+void main() {

+  testInterface1();

+  testInterface2();

+  testGeneric();

+  testMixin();

+  testFunction();

+  testTypeVariable();

+}

+

+void testInterface1() {

+  asyncTest(() => TypeEnvironment.create(r"""

+      class A {} // A and B have equal depth.

+      class B {}

+      class I implements A, B {}

+      class J implements A, B {}

+      """).then((env) {

+

+    DartType Object_ = env['Object'];

+    DartType A = env['A'];

+    DartType B = env['B'];

+    DartType I = env['I'];

+    DartType J = env['J'];

+

+    checkLub(DartType a, DartType b, DartType expect) {

+      DartType lub = env.computeLeastUpperBound(a, b);

+      Expect.equals(expect, lub,

+          'Unexpected lub($a,$b) = $lub, expected $expect.');

+    }

+

+    checkLub(Object_, Object_, Object_);

+    checkLub(Object_, A, Object_);

+    checkLub(Object_, B, Object_);

+    checkLub(Object_, I, Object_);

+    checkLub(Object_, J, Object_);

+

+    checkLub(A, Object_, Object_);

+    checkLub(A, A, A);

+    checkLub(A, B, Object_);

+    checkLub(A, I, A);

+    checkLub(A, J, A);

+

+    checkLub(B, Object_, Object_);

+    checkLub(B, A, Object_);

+    checkLub(B, B, B);

+    checkLub(B, I, B);

+    checkLub(B, J, B);

+

+    checkLub(I, Object_, Object_);

+    checkLub(I, A, A);

+    checkLub(I, B, B);

+    checkLub(I, I, I);

+    checkLub(I, J, Object_);

+

+    checkLub(J, Object_, Object_);

+    checkLub(J, A, A);

+    checkLub(J, B, B);

+    checkLub(J, I, Object_);

+    checkLub(J, J, J);

+  }));

+}

+

+void testInterface2() {

+  asyncTest(() => TypeEnvironment.create(r"""

+      class A {}

+      class B {}

+      class C extends B {} // This makes C have higher depth than A.

+      class I implements A, C {}

+      class J implements A, C {}

+      """).then((env) {

+

+    DartType Object_ = env['Object'];

+    DartType A = env['A'];

+    DartType B = env['B'];

+    DartType C = env['C'];

+    DartType I = env['I'];

+    DartType J = env['J'];

+

+    checkLub(DartType a, DartType b, DartType expectedLub) {

+      DartType lub = env.computeLeastUpperBound(a, b);

+      Expect.equals(expectedLub, lub,

+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

+    }

+

+    checkLub(Object_, Object_, Object_);

+    checkLub(Object_, A, Object_);

+    checkLub(Object_, B, Object_);

+    checkLub(Object_, C, Object_);

+    checkLub(Object_, I, Object_);

+    checkLub(Object_, J, Object_);

+

+    checkLub(A, Object_, Object_);

+    checkLub(A, A, A);

+    checkLub(A, B, Object_);

+    checkLub(A, C, Object_);

+    checkLub(A, I, A);

+    checkLub(A, J, A);

+

+    checkLub(B, Object_, Object_);

+    checkLub(B, A, Object_);

+    checkLub(B, B, B);

+    checkLub(B, C, B);

+    checkLub(B, I, B);

+    checkLub(B, J, B);

+

+    checkLub(C, Object_, Object_);

+    checkLub(C, A, Object_);

+    checkLub(C, B, B);

+    checkLub(C, C, C);

+    checkLub(C, I, C);

+    checkLub(C, J, C);

+

+    checkLub(I, Object_, Object_);

+    checkLub(I, A, A);

+    checkLub(I, B, B);

+    checkLub(I, C, C);

+    checkLub(I, I, I);

+    checkLub(I, J, C);

+

+    checkLub(J, Object_, Object_);

+    checkLub(J, A, A);

+    checkLub(J, B, B);

+    checkLub(J, C, C);

+    checkLub(J, I, C);

+    checkLub(J, J, J);

+  }));

+}

+

+void testGeneric() {

+  asyncTest(() => TypeEnvironment.create(r"""

+      class A {}

+      class B {}

+      class C extends B {}

+      class I<T> {}

+      """).then((env) {

+

+    DartType Object_ = env['Object'];

+    DartType A = env['A'];

+    DartType B = env['B'];

+    DartType C = env['C'];

+    ClassElement I = env.getElement('I');

+    DartType I_A = instantiate(I, [A]);

+    DartType I_B = instantiate(I, [B]);

+    DartType I_C = instantiate(I, [C]);

+

+    checkLub(DartType a, DartType b, DartType expectedLub) {

+      DartType lub = env.computeLeastUpperBound(a, b);

+      Expect.equals(expectedLub, lub,

+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

+    }

+

+    checkLub(Object_, Object_, Object_);

+    checkLub(Object_, A, Object_);

+    checkLub(Object_, B, Object_);

+    checkLub(Object_, C, Object_);

+    checkLub(Object_, I_A, Object_);

+    checkLub(Object_, I_B, Object_);

+    checkLub(Object_, I_C, Object_);

+

+    checkLub(A, Object_, Object_);

+    checkLub(A, A, A);

+    checkLub(A, B, Object_);

+    checkLub(A, C, Object_);

+    checkLub(A, I_A, Object_);

+    checkLub(A, I_B, Object_);

+    checkLub(A, I_C, Object_);

+

+    checkLub(B, Object_, Object_);

+    checkLub(B, A, Object_);

+    checkLub(B, B, B);

+    checkLub(B, C, B);

+    checkLub(B, I_A, Object_);

+    checkLub(B, I_B, Object_);

+    checkLub(B, I_C, Object_);

+

+    checkLub(C, Object_, Object_);

+    checkLub(C, A, Object_);

+    checkLub(C, B, B);

+    checkLub(C, C, C);

+    checkLub(C, I_A, Object_);

+    checkLub(C, I_B, Object_);

+    checkLub(C, I_C, Object_);

+

+    checkLub(I_A, Object_, Object_);

+    checkLub(I_A, A, Object_);

+    checkLub(I_A, B, Object_);

+    checkLub(I_A, C, Object_);

+    checkLub(I_A, I_A, I_A);

+    checkLub(I_A, I_B, Object_);

+    checkLub(I_A, I_C, Object_);

+

+    checkLub(I_B, Object_, Object_);

+    checkLub(I_B, A, Object_);

+    checkLub(I_B, B, Object_);

+    checkLub(I_B, C, Object_);

+    checkLub(I_B, I_A, Object_);

+    checkLub(I_B, I_B, I_B);

+    checkLub(I_B, I_C, Object_);

+

+    checkLub(I_C, Object_, Object_);

+    checkLub(I_C, A, Object_);

+    checkLub(I_C, B, Object_);

+    checkLub(I_C, C, Object_);

+    checkLub(I_C, I_A, Object_);

+    checkLub(I_C, I_B, Object_);

+    checkLub(I_C, I_C, I_C);

+  }));

+}

+

+void testMixin() {

+  asyncTest(() => TypeEnvironment.create(r"""

+      class A {}

+      class B {}

+      class C extends B {}

+      class D extends C {} // This makes D have higher depth than Object+A.

+      class I extends Object with A, B implements A, D {}

+      class I2 extends Object with A, B implements A, D {}

+      class J extends Object with B, A implements A, D {}

+      """).then((env) {

+

+    DartType Object_ = env['Object'];

+    DartType A = env['A'];

+    DartType B = env['B'];

+    DartType C = env['C'];

+    DartType D = env['D'];

+    DartType I = env['I'];

+    DartType I2 = env['I2'];

+    DartType J = env['J'];

+

+    checkLub(DartType a, DartType b, DartType expectedLub) {

+      DartType lub = env.computeLeastUpperBound(a, b);

+      Expect.equals(expectedLub, lub,

+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

+    }

+

+    checkLub(Object_, Object_, Object_);

+    checkLub(Object_, A, Object_);

+    checkLub(Object_, B, Object_);

+    checkLub(Object_, C, Object_);

+    checkLub(Object_, D, Object_);

+    checkLub(Object_, I, Object_);

+    checkLub(Object_, I2, Object_);

+    checkLub(Object_, J, Object_);

+

+    checkLub(A, Object_, Object_);

+    checkLub(A, A, A);

+    checkLub(A, B, Object_);

+    checkLub(A, C, Object_);

+    checkLub(A, D, Object_);

+    checkLub(A, I, A);

+    checkLub(A, I2, A);

+    checkLub(A, J, A);

+

+    checkLub(B, Object_, Object_);

+    checkLub(B, A, Object_);

+    checkLub(B, B, B);

+    checkLub(B, C, B);

+    checkLub(B, D, B);

+    checkLub(B, I, B);

+    checkLub(B, I2, B);

+    checkLub(B, J, B);

+

+    checkLub(C, Object_, Object_);

+    checkLub(C, A, Object_);

+    checkLub(C, B, B);

+    checkLub(C, C, C);

+    checkLub(C, D, C);

+    checkLub(C, I, C);

+    checkLub(C, I2, C);

+    checkLub(C, J, C);

+

+    checkLub(D, Object_, Object_);

+    checkLub(D, A, Object_);

+    checkLub(D, B, B);

+    checkLub(D, C, C);

+    checkLub(D, D, D);

+    checkLub(D, I, D);

+    checkLub(D, I2, D);

+    checkLub(D, J, D);

+

+    checkLub(I, Object_, Object_);

+    checkLub(I, A, A);

+    checkLub(I, B, B);

+    checkLub(I, C, C);

+    checkLub(I, D, D);

+    checkLub(I, I, I);

+    checkLub(I, I2, D);

+    checkLub(I, J, D);

+

+    checkLub(I2, Object_, Object_);

+    checkLub(I2, A, A);

+    checkLub(I2, B, B);

+    checkLub(I2, C, C);

+    checkLub(I2, D, D);

+    checkLub(I2, I, D);

+    checkLub(I2, I2, I2);

+    checkLub(I2, J, D);

+

+    checkLub(J, Object_, Object_);

+    checkLub(J, A, A);

+    checkLub(J, B, B);

+    checkLub(J, C, C);

+    checkLub(J, D, D);

+    checkLub(J, I, D);

+    checkLub(J, I2, D);

+    checkLub(J, J, J);

+  }));

+}

+

+void testFunction() {

+  asyncTest(() => TypeEnvironment.create(r"""

+      class A {}

+      class B {}

+      class C extends B {}

+

+      typedef dynamic__();

+      typedef void void__();

+      typedef A A__();

+      typedef B B__();

+      typedef C C__();

+

+      typedef void void__A_B(A a, B b);

+      typedef void void__A_C(A a, C b);

+      typedef void void__B_A(B a, A b);

+      typedef void void__B_C(B a, C b);

+

+      typedef void void___B([B a]);

+      typedef void void___B_C([B a, C b]);

+      typedef void void___C_C([C a, C b]);

+

+      typedef void void____B({B a});

+      typedef void void____B_C({B a, C b});

+      typedef void void____C_C({C a, C b});

+      """).then((env) {

+

+    DartType Object_ = env['Object'];

+    DartType Function_ = env['Function'];

+    DartType dynamic__ = env['dynamic__'];

+    DartType void__ = env['void__'];

+    DartType A__ = env['A__'];

+    DartType B__ = env['B__'];

+    DartType C__ = env['C__'];

+    DartType void__A_B = env['void__A_B'];

+    DartType void__A_C = env['void__A_C'];

+    DartType void__B_A = env['void__B_A'];

+    DartType void__B_C = env['void__B_C'];

+    DartType void___B = env['void___B'];

+    DartType void___B_C = env['void___B_C'];

+    DartType void___C_C = env['void___C_C'];

+    DartType void____B = env['void____B'];

+    DartType void____B_C = env['void____B_C'];

+    DartType void____C_C = env['void____C_C'];

+

+    // Types used only for checking results.

+    DartType void_ = env['void'];

+    DartType B = env['B'];

+    DartType C = env['C'];

+    FunctionType Object__ = env.functionType(Object_, []);

+    FunctionType void__Object_Object =

+        env.functionType(void_, [Object_, Object_]);

+    FunctionType void__Object_B =

+        env.functionType(void_, [Object_, B]);

+    FunctionType void__Object_C =

+        env.functionType(void_, [Object_, C]);

+    FunctionType void__B_Object =

+        env.functionType(void_, [B, Object_]);

+

+    checkLub(DartType a, DartType b, DartType expectedLub) {

+      DartType lub = env.computeLeastUpperBound(a, b);

+      if (a != b) {

+        expectedLub = expectedLub.unalias(env.compiler);

+        lub = lub.unalias(env.compiler);

+      }

+      Expect.equals(expectedLub, lub,

+          'Unexpected lub(${a.unalias(env.compiler)},'

+                         '${b.unalias(env.compiler)}) = '

+                         '${lub}, expected ${expectedLub}');

+    }

+

+    checkLub(Object_, Object_, Object_);

+    checkLub(Object_, Function_, Object_);

+    checkLub(Object_, dynamic__, Object_);

+    checkLub(Object_, void__, Object_);

+    checkLub(Object_, A__, Object_);

+    checkLub(Object_, B__, Object_);

+    checkLub(Object_, C__, Object_);

+    checkLub(Object_, void__A_B, Object_);

+    checkLub(Object_, void__A_C, Object_);

+    checkLub(Object_, void__B_A, Object_);

+    checkLub(Object_, void__B_C, Object_);

+    checkLub(Object_, void___B, Object_);

+    checkLub(Object_, void___B_C, Object_);

+    checkLub(Object_, void___C_C, Object_);

+    checkLub(Object_, void____B, Object_);

+    checkLub(Object_, void____B_C, Object_);

+    checkLub(Object_, void____C_C, Object_);

+

+    checkLub(Function_, Object_, Object_);

+    checkLub(Function_, Function_, Function_);

+    checkLub(Function_, dynamic__, Function_);

+    checkLub(Function_, void__, Function_);

+    checkLub(Function_, A__, Function_);

+    checkLub(Function_, B__, Function_);

+    checkLub(Function_, C__, Function_);

+    checkLub(Function_, void__A_B, Function_);

+    checkLub(Function_, void__A_C, Function_);

+    checkLub(Function_, void__B_A, Function_);

+    checkLub(Function_, void__B_C, Function_);

+    checkLub(Function_, void___B, Function_);

+    checkLub(Function_, void___B_C, Function_);

+    checkLub(Function_, void___C_C, Function_);

+    checkLub(Function_, void____B, Function_);

+    checkLub(Function_, void____B_C, Function_);

+    checkLub(Function_, void____C_C, Function_);

+

+    checkLub(dynamic__, Object_, Object_);

+    checkLub(dynamic__, Function_, Function_);

+    checkLub(dynamic__, dynamic__, dynamic__);

+    checkLub(dynamic__, void__, dynamic__);

+    checkLub(dynamic__, A__, dynamic__);

+    checkLub(dynamic__, B__, dynamic__);

+    checkLub(dynamic__, C__, dynamic__);

+    checkLub(dynamic__, void__A_B, Function_);

+    checkLub(dynamic__, void__A_C, Function_);

+    checkLub(dynamic__, void__B_A, Function_);

+    checkLub(dynamic__, void__B_C, Function_);

+    checkLub(dynamic__, void___B, dynamic__);

+    checkLub(dynamic__, void___B_C, dynamic__);

+    checkLub(dynamic__, void___C_C, dynamic__);

+    checkLub(dynamic__, void____B, dynamic__);

+    checkLub(dynamic__, void____B_C, dynamic__);

+    checkLub(dynamic__, void____C_C, dynamic__);

+

+    checkLub(void__, Object_, Object_);

+    checkLub(void__, Function_, Function_);

+    checkLub(void__, dynamic__, dynamic__);

+    checkLub(void__, void__, void__);

+    checkLub(void__, A__, void__);

+    checkLub(void__, B__, void__);

+    checkLub(void__, C__, void__);

+    checkLub(void__, void__A_B, Function_);

+    checkLub(void__, void__A_C, Function_);

+    checkLub(void__, void__B_A, Function_);

+    checkLub(void__, void__B_C, Function_);

+    checkLub(void__, void___B, void__);

+    checkLub(void__, void___B_C, void__);

+    checkLub(void__, void___C_C, void__);

+    checkLub(void__, void____B, void__);

+    checkLub(void__, void____B_C, void__);

+    checkLub(void__, void____C_C, void__);

+

+    checkLub(A__, Object_, Object_);

+    checkLub(A__, Function_, Function_);

+    checkLub(A__, dynamic__, dynamic__);

+    checkLub(A__, void__, void__);

+    checkLub(A__, A__, A__);

+    checkLub(A__, B__, Object__);

+    checkLub(A__, C__, Object__);

+    checkLub(A__, void__A_B, Function_);

+    checkLub(A__, void__A_C, Function_);

+    checkLub(A__, void__B_A, Function_);

+    checkLub(A__, void__B_C, Function_);

+    checkLub(A__, void___B, void__);

+    checkLub(A__, void___B_C, void__);

+    checkLub(A__, void___C_C, void__);

+    checkLub(A__, void____B, void__);

+    checkLub(A__, void____B_C, void__);

+    checkLub(A__, void____C_C, void__);

+

+    checkLub(B__, Object_, Object_);

+    checkLub(B__, Function_, Function_);

+    checkLub(B__, dynamic__, dynamic__);

+    checkLub(B__, void__, void__);

+    checkLub(B__, A__, Object__);

+    checkLub(B__, B__, B__);

+    checkLub(B__, C__, B__);

+    checkLub(B__, void__A_B, Function_);

+    checkLub(B__, void__A_C, Function_);

+    checkLub(B__, void__B_A, Function_);

+    checkLub(B__, void__B_C, Function_);

+    checkLub(B__, void___B, void__);

+    checkLub(B__, void___B_C, void__);

+    checkLub(B__, void___C_C, void__);

+    checkLub(B__, void____B, void__);

+    checkLub(B__, void____B_C, void__);

+    checkLub(B__, void____C_C, void__);

+

+    checkLub(C__, Object_, Object_);

+    checkLub(C__, Function_, Function_);

+    checkLub(C__, dynamic__, dynamic__);

+    checkLub(C__, void__, void__);

+    checkLub(C__, A__, Object__);

+    checkLub(C__, B__, B__);

+    checkLub(C__, C__, C__);

+    checkLub(C__, void__A_B, Function_);

+    checkLub(C__, void__A_C, Function_);

+    checkLub(C__, void__B_A, Function_);

+    checkLub(C__, void__B_C, Function_);

+    checkLub(C__, void___B, void__);

+    checkLub(C__, void___B_C, void__);

+    checkLub(C__, void___C_C, void__);

+    checkLub(C__, void____B, void__);

+    checkLub(C__, void____B_C, void__);

+    checkLub(C__, void____C_C, void__);

+

+    checkLub(void__A_B, Object_, Object_);

+    checkLub(void__A_B, Function_, Function_);

+    checkLub(void__A_B, dynamic__, Function_);

+    checkLub(void__A_B, void__, Function_);

+    checkLub(void__A_B, A__, Function_);

+    checkLub(void__A_B, B__, Function_);

+    checkLub(void__A_B, C__, Function_);

+    checkLub(void__A_B, void__A_B, void__A_B);

+    checkLub(void__A_B, void__A_C, void__A_B);

+    checkLub(void__A_B, void__B_A, void__Object_Object);

+    checkLub(void__A_B, void__B_C, void__Object_B);

+    checkLub(void__A_B, void___B, Function_);

+    checkLub(void__A_B, void___B_C, Function_);

+    checkLub(void__A_B, void___C_C, Function_);

+    checkLub(void__A_B, void____B, Function_);

+    checkLub(void__A_B, void____B_C, Function_);

+    checkLub(void__A_B, void____C_C, Function_);

+

+    checkLub(void__A_C, Object_, Object_);

+    checkLub(void__A_C, Function_, Function_);

+    checkLub(void__A_C, dynamic__, Function_);

+    checkLub(void__A_C, void__, Function_);

+    checkLub(void__A_C, A__, Function_);

+    checkLub(void__A_C, B__, Function_);

+    checkLub(void__A_C, C__, Function_);

+    checkLub(void__A_C, void__A_B, void__A_B);

+    checkLub(void__A_C, void__A_C, void__A_C);

+    checkLub(void__A_C, void__B_A, void__Object_Object);

+    checkLub(void__A_C, void__B_C, void__Object_C);

+    checkLub(void__A_C, void___B, Function_);

+    checkLub(void__A_C, void___B_C, Function_);

+    checkLub(void__A_C, void___C_C, Function_);

+    checkLub(void__A_C, void____B, Function_);

+    checkLub(void__A_C, void____B_C, Function_);

+    checkLub(void__A_C, void____C_C, Function_);

+

+    checkLub(void__B_A, Object_, Object_);

+    checkLub(void__B_A, Function_, Function_);

+    checkLub(void__B_A, dynamic__, Function_);

+    checkLub(void__B_A, void__, Function_);

+    checkLub(void__B_A, A__, Function_);

+    checkLub(void__B_A, B__, Function_);

+    checkLub(void__B_A, C__, Function_);

+    checkLub(void__B_A, void__A_B, void__Object_Object);

+    checkLub(void__B_A, void__A_C, void__Object_Object);

+    checkLub(void__B_A, void__B_A, void__B_A);

+    checkLub(void__B_A, void__B_C, void__B_Object);

+    checkLub(void__B_A, void___B, Function_);

+    checkLub(void__B_A, void___B_C, Function_);

+    checkLub(void__B_A, void___C_C, Function_);

+    checkLub(void__B_A, void____B, Function_);

+    checkLub(void__B_A, void____B_C, Function_);

+    checkLub(void__B_A, void____C_C, Function_);

+

+    checkLub(void__B_C, Object_, Object_);

+    checkLub(void__B_C, Function_, Function_);

+    checkLub(void__B_C, dynamic__, Function_);

+    checkLub(void__B_C, void__, Function_);

+    checkLub(void__B_C, A__, Function_);

+    checkLub(void__B_C, B__, Function_);

+    checkLub(void__B_C, C__, Function_);

+    checkLub(void__B_C, void__A_B, void__Object_B);

+    checkLub(void__B_C, void__A_C, void__Object_C);

+    checkLub(void__B_C, void__B_A, void__B_Object);

+    checkLub(void__B_C, void__B_C, void__B_C);

+    checkLub(void__B_C, void___B, Function_);

+    checkLub(void__B_C, void___B_C, Function_);

+    checkLub(void__B_C, void___C_C, Function_);

+    checkLub(void__B_C, void____B, Function_);

+    checkLub(void__B_C, void____B_C, Function_);

+    checkLub(void__B_C, void____C_C, Function_);

+

+    checkLub(void___B, Object_, Object_);

+    checkLub(void___B, Function_, Function_);

+    checkLub(void___B, dynamic__, dynamic__);

+    checkLub(void___B, void__, void__);

+    checkLub(void___B, A__, void__);

+    checkLub(void___B, B__, void__);

+    checkLub(void___B, C__, void__);

+    checkLub(void___B, void__A_B, Function_);

+    checkLub(void___B, void__A_C, Function_);

+    checkLub(void___B, void__B_A, Function_);

+    checkLub(void___B, void__B_C, Function_);

+    checkLub(void___B, void___B, void___B);

+    checkLub(void___B, void___B_C, void___B);

+    checkLub(void___B, void___C_C, void___B);

+    checkLub(void___B, void____B, void__);

+    checkLub(void___B, void____B_C, void__);

+    checkLub(void___B, void____C_C, void__);

+

+    checkLub(void___B_C, Object_, Object_);

+    checkLub(void___B_C, Function_, Function_);

+    checkLub(void___B_C, dynamic__, dynamic__);

+    checkLub(void___B_C, void__, void__);

+    checkLub(void___B_C, A__, void__);

+    checkLub(void___B_C, B__, void__);

+    checkLub(void___B_C, C__, void__);

+    checkLub(void___B_C, void__A_B, Function_);

+    checkLub(void___B_C, void__A_C, Function_);

+    checkLub(void___B_C, void__B_A, Function_);

+    checkLub(void___B_C, void__B_C, Function_);

+    checkLub(void___B_C, void___B, void___B);

+    checkLub(void___B_C, void___B_C, void___B_C);

+    checkLub(void___B_C, void___C_C, void___B_C);

+    checkLub(void___B_C, void____B, void__);

+    checkLub(void___B_C, void____B_C, void__);

+    checkLub(void___B_C, void____C_C, void__);

+

+    checkLub(void___C_C, Object_, Object_);

+    checkLub(void___C_C, Function_, Function_);

+    checkLub(void___C_C, dynamic__, dynamic__);

+    checkLub(void___C_C, void__, void__);

+    checkLub(void___C_C, A__, void__);

+    checkLub(void___C_C, B__, void__);

+    checkLub(void___C_C, C__, void__);

+    checkLub(void___C_C, void__A_B, Function_);

+    checkLub(void___C_C, void__A_C, Function_);

+    checkLub(void___C_C, void__B_A, Function_);

+    checkLub(void___C_C, void__B_C, Function_);

+    checkLub(void___C_C, void___B, void___B);

+    checkLub(void___C_C, void___B_C, void___B_C);

+    checkLub(void___C_C, void___C_C, void___C_C);

+    checkLub(void___C_C, void____B, void__);

+    checkLub(void___C_C, void____B_C, void__);

+    checkLub(void___C_C, void____C_C, void__);

+

+    checkLub(void____B, Object_, Object_);

+    checkLub(void____B, Function_, Function_);

+    checkLub(void____B, dynamic__, dynamic__);

+    checkLub(void____B, void__, void__);

+    checkLub(void____B, A__, void__);

+    checkLub(void____B, B__, void__);

+    checkLub(void____B, C__, void__);

+    checkLub(void____B, void__A_B, Function_);

+    checkLub(void____B, void__A_C, Function_);

+    checkLub(void____B, void__B_A, Function_);

+    checkLub(void____B, void__B_C, Function_);

+    checkLub(void____B, void___B, void__);

+    checkLub(void____B, void___B_C, void__);

+    checkLub(void____B, void___C_C, void__);

+    checkLub(void____B, void____B, void____B);

+    checkLub(void____B, void____B_C, void____B);

+    checkLub(void____B, void____C_C, void____B);

+

+    checkLub(void____B_C, Object_, Object_);

+    checkLub(void____B_C, Function_, Function_);

+    checkLub(void____B_C, dynamic__, dynamic__);

+    checkLub(void____B_C, void__, void__);

+    checkLub(void____B_C, A__, void__);

+    checkLub(void____B_C, B__, void__);

+    checkLub(void____B_C, C__, void__);

+    checkLub(void____B_C, void__A_B, Function_);

+    checkLub(void____B_C, void__A_C, Function_);

+    checkLub(void____B_C, void__B_A, Function_);

+    checkLub(void____B_C, void__B_C, Function_);

+    checkLub(void____B_C, void___B, void__);

+    checkLub(void____B_C, void___B_C, void__);

+    checkLub(void____B_C, void___C_C, void__);

+    checkLub(void____B_C, void____B, void____B);

+    checkLub(void____B_C, void____B_C, void____B_C);

+    checkLub(void____B_C, void____C_C, void____B_C);

+

+    checkLub(void____C_C, Object_, Object_);

+    checkLub(void____C_C, Function_, Function_);

+    checkLub(void____C_C, dynamic__, dynamic__);

+    checkLub(void____C_C, void__, void__);

+    checkLub(void____C_C, A__, void__);

+    checkLub(void____C_C, B__, void__);

+    checkLub(void____C_C, C__, void__);

+    checkLub(void____C_C, void__A_B, Function_);

+    checkLub(void____C_C, void__A_C, Function_);

+    checkLub(void____C_C, void__B_A, Function_);

+    checkLub(void____C_C, void__B_C, Function_);

+    checkLub(void____C_C, void___B, void__);

+    checkLub(void____C_C, void___B_C, void__);

+    checkLub(void____C_C, void___C_C, void__);

+    checkLub(void____C_C, void____B, void____B);

+    checkLub(void____C_C, void____B_C, void____B_C);

+    checkLub(void____C_C, void____C_C, void____C_C);

+  }));

+}

+

+void testTypeVariable() {

+  asyncTest(() => TypeEnvironment.create(r"""

+      class A {}

+      class B {}

+      class C extends B {}

+      class I<S extends A,

+              T extends B,

+              U extends C,

+              V extends T,

+              W extends V,

+              X extends T> {}

+      """).then((env) {

+

+    //  A     B

+    //  |    / \

+    //  S   T   C

+    //     / \   \

+    //    V   X   U

+    //   /

+    //  W

+

+    DartType Object_ = env['Object'];

+    DartType A = env['A'];

+    DartType B = env['B'];

+    DartType C = env['C'];

+    ClassElement I = env.getElement('I');

+    DartType S = I.typeVariables.head;

+    DartType T = I.typeVariables.tail.head;

+    DartType U = I.typeVariables.tail.tail.head;

+    DartType V = I.typeVariables.tail.tail.tail.head;

+    DartType W = I.typeVariables.tail.tail.tail.tail.head;

+    DartType X = I.typeVariables.tail.tail.tail.tail.tail.head;

+

+    checkLub(DartType a, DartType b, DartType expectedLub) {

+      DartType lub = env.computeLeastUpperBound(a, b);

+      Expect.equals(expectedLub, lub,

+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

+    }

+

+    checkLub(Object_, Object_, Object_);

+    checkLub(Object_, A, Object_);

+    checkLub(Object_, B, Object_);

+    checkLub(Object_, C, Object_);

+    checkLub(Object_, S, Object_);

+    checkLub(Object_, T, Object_);

+    checkLub(Object_, U, Object_);

+    checkLub(Object_, V, Object_);

+    checkLub(Object_, W, Object_);

+    checkLub(Object_, X, Object_);

+

+    checkLub(A, Object_, Object_);

+    checkLub(A, A, A);

+    checkLub(A, B, Object_);

+    checkLub(A, C, Object_);

+    checkLub(A, S, A);

+    checkLub(A, T, Object_);

+    checkLub(A, U, Object_);

+    checkLub(A, V, Object_);

+    checkLub(A, W, Object_);

+    checkLub(A, X, Object_);

+

+    checkLub(B, Object_, Object_);

+    checkLub(B, A, Object_);

+    checkLub(B, B, B);

+    checkLub(B, C, B);

+    checkLub(B, S, Object_);

+    checkLub(B, T, B);

+    checkLub(B, U, B);

+    checkLub(B, V, B);

+    checkLub(B, W, B);

+    checkLub(B, X, B);

+

+    checkLub(C, Object_, Object_);

+    checkLub(C, A, Object_);

+    checkLub(C, B, B);

+    checkLub(C, C, C);

+    checkLub(C, S, Object_);

+    checkLub(C, T, B);

+    checkLub(C, U, C);

+    checkLub(C, V, B);

+    checkLub(C, W, B);

+    checkLub(C, X, B);

+

+    checkLub(S, Object_, Object_);

+    checkLub(S, A, A);

+    checkLub(S, B, Object_);

+    checkLub(S, C, Object_);

+    checkLub(S, S, S);

+    checkLub(S, T, Object_);

+    checkLub(S, U, Object_);

+    checkLub(S, V, Object_);

+    checkLub(S, W, Object_);

+    checkLub(S, X, Object_);

+

+    checkLub(T, Object_, Object_);

+    checkLub(T, A, Object_);

+    checkLub(T, B, B);

+    checkLub(T, C, B);

+    checkLub(T, S, Object_);

+    checkLub(T, T, T);

+    checkLub(T, U, B);

+    checkLub(T, V, T);

+    checkLub(T, W, T);

+    checkLub(T, X, T);

+

+    checkLub(U, Object_, Object_);

+    checkLub(U, A, Object_);

+    checkLub(U, B, B);

+    checkLub(U, C, C);

+    checkLub(U, S, Object_);

+    checkLub(U, T, B);

+    checkLub(U, U, U);

+    checkLub(U, V, B);

+    checkLub(U, W, B);

+    checkLub(U, X, B);

+

+    checkLub(V, Object_, Object_);

+    checkLub(V, A, Object_);

+    checkLub(V, B, B);

+    checkLub(V, C, B);

+    checkLub(V, S, Object_);

+    checkLub(V, T, T);

+    checkLub(V, U, B);

+    checkLub(V, V, V);

+    checkLub(V, W, V);

+    checkLub(V, X, T);

+

+    checkLub(W, Object_, Object_);

+    checkLub(W, A, Object_);

+    checkLub(W, B, B);

+    checkLub(W, C, B);

+    checkLub(W, S, Object_);

+    checkLub(W, T, T);

+    checkLub(W, U, B);

+    checkLub(W, V, V);

+    checkLub(W, W, W);

+    checkLub(W, X, T);

+

+    checkLub(X, Object_, Object_);

+    checkLub(X, A, Object_);

+    checkLub(X, B, B);

+    checkLub(X, C, B);

+    checkLub(X, S, Object_);

+    checkLub(X, T, T);

+    checkLub(X, U, B);

+    checkLub(X, V, T);

+    checkLub(X, W, T);

+    checkLub(X, X, X);

+  }));

+}

+

+

diff --git a/tests/compiler/dart2js/list_tracer2_test.dart b/tests/compiler/dart2js/list_tracer2_test.dart
index cb7734d..56c5fff 100644
--- a/tests/compiler/dart2js/list_tracer2_test.dart
+++ b/tests/compiler/dart2js/list_tracer2_test.dart
@@ -35,6 +35,6 @@
       Expect.equals(type, mask.elementType.simplify(compiler), name);
     }
 
-    checkType('myList', compiler.typesTask.intType);
+    checkType('myList', compiler.typesTask.uint31Type);
   }));
 }
diff --git a/tests/compiler/dart2js/list_tracer_test.dart b/tests/compiler/dart2js/list_tracer_test.dart
index aaa56b5..e599732 100644
--- a/tests/compiler/dart2js/list_tracer_test.dart
+++ b/tests/compiler/dart2js/list_tracer_test.dart
@@ -209,15 +209,15 @@
     checkType('listPassedToSelector', typesTask.numType);
     checkType('listReturnedFromSelector', typesTask.numType);
     checkType('listUsedWithAddAndInsert', typesTask.numType);
-    checkType('listUsedWithConstraint', typesTask.intType);
+    checkType('listUsedWithConstraint', typesTask.positiveIntType);
     checkType('listEscapingFromSetter', typesTask.numType);
     checkType('listUsedInLocal', typesTask.numType);
     checkType('listEscapingInSetterValue', typesTask.numType);
     checkType('listEscapingInIndex', typesTask.numType);
-    checkType('listEscapingInIndexSet', typesTask.intType);
+    checkType('listEscapingInIndexSet', typesTask.uint31Type);
     checkType('listEscapingTwiceInIndexSet', typesTask.numType);
     checkType('listSetInNonFinalField', typesTask.numType);
-    checkType('listWithChangedLength', typesTask.intType.nullable());
+    checkType('listWithChangedLength', typesTask.uint31Type.nullable());
 
     checkType('listPassedToClosure', typesTask.dynamicType);
     checkType('listReturnedFromClosure', typesTask.dynamicType);
@@ -227,8 +227,7 @@
 
     if (!allocation.contains('filled')) {
       checkType('listUnset', new TypeMask.nonNullEmpty());
-      // TODO(ngeoffray): Re-enable this test.
-      // checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
+      checkType('listOnlySetWithConstraint', new TypeMask.nonNullEmpty());
     }
   }));
 }
diff --git a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
index fcedf81..95c7e6b 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer2_test.dart
@@ -28,7 +28,7 @@
     var element = findElement(compiler, 'field');
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;        
-    Expect.equals(typesTask.intType,
+    Expect.equals(typesTask.uint31Type,
                   typesInferrer.getTypeOfElement(element).simplify(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 fb0c0a1..0dccbe2 100644
--- a/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
+++ b/tests/compiler/dart2js/mirror_final_field_inferrer_test.dart
@@ -28,7 +28,7 @@
     var element = findElement(compiler, 'field');
     var typesTask = compiler.typesTask;
     var typesInferrer = typesTask.typesInferrer;        
-    Expect.equals(typesTask.intType,
+    Expect.equals(typesTask.uint31Type,
                   typesInferrer.getTypeOfElement(element).simplify(compiler),
                   'field');
   }));
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 15ce07c..8269768 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -122,6 +122,9 @@
     toString() {}
     operator+(other) => this;
   }
+  class JSPositiveInt extends JSInt {}
+  class JSUInt32 extends JSPositiveInt {}
+  class JSUInt31 extends JSUInt32 {}
   class JSNumber extends Interceptor implements num {
     // All these methods return a number to please type inferencing.
     operator-() => (this is JSInt) ? 42 : 42.2;
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 9081c3d..72277c8 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -646,10 +646,20 @@
 testClassHierarchy() {
   final MAIN = "main";
   MockCompiler compiler = new MockCompiler();
+  compiler.parseScript("""class A extends A {}
+                          main() { return new A(); }""");
+  FunctionElement mainElement = compiler.mainApp.find(MAIN);
+  compiler.resolver.resolve(mainElement);
+  Expect.equals(0, compiler.warnings.length);
+  Expect.equals(1, compiler.errors.length);
+  Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
+                compiler.errors[0].message.kind);
+
+  compiler = new MockCompiler();
   compiler.parseScript("""class A extends B {}
                           class B extends A {}
                           main() { return new A(); }""");
-  FunctionElement mainElement = compiler.mainApp.find(MAIN);
+  mainElement = compiler.mainApp.find(MAIN);
   compiler.resolver.resolve(mainElement);
   Expect.equals(0, compiler.warnings.length);
   Expect.equals(2, compiler.errors.length);
@@ -714,6 +724,17 @@
   supertypes = aElement.allSupertypes;
   Expect.equals(<String>['A<E>', 'D', 'Object'].toString(),
                 asSortedStrings(supertypes).toString());
+
+  compiler = new MockCompiler();
+  compiler.parseScript("""class A<T> {}
+                          class D extends A<int> implements A<double> {}
+                          main() { return new D(); }""");
+  mainElement = compiler.mainApp.find(MAIN);
+  compiler.resolver.resolve(mainElement);
+  Expect.equals(0, compiler.warnings.length);
+  Expect.equals(1, compiler.errors.length);
+  Expect.equals(MessageKind.MULTI_INHERITANCE,
+                compiler.errors[0].message.kind);
 }
 
 testInitializers() {
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index e087982..3476096 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -123,14 +123,15 @@
     checkReturn(String name, type) {
       var element = findElement(compiler, name);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          name);
     }
 
-    checkReturn('returnInt1', compiler.typesTask.intType);
-    checkReturn('returnInt2', compiler.typesTask.intType);
-    checkReturn('returnInt3', compiler.typesTask.intType);
-    checkReturn('returnInt4', compiler.typesTask.intType);
-    checkReturn('returnIntOrNull', compiler.typesTask.intType.nullable());
+    checkReturn('returnInt1', compiler.typesTask.uint31Type);
+    checkReturn('returnInt2', compiler.typesTask.uint31Type);
+    checkReturn('returnInt3', compiler.typesTask.uint31Type);
+    checkReturn('returnInt4', compiler.typesTask.uint31Type);
+    checkReturn('returnIntOrNull', compiler.typesTask.uint31Type.nullable());
 
     checkReturn('returnDyn1', compiler.typesTask.dynamicType.nonNullable());
     checkReturn('returnDyn2', compiler.typesTask.dynamicType.nonNullable());
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
index a18aa9a..9447cfb 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field2_test.dart
@@ -36,7 +36,7 @@
       Expect.equals(type, typesInferrer.getTypeOfElement(element));
     }
 
-    checkFieldTypeInClass('A', 'intField', compiler.typesTask.intType);
+    checkFieldTypeInClass('A', 'intField', compiler.typesTask.uint31Type);
     checkFieldTypeInClass('A', 'stringField', compiler.typesTask.stringType);
   }));
 }
diff --git a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
index 7c195c3..15f77ab 100644
--- a/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_final_field_test.dart
@@ -39,11 +39,11 @@
           typesInferrer.getTypeOfElement(element).simplify(compiler));
     }
 
-    checkFieldTypeInClass('A', 'intField', compiler.typesTask.intType);
+    checkFieldTypeInClass('A', 'intField', compiler.typesTask.uint31Type);
     checkFieldTypeInClass('A', 'giveUpField1',
         findTypeMask(compiler, 'Interceptor', 'nonNullSubclass'));
     checkFieldTypeInClass('A', 'giveUpField2',
         compiler.typesTask.dynamicType.nonNullable());
-    checkFieldTypeInClass('A', 'fieldParameter', compiler.typesTask.intType);
+    checkFieldTypeInClass('A', 'fieldParameter', compiler.typesTask.uint31Type);
   }));
 }
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 bc17e71..3daef45 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -107,10 +107,10 @@
 
   var compiler1 = compilerFor(TEST1, uri);
   asyncTest(() => compiler1.runCompiler(uri).then((_) {
-    checkReturn(compiler1, 'test1', compiler1.typesTask.intType);
+    checkReturn(compiler1, 'test1', compiler1.typesTask.uint31Type);
     checkReturn(compiler1, 'test2',
         compiler1.typesTask.dynamicType.nonNullable());
-    checkReturn(compiler1, 'test3', compiler1.typesTask.intType);
+    checkReturn(compiler1, 'test3', compiler1.typesTask.uint31Type);
     checkReturn(compiler1, 'test4', compiler1.typesTask.mapType);
     checkReturn(compiler1, 'test5',
         compiler1.typesTask.dynamicType.nonNullable());
@@ -127,9 +127,9 @@
     checkReturn(compiler2, 'test5', compiler2.typesTask.mapType);
 
     checkReturn(compiler2, 'test6', compiler2.typesTask.numType);
-    checkReturn(compiler2, 'test7', compiler2.typesTask.intType);
-    checkReturn(compiler2, 'test8', compiler2.typesTask.intType);
-    checkReturn(compiler2, 'test9', compiler2.typesTask.intType);
+    checkReturn(compiler2, 'test7', compiler2.typesTask.uint31Type);
+    checkReturn(compiler2, 'test8', compiler2.typesTask.uint31Type);
+    checkReturn(compiler2, 'test9', compiler2.typesTask.uint31Type);
     checkReturn(compiler2, 'test10', compiler2.typesTask.numType);
     checkReturn(compiler2, 'test11', compiler2.typesTask.doubleType);
   }));
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 93d2737..81007d0 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -717,18 +717,18 @@
 
     checkReturn('returnNum1', typesTask.numType);
     checkReturn('returnNum2', typesTask.numType);
-    checkReturn('returnInt1', typesTask.intType);
-    checkReturn('returnInt2', typesTask.intType);
+    checkReturn('returnInt1', typesTask.uint31Type);
+    checkReturn('returnInt2', typesTask.uint31Type);
     checkReturn('returnDouble', typesTask.doubleType);
     checkReturn('returnGiveUp', interceptorType);
-    checkReturn('returnInt5', typesTask.intType);
-    checkReturn('returnInt6', typesTask.intType);
-    checkReturn('returnIntOrNull', typesTask.intType.nullable());
-    checkReturn('returnInt3', typesTask.intType);
+    checkReturn('returnInt5', typesTask.positiveIntType);
+    checkReturn('returnInt6', typesTask.positiveIntType);
+    checkReturn('returnIntOrNull', typesTask.uint31Type.nullable());
+    checkReturn('returnInt3', typesTask.uint31Type);
     checkReturn('returnDynamic', typesTask.dynamicType);
-    checkReturn('returnInt4', typesTask.intType);
-    checkReturn('returnInt7', typesTask.intType);
-    checkReturn('returnInt8', typesTask.intType);
+    checkReturn('returnInt4', typesTask.uint31Type);
+    checkReturn('returnInt7', typesTask.positiveIntType);
+    checkReturn('returnInt8', typesTask.positiveIntType);
     checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
     checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
     TypeMask intType = new TypeMask.nonNullSubtype(compiler.intClass);
@@ -761,60 +761,61 @@
     checkReturn('testIsCheck27', intType);
     checkReturn('testIsCheck28', typesTask.dynamicType);
     checkReturn('testIsCheck29', typesTask.dynamicType);
-    checkReturn('testIf1', typesTask.intType.nullable());
-    checkReturn('testIf2', typesTask.intType.nullable());
+    checkReturn('testIf1', typesTask.uint31Type.nullable());
+    checkReturn('testIf2', typesTask.uint31Type.nullable());
     checkReturn('returnAsString',
         new TypeMask.subtype(compiler.stringClass));
-    checkReturn('returnIntAsNum', typesTask.intType);
+    checkReturn('returnIntAsNum', typesTask.uint31Type);
     checkReturn('returnAsTypedef', typesTask.functionType.nullable());
-    checkReturn('returnTopLevelGetter', typesTask.intType);
-    checkReturn('testDeadCode', typesTask.intType);
-    checkReturn('testLabeledIf', typesTask.intType.nullable());
+    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('testSwitch2', typesTask.intType);
+    checkReturn('testSwitch2', typesTask.uint31Type);
     checkReturn('testSwitch3', interceptorType.nullable());
-    checkReturn('testSwitch4', typesTask.intType);
-    checkReturn('testSwitch5', typesTask.intType);
+    checkReturn('testSwitch4', typesTask.uint31Type);
+    checkReturn('testSwitch5', typesTask.uint31Type);
     checkReturn('testContinue1', interceptorType.nullable());
     checkReturn('testBreak1', interceptorType.nullable());
     checkReturn('testContinue2', interceptorType.nullable());
-    checkReturn('testBreak2', typesTask.intType.nullable());
-    checkReturn('testReturnElementOfConstList1', typesTask.intType);
-    checkReturn('testReturnElementOfConstList2', typesTask.intType);
-    checkReturn('testReturnItselfOrInt', typesTask.intType);
+    checkReturn('testBreak2', typesTask.positiveIntType.nullable());
+    checkReturn('testReturnElementOfConstList1', typesTask.uint31Type);
+    checkReturn('testReturnElementOfConstList2', typesTask.uint31Type);
+    checkReturn('testReturnItselfOrInt', typesTask.uint31Type);
     checkReturn('testReturnInvokeDynamicGetter', typesTask.dynamicType);
 
     checkReturn('testDoWhile1', typesTask.stringType);
     checkReturn('testDoWhile2', typesTask.nullType);
-    checkReturn('testDoWhile3', typesTask.intType);
+    checkReturn('testDoWhile3', typesTask.uint31Type);
     checkReturn('testDoWhile4', typesTask.numType);
 
     checkReturnInClass(String className, String methodName, type) {
       var cls = findElement(compiler, className);
       var element = cls.lookupLocalMember(methodName);
       Expect.equals(type,
-          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+          typesInferrer.getReturnTypeOfElement(element).simplify(compiler),
+          '$className:$methodName');
     }
 
-    checkReturnInClass('A', 'returnInt1', typesTask.intType);
-    checkReturnInClass('A', 'returnInt2', typesTask.intType);
-    checkReturnInClass('A', 'returnInt3', typesTask.intType);
-    checkReturnInClass('A', 'returnInt4', typesTask.intType);
-    checkReturnInClass('A', 'returnInt5', typesTask.intType);
-    checkReturnInClass('A', 'returnInt6', typesTask.intType);
+    checkReturnInClass('A', 'returnInt1', typesTask.positiveIntType);
+    checkReturnInClass('A', 'returnInt2', typesTask.positiveIntType);
+    checkReturnInClass('A', 'returnInt3', typesTask.positiveIntType);
+    checkReturnInClass('A', 'returnInt4', typesTask.positiveIntType);
+    checkReturnInClass('A', 'returnInt5', typesTask.positiveIntType);
+    checkReturnInClass('A', 'returnInt6', typesTask.positiveIntType);
     checkReturnInClass('A', '==', interceptorType);
 
-    checkReturnInClass('B', 'returnInt1', typesTask.intType);
-    checkReturnInClass('B', 'returnInt2', typesTask.intType);
-    checkReturnInClass('B', 'returnInt3', typesTask.intType);
-    checkReturnInClass('B', 'returnInt4', typesTask.intType);
-    checkReturnInClass('B', 'returnInt5', typesTask.intType);
-    checkReturnInClass('B', 'returnInt6', typesTask.intType);
-    checkReturnInClass('B', 'returnInt7', typesTask.intType);
-    checkReturnInClass('B', 'returnInt8', typesTask.intType);
-    checkReturnInClass('B', 'returnInt9', typesTask.intType);
+    checkReturnInClass('B', 'returnInt1', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt2', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt3', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt4', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt5', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt6', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt7', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt8', typesTask.positiveIntType);
+    checkReturnInClass('B', 'returnInt9', typesTask.uint31Type);
 
     checkFactoryConstructor(String className, String factoryName) {
       var cls = findElement(compiler, className);
@@ -829,7 +830,7 @@
         findElement(compiler, 'CascadeHelper')));
     checkReturn('testSpecialization1', typesTask.numType);
     checkReturn('testSpecialization2', typesTask.dynamicType);
-    checkReturn('testSpecialization3', typesTask.intType.nullable());
+    checkReturn('testSpecialization3', typesTask.uint31Type.nullable());
     checkReturn('testReturnNull1', typesTask.nullType);
     checkReturn('testReturnNull2', typesTask.nullType);
     checkReturn('testReturnNull3', typesTask.dynamicType);
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index 55ed3a7..331f76a 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -177,11 +177,11 @@
           typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
     }
 
-    checkReturn('returnInt1', typesTask.intType);
-    checkReturn('returnInt2', typesTask.intType);
-    checkReturn('returnInt3', typesTask.intType);
-    checkReturn('returnInt4', typesTask.intType);
-    checkReturn('returnInt5', typesTask.intType);
+    checkReturn('returnInt1', typesTask.uint31Type);
+    checkReturn('returnInt2', typesTask.uint31Type);
+    checkReturn('returnInt3', typesTask.uint31Type);
+    checkReturn('returnInt4', typesTask.uint31Type);
+    checkReturn('returnInt5', typesTask.uint31Type);
     checkReturn('returnInt6',
         new TypeMask.nonNullSubtype(compiler.intClass));
 
diff --git a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
index 3244287..5c2e11f 100644
--- a/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_unregister_call_test.dart
@@ -41,6 +41,6 @@
       Expect.equals(type, typesInferrer.getReturnTypeOfElement(element));
     }
 
-    checkReturnInClass('A', '+', compiler.typesTask.intType);
+    checkReturnInClass('A', '+', compiler.typesTask.uint31Type);
   }));
 }
diff --git a/tests/compiler/dart2js/type_promotion_test.dart b/tests/compiler/dart2js/type_promotion_test.dart
index a25c221..8739394 100644
--- a/tests/compiler/dart2js/type_promotion_test.dart
+++ b/tests/compiler/dart2js/type_promotion_test.dart
@@ -3,18 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.

 

 // Test that dart2js produces the expected static type warnings for type

-// promotion langauge tests. This ensures that the analyzer and dart2js agrees

+// promotion language tests. This ensures that the analyzer and dart2js agrees

 // on these tests.

 

-import 'dart:async';

-import 'dart:io';

-import 'package:expect/expect.dart';

-import 'memory_compiler.dart';

-import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';

-import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart';

-import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart';

-import '../../../sdk/lib/_internal/compiler/implementation/util/uri_extras.dart';

-import 'dart:convert';

+import 'warnings_checker.dart';

 

 /// Map from test files to a map of their expected status. If the status map is

 /// `null` no warnings must be missing or unexpected, otherwise the status map

@@ -33,64 +25,5 @@
 };

 

 void main() {

-  bool isWindows = Platform.isWindows;

-  Uri script = currentDirectory.resolveUri(Platform.script);

-  bool warningsMismatch = false;

-  Future.forEach(TESTS.keys, (String test) {

-    Uri uri = script.resolve('../../$test');

-    String source = UTF8.decode(readAll(uriPathToNative(uri.path)));

-    SourceFile file = new StringSourceFile(

-        relativize(currentDirectory, uri, isWindows), source);

-    Map<int,String> expectedWarnings = {};

-    int lineNo = 0;

-    for (String line in source.split('\n')) {

-      if (line.contains('///') && line.contains('static type warning')) {

-        expectedWarnings[lineNo] = line;

-      }

-      lineNo++;

-    }

-    Set<int> unseenWarnings = new Set<int>.from(expectedWarnings.keys);

-    DiagnosticCollector collector = new DiagnosticCollector();

-    var compiler = compilerFor(const {},

-         diagnosticHandler: collector,

-         options: ['--analyze-only'],

-         showDiagnostics: false);

-    return compiler.run(uri).then((_) {

-      Map<String, List<int>> statusMap = TESTS[test];

-      // Line numbers with known unexpected warnings.

-      List<int> unexpectedStatus = [];

-      if (statusMap != null && statusMap.containsKey('unexpected')) {

-        unexpectedStatus = statusMap['unexpected'];

-      }

-      // Line numbers with known missing warnings.

-      List<int> missingStatus = [];

-      if (statusMap != null && statusMap.containsKey('missing')) {

-        missingStatus = statusMap['missing'];

-      }

-      for (DiagnosticMessage message in collector.warnings) {

-        Expect.equals(uri, message.uri);

-        int lineNo = file.getLine(message.begin);

-        if (expectedWarnings.containsKey(lineNo)) {

-          unseenWarnings.remove(lineNo);

-        } else if (!unexpectedStatus.contains(lineNo+1)) {

-          warningsMismatch = true;

-          print(file.getLocationMessage(

-              'Unexpected warning: ${message.message}',

-              message.begin, message.end, true, (x) => x));

-        }

-      }

-      if (!unseenWarnings.isEmpty) {

-        for (int lineNo in unseenWarnings) {

-          if (!missingStatus.contains(lineNo+1)) {

-            warningsMismatch = true;

-            String line = expectedWarnings[lineNo];

-            print('$uri [${lineNo+1}]: Missing static type warning.');

-            print(line);

-          }

-        }

-      }

-    });

-  }).then((_) {

-    Expect.isFalse(warningsMismatch);

-  });

+  checkWarnings(TESTS);

 }

diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 7f2a8fd..d616835 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -71,6 +71,10 @@
     return compiler.types.isMoreSpecific(T, S);
   }
 
+  DartType computeLeastUpperBound(DartType T, DartType S) {
+    return compiler.types.computeLeastUpperBound(T, S);
+  }
+
   FunctionType functionType(DartType returnType,
                             List<DartType> parameters,
                             {List<DartType> optionalParameter,
@@ -88,7 +92,7 @@
         namedParameterTypes.addLast(type);
       });
     }
-    FunctionType type = new FunctionType(
+    return new FunctionType(
         compiler.functionClass,
         returnType, parameterTypes, optionalParameterTypes,
         namedParameterNames.toLink(), namedParameterTypes.toLink());
diff --git a/tests/compiler/dart2js/value_range2_test.dart b/tests/compiler/dart2js/value_range2_test.dart
index 3b5bfeb..df274a8 100644
--- a/tests/compiler/dart2js/value_range2_test.dart
+++ b/tests/compiler/dart2js/value_range2_test.dart
@@ -10,7 +10,7 @@
 ValueRangeInfo info = new ValueRangeInfo(const JavaScriptConstantSystem());
 
 Value instructionValue = info.newInstructionValue(new HBreak(null));
-Value lengthValue = info.newLengthValue(new HBreak(null));
+Value lengthValue = info.newPositiveValue(new HBreak(null));
 
 Range createSingleRange(Value value) => info.newNormalizedRange(value, value);
 
diff --git a/tests/compiler/dart2js/value_range3_test.dart b/tests/compiler/dart2js/value_range3_test.dart
new file mode 100644
index 0000000..d2c95c8
--- /dev/null
+++ b/tests/compiler/dart2js/value_range3_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.
+
+// Test that global analysis in dart2js propagates positive integers.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'memory_compiler.dart';
+
+const MEMORY_SOURCE_FILES = const {
+  'main.dart': '''
+
+var a = [42];
+
+main() {
+  var value = a[0];
+  if (value < 42) {
+    return new List(42)[value];
+  }
+}
+''',
+};
+
+main() {
+  var compiler = compilerFor(MEMORY_SOURCE_FILES);  
+  asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    var element = compiler.mainApp.findExported('main');
+    var code = compiler.backend.assembleCode(element);
+    Expect.isFalse(code.contains('ioore'));
+  }));
+}
+
diff --git a/tests/compiler/dart2js/value_range_test.dart b/tests/compiler/dart2js/value_range_test.dart
index e4b9572..92ae4c4 100644
--- a/tests/compiler/dart2js/value_range_test.dart
+++ b/tests/compiler/dart2js/value_range_test.dart
@@ -334,6 +334,9 @@
   }
   class ObjectInterceptor {
   }
+  class JSPositiveInt extends JSInt {}
+  class JSUInt32 extends JSPositiveInt {}
+  class JSUInt31 extends JSUInt32 {}
   getInterceptor(x) {}''';
 
 expect(String code, int kind) {
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
new file mode 100644
index 0000000..1105b38
--- /dev/null
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -0,0 +1,80 @@
+// 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 dart2js produces the expected static type warnings to ensures that

+// the analyzer and dart2js agrees on the tests.

+

+import 'dart:async';

+import 'dart:io';

+import 'package:expect/expect.dart';

+import 'package:async_helper/async_helper.dart';

+import 'memory_compiler.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/source_file.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart';

+import '../../../sdk/lib/_internal/compiler/implementation/util/uri_extras.dart';

+import 'dart:convert';

+

+void checkWarnings(Map<String, dynamic> tests) {

+  bool isWindows = Platform.isWindows;

+  Uri script = currentDirectory.resolveUri(Platform.script);

+  bool warningsMismatch = false;

+  asyncTest(() => Future.forEach(tests.keys, (String test) {

+    Uri uri = script.resolve('../../$test');

+    String source = UTF8.decode(readAll(uriPathToNative(uri.path)));

+    SourceFile file = new StringSourceFile(

+        relativize(currentDirectory, uri, isWindows), source);

+    Map<int,String> expectedWarnings = {};

+    int lineNo = 0;

+    for (String line in source.split('\n')) {

+      if (line.contains('///') && line.contains('static type warning')) {

+        expectedWarnings[lineNo] = line;

+      }

+      lineNo++;

+    }

+    Set<int> unseenWarnings = new Set<int>.from(expectedWarnings.keys);

+    DiagnosticCollector collector = new DiagnosticCollector();

+    var compiler = compilerFor(const {},

+         diagnosticHandler: collector,

+         options: ['--analyze-only'],

+         showDiagnostics: false);

+    return compiler.run(uri).then((_) {

+      Map<String, List<int>> statusMap = tests[test];

+      // Line numbers with known unexpected warnings.

+      List<int> unexpectedStatus = [];

+      if (statusMap != null && statusMap.containsKey('unexpected')) {

+        unexpectedStatus = statusMap['unexpected'];

+      }

+      // Line numbers with known missing warnings.

+      List<int> missingStatus = [];

+      if (statusMap != null && statusMap.containsKey('missing')) {

+        missingStatus = statusMap['missing'];

+      }

+      for (DiagnosticMessage message in collector.warnings) {

+        Expect.equals(uri, message.uri);

+        int lineNo = file.getLine(message.begin);

+        if (expectedWarnings.containsKey(lineNo)) {

+          unseenWarnings.remove(lineNo);

+        } else if (!unexpectedStatus.contains(lineNo+1)) {

+          warningsMismatch = true;

+          print(file.getLocationMessage(

+              'Unexpected warning: ${message.message}',

+              message.begin, message.end, true, (x) => x));

+        }

+      }

+      if (!unseenWarnings.isEmpty) {

+        for (int lineNo in unseenWarnings) {

+          if (!missingStatus.contains(lineNo+1)) {

+            warningsMismatch = true;

+            String line = expectedWarnings[lineNo];

+            print('$uri [${lineNo+1}]: Missing static type warning.');

+            print(line);

+          }

+        }

+      }

+    });

+  }).then((_) {

+    Expect.isFalse(warningsMismatch);

+  }));

+}

diff --git a/tests/compiler/dart2js_extra/mirrors_used_native_test.dart b/tests/compiler/dart2js_extra/mirrors_used_native_test.dart
index f040e5b..a546682 100644
--- a/tests/compiler/dart2js_extra/mirrors_used_native_test.dart
+++ b/tests/compiler/dart2js_extra/mirrors_used_native_test.dart
@@ -8,7 +8,6 @@
 import 'package:expect/expect.dart';
 
 main() {
-  List;  // work-around for a bug in the type-variable handler. TODO(zarah): remove.
   Expect.equals(3, reflect([1, 2, 3]).getField(#length).reflectee);
   Expect.throws(() => reflect({"hest": 42}).getField(#length),
                 (e) => e is UnsupportedError);
diff --git a/tests/compiler/dart2js_extra/type_constant_switch_test.dart b/tests/compiler/dart2js_extra/type_constant_switch_test.dart
new file mode 100644
index 0000000..b28d6dc
--- /dev/null
+++ b/tests/compiler/dart2js_extra/type_constant_switch_test.dart
@@ -0,0 +1,16 @@
+// 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 switching on type literals leads to a compile time error in
+// dart2js since its implementation of [Type] implements 'operator =='.
+
+class C {}
+
+var v;
+
+main() {
+  switch (v) {
+    case C: break;  /// 01: compile-time error
+  }
+}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 7e0a5e1..944143f 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -86,8 +86,6 @@
 string_base_vm_test: RuntimeError, OK # VM specific test.
 nan_infinity_test/01: Fail # Issue 11551
 
-list_test/01: RuntimeError # Issue 14616
-
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
@@ -136,6 +134,9 @@
 [ $arch == simmips && $checked ]
 collection_length_test: Pass, Timeout
 
+[ $arch == simarm && $checked ]
+num_parse_test: Pass, Timeout
+
 [ $arch == simmips && $mode == debug ]
 collection_to_string_test: Pass, Crash # Issue: 11207
 
@@ -144,3 +145,10 @@
 iterable_element_at_test: StaticWarning, OK # Test generates errors on purpose.
 num_clamp_test: StaticWarning, OK # Test generates errors on purpose.
 string_test: StaticWarning, OK # Test generates error on purpose.
+
+[ $compiler == dart2js && $runtime == safari ]
+list_test/01: Fail # Safari bug: Array(-2) seen as dead code.
+
+[ $runtime == ie9 || $runtime == ie10 ]
+num_parse_test: RuntimeError  # Issue 15316
+num_parse_test/01: RuntimeError  # Issue 15316
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index bdd449a..5187ee8 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -497,8 +497,8 @@
 
 void testListConstructor() {
   Expect.throws(() { new List(0).add(4); });  // Is fixed-length.
-  Expect.throws(() { new List(-2); });  // Not negative.
-  Expect.throws(() { new List(null); });  // Not null. /// 01: ok
+  Expect.throws(() { new List(-2); });  // Not negative. /// 01: ok
+  Expect.throws(() { new List(null); });  // Not null.
   Expect.listEquals([4], new List()..add(4));
   Expect.throws(() { new List.filled(0, 42).add(4); });  // Is fixed-length.
   Expect.throws(() { new List.filled(-2, 42); });  // Not negative.
diff --git a/tests/corelib/num_parse_test.dart b/tests/corelib/num_parse_test.dart
new file mode 100644
index 0000000..c0b80e4
--- /dev/null
+++ b/tests/corelib/num_parse_test.dart
@@ -0,0 +1,235 @@
+// 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";
+
+const whiteSpace = const [
+  "",
+  "\x09",
+  "\x0a",
+  "\x0b",
+  "\x0c",
+  "\x0d",
+  "\x85",
+  "\xa0",
+  "\u1680",
+  "\u180e",
+  "\u2000",
+  "\u2001",
+  "\u2002",
+  "\u2003",
+  "\u2004",
+  "\u2005",
+  "\u2006",
+  "\u2007",
+  "\u2008",
+  "\u2009",
+  "\u200a",
+  "\u2028",
+  "\u2029",
+  "\u202f",
+  "\u205f",
+  "\u3000",
+  "\uFEFF"
+];
+
+void expectNumEquals(num expect, num actual, String message) {
+  if (expect is double && expect.isNaN) {
+    Expect.isTrue(actual is double && actual.isNaN, "isNaN: $message");
+  } else {
+    Expect.identical(expect, actual, message);
+  }
+}
+
+// Test source surrounded by any combination of whitespace.
+void testParseAllWhitespace(String source, num result) {
+  for (String ws1 in whiteSpace) {
+    for (String ws2 in whiteSpace) {
+      String padded = "$ws1$source$ws2";
+      // Use Expect.identical because it also handles NaN and 0.0/-0.0.
+      // Except on dart2js: http://dartbug.com/11551
+      expectNumEquals(result, num.parse(padded), "parse '$padded'");
+      padded = "$ws1$ws2$source";
+      expectNumEquals(result, num.parse(padded), "parse '$padded'");
+      padded = "$source$ws1$ws2";
+      expectNumEquals(result, num.parse(padded), "parse '$padded'");
+    }
+  }
+}
+
+// Test source and -source surrounded by any combination of whitespace.
+void testParseWhitespace(String source, num result) {
+  assert(result >= 0);
+  testParseAllWhitespace(source, result);
+  testParseAllWhitespace("-$source", -result);
+}
+
+// Test parsing source, optionally preceeded and/or followed by whitespace.
+void testParse(String source, num result) {
+  expectNumEquals(result, num.parse(source), "parse '$source'");
+  expectNumEquals(result, num.parse(" $source"), "parse ' $source'");
+  expectNumEquals(result, num.parse("$source "), "parse '$source '");
+  expectNumEquals(result, num.parse(" $source "), "parse ' $source '");
+}
+
+// Test parsing an integer in decimal or hex format, with or without signs.
+void testInt(int value) {
+  testParse("$value", value);
+  testParse("+$value", value);
+  testParse("-$value", -value);
+  var hex = "0x${value.toRadixString(16)}";
+  var lchex = hex.toLowerCase();
+  testParse(lchex, value);
+  testParse("+$lchex", value);
+  testParse("-$lchex", -value);
+  var uchex = hex.toUpperCase();
+  testParse(uchex, value);
+  testParse("+$uchex", value);
+  testParse("-$uchex", -value);
+}
+
+// Test parsing an integer, and the integers just around it.
+void testIntAround(int value) {
+  testInt(value - 1);
+  testInt(value);
+  testInt(value + 1);
+}
+
+void testDouble(double value) {
+  testParse("$value", value);
+  testParse("+$value", value);
+  testParse("-$value", -value);
+  if (value.isFinite) {
+    String exp = value.toStringAsExponential();
+    String lcexp = exp.toLowerCase();
+    testParse(lcexp, value);
+    testParse("+$lcexp", value);
+    testParse("-$lcexp", -value);
+    String ucexp = exp.toUpperCase();
+    testParse(ucexp, value);
+    testParse("+$ucexp", value);
+    testParse("-$ucexp", -value);
+  }
+}
+
+void testFail(String source) {
+  var object = new Object();
+  Expect.throws(() {
+    num.parse(source, (s) {
+      Expect.equals(source, s);
+      throw object;
+    });
+  }, (e) => identical(object, e), "Fail: '$source'");
+}
+
+void main() {
+  testInt(0);
+  testInt(1);
+  testInt(9);
+  testInt(10);
+  testInt(99);
+  testInt(100);
+  testIntAround(256);
+  testIntAround(0x80000000);  // 2^31
+  testIntAround(0x100000000);  // 2^32
+  testIntAround(0x10000000000000);  // 2^52
+  testIntAround(0x20000000000000);  // 2^53
+  testIntAround(0x40000000000000);  // 2^54
+  testIntAround(0x8000000000000000);  // 2^63
+  testIntAround(0x10000000000000000);  // 2^64
+  testIntAround(0x100000000000000000000);  // 2^80
+
+  testDouble(0.0);
+  testDouble(5e-324);
+  testDouble(2.225073858507201e-308);
+  testDouble(2.2250738585072014e-308);
+  testDouble(0.49999999999999994);
+  testDouble(0.5);
+  testDouble(0.50000000000000006);
+  testDouble(0.9999999999999999);
+  testDouble(1.0);
+  testDouble(1.0000000000000002);
+  testDouble(4294967295.0);
+  testDouble(4294967296.0);
+  testDouble(4503599627370495.5);
+  testDouble(4503599627370497.0);
+  testDouble(9007199254740991.0);
+  testDouble(9007199254740992.0);
+  testDouble(1.7976931348623157e+308);
+  testDouble(double.INFINITY);
+  testDouble(double.NAN);          /// 01: ok
+
+  // Strings that cannot occur from toString of a number.
+  testParse("000000000000", 0);
+  testParse("000000000001", 1);
+  testParse("000000000000.0000000000000", 0.0);
+  testParse("000000000001.0000000000000", 1.0);
+  testParse("0x0000000000", 0);
+  testParse("0e0", 0.0);
+  testParse("0e+0", 0.0);
+  testParse("0e-0", 0.0);
+  testParse("-0e0", -0.0);
+  testParse("-0e+0", -0.0);
+  testParse("-0e-0", -0.0);
+  testParse("1e0", 1.0);
+  testParse("1e+0", 1.0);
+  testParse("1e-0", 1.0);
+  testParse("-1e0", -1.0);
+  testParse("-1e+0", -1.0);
+  testParse("-1e-0", -1.0);
+  testParse("1.", 1.0);
+  testParse(".1", 0.1);
+  testParse("1.e1", 10.0);
+  testParse(".1e1", 1.0);
+
+  testParseWhitespace("0x1", 1);
+  testParseWhitespace("1", 1);
+  testParseWhitespace("1.0", 1.0);
+  testParseWhitespace("1e1", 10.0);
+  testParseWhitespace(".1e1", 1.0);
+  testParseWhitespace("1.e1", 10.0);
+  testParseWhitespace("1e+1", 10.0);
+  testParseWhitespace("1e-1", 0.1);
+
+  // Negative tests - things not to allow.
+
+  // Spaces inside the numeral.
+  testFail("- 1");
+  testFail("+ 1");
+  testFail("2 2");
+  testFail("0x 42");
+  testFail("1 .");
+  testFail(". 1");
+  testFail("1e 2");
+  testFail("1 e2");
+  // Invalid characters.
+  testFail("0x1H");
+  testFail("12H");
+  testFail("1x2");
+  testFail("00x2");
+  testFail("0x2.2");
+  // Empty hex number.
+  testFail("0x");
+  testFail("-0x");
+  testFail("+0x");
+  // Double exponent without value.
+  testFail(".e1");
+  testFail("e1");
+  testFail("e+1");
+  testFail("e-1");
+  testFail("-e1");
+  testFail("-e+1");
+  testFail("-e-1");
+  // Incorrect ways to write NaN/Infinity.
+  testFail("infinity");
+  testFail("INFINITY");
+  testFail("1.#INF");
+  testFail("inf");
+  testFail("nan");
+  testFail("NAN");
+  testFail("1.#IND");
+  testFail("indef");
+  testFail("qnan");
+  testFail("snan");
+}
diff --git a/tests/html/async_window_test.dart b/tests/html/async_window_test.dart
deleted file mode 100644
index 6cdb5dd..0000000
--- a/tests/html/async_window_test.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-library AsyncWindowTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-import 'dart:async';
-
-main() {
-  useHtmlConfiguration();
-  test('Timer', () {
-    new Timer(const Duration(milliseconds: 10), expectAsync0((){}));
-  });
-  test('Timer.periodic', () {
-    int counter = 0;
-    int id = null;
-    new Timer.periodic(const Duration(milliseconds: 10),
-        expectAsyncUntil1(
-        (timer) {
-          if (counter == 3) {
-            counter = 1024;
-            timer.cancel();
-            // Wait some more time to be sure callback won't be invoked any
-            // more.
-            new Timer(const Duration(milliseconds: 50), expectAsync0((){}));
-            return;
-          }
-          // As callback should have been cleared on 4th invocation, counter
-          // should never be greater than 3.
-          assert(counter < 3);
-          counter++;
-        },
-        () => counter == 3));
-  });
-}
diff --git a/tests/html/html.status b/tests/html/html.status
index 850c938..4117007 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -2,7 +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.
 
-async_window_test: Skip #TODO(gram): investigating
 event_test: Skip  # Issue 1996
 interactive_test: Skip # Must be run manually.
 dromaeo_smoke_test: Skip # Issue 14521, 8257
@@ -89,6 +88,8 @@
 xhr_test: Pass, Fail # Issue 11884
 xhr_cross_origin_test: Pass, Fail # Issue 11884
 
+fileapi_test/fileEntry: Pass, Fail # Issue 15355
+
 [$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid]
 webgl_1_test: Pass, Fail # Issue 8219
 
diff --git a/tests/isolate/browser/compute_this_script_browser_test.dart b/tests/isolate/browser/compute_this_script_browser_test.dart
index 2b71451..63a886d 100644
--- a/tests/isolate/browser/compute_this_script_browser_test.dart
+++ b/tests/isolate/browser/compute_this_script_browser_test.dart
@@ -11,6 +11,7 @@
 import 'dart:isolate';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
+import "../remote_unittest_helper.dart";
 
 child(var message) {
   var data = message[0];
@@ -18,7 +19,8 @@
   reply.send('re: $data');
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   useHtmlConfiguration();
   var script = new ScriptElement();
   document.body.append(script);
diff --git a/tests/isolate/browser/typed_data_message_test.dart b/tests/isolate/browser/typed_data_message_test.dart
index 9432290..61954b9 100644
--- a/tests/isolate/browser/typed_data_message_test.dart
+++ b/tests/isolate/browser/typed_data_message_test.dart
@@ -9,6 +9,7 @@
 import 'dart:isolate';
 import 'dart:typed_data';
 import 'package:unittest/unittest.dart';
+import "../remote_unittest_helper.dart";
 
 // ---------------------------------------------------------------------------
 // Message passing test.
@@ -86,7 +87,8 @@
   return response.first;
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   initializeList();
   test("send objects and receive them back", () {
     ReceivePort response = new ReceivePort();
diff --git a/tests/isolate/compile_time_error_test.dart b/tests/isolate/compile_time_error_test.dart
new file mode 100644
index 0000000..4bb70c7
--- /dev/null
+++ b/tests/isolate/compile_time_error_test.dart
@@ -0,0 +1,35 @@
+// 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 program for testing that errors thrown from isolates are
+// processed correctly and don't result in crashes.
+
+library Isolate3NegativeTest;
+import 'dart:isolate';
+import 'dart:async';
+import "package:async_helper/async_helper.dart";
+
+class TestClass {
+  TestClass.named(num this.fld1)
+    // Should cause a compilation error (for the spawned isolate). It is a
+    // runtime error for the test.
+    : fld2 = fld1  /// 01: compile-time error
+  ;
+  num fld1;
+  num fld2;
+}
+
+void entry(SendPort replyTo) {
+  var tmp = new TestClass.named(10);
+  replyTo.send("done");
+}
+
+main() {
+  asyncStart();
+  ReceivePort response = new ReceivePort();
+  Isolate.spawn(entry, response.sendPort);
+  response.first.then((_) {
+    asyncEnd();
+  });
+}
diff --git a/tests/isolate/count_test.dart b/tests/isolate/count_test.dart
index c0cbde3..881ac6b 100644
--- a/tests/isolate/count_test.dart
+++ b/tests/isolate/count_test.dart
@@ -3,8 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library CountTest;
-import '../../pkg/unittest/lib/unittest.dart';
 import 'dart:isolate';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 void countMessages(replyTo) {
   int count = 0;
@@ -23,7 +24,8 @@
   });
 }
 
-void main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("count 10 consecutive messages", () {
     ReceivePort local = new ReceivePort();
     Isolate.spawn(countMessages, local.sendPort);
diff --git a/tests/isolate/cross_isolate_message_test.dart b/tests/isolate/cross_isolate_message_test.dart
index 00874d0..56181c8 100644
--- a/tests/isolate/cross_isolate_message_test.dart
+++ b/tests/isolate/cross_isolate_message_test.dart
@@ -7,7 +7,8 @@
 
 library CrossIsolateMessageTest;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 /*
  * Everything starts in the main-isolate (in the main-method).
@@ -34,7 +35,8 @@
   toIsolate1.send(["fromIsolate2", 42]);
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("send message cross isolates ", () {
     ReceivePort fromIsolate1 = new ReceivePort();
     Isolate.spawn(crossIsolate1, fromIsolate1.sendPort);
diff --git a/tests/isolate/illegal_msg_function_test.dart b/tests/isolate/illegal_msg_function_test.dart
index f967afd..8767994 100644
--- a/tests/isolate/illegal_msg_function_test.dart
+++ b/tests/isolate/illegal_msg_function_test.dart
@@ -4,10 +4,10 @@
 
 library illegal_msg_function_test;
 
-import "package:expect/expect.dart";
 import "dart:isolate";
 import "dart:async" show Future;
-import "package:async_helper/async_helper.dart";
+import "package:unittest/unittest.dart";
+import "remote_unittest_helper.dart";
 
 funcFoo(x) => x + 2;
 
@@ -19,31 +19,29 @@
   });
 }
 
-main() {
-  var function = funcFoo;
+void main([args, port]) {
+  if (testRemote(main, port)) return;
+  test("msg_function", () {
+    var function = funcFoo;
+    ReceivePort port = new ReceivePort();
+    Future spawn = Isolate.spawn(echo, port.sendPort);
+    var caught_exception = false;
+    var stream = port.asBroadcastStream();
+    stream.first.then(expectAsync1((snd) {
+      try {
+        snd.send(function);
+      } catch (e) {
+        caught_exception = true;
+      }
 
-  ReceivePort port = new ReceivePort();
-  Future spawn = Isolate.spawn(echo, port.sendPort);
-  var caught_exception = false;
-  var stream = port.asBroadcastStream();
-  asyncStart();
-  stream.first.then((snd) {
-    try {
-      snd.send(function);
-    } catch (e) {
-      caught_exception = true;
-    }
-
-    if (caught_exception) {
-      port.close();
-    } else {
-      asyncStart();
-      stream.first.then((msg) {
-        print("from worker ${msg}");
-        asyncEnd();
-      });
-    }
-    Expect.isTrue(caught_exception);
-    asyncEnd();
+      if (caught_exception) {
+        port.close();
+      } else {
+        stream.first.then(expectAsync1((msg) {
+          print("from worker ${msg}");
+        }));
+      }
+      expect(caught_exception, isTrue);
+    }));
   });
 }
diff --git a/tests/isolate/illegal_msg_mirror_test.dart b/tests/isolate/illegal_msg_mirror_test.dart
index eed2981..dcf80a01 100644
--- a/tests/isolate/illegal_msg_mirror_test.dart
+++ b/tests/isolate/illegal_msg_mirror_test.dart
@@ -4,11 +4,12 @@
 
 library illegal_msg_mirror_test;
 
-import "package:expect/expect.dart";
 import "dart:isolate";
 import "dart:async" show Future;
-import "package:async_helper/async_helper.dart";
+@MirrorsUsed(targets: "Class")
 import "dart:mirrors";
+import "package:unittest/unittest.dart";
+import "remote_unittest_helper.dart";
 
 class Class {
   method() {}
@@ -22,31 +23,30 @@
   });
 }
 
-main() {
-  var methodMirror = reflectClass(Class).declarations[#method];
+void main([args, port]) {
+  if (testRemote(main, port)) return;
+  test("msg-mirror", () {
+    var methodMirror = reflectClass(Class).declarations[#method];
 
-  ReceivePort port = new ReceivePort();
-  Future spawn = Isolate.spawn(echo, port.sendPort);
-  var caught_exception = false;
-  var stream = port.asBroadcastStream();
-  asyncStart();
-  stream.first.then((snd) {
-    try {
-      snd.send(methodMirror);
-    } catch (e) {
-      caught_exception = true;
-    }
+    ReceivePort port = new ReceivePort();
+    Future spawn = Isolate.spawn(echo, port.sendPort);
+    var caught_exception = false;
+    var stream = port.asBroadcastStream();
+    stream.first.then(expectAsync1((snd) {
+      try {
+        snd.send(methodMirror);
+      } catch (e) {
+        caught_exception = true;
+      }
 
-    if (caught_exception) {
-      port.close();
-    } else {
-      asyncStart();
-      stream.first.then((msg) {
-        print("from worker ${msg}");
-        asyncEnd();
-      });
-    }
-    Expect.isTrue(caught_exception);
-    asyncEnd();
+      if (caught_exception) {
+        port.close();
+      } else {
+        stream.first.then(expectAsync1((msg) {
+          print("from worker ${msg}");
+        }));
+      }
+      expect(caught_exception, isTrue);
+    }));
   });
 }
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index e87e71a..4338e96 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -8,19 +8,13 @@
 
 [ $compiler == none ]
 serialization_test: SkipByDesign # Tests dart2js-specific serialization code
-isolate2_negative_test: Skip  # Issue 12587.
-isolate3_negative_test: Skip  # Issue 12587.
-
-[ $analyzer ]
-isolate2_negative_test: Fail
-isolate_import_negative_test: Fail
-unresolved_ports_test: Pass
+isolate_throws_test/01: Skip # Issue 12587
+compile_time_error_test/01: Skip # Issue 12587
 
 [ $compiler == dart2js && $jscl ]
 browser/*: SkipByDesign  # Browser specific tests
 
 [ $compiler == dart2js && $runtime == drt ]
-unresolved_ports_negative_test: Pass, Crash # Issue 10613
 isolate_stress_test: Pass, Crash # Issue 14438
 
 [ $compiler == dart2js ]
@@ -33,17 +27,9 @@
 cross_isolate_message_test: Skip # Issue 12627
 message_test: Skip # Issue 12627
 
-[ $compiler == dart2js && $runtime == opera ]
-isolate2_negative_test: Skip # Issue 12625
-unresolved_ports_negative_test: Skip # Issue 12626
-
 [ $compiler == dart2js ]
 spawn_uri_vm_test: SkipByDesign # Test uses a ".dart" URI.
 spawn_uri_nested_vm_test: SkipByDesign # Test uses a ".dart" URI.
-spawn_uri_vm_negative_test: SkipByDesign # Test uses a ".dart" URI.
-
-[ $compiler == dart2js && $browser ]
-isolate2_negative_test: Fail, Pass # Issue 7769
 
 [ $compiler == dart2js && $jscl ]
 spawn_uri_test: SkipByDesign # Loading another file is not supported in JS shell
@@ -52,12 +38,7 @@
 spawn_uri_test: Fail # Issue 12630
 
 [ $compiler == dart2js && $runtime == none ]
-spawn_function_negative_test: Fail # Issue 12628
-unresolved_ports_negative_test: Fail # Issue 12628
-isolate_negative_test: Fail # Issue 12628
 serialization_test: Pass # Issue 12628
-isolate_import_negative_test: Fail # Issue 12628
-isolate2_negative_test: Fail # Issue 12628
 illegal_msg_function_test: Pass # Issue 12628
 illegal_msg_mirror_test: Pass # Issue 12628
 
@@ -90,35 +71,16 @@
 [ $compiler == none && $runtime == dartium ]
 spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out.
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
-# Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
-browser/compute_this_script_browser_test: Fail
-browser/typed_data_message_test: Skip # 13961
-count_test: Fail
-cross_isolate_message_test: Fail
-illegal_msg_function_test: Fail
-illegal_msg_mirror_test: Fail
-isolate_complex_messages_test: Fail
-isolate_stress_test: Fail
-mandel_isolate_test: Fail
-message2_test: Fail
-message_test: Fail
-mint_maker_test: Fail
-nested_spawn2_test: Fail
-nested_spawn_test: Fail
-raw_port_test: Fail
-request_reply_test: Fail
-spawn_function_custom_class_test: Fail
-spawn_function_test: Fail
-stacktrace_message_test: Fail
-unresolved_ports_test: Fail
-static_function_test: Fail
+[ $compiler == none && $runtime == dartium ]
+isolate_stress_test: Skip # Issue 14463
+
+[ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
+compile_time_error_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
+isolate_import_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
+isolate_throws_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
+simple_message_test/none: Fail, OK # Issue 13921 Dom isolates don't support spawnFunction
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 browser/typed_data_message_test: StaticWarning
-isolate3_negative_test: CompileTimeError
-isolate_import_negative_test: CompileTimeError
 mint_maker_test: StaticWarning
 serialization_test: StaticWarning
-unresolved_ports_test: StaticWarning
-
diff --git a/tests/isolate/isolate2_negative_test.dart b/tests/isolate/isolate2_negative_test.dart
deleted file mode 100644
index 03fdb3c..0000000
--- a/tests/isolate/isolate2_negative_test.dart
+++ /dev/null
@@ -1,22 +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.
-
-// Dart test program for testing that exceptions in other isolates bring down
-// the program.
-
-library isolate2_negative_test;
-import 'dart:isolate';
-import "package:async_helper/async_helper.dart";
-
-void entry(msg) {
-  throw "foo";
-}
-
-main() {
-  // We start an asynchronous operation, but since we don't expect to get
-  // anything back except an exception there is no asyncEnd().
-  // If the exception is not thrown this test will timeout.
-  asyncStart();
-  Isolate.spawn(entry);
-}
diff --git a/tests/isolate/isolate3_negative_test.dart b/tests/isolate/isolate3_negative_test.dart
deleted file mode 100644
index ed46f27..0000000
--- a/tests/isolate/isolate3_negative_test.dart
+++ /dev/null
@@ -1,34 +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.
-
-// Dart test program for testing that errors thrown from isolates are
-// processed correctly and don't result in crashes.
-
-library Isolate3NegativeTest;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-class TestClass {
-  TestClass.named(num this.fld1) : fld2=fld1 {
-    TestClass.i = 0;  // Should cause a compilation error.
-  }
-  num fld1;
-  num fld2;
-}
-
-void entry(SendPort replyTo) {
-  var tmp = new TestClass.named(10);
-  replyTo.send(tmp);
-}
-
-main() {
-  test("child isolate compilation errors propagate correctly. ", () {
-    void msg_callback(var message) {
-      // This test is a negative test and should not complete successfully.
-    }
-    ReceivePort response = new ReceivePort();
-    Isolate.spawn(entry, response.sendPort);
-    response.first.then(expectAsync1(msg_callback));
-  });
-}
diff --git a/tests/isolate/isolate_complex_messages_test.dart b/tests/isolate/isolate_complex_messages_test.dart
index 3a18ec5..92c26d9 100644
--- a/tests/isolate/isolate_complex_messages_test.dart
+++ b/tests/isolate/isolate_complex_messages_test.dart
@@ -7,9 +7,11 @@
 
 library IsolateComplexMessagesTest;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("complex messages are serialized correctly", () {
     ReceivePort local = new ReceivePort();
     Isolate.spawn(logMessages, local.sendPort);
diff --git a/tests/isolate/isolate_import_negative_test.dart b/tests/isolate/isolate_import_test.dart
similarity index 72%
rename from tests/isolate/isolate_import_negative_test.dart
rename to tests/isolate/isolate_import_test.dart
index 1ea9102..5fa0f32 100644
--- a/tests/isolate/isolate_import_negative_test.dart
+++ b/tests/isolate/isolate_import_test.dart
@@ -4,11 +4,13 @@
 
 library IsolateImportNegativeTest;
 // Omitting the following import is an error:
-// import 'dart:isolate';
+/*  /// 01: runtime error, static type warning
+import 'dart:isolate';
+*/  /// 01: continued
 
 void entry(msg) {}
 
 main() {
-  Isolate.spawn(entry);
+  Isolate.spawn(entry, null);
 }
 
diff --git a/tests/isolate/isolate_negative_test.dart b/tests/isolate/isolate_negative_test.dart
deleted file mode 100644
index e40d23e..0000000
--- a/tests/isolate/isolate_negative_test.dart
+++ /dev/null
@@ -1,24 +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.
-
-// Dart test program for testing that isolates are spawned.
-
-library IsolateNegativeTest;
-import "package:expect/expect.dart";
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-void entry(SendPort replyTo) {
-  replyTo.send("foo");
-}
-
-main() {
-  test("ensure isolate code is executed", () {
-    ReceivePort response = new ReceivePort();
-    Isolate.spawn(entry, response.sendPort);
-    response.first.then(expectAsync1((message) {
-      expect("Expected fail", isTrue);   // <=-------- Should fail here.
-    }));
-  });
-}
diff --git a/tests/isolate/isolate_throws_test.dart b/tests/isolate/isolate_throws_test.dart
new file mode 100644
index 0000000..aecbe6e
--- /dev/null
+++ b/tests/isolate/isolate_throws_test.dart
@@ -0,0 +1,26 @@
+// 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 program for testing that exceptions in other isolates bring down
+// the program.
+
+import 'dart:async';
+import 'dart:isolate';
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+void entry(SendPort replyTo) {
+  throw "foo";  /// 01: runtime error
+  replyTo.send("done");
+}
+
+main() {
+  asyncStart();
+  ReceivePort rp = new ReceivePort();
+  Isolate.spawn(entry, rp.sendPort);
+  rp.first.then((msg) {
+    Expect.equals("done", msg);
+    asyncEnd();
+  });
+}
diff --git a/tests/isolate/mandel_isolate_test.dart b/tests/isolate/mandel_isolate_test.dart
index b1e3656..7099abe 100644
--- a/tests/isolate/mandel_isolate_test.dart
+++ b/tests/isolate/mandel_isolate_test.dart
@@ -6,15 +6,17 @@
 import 'dart:async';
 import 'dart:isolate';
 import 'dart:math';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 const TERMINATION_MESSAGE = -1;
 const N = 100;
 const ISOLATES = 20;
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   // Test is really slow in debug builds of the VM.
-  SimpleConfiguration configuration = unittestConfiguration;
+  var configuration = unittestConfiguration;
   configuration.timeout = const Duration(seconds: 480);
   test("Render Mandelbrot in parallel", () {
     final state = new MandelbrotState();
diff --git a/tests/isolate/message2_test.dart b/tests/isolate/message2_test.dart
index 334ae04..eaa5c956 100644
--- a/tests/isolate/message2_test.dart
+++ b/tests/isolate/message2_test.dart
@@ -7,7 +7,8 @@
 
 library Message2Test;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 // ---------------------------------------------------------------------------
 // Message passing test 2.
@@ -55,7 +56,8 @@
   replyPort.send(port.sendPort);
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("map is equal after it is sent back and forth", () {
     ReceivePort port = new ReceivePort();
     Isolate.spawn(pingPong, port.sendPort);
diff --git a/tests/isolate/message_test.dart b/tests/isolate/message_test.dart
index de252c5..ead8cfe 100644
--- a/tests/isolate/message_test.dart
+++ b/tests/isolate/message_test.dart
@@ -8,7 +8,8 @@
 library MessageTest;
 import 'dart:isolate';
 import 'dart:async';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 // ---------------------------------------------------------------------------
 // Message passing test.
@@ -93,7 +94,8 @@
   return receivePort.first;
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("send objects and receive them back", () {
     ReceivePort port = new ReceivePort();
     Isolate.spawn(pingPong, port.sendPort);
diff --git a/tests/isolate/mint_maker_test.dart b/tests/isolate/mint_maker_test.dart
index 3607df4..60b430f 100644
--- a/tests/isolate/mint_maker_test.dart
+++ b/tests/isolate/mint_maker_test.dart
@@ -5,7 +5,8 @@
 library MintMakerTest;
 import 'dart:async';
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 class Mint {
   Map<SendPort, Purse> _registry;
@@ -154,7 +155,8 @@
   }));
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("creating purse, deposit, and query balance", () {
     MintMakerWrapper.create().then(expectAsync1((mintMaker) {
       mintMaker.makeMint(expectAsync1((MintWrapper mint) {
diff --git a/tests/isolate/nested_spawn2_test.dart b/tests/isolate/nested_spawn2_test.dart
index 0c477dd..ea6331e 100644
--- a/tests/isolate/nested_spawn2_test.dart
+++ b/tests/isolate/nested_spawn2_test.dart
@@ -8,7 +8,8 @@
 
 library NestedSpawn2Test;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 void isolateA(SendPort init) {
   ReceivePort port = new ReceivePort();
@@ -51,7 +52,8 @@
   }));
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("spawned isolate can spawn other isolates", () {
     ReceivePort init = new ReceivePort();
     Isolate.spawn(isolateA, init.sendPort);
diff --git a/tests/isolate/nested_spawn_test.dart b/tests/isolate/nested_spawn_test.dart
index 51157f3..0dc35a0 100644
--- a/tests/isolate/nested_spawn_test.dart
+++ b/tests/isolate/nested_spawn_test.dart
@@ -6,7 +6,8 @@
 
 library NestedSpawnTest;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 void isolateA(message) {
   message.add("isolateA");
@@ -18,7 +19,8 @@
   message[0].send(message);
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("spawned isolates can spawn nested isolates", () {
     ReceivePort port = new ReceivePort();
     Isolate.spawn(isolateA, [port.sendPort, "main"]);
diff --git a/tests/isolate/raw_port_test.dart b/tests/isolate/raw_port_test.dart
index 8e334ca..a7cd2fb 100644
--- a/tests/isolate/raw_port_test.dart
+++ b/tests/isolate/raw_port_test.dart
@@ -6,17 +6,22 @@
 
 library raw_port_test;
 import 'dart:isolate';
-import 'dart:async';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import 'remote_unittest_helper.dart';
 
 
-void remote(SendPort port) { port.send("reply"); }
+void remote(SendPort port) {
+  port.send("reply");
+}
+
 void remote2(SendPort port) {
   port.send("reply 1");
   port.send("reply 2");
 }
 
-main() {
+main([args, port]) {
+  if (testRemote(main, port)) return;
+
   test("raw receive", () {
     RawReceivePort port = new RawReceivePort();
     Isolate.spawn(remote, port.sendPort);
@@ -25,6 +30,7 @@
       port.close();
     });
   });
+
   test("raw receive twice - change handler", () {
     RawReceivePort port = new RawReceivePort();
     Isolate.spawn(remote2, port.sendPort);
@@ -36,6 +42,7 @@
       });
     });
   });
+
   test("from-raw-port", () {
     RawReceivePort rawPort = new RawReceivePort();
     Isolate.spawn(remote, rawPort.sendPort);
@@ -53,5 +60,4 @@
                   onDone: expectAsync0((){}));
     });
   });
-
 }
diff --git a/tests/isolate/remote_unittest_helper.dart b/tests/isolate/remote_unittest_helper.dart
new file mode 100644
index 0000000..edc90ef
--- /dev/null
+++ b/tests/isolate/remote_unittest_helper.dart
@@ -0,0 +1,134 @@
+// 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.
+
+// Helper functions and classes for running a set of unittests in a
+// remote isolate.
+// Used to test Isolate.spawn because dartium/drt does not allow it in the DOM
+// isolate.
+
+import "dart:isolate";
+import "package:unittest/unittest.dart";
+@MirrorsUsed(symbols: "main", targets: "main", override: "*")
+import "dart:mirrors";
+
+/**
+ * Use this function at the beginning of the main method:
+ *
+ *     void main([args, port]) {
+ *       if (testRemote(main, port)) return;
+ *       // the usual test.
+ *     }
+ *
+ * Remember to import unittest using the URI `package:inittest/unittest.dart`.
+ * Otherwise it won't be sharing the `unittestConfiguration` with this library,
+ * and the override set below won't work.
+ *
+ * Returns `true` if the tests are being run remotely, and
+ * `false` if the tests should be run locally.
+ */
+bool testRemote(Function main, SendPort port) {
+  if (port != null) {
+    unittestConfiguration = new RemoteConfiguration(port);
+    return false;
+  }
+  var testResponses = new Map<String, List>();
+
+
+  ClosureMirror closure = reflect(main);
+  LibraryMirror library = closure.function.owner;
+
+  var receivePort = new ReceivePort();
+  void remoteAction(message) {
+    switch (message[0]) {
+      case "testStart":
+        String name = message[1];
+        testResponses[name] = null;
+        break;
+      case "testResult":
+      case "testResultChanged":
+        String name = message[1];
+        testResponses[name] = message;
+        break;
+      case "logMessage":
+        break;  // Ignore.
+      case "summary":
+        throw message[1];  // Uncaught error.
+      case "done":
+        receivePort.close();
+        _simulateTests(testResponses);
+        break;
+    }
+  }
+  try {
+    Isolate.spawnUri(library.uri, null, receivePort.sendPort);
+    receivePort.listen(remoteAction);
+    return true;
+  } catch (e) {
+    // spawnUri is only supported by dart2js if web workers are available.
+    // If the spawnUri fails, run the tests locally instead, since we are
+    // not in a browser anyway.
+    //
+    // That is, we assume that either Isolate.spawn or Isolate.spawnUri must
+    // work, so if spawnUri doesn't work, we can run the tests directly.
+    receivePort.close();
+    return false;
+  }
+}
+
+class RemoteConfiguration implements Configuration {
+  final SendPort _port;
+  Duration timeout = const Duration(minutes: 2);
+
+  RemoteConfiguration(this._port);
+
+  bool get autoStart => true;
+
+  void onInit() { }
+
+  void onStart() { }
+
+  void onTestStart(TestCase testCase) {
+    _port.send(["testStart", testCase.description]);
+  }
+
+  void onTestResult(TestCase testCase) {
+    _port.send(["testResult", testCase.description,
+                testCase.result, testCase.message]);
+  }
+
+  void onTestResultChanged(TestCase testCase) {
+    _port.send(["testResultChanged", testCase.description,
+                testCase.result, testCase.message]);
+  }
+
+  void onLogMessage(TestCase testCase, String message) {
+    _port.send(["logMessage", testCase.description, message]);
+  }
+
+  void onDone(bool success) {
+    _port.send(["done", success]);
+  }
+
+  void onSummary(int passed, int failed, int errors, List<TestCase> results,
+      String uncaughtError) {
+    if (uncaughtError != null) {
+      _port.send(["summary", uncaughtError]);
+    }
+  }
+}
+
+void _simulateTests(Map<String, List> responses) {
+  // Start all unit tests in the same event.
+  responses.forEach((name, response) {
+    test(name, () {
+      var result = response[2];
+      var message = response[3];
+      if (result == FAIL) {
+        fail(message);
+      } else if (result == ERROR) {
+        throw message;
+      }
+    });
+  });
+}
diff --git a/tests/isolate/request_reply_test.dart b/tests/isolate/request_reply_test.dart
index f70fb5a..713f7bb 100644
--- a/tests/isolate/request_reply_test.dart
+++ b/tests/isolate/request_reply_test.dart
@@ -5,7 +5,8 @@
 library RequestReplyTest;
 
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 void entry(initPort) {
   ReceivePort port = new ReceivePort();
@@ -18,7 +19,8 @@
   });
 }
 
-void main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test("send", () {
     ReceivePort init = new ReceivePort();
     Isolate.spawn(entry, init.sendPort);
diff --git a/tests/isolate/simple_message_test.dart b/tests/isolate/simple_message_test.dart
new file mode 100644
index 0000000..8338bd6
--- /dev/null
+++ b/tests/isolate/simple_message_test.dart
@@ -0,0 +1,26 @@
+// 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 program for testing that isolates are spawned.
+
+library IsolateNegativeTest;
+import "package:expect/expect.dart";
+import 'dart:isolate';
+import "package:async_helper/async_helper.dart";
+
+void entry(SendPort replyTo) {
+  var message = "foo";
+  message = "bar";  /// 01: runtime error
+  replyTo.send(message);
+}
+
+main() {
+  asyncStart();
+  ReceivePort response = new ReceivePort();
+  Isolate.spawn(entry, response.sendPort);
+  response.first.then((message) {
+    Expect.equals("foo", message);
+    asyncEnd();
+  });
+}
diff --git a/tests/isolate/spawn_function_custom_class_test.dart b/tests/isolate/spawn_function_custom_class_test.dart
index 9e83b6f..75c992d 100644
--- a/tests/isolate/spawn_function_custom_class_test.dart
+++ b/tests/isolate/spawn_function_custom_class_test.dart
@@ -9,7 +9,8 @@
 
 library spawn_tests;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 class MyClass {
   var myVar = 'there';
@@ -24,7 +25,8 @@
   reply.send('re: ${new MyClass().myFunc(msg)}');
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test('message - reply chain', () {
     ReceivePort port = new ReceivePort();
     Isolate.spawn(child, ['hi', port.sendPort]);
diff --git a/tests/isolate/spawn_function_negative_test.dart b/tests/isolate/spawn_function_negative_test.dart
deleted file mode 100644
index 1806312..0000000
--- a/tests/isolate/spawn_function_negative_test.dart
+++ /dev/null
@@ -1,25 +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.
-
-// Negative test to make sure that we are reaching all assertions.
-library spawn_tests;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-child(args) {
-  var msg = args[0];
-  var reply = args[1];
-  reply.send('re: $msg');
-}
-
-main() {
-  test('message - reply chain', () {
-    ReceivePort port = new ReceivePort();
-    Isolate.spawn(child, ['hi', port.sendPort]);
-    port.listen(expectAsync1((msg) {
-      port.close();
-      expect(msg, equals('re: hello')); // should be hi, not hello
-    }));
-  });
-}
diff --git a/tests/isolate/spawn_function_test.dart b/tests/isolate/spawn_function_test.dart
index a452477..54cfb5a 100644
--- a/tests/isolate/spawn_function_test.dart
+++ b/tests/isolate/spawn_function_test.dart
@@ -5,7 +5,8 @@
 // Example of spawning an isolate from a function.
 library spawn_tests;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 child(args) {
   var msg = args[0];
@@ -13,7 +14,8 @@
   reply.send('re: $msg');
 }
 
-main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   test('message - reply chain', () {
     ReceivePort port = new ReceivePort();
     Isolate.spawn(child, ['hi', port.sendPort]);
diff --git a/tests/isolate/spawn_uri_vm_negative_test.dart b/tests/isolate/spawn_uri_vm_negative_test.dart
deleted file mode 100644
index 9bc6111..0000000
--- a/tests/isolate/spawn_uri_vm_negative_test.dart
+++ /dev/null
@@ -1,23 +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.
-
-// Negative test to make sure that we are reaching all assertions.
-// Note: the following comment is used by test.dart to additionally compile the
-// other isolate's code.
-// OtherScripts=spawn_uri_child_isolate.dart
-library spawn_tests;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-
-main() {
-  test('isolate fromUri - negative test', () {
-    ReceivePort port = new ReceivePort();
-    port.first.then(expectAsync1((msg) {
-      expect(msg, equals('re: hello')); // should be hi, not hello
-    }));
-
-    Isolate.spawnUri(Uri.parse('spawn_uri_child_isolate.dart'),
-                     ['hi'], port.sendPort);
-  });
-}
diff --git a/tests/isolate/stacktrace_message_test.dart b/tests/isolate/stacktrace_message_test.dart
index 56ec95f..c22fa01 100644
--- a/tests/isolate/stacktrace_message_test.dart
+++ b/tests/isolate/stacktrace_message_test.dart
@@ -3,12 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:isolate';
+import "package:unittest/unittest.dart";
+import "remote_unittest_helper.dart";
 
-main() {
-  ReceivePort reply = new ReceivePort();
-  Isolate.spawn(runTest, reply.sendPort);
-  reply.first.then((StackTrace stack) {
-    print(stack);
+void main([args, port]) {
+  if (testRemote(main, port)) return;
+  test("stacktrace_message", () {
+    ReceivePort reply = new ReceivePort();
+    Isolate.spawn(runTest, reply.sendPort);
+    reply.first.then(expectAsync1((StackTrace stack) {
+      print(stack);
+    }));
   });
 }
 
diff --git a/tests/isolate/static_function_test.dart b/tests/isolate/static_function_test.dart
index d5745cc..db0beba 100644
--- a/tests/isolate/static_function_test.dart
+++ b/tests/isolate/static_function_test.dart
@@ -8,7 +8,8 @@
 import 'dart:isolate';
 import 'dart:async';
 import 'static_function_lib.dart' as lib;
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import 'remote_unittest_helper.dart';
 
 void function(SendPort port) { port.send("TOP"); }
 void _function(SendPort port) { port.send("_TOP"); }
@@ -75,7 +76,8 @@
   });
 }
 
-void main() {
+void main([args, port]) {
+  if (testRemote(main, port)) return;
   // Sanity check.
   spawnTest("function", function, "TOP");
   spawnTest("_function", _function, "_TOP");
diff --git a/tests/isolate/unresolved_ports_negative_test.dart b/tests/isolate/unresolved_ports_negative_test.dart
deleted file mode 100644
index 3007645..0000000
--- a/tests/isolate/unresolved_ports_negative_test.dart
+++ /dev/null
@@ -1,13 +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.
-
-// negative test to ensure that unresolved_ports works.
-library unresolved_ports_negative;
-import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
-import 'unresolved_ports_test.dart' as positive_test;
-
-main() {
-  positive_test.baseTest(failForNegativeTest: true);
-}
diff --git a/tests/isolate/unresolved_ports_test.dart b/tests/isolate/unresolved_ports_test.dart
index c7fdb41..8fe11c9 100644
--- a/tests/isolate/unresolved_ports_test.dart
+++ b/tests/isolate/unresolved_ports_test.dart
@@ -6,7 +6,8 @@
 library unresolved_ports;
 import 'dart:async';
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
+import "remote_unittest_helper.dart";
 
 // This test does the following:
 //  - main spawns two isolates: 'tim' and 'beth'
@@ -72,4 +73,7 @@
   });
 }
 
-main() => baseTest();
+void main([args, port]) {
+  if (testRemote(main, port)) return;
+  baseTest();
+}
diff --git a/tests/language/call_type_literal_test.dart b/tests/language/call_type_literal_test.dart
new file mode 100644
index 0000000..d24e778
--- /dev/null
+++ b/tests/language/call_type_literal_test.dart
@@ -0,0 +1,11 @@
+// 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";
+
+class C { void a() {} }
+
+void main() {
+  Expect.throws(() => C().a(), (e) => e is NoSuchMethodError); /// 01: static type warning
+}
diff --git a/tests/language/function_subtype2_test.dart b/tests/language/function_subtype2_test.dart
new file mode 100644
index 0000000..861b465
--- /dev/null
+++ b/tests/language/function_subtype2_test.dart
@@ -0,0 +1,140 @@
+// 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for optional parameters.
+
+import 'package:expect/expect.dart';
+
+typedef void T1(int a, int b);
+typedef void T2(int a, [int b]);
+typedef void T3([int a, int b]);
+typedef void T4(int a, [int b, int c]);
+typedef void T5([int a, int b, int c]);
+
+class C<T, S, U> {
+  void m1(T a, S b) {}
+  void m2(T a, [S b]) {}
+  void m3([T a, S b]) {}
+  void m4(T a, [S b, U c]) {}
+  void m5([T a, S b, U c]) {}
+}
+
+main() {
+  var c1 = new C<int, int, int>();
+  Expect.isTrue(c1.m1 is T1, "(int,int)->void is (int,int)->void");
+  Expect.isFalse(c1.m1 is T2, "(int,int)->void is not (int,[int])->void");
+  Expect.isFalse(c1.m1 is T3, "(int,int)->void is not ([int,int])->void");
+  Expect.isFalse(c1.m1 is T4, "(int,int)->void is not (int,[int,int])->void");
+  Expect.isFalse(c1.m1 is T5, "(int,int)->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c1.m2 is T1, "(int,[int])->void is (int,int)->void");
+  Expect.isTrue(c1.m2 is T2, "(int,[int])->void is (int,[int])->void");
+  Expect.isFalse(c1.m2 is T3, "(int,[int])->void is not ([int,int])->void");
+  Expect.isFalse(c1.m2 is T4, "(int,[int])->void is not (int,[int,int])->void");
+  Expect.isFalse(c1.m2 is T5, "(int,[int])->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c1.m3 is T1, "([int,int])->void is (int,int)->void");
+  Expect.isTrue(c1.m3 is T2, "([int,int])->void is (int,[int])->void");
+  Expect.isTrue(c1.m3 is T3, "([int,int])->void is ([int,int])->void");
+  Expect.isFalse(c1.m3 is T4, "([int,int])->void is not (int,[int,int])->void");
+  Expect.isFalse(c1.m3 is T5, "([int,int])->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c1.m4 is T1, "(int,[int,int])->void is (int,int)->void");
+  Expect.isTrue(c1.m4 is T2, "(int,[int,int])->void is (int,[int])->void");
+  Expect.isFalse(c1.m4 is T3, "(int,[int,int])->void is not ([int,int])->void");
+  Expect.isTrue(c1.m4 is T4, "(int,[int,int])->void is (int,[int,int])->void");
+  Expect.isFalse(c1.m4 is T5,
+                 "(int,[int,int])->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c1.m5 is T1, "([int,int,int])->void is (int,int)->void");
+  Expect.isTrue(c1.m5 is T2, "([int,int,int])->void is (int,[int])->void");
+  Expect.isTrue(c1.m5 is T3, "([int,int,int])->void is ([int,int])->void");
+  Expect.isTrue(c1.m5 is T4, "([int,int,int])->void is (int,[int,int])->void");
+  Expect.isTrue(c1.m5 is T5, "([int,int,int])->void is ([int,int,int])->void");
+
+  var c2 = new C<int, double, int>();
+  Expect.isFalse(c2.m1 is T1, "(int,double)->void is not (int,int)->void");
+  Expect.isFalse(c2.m1 is T2,
+                 "(int,double)->void is not not (int,[int])->void");
+  Expect.isFalse(c2.m1 is T3, "(int,double)->void is not ([int,int])->void");
+  Expect.isFalse(c2.m1 is T4,
+                 "(int,double)->void is not (int,[int,int])->void");
+  Expect.isFalse(c2.m1 is T5,
+                 "(int,double)->void is not ([int,int,int])->void");
+
+  Expect.isFalse(c2.m2 is T1, "(int,[double])->void is not (int,int)->void");
+  Expect.isFalse(c2.m2 is T2, "(int,[double])->void is not (int,[int])->void");
+  Expect.isFalse(c2.m2 is T3, "(int,[double])->void is not ([int,int])->void");
+  Expect.isFalse(c2.m2 is T4,
+                 "(int,[double])->void is not (int,[int,int])->void");
+  Expect.isFalse(c2.m2 is T5,
+                 "(int,[double])->void is not ([int,int,int])->void");
+
+  Expect.isFalse(c2.m3 is T1, "([int,double])->void is not (int,int)->void");
+  Expect.isFalse(c2.m3 is T2, "([int,double])->void is not (int,[int])->void");
+  Expect.isFalse(c2.m3 is T3, "([int,double])->void is not ([int,int])->void");
+  Expect.isFalse(c2.m3 is T4,
+                 "([int,double])->void is not (int,[int,int])->void");
+  Expect.isFalse(c2.m3 is T5,
+                 "([int,double])->void is not ([int,int,int])->void");
+
+  Expect.isFalse(c2.m4 is T1,
+                 "(int,[double,int])->void is not (int,int)->void");
+  Expect.isFalse(c2.m4 is T2,
+                 "(int,[double,int])->void is not (int,[int])->void");
+  Expect.isFalse(c2.m4 is T3,
+                 "(int,[double,int])->void is not ([int,int])->void");
+  Expect.isFalse(c2.m4 is T4,
+                 "(int,[double,int])->void is (int,[int,int])->void");
+  Expect.isFalse(c2.m4 is T5,
+                 "(int,[double,int])->void is ([int,int,int])->void");
+
+  Expect.isFalse(c2.m5 is T1,
+                 "([int,double,int])->void is not (int,int)->void");
+  Expect.isFalse(c2.m5 is T2,
+                 "([int,double,int])->void is not (int,[int])->void");
+  Expect.isFalse(c2.m5 is T3,
+                 "([int,double,int])->void is not ([int,int])->void");
+  Expect.isFalse(c2.m5 is T4,
+                 "([int,double,int])->void is (int,[int,int])->void");
+  Expect.isFalse(c2.m5 is T5,
+                 "([int,double,int])->void is ([int,int,int])->void");
+
+  var c3 = new C<int, int, double>();
+  Expect.isTrue(c3.m1 is T1, "(int,int)->void is (int,int)->void");
+  Expect.isFalse(c3.m1 is T2, "(int,int)->void is not (int,[int])->void");
+  Expect.isFalse(c3.m1 is T3, "(int,int)->void is not ([int,int])->void");
+  Expect.isFalse(c3.m1 is T4, "(int,int)->void is not (int,[int,int])->void");
+  Expect.isFalse(c3.m1 is T5, "(int,int)->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c3.m2 is T1, "(int,[int])->void is (int,int)->void");
+  Expect.isTrue(c3.m2 is T2, "(int,[int])->void is (int,[int])->void");
+  Expect.isFalse(c3.m2 is T3, "(int,[int])->void is not ([int,int])->void");
+  Expect.isFalse(c3.m2 is T4, "(int,[int])->void is not (int,[int,int])->void");
+  Expect.isFalse(c3.m2 is T5, "(int,[int])->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c3.m3 is T1, "([int,int])->void is (int,int)->void");
+  Expect.isTrue(c3.m3 is T2, "([int,int])->void is (int,[int])->void");
+  Expect.isTrue(c3.m3 is T3, "([int,int])->void is ([int,int])->void");
+  Expect.isFalse(c3.m3 is T4, "([int,int])->void is not (int,[int,int])->void");
+  Expect.isFalse(c3.m3 is T5, "([int,int])->void is not ([int,int,int])->void");
+
+  Expect.isTrue(c3.m4 is T1, "(int,[int,double])->void is (int,int)->void");
+  Expect.isTrue(c3.m4 is T2, "(int,[int,double])->void is (int,[int])->void");
+  Expect.isFalse(c3.m4 is T3,
+                 "(int,[int,double])->void is not ([int,int])->void");
+  Expect.isFalse(c3.m4 is T4,
+                 "(int,[int,double])->void is (int,[int,int])->void");
+  Expect.isFalse(c3.m4 is T5,
+                 "(int,[int,double])->void is ([int,int,int])->void");
+
+  Expect.isTrue(c3.m5 is T1, "([int,int,double])->void is (int,int)->void");
+  Expect.isTrue(c3.m5 is T2, "([int,int,double])->void is (int,[int])->void");
+  Expect.isTrue(c3.m5 is T3, "([int,int,double])->void is ([int,int])->void");
+  Expect.isFalse(c3.m5 is T4,
+                 "([int,int,double])->void is (int,[int,int])->void");
+  Expect.isFalse(c3.m5 is T5,
+                 "([int,int,double])->void is ([int,int,int])->void");
+}
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 1ce4a22..aecedf1 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -9,9 +9,10 @@
 # Test issue 12694 (was analyzer issue), (1) when "abstract" is import prefix using it as type is warning; (2) currently analyzer resolves prefix as field (don't ask)
 built_in_identifier_prefix_test: CompileTimeError # Issue 12694
 
-# TBD: these look like bad tests, no issue number
+# Issue 15315
 class_literal_test: fail
 constructor_call_as_function_test/01: fail
+call_type_literal_test/01: fail
 
 # TBF: we should check conflicts not only for methods, but for accessors too
 override_field_test/03: fail
@@ -151,8 +152,22 @@
 # test issue 14736, It is a static warning if a class C declares an instance method named n and has a setter named n=.
 setter4_test: StaticWarning
 
-
-
+# test issue 15060
+least_upper_bound_test/23: StaticWarning # Issue 15060
+least_upper_bound_test/24: StaticWarning # Issue 15060
+least_upper_bound_test/25: MissingStaticWarning # Issue 15060
+least_upper_bound_test/26: MissingStaticWarning # Issue 15060
+least_upper_bound_test/29: StaticWarning # Issue 15060
+least_upper_bound_test/30: StaticWarning # Issue 15060
+least_upper_bound_test/31: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/02: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/04: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/05: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/06: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/08: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/10: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/11: MissingStaticWarning # Issue 15060
+least_upper_bound_expansive_test/12: MissingStaticWarning # Issue 15060
 
 abstract_exact_selector_test: StaticWarning
 abstract_getter_test: StaticWarning
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 42c7dd2..408d7a0 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -134,6 +134,7 @@
 mixin_mixin7_test: RuntimeError # Issue 13109.
 mixin_regress_13688_test: RuntimeError # Issue 13109.
 modulo_test: RuntimeError # Issue 15246
+truncdiv_test: RuntimeError # Issue 15246
 
 # Compilation errors.
 const_var_test: CompileTimeError # Issue 12793
@@ -153,6 +154,19 @@
 
 null_test/none: RuntimeError  # Issue 12482
 
+[ $compiler == dart2js || $compiler == dart2dart ]
+
+function_type_alias9_test/00: Crash # Issue 15237
+string_interpolation9_test/11: Crash # Issue 15237
+string_interpolation9_test/12: Crash # Issue 15237
+string_interpolation9_test/13: Crash # Issue 15237
+string_interpolation9_test/16: Crash # Issue 15237
+string_interpolation9_test/17: Crash # Issue 15237
+string_interpolation9_test/18: Crash # Issue 15237
+mixin_invalid_inheritance2_test/03: Crash # Issue 15237
+
+[ ($compiler == dart2js || $compiler == dart2dart) && $checked ]
+cyclic_typedef_test/07: Crash # Issue 15237
 
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
diff --git a/tests/language/least_upper_bound_expansive_test.dart b/tests/language/least_upper_bound_expansive_test.dart
new file mode 100644
index 0000000..704b2a3
--- /dev/null
+++ b/tests/language/least_upper_bound_expansive_test.dart
@@ -0,0 +1,101 @@
+// 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 least upper bound through type checking of conditionals.
+
+class N<T> {
+  T get n => null;
+}
+
+class C1<T> extends N<N<C1<T>>> {
+  T get c1 => null;
+}
+
+class C2<T> extends N<N<C2<N<C2<T>>>>> {
+  T get c2 => null;
+}
+
+/**
+ * Test that we don't try to find the least upper bound by applying the
+ * algorithm for finding the most specific common declaration recursively on
+ * type arguments.
+ *
+ * For C1<int> and N<C1<String>> this would result in this infinite chain of
+ * computations:
+ *
+ * lub(C1<int>, N<C1<String>>) = lub(N<N<C1<int>>>, N<C1<String>>)
+ * =>
+ * lub(N<C1<int>>, C1<String>) = lub(N<C1<int>>, N<N<C1<String>>>)
+ * =>
+ * lub(C1<int>, N<C1<String>>) = lub(N<N<C1<int>>>, N<C1<String>>>)
+ * => ...
+ */
+void testC1(bool z, C1<int> a, N<C1<String>> b) {
+  if (z) {
+    // The least upper bound of C1<int> and N<C1<String>> is Object since the
+    // supertypes are
+    //     {C1<int>, N<N<C1<int>>>, Object} for C1<int> and
+    //     {N<C1<String>>, Object} for N<C1<String>> and
+    // Object is the most specific type in the intersection of the supertypes.
+
+    // Is least upper bound dynamic?
+    (z ? a : b).z; /// 01: static type warning
+    // Is least upper bound N<...> ?
+    (z ? a : b).n; /// 02: static type warning
+    // Is least upper bound C1<...> ?
+    (z ? a : b).c1; /// 03: static type warning
+    // Is least upper bound N<dynamic> ?
+    (z ? a : b).n.z; /// 04: static type warning
+    // Is least upper bound N<N<...>> ?
+    (z ? a : b).n.n; /// 05: static type warning
+    // Is least upper bound N<C1<...>> ?
+    (z ? a : b).n.c1; /// 06: static type warning
+  }
+}
+
+/**
+ * Test that we don't try to find the least upper bound by applying the
+ * algorithm for finding the most specific common declaration recursively on
+ * type arguments.
+ *
+ * For C1<int> and N<C1<String>> this would result in this infinite and
+ * expanding chain of computations:
+ *
+ * lub(C2<int>, N<C2<String>>) = lub(N<N<C2<N<C2<int>>>>>, N<C2<String>>)
+ * =>
+ * lub(N<C2<N<C2<int>>>>, C2<String>) =
+ *                               lub(N<C2<N<C2<int>>>>, N<N<C2<N<C2<String>>>>>)
+ * =>
+ * lub(C2<N<C2<int>>>, N<C2<N<C2<String>>>>) =
+ *                              lub(N<N<C2<N<C2<int>>>>>, N<C2<N<C2<String>>>>>)
+ * => ...
+ */
+
+void testC2(bool z, C2<int> a, N<C2<String>> b) {
+  if (z) {
+    // The least upper bound of C2<int> and N<C2<String>> is Object since the
+    // supertypes are
+    //     {C2<int>, N<N<C2<N<C2<int>>>>>, Object} for C1<int> and
+    //     {N<C2<String>>, Object} for N<C1<String>> and
+    // Object is the most specific type in the intersection of the supertypes.
+
+    // Is least upper bound dynamic?
+    (z ? a : b).z; /// 07: static type warning
+    // Is least upper bound N<...> ?
+    (z ? a : b).n; /// 08: static type warning
+    // Is least upper bound C2<...> ?
+    (z ? a : b).c2; /// 09: static type warning
+    // Is least upper bound N<dynamic> ?
+    (z ? a : b).n.z; /// 10: static type warning
+    // Is least upper bound N<N<...>> ?
+    (z ? a : b).n.n; /// 11: static type warning
+    // Is least upper bound N<C2<...>> ?
+    (z ? a : b).n.c2; /// 12: static type warning
+  }
+}
+
+void main() {
+  testC1(false, null, null);
+  testC2(false, null, null);
+}
\ No newline at end of file
diff --git a/tests/language/least_upper_bound_test.dart b/tests/language/least_upper_bound_test.dart
new file mode 100644
index 0000000..410671a
--- /dev/null
+++ b/tests/language/least_upper_bound_test.dart
@@ -0,0 +1,103 @@
+// 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 least upper bound through type checking of conditionals.
+
+class A {
+  var a;
+}
+class B {
+  var b;
+}
+class C extends B {
+  var c;
+}
+class D extends B {
+  var d;
+}
+
+class E<T> {
+  T e;
+
+  E(this.e);
+}
+class F<T> extends E<T> {
+  T f;
+
+  F(T f) : this.f = f, super(f);
+}
+
+void main() {
+  testAB(new A(), new B());
+  testBC(new C(), new C());
+  testCD(new C(), new D());
+  testEE(new F<C>(new C()), new F<C>(new C()));
+  testEF(new F<C>(new C()), new F<C>(new C()));
+}
+
+void testAB(A a, B b) {
+  A r1 = true ? a : b; /// 01: ok
+  B r2 = false ? a : b; /// 02: ok
+  (true ? a : b).a = 0; /// 03: static type warning
+  (false ? a : b).b = 0; /// 04: static type warning
+  var c = new C();
+  (true ? a : c).a = 0; /// 05: ok
+  (false ? c : b).b = 0; /// 06: ok
+}
+
+void testBC(B b, C c) {
+  B r1 = true ? b : c; /// 07: ok
+  C r2 = false ? b : c; /// 08: ok
+  (true ? b : c).b = 0; /// 09: ok
+  (false ? b : c).c = 0; /// 10: static type warning
+  var a = null;
+  (true ? b : a).b = 0; /// 11: ok
+  (false ? a : b).c = 0; /// 12: ok
+  (true ? c : a).b = 0; /// 13: ok
+  (false ? a : c).c = 0; /// 14: ok
+}
+
+void testCD(C c, D d) {
+  C r1 = true ? c : d; /// 15: ok
+  D r2 = false ? c : d; /// 16: ok
+  (true ? c : d).b = 0; /// 17: ok
+  (false ? c : d).b = 0; /// 18: ok
+  (true ? c : d).c = 0; /// 19: static type warning
+  (false ? c : d).d = 0; /// 20: static type warning
+}
+
+void testEE(E<B> e, E<C> f) {
+  // The least upper bound of E<B> and E<C> is Object since the supertypes are
+  //     {E<B>, Object} for E<B> and
+  //     {E<C>, Object} for E<C> and
+  // Object is the most specific type in the intersection of the supertypes.
+  E<B> r1 = true ? e : f; /// 21: ok
+  F<C> r2 = false ? e : f; /// 22: ok
+  try {
+    A r3 = true ? e : f; /// 23: ok
+    B r4 = false ? e : f; /// 24: ok
+  } catch (e) {
+    // Type error in checked mode.
+  }
+  (true ? e : f).e = null; /// 25: static type warning
+  (false ? e : f).e = null; /// 26: static type warning
+}
+
+void testEF(E<B> e, F<C> f) {
+  // The least upper bound of E<B> and F<C> is Object since the supertypes are
+  //     {E<B>, Object} for E<B> and
+  //     {F<C>, E<C>, Object} for F<C> and
+  // Object is the most specific type in the intersection of the supertypes.
+  E<B> r1 = true ? e : f; /// 27: ok
+  F<C> r2 = false ? e : f; /// 28: ok
+  try {
+    A r3 = true ? e : f; /// 29: ok
+    B r4 = false ? e : f; /// 30: ok
+  } catch (e) {
+    // Type error in checked mode.
+  }
+  var r5;
+  r5 = (true ? e : f).e; /// 31: static type warning
+  r5 = (false ? e : f).f; /// 32: static type warning
+}
\ No newline at end of file
diff --git a/tests/language/modulo_test.dart b/tests/language/modulo_test.dart
index 939d7c0..6dc22cf 100644
--- a/tests/language/modulo_test.dart
+++ b/tests/language/modulo_test.dart
@@ -26,7 +26,18 @@
     }
     Expect.equals((i ~/ 10) + (i ~/ 10) + (i % 10), threeOp(i));
     Expect.equals((i ~/ 10) + (i ~/ 12) + (i % 10) + (i % 12), fourOp(i));
+    
+    // Zero test is done outside the loop.
+    if (i < 0) {
+      Expect.equals(i % -i, foo2(i));
+      Expect.equals(i ~/ -i + i % -i, fooTwo2(i));
+    } else if (i > 0) {
+      Expect.equals(i % i, foo2(i));
+      Expect.equals(i ~/ i + i % i, fooTwo2(i));
+    }
   }
+  Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
+  Expect.throws(() => fooTwo2(0), (e) => e is IntegerDivisionByZeroException);
 }
 
 foo(i) => i % 256;  // This will get optimized to AND instruction.
@@ -61,4 +72,27 @@
   var y0 = a % 10; 
   var y1 = a % 12;
   return x0 + x1 + y0 + y1;
-}
\ No newline at end of file
+}
+
+foo2(i) {
+  // Make sure x has a range computed. 
+  var x = 0;
+  if (i < 0) {
+    x = -i;
+  } else {
+    x = i;
+  }
+  return i % x;
+}
+
+
+fooTwo2(i) {
+  // Make sure x has a range computed. 
+  var x = 0;
+  if (i < 0) {
+    x = -i;
+  } else {
+    x = i;
+  }
+  return i ~/ x + i % x;
+}
diff --git a/tests/language/switch8_test.dart b/tests/language/switch8_test.dart
new file mode 100644
index 0000000..fd3b5cc
--- /dev/null
+++ b/tests/language/switch8_test.dart
@@ -0,0 +1,16 @@
+// 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 dart2js that used to not generate code for
+// compile-time constants only seen in case expressions.
+
+class A {
+  const A();
+}
+
+main() {
+  switch (new List(1)[0]) {
+    case const A(): throw 'Test failed';
+  }
+}
diff --git a/tests/language/truncdiv_test.dart b/tests/language/truncdiv_test.dart
new file mode 100644
index 0000000..8a00c73
--- /dev/null
+++ b/tests/language/truncdiv_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.
+// Dart test optimization of modulo operator on Smi.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+
+main() {
+  for (int i = -30; i < 30; i++) {
+    Expect.equals(i % 9, foo(i, 9));
+    // Zero test is done outside the loop.
+    if (i < 0) {
+      Expect.equals(i ~/ -i, foo2(i));
+    } else if (i > 0) {
+      Expect.equals(i ~/ i, foo2(i));
+    }
+  }
+  Expect.throws(() => foo(12, 0), (e) => e is IntegerDivisionByZeroException);
+  Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
+}
+
+foo(i, x) => i % x;
+
+foo2(i) {
+  // Make sure x has a range computed. 
+  var x = 0;
+  if (i < 0) {
+    x = -i;
+  } else {
+    x = i;
+  }
+  return i ~/ x;
+}
\ No newline at end of file
diff --git a/tests/language/type_promotion_closure_test.dart b/tests/language/type_promotion_closure_test.dart
index bb514da..5c59443 100644
--- a/tests/language/type_promotion_closure_test.dart
+++ b/tests/language/type_promotion_closure_test.dart
@@ -30,9 +30,11 @@
   test1();
   test2();
   test3();
+  test3a();
   test4();
   test5();
   test6();
+  test6a();
   test7();
   test8();
   test9();
@@ -79,6 +81,22 @@
   }
 }
 
+void test3a() {
+  A a = new E();
+  void foo() {
+    a = new D();
+  }
+  if ((((a)) is B)) {
+    print(a.a);
+    print(a.b); /// 15: static type warning
+    void foo() {
+      a = new D();
+    }
+    print(a.a);
+    print(a.b); /// 16: static type warning
+  }
+}
+
 void test4() {
   A a = new E();
   if (a is B) {
@@ -107,6 +125,16 @@
   a = null;
 }
 
+void test6a() {
+  A a = new E();
+  if (((a) is B)) {
+    func(() => a);
+    print(a.a);
+    print(a.b); /// 14: static type warning
+  }
+  a = null;
+}
+
 void test7() {
   A a = new E();
   if (a is B && func(() => a)) {
diff --git a/tests/language/type_promotion_logical_and_test.dart b/tests/language/type_promotion_logical_and_test.dart
index 92a4758..1ee6296 100644
--- a/tests/language/type_promotion_logical_and_test.dart
+++ b/tests/language/type_promotion_logical_and_test.dart
@@ -33,6 +33,10 @@
     b = a.d; /// 02: static type warning
     a = null;
   }
+  if ((((a) is D) && (b = (a).d))) {
+    b = a.d; /// 03: static type warning
+    a = null;
+  }
   if (f(a = null) && a is D) {
     b = a.d;
   }
diff --git a/tests/language/type_promotion_parameter_test.dart b/tests/language/type_promotion_parameter_test.dart
index b390ede..6fe7ecc 100644
--- a/tests/language/type_promotion_parameter_test.dart
+++ b/tests/language/type_promotion_parameter_test.dart
@@ -190,8 +190,14 @@
   }
   if ((a is B)) {
     print(a.a);
-    print(a.b); /// 53: static type warning
+    print(a.b);
     print(a.c); /// 54: static type warning
     print(a.d); /// 55: static type warning
   }
+  if ((a is B && (a) is C) && a is B) {
+    print(a.a);
+    print(a.b);
+    print(a.c);
+    print(a.d); /// 56: static type warning
+  }
 }
diff --git a/tests/language/vm/if_conversion_vm_test.dart b/tests/language/vm/if_conversion_vm_test.dart
index 0837030..2d97d4d 100644
--- a/tests/language/vm/if_conversion_vm_test.dart
+++ b/tests/language/vm/if_conversion_vm_test.dart
@@ -42,6 +42,15 @@
 
 f19(i) => i == 0 ? 0 : 0;
 
+f20(i) => i > 0 ? 0 : 1;
+f21(i) => i > 0 ? 2 : 3;
+f22(i) => i & 1 == 0 ? 0 : 1;
+f23(i) => i & 1 != 0 ? 1 : 0;
+
+f24(i) => i >= 0 ? 0 : 1;
+f25(i) => i < 0 ? 0 : 1;
+f26(i) => i <= 0 ? 0 : 1;
+
 main() {
   for (var i = 0; i < 20; i++) {
     f1(i);
@@ -65,6 +74,13 @@
     f17(true);
     f18(true);
     f19(i);
+    f20(i);
+    f21(i);
+    f22(i);
+    f23(i);
+    f24(i);
+    f25(i);
+    f26(i);
   }
 
   Expect.equals(0, f1(0));
@@ -117,4 +133,20 @@
 
   Expect.equals(0, f19(0));
   Expect.equals(0, f19(1));
+
+  Expect.equals(0, f20(123));
+  Expect.equals(2, f21(123));
+  Expect.equals(0, f22(122));
+  Expect.equals(1, f22(123));
+  Expect.equals(0, f23(122));
+  Expect.equals(1, f23(123));
+
+  Expect.equals(0, f24(0));
+  Expect.equals(1, f24(-1));
+
+  Expect.equals(0, f25(-1));
+  Expect.equals(1, f25(0));
+
+  Expect.equals(0, f26(0));
+  Expect.equals(1, f26(1));
 }
diff --git a/tests/language/vm/optimized_testsmi_test.dart b/tests/language/vm/optimized_testsmi_test.dart
new file mode 100644
index 0000000..d538f20
--- /dev/null
+++ b/tests/language/vm/optimized_testsmi_test.dart
@@ -0,0 +1,30 @@
+// 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=--optimization_counter_threshold=10
+
+// Test branch optimization for TestSmiInstr
+
+import "package:expect/expect.dart";
+
+test(bool b) {
+  var a = 0;
+  if (b) {
+    a++;
+  } else {
+    a += 2;
+  }
+  if (a & 1 == 0) {
+    return "even";
+  }
+  return "odd";
+}
+
+main() {
+  Expect.equals("odd", test(true));
+  Expect.equals("even", test(false));
+  for (var i=0; i<20; i++) test(false);
+  Expect.equals("odd", test(true));
+  Expect.equals("even", test(false));
+}
+
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index b3c0c30..d0eed98 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -27,7 +27,6 @@
 lib/_internal/dartdoc/lib/src/client/dropdown: CompileTimeError
 lib/_internal/dartdoc/lib/src/client/search: CompileTimeError
 lib/_internal/dartdoc/lib/universe_serializer: CompileTimeError
-lib/_internal/pub/bin/pub: CompileTimeError
 lib/_internal/pub/lib/src/barback: Pass, CompileTimeError # Pass necessary, since CompileTimeError is valid for everything in that directory (not only for src/barback.dart)
 lib/_internal/pub/lib/src/barback/dart2js_transformer: CompileTimeError
 lib/_internal/pub/lib/src/barback/dart_forwarding_transformer: CompileTimeError
@@ -41,43 +40,7 @@
 lib/_internal/pub/lib/src/command/list_package_dirs: CompileTimeError
 lib/_internal/pub/lib/src/command: Pass, CompileTimeError # Pass necessary, since CompileTimeError is valid for everything in that directory (not only for src/command.dart)
 lib/_internal/pub/lib/src/command/uploader: CompileTimeError
-lib/_internal/pub/lib/src/dart: CompileTimeError
-lib/_internal/pub/lib/src/directory_tree: CompileTimeError
-lib/_internal/pub/lib/src/entrypoint: CompileTimeError
-lib/_internal/pub/lib/src/git: CompileTimeError
-lib/_internal/pub/lib/src/http: CompileTimeError
-lib/_internal/pub/lib/src/io: CompileTimeError
-lib/_internal/pub/lib/src/lock_file: CompileTimeError
-lib/_internal/pub/lib/src/log: CompileTimeError
-lib/_internal/pub/lib/src/oauth2: CompileTimeError
-lib/_internal/pub/lib/src/package: CompileTimeError
-lib/_internal/pub/lib/src/package_graph: CompileTimeError
-lib/_internal/pub/lib/src/pubspec: CompileTimeError
-lib/_internal/pub/lib/src/safe_http_server: CompileTimeError
-lib/_internal/pub/lib/src/sdk: CompileTimeError
-lib/_internal/pub/lib/src/solver/backtracking_solver: CompileTimeError
-lib/_internal/pub/lib/src/solver/version_solver: CompileTimeError
-lib/_internal/pub/lib/src/source: CompileTimeError
-lib/_internal/pub/lib/src/source/git: CompileTimeError
-lib/_internal/pub/lib/src/source/hosted: CompileTimeError
-lib/_internal/pub/lib/src/source/path: CompileTimeError
-lib/_internal/pub/lib/src/source_registry: CompileTimeError
-lib/_internal/pub/lib/src/system_cache: CompileTimeError
-lib/_internal/pub/lib/src/utils: CompileTimeError
-lib/_internal/pub/lib/src/validator/compiled_dartdoc: CompileTimeError
-lib/_internal/pub/lib/src/validator: CompileTimeError
-lib/_internal/pub/lib/src/validator/dependency: CompileTimeError
-lib/_internal/pub/lib/src/validator/dependency_override: CompileTimeError
-lib/_internal/pub/lib/src/validator/directory: CompileTimeError
-lib/_internal/pub/lib/src/validator/lib: CompileTimeError
-lib/_internal/pub/lib/src/validator/license: CompileTimeError
-lib/_internal/pub/lib/src/validator/name: CompileTimeError
-lib/_internal/pub/lib/src/validator/pubspec_field: CompileTimeError
-lib/_internal/pub/lib/src/validator/size: CompileTimeError
-lib/_internal/pub/lib/src/validator/utf8_readme: CompileTimeError
-lib/_internal/pub/test/descriptor: CompileTimeError
-lib/_internal/pub/test/descriptor/git: CompileTimeError
-lib/_internal/pub/test/descriptor/tar: CompileTimeError
+lib/_internal/pub/test/descriptor: Pass, CompileTimeError # Pass necessary, since CompileTimeError is valid for everything in that directory (not only for test/descriptor.dart)
 lib/_internal/pub/test/lish/utils: CompileTimeError
 lib/_internal/pub/test/oauth2/utils: CompileTimeError
 lib/_internal/pub/test/serve/utils: CompileTimeError
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index ed342bc..20ae1c5 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -808,6 +808,8 @@
   Future catchError(Function onError, {bool test(e)}) =>
       _realFuture.catchError(onError, test: test);
   Future whenComplete(action()) => _realFuture.whenComplete(action);
+  Future timeout(Duration timeLimit, [void onTimeout()]) =>
+      _realFuture.timeout(timeLimit, onTimeout);
   Stream asStream() => _realFuture.asStream();
   String toString() => "CustomFuture@${_realFuture.hashCode}";
   int get hashCode => _realFuture.hashCode;
diff --git a/tests/lib/async/future_timeout_test.dart b/tests/lib/async/future_timeout_test.dart
new file mode 100644
index 0000000..f123118
--- /dev/null
+++ b/tests/lib/async/future_timeout_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library future_timeout_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("timeoutNoComplete", () {
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => 42);
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutCompleteAfterTimeout", () {
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => 42);
+    Timer timer = new Timer(const Duration(seconds: 1), () {
+      completer.complete(-1);
+    });
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutCompleteBeforeTimeout", () {
+    Completer completer = new Completer();
+    Timer timer = new Timer(const Duration(milliseconds: 5), () {
+      completer.complete(42);
+    });
+    Future timedOut = completer.future.timeout(
+        const Duration(seconds: 1), () => -1);
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutCompleteBeforeCreate", () {
+    Completer completer = new Completer.sync();
+    completer.complete(42);
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => -1);
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutThrows", () {
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () { throw "EXN1"; });
+    timedOut.catchError(expectAsync2((e, s) {
+      expect(e, "EXN1");
+    }));
+  });
+
+  test("timeoutThrowAfterTimeout", () {
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => 42);
+    Timer timer = new Timer(const Duration(seconds: 1), () {
+      completer.completeError("EXN2");
+    });
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutThrowBeforeTimeout", () {
+    Completer completer = new Completer();
+    Timer timer = new Timer(const Duration(milliseconds: 5), () {
+      completer.completeError("EXN3");
+    });
+    Future timedOut = completer.future.timeout(
+        const Duration(seconds: 1), () => -1);
+    timedOut.catchError(expectAsync2((e, s) {
+      expect(e, "EXN3");
+    }));
+  });
+
+  test("timeoutThrowBeforeCreate", () {
+    // Prevent uncaught error when we create the error.
+    Completer completer = new Completer.sync()..future.catchError((e){});
+    completer.completeError("EXN4");
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => -1);
+    timedOut.catchError(expectAsync2((e, s) {
+      expect(e, "EXN4");
+    }));
+  });
+
+  test("timeoutReturnFutureValue", () {
+    Future result = new Future.value(42);
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => result);
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutReturnFutureError", () {
+    Future result = new Future.error("EXN5")..catchError((e){});
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () => result);
+    timedOut.catchError(expectAsync2((e, s) {
+      expect(e, "EXN5");
+    }));
+  });
+
+  test("timeoutReturnFutureValueLater", () {
+    Completer result = new Completer();
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () {
+      result.complete(42);
+      return result.future;
+    });
+    timedOut.then(expectAsync1((v) {
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutReturnFutureErrorLater", () {
+    Completer result = new Completer();
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5), () {
+      result.completeError("EXN6");
+      return result.future;
+    });
+    timedOut.catchError(expectAsync2((e, s) {
+      expect(e, "EXN6");
+    }));
+  });
+
+  test("timeoutZone", () {
+    Zone forked;
+    int registerCallDelta = 0;
+    bool callbackCalled = false;
+    Function callback = () {
+      expect(callbackCalled, false);
+      callbackCalled = true;
+      expect(Zone.current, forked);
+      return 42;
+    };
+    forked = Zone.current.fork(specification: new ZoneSpecification(
+        registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
+          if (!identical(f, callback)) return f;
+          registerCallDelta++;  // Increment calls to register.
+          expect(origin, forked);
+          expect(self, forked);
+          return expectAsync0(() { registerCallDelta--; return f(); });
+        }
+    ));
+    Completer completer = new Completer();
+    Future timedOut;
+    forked.run(() {
+      timedOut = completer.future.timeout(const Duration(milliseconds: 5),
+                                          callback);
+    });
+    timedOut.then(expectAsync1((v) {
+      expect(callbackCalled, true);
+      expect(registerCallDelta, 0);
+      expect(Zone.current, Zone.ROOT);
+      expect(v, 42);
+    }));
+  });
+
+  test("timeoutNoFunction", () {
+    Completer completer = new Completer();
+    Future timedOut = completer.future.timeout(
+        const Duration(milliseconds: 5));
+    timedOut.catchError(expectAsync2((e, s) {
+      expect(e, new isInstanceOf<TimeoutException>());
+      expect(e.duration, const Duration(milliseconds: 5));
+      expect(s, null);
+    }));
+  });
+}
diff --git a/tests/lib/async/future_value_chain4_test.dart b/tests/lib/async/future_value_chain4_test.dart
index 8e640b5..926e1b4 100644
--- a/tests/lib/async/future_value_chain4_test.dart
+++ b/tests/lib/async/future_value_chain4_test.dart
@@ -13,6 +13,7 @@
   catchError(_, {test}) => null;
   whenComplete(_) => null;
   asStream() => null;
+  timeout(Duration timeLimit, [void onTimeout()]) => null;
 }
 
 main() {
diff --git a/tests/lib/async/zone_bind_test.dart b/tests/lib/async/zone_bind_test.dart
new file mode 100644
index 0000000..fcca4c0
--- /dev/null
+++ b/tests/lib/async/zone_bind_test.dart
@@ -0,0 +1,31 @@
+// 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';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+
+main() {
+  Completer done = new Completer();
+
+  Expect.identical(Zone.ROOT, Zone.current);
+  // New zone, does nothing by itself.
+  Zone forked = Zone.current.fork(specification: new ZoneSpecification());
+
+  int ctr = 0;
+  void expectZone([timer]) {
+    Expect.identical(forked, Zone.current);
+    if (timer != null) timer.cancel();
+    if (++ctr == 3) {
+      asyncEnd();
+    }
+  }
+
+  asyncStart();
+  Duration now = const Duration(seconds: 0);
+  // Check that the callback is bound to the zone.
+  forked.scheduleMicrotask(expectZone);
+  forked.createTimer(now, expectZone);
+  forked.createPeriodicTimer(now, expectZone);
+}
diff --git a/tests/lib/async/zone_empty_description2_test.dart b/tests/lib/async/zone_empty_description2_test.dart
index 68e1453..ce123e9 100644
--- a/tests/lib/async/zone_empty_description2_test.dart
+++ b/tests/lib/async/zone_empty_description2_test.dart
@@ -14,8 +14,8 @@
   asyncStart();
   bool timerDidRun = false;
   forked.createTimer(const Duration(milliseconds: 20), () {
-    // The createTimer functions on the Zone don't bind the closures.
-    Expect.identical(Zone.ROOT, Zone.current);
+    // The createTimer function on the Zone binds the closures.
+    Expect.identical(forked, Zone.current);
     timerDidRun = true;
     asyncEnd();
   });
@@ -29,8 +29,8 @@
       timer.cancel();
       asyncEnd();
     }
-    // The createPeriodicTimer functions on the Zone don't bind the closures.
-    Expect.identical(Zone.ROOT, Zone.current);
+    // The createPeriodicTimer function on the Zone binds the closures.
+    Expect.identical(forked, Zone.current);
   });
   Expect.identical(Zone.ROOT, Zone.current);
 }
diff --git a/tests/lib/async/zone_empty_description_test.dart b/tests/lib/async/zone_empty_description_test.dart
index 1a35dc0..30e494f 100644
--- a/tests/lib/async/zone_empty_description_test.dart
+++ b/tests/lib/async/zone_empty_description_test.dart
@@ -51,8 +51,7 @@
   asyncStart();
   bool asyncDidRun = false;
   forked.scheduleMicrotask(() {
-    // The scheduleMicrotask functions on the Zone don't bind the closures.
-    Expect.identical(Zone.ROOT, Zone.current);
+    Expect.identical(forked, Zone.current);
     asyncDidRun = true;
     asyncEnd();
   });
@@ -62,8 +61,7 @@
   asyncStart();
   bool timerDidRun = false;
   forked.createTimer(const Duration(milliseconds: 0), () {
-    // The createTimer functions on the Zone don't bind the closures.
-    Expect.identical(Zone.ROOT, Zone.current);
+    Expect.identical(forked, Zone.current);
     timerDidRun = true;
     asyncEnd();
   });
diff --git a/tests/lib/async/zone_run_guarded_test.dart b/tests/lib/async/zone_run_guarded_test.dart
index 60ffe5a..4145443 100644
--- a/tests/lib/async/zone_run_guarded_test.dart
+++ b/tests/lib/async/zone_run_guarded_test.dart
@@ -57,7 +57,7 @@
   result = forked.runGuarded(() {
     Expect.identical(forked, Zone.current);
     events.add("run closure");
-    scheduleMicrotask(() {
+    forked.scheduleMicrotask(() {
       events.add("run closure 2");
       Expect.identical(forked, Zone.current);
       done.complete(true);
@@ -76,4 +76,4 @@
         events);
     asyncEnd();
   });
-}
\ No newline at end of file
+}
diff --git a/tests/lib/async/zone_run_test.dart b/tests/lib/async/zone_run_test.dart
index 2af32df..3c13c46 100644
--- a/tests/lib/async/zone_run_test.dart
+++ b/tests/lib/async/zone_run_test.dart
@@ -44,7 +44,7 @@
   result = forked.run(() {
     Expect.identical(forked, Zone.current);
     events.add("run closure 2");
-    scheduleMicrotask(() {
+    forked.scheduleMicrotask(() {
       events.add("run closure 3");
       Expect.identical(forked, Zone.current);
       done.complete(true);
@@ -62,4 +62,4 @@
         events);
     asyncEnd();
   });
-}
\ No newline at end of file
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 75bf9c5..d0c4728 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -24,7 +24,6 @@
 mirrors/find_in_context_private_test: Fail # Issue 6490
 mirrors/find_in_context_fake_function_test: Fail # Issue 6490
 mirrors/function_type_mirror_test: RuntimeError # Issue 12166
-mirrors/generics_test/01: RuntimeError # Issue 12087
 mirrors/generic_f_bounded_mixin_application_test: RuntimeError # Issue 12087
 mirrors/generic_function_typedef_test: RuntimeError # Issue 12333
 mirrors/generic_interface_test: RuntimeError # Issue 12087
@@ -35,7 +34,6 @@
 mirrors/hierarchy_invariants_test: RuntimeError # Issue 11863
 mirrors/immutable_collections_test: RuntimeError # Issue 14030
 mirrors/initializing_formals_test/01: RuntimeError # Issue 6490
-mirrors/initializing_formals_test/02: RuntimeError # Issue 12087
 mirrors/initializing_formals_test/03: CompileTimeError # Issue 12164
 mirrors/instance_members_test: RuntimeError # Issue 14633
 mirrors/instance_members_with_override_test: RuntimeError # Issue 14633
@@ -128,7 +126,8 @@
 async/catch_errors28_test: Fail # Timer interface not supported: dartbug.com/7728.
 async/catch_errors8_test: Fail # Timer interface not supported: dartbug.com/7728.
 async/run_zoned8_test: Fail # Timer interface not supported: dartbug.com/7728.
-
+async/zone_bind_test: Fail # Timer interface not supported: dartbug.com/7728.
+async/future_timeout_test: Fail # Timer interface not supported: dartbug.com/7728.
 
 [ $compiler == dart2js && $checked ]
 convert/utf85_test: Pass, Slow # Issue 12029.
@@ -168,6 +167,7 @@
 
 [ $compiler == dart2js ]
 typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
+typed_data/int32x4_bigint_test: RuntimeError # Issue 1533
 
 [ $runtime == opera ]
 async/multiple_timer_test: Pass, Fail # Probably issue 14734
diff --git a/tests/lib/math/double_pow_test.dart b/tests/lib/math/double_pow_test.dart
index c3ce04c..ca35db0 100644
--- a/tests/lib/math/double_pow_test.dart
+++ b/tests/lib/math/double_pow_test.dart
@@ -66,18 +66,18 @@
   }
   for (var d in samples) {
     // otherwise, if either `x` or `y` is NaN then the result is NaN.
-    if (d != 0.0) Expect.identical(NaN, pow(NaN, d), "$d");
-    if (d != 1.0) Expect.identical(NaN, pow(d, NaN), "$d");
+    if (d != 0.0) Expect.isTrue(pow(NaN, d).isNaN, "$d");
+    if (d != 1.0) Expect.isTrue(pow(d, NaN).isNaN, "$d");
   }
 
   for (var d in samples) {
     // if `x` is a finite and strictly negative and `y` is a finite non-integer,
     // the result is NaN.
     if (d < 0 && !d.isInfinite) {
-      Expect.identical(NaN, pow(d, 0.5), "$d");
-      Expect.identical(NaN, pow(d, -0.5), "$d");
-      Expect.identical(NaN, pow(d, 1.5), "$d");
-      Expect.identical(NaN, pow(d, -1.5), "$d");
+      Expect.isTrue(pow(d, 0.5).isNaN, "$d");
+      Expect.isTrue(pow(d, -0.5).isNaN, "$d");
+      Expect.isTrue(pow(d, 1.5).isNaN, "$d");
+      Expect.isTrue(pow(d, -1.5).isNaN, "$d");
     }
   }
 
diff --git a/tests/lib/mirrors/array_tracing2_test.dart b/tests/lib/mirrors/array_tracing2_test.dart
new file mode 100644
index 0000000..39411a1
--- /dev/null
+++ b/tests/lib/mirrors/array_tracing2_test.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.
+
+import 'dart:mirrors';
+
+class A {
+  var field;
+}
+
+main() {
+  var a = new A();
+  var mirror = reflect(a);
+  var array = [42];
+  a.field = array;
+  var field = mirror.getField(#field);
+  field.invoke(#clear, []);
+  if (array.length == 1) throw 'Test failed';
+}
diff --git a/tests/lib/mirrors/array_tracing3_test.dart b/tests/lib/mirrors/array_tracing3_test.dart
new file mode 100644
index 0000000..38a6a61
--- /dev/null
+++ b/tests/lib/mirrors/array_tracing3_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+@MirrorsUsed(targets: 'A, List')
+import 'dart:mirrors';
+
+class A {
+  static var field;
+}
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  ClassMirror a = reflectClass(A);
+  var array = [42];
+  A.field = array;
+  var field = a.getField(#field);
+  field.invoke(#clear, []);
+  if (array.length == 1) throw 'Test failed';
+}
diff --git a/tests/lib/mirrors/array_tracing_test.dart b/tests/lib/mirrors/array_tracing_test.dart
new file mode 100644
index 0000000..092feac
--- /dev/null
+++ b/tests/lib/mirrors/array_tracing_test.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.
+
+import 'dart:mirrors';
+
+class A {
+  static var field;
+}
+
+main() {
+  MirrorSystem mirrors = currentMirrorSystem();
+  ClassMirror a = reflectClass(A);
+  var array = [42];
+  A.field = array;
+  var field = a.getField(#field);
+  field.invoke(#clear, []);
+  if (array.length == 1) throw 'Test failed';
+}
diff --git a/tests/lib/mirrors/generics_dynamic_test.dart b/tests/lib/mirrors/generics_dynamic_test.dart
new file mode 100644
index 0000000..b8abf53
--- /dev/null
+++ b/tests/lib/mirrors/generics_dynamic_test.dart
@@ -0,0 +1,66 @@
+// 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:expect/expect.dart';
+
+class A<T> {}
+class B<T extends A> extends A implements C{
+  A m(A a) {}
+  A field;
+}
+class C<S,T> {}
+class D extends A<int> {}
+
+main() {
+  ClassMirror aDecl = reflectClass(A);
+  ClassMirror bDecl = reflectClass(B);
+  ClassMirror cDecl = reflectClass(C);
+  TypeMirror aInstance = reflect(new A()).type;
+  TypeMirror aInstanceDynamic = reflect(new A<dynamic>()).type;
+  TypeMirror dInstance = reflect(new D()).type;
+  TypeMirror cInstance = reflect(new C<dynamic, dynamic>()).type;
+  TypeMirror cNestedInstance = reflect(new C<C, dynamic>()).type;
+  TypeMirror cTypeArgument = cNestedInstance.typeArguments.first;
+  TypeMirror superA = bDecl.superclass;
+  TypeMirror superC = bDecl.superinterfaces.single;
+  MethodMirror m = bDecl.declarations[#m];
+  VariableMirror field = bDecl.declarations[#field];
+  TypeMirror returnTypeA = m.returnType;
+  TypeMirror parameterTypeA = m.parameters.first.type;
+  TypeMirror fieldTypeA = field.type;
+  TypeMirror upperBoundA = bDecl.typeVariables.single.upperBound;
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  Expect.isTrue(aDecl.isOriginalDeclaration);
+  Expect.isTrue(reflect(dInstance).type.isOriginalDeclaration);
+  Expect.isFalse(aInstance.isOriginalDeclaration);
+  Expect.isFalse(aInstanceDynamic.isOriginalDeclaration);
+  Expect.isFalse(superA.isOriginalDeclaration);
+  Expect.isFalse(superC.isOriginalDeclaration);
+  Expect.isFalse(returnTypeA.isOriginalDeclaration);
+  Expect.isFalse(parameterTypeA.isOriginalDeclaration);
+  Expect.isFalse(fieldTypeA.isOriginalDeclaration);
+  Expect.isFalse(upperBoundA.isOriginalDeclaration);
+  Expect.isFalse(cInstance.isOriginalDeclaration);
+  Expect.isFalse(cNestedInstance.isOriginalDeclaration);
+  Expect.isFalse(cTypeArgument.isOriginalDeclaration);
+  
+  Expect.isTrue(aDecl.typeArguments.isEmpty);
+  Expect.isTrue(dInstance.typeArguments.isEmpty);
+  Expect.equals(dynamicMirror, aInstance.typeArguments.single);
+  Expect.equals(dynamicMirror, aInstanceDynamic.typeArguments.single);
+  Expect.equals(dynamicMirror, superA.typeArguments.single);
+  Expect.equals(dynamicMirror, superC.typeArguments.first);
+  Expect.equals(dynamicMirror, superC.typeArguments.last);
+  Expect.equals(dynamicMirror, returnTypeA.typeArguments.single);
+  Expect.equals(dynamicMirror, parameterTypeA.typeArguments.single);
+  Expect.equals(dynamicMirror, fieldTypeA.typeArguments.single);
+  Expect.equals(dynamicMirror, upperBoundA.typeArguments.single);
+  Expect.equals(dynamicMirror, cInstance.typeArguments.first);
+  Expect.equals(dynamicMirror, cInstance.typeArguments.last);
+  Expect.equals(dynamicMirror, cNestedInstance.typeArguments.last);
+  Expect.equals(dynamicMirror, cTypeArgument.typeArguments.first);
+  Expect.equals(dynamicMirror, cTypeArgument.typeArguments.last);  
+}
\ No newline at end of file
diff --git a/tests/lib/mirrors/generics_test.dart b/tests/lib/mirrors/generics_test.dart
index 085dc37..10fe2e3 100644
--- a/tests/lib/mirrors/generics_test.dart
+++ b/tests/lib/mirrors/generics_test.dart
@@ -79,20 +79,20 @@
   var numMirror = reflectClass(num);
   var dynamicMirror = currentMirrorSystem().dynamicType;
   typeArguments(reflect(new A<num>()).type, [numMirror]);
-  typeArguments(reflect(new A<dynamic>()).type, [dynamicMirror]); /// 01: ok
-  typeArguments(reflect(new A()).type, [dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new A<dynamic>()).type, [dynamicMirror]);
+  typeArguments(reflect(new A()).type, [dynamicMirror]); 
   typeArguments(reflect(new B()).type, []);
   typeArguments(reflect(new C()).type, []);
   typeArguments(reflect(new D()).type, []);
   typeArguments(reflect(new E<num>()).type, [numMirror]);
-  typeArguments(reflect(new E<dynamic>()).type, [dynamicMirror]); /// 01: ok
-  typeArguments(reflect(new E()).type, [dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new E<dynamic>()).type, [dynamicMirror]); 
+  typeArguments(reflect(new E()).type, [dynamicMirror]); 
   typeArguments(reflect(new F<num>()).type, [numMirror]);
-  typeArguments(reflect(new F<dynamic>()).type, [dynamicMirror]); /// 01: ok
-  typeArguments(reflect(new F()).type, [dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new F<dynamic>()).type, [dynamicMirror]); 
+  typeArguments(reflect(new F()).type, [dynamicMirror]); 
   typeArguments(reflect(new G()).type, []);
-  typeArguments(reflect(new H<dynamic, num, dynamic>()).type, /// 01: ok
-      [dynamicMirror, numMirror, dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new H<dynamic, num, dynamic>()).type, 
+      [dynamicMirror, numMirror, dynamicMirror]); 
   typeArguments(reflect(new I()).type, []);
 
   Expect.isFalse(reflect(new A<num>()).type.isOriginalDeclaration);
@@ -102,7 +102,7 @@
   Expect.isFalse(reflect(new E<num>()).type.isOriginalDeclaration);
   Expect.isFalse(reflect(new F<num>()).type.isOriginalDeclaration);
   Expect.isTrue(reflect(new G()).type.isOriginalDeclaration);
-  Expect.isFalse(reflect(new H()).type.isOriginalDeclaration); /// 01: ok
+  Expect.isFalse(reflect(new H()).type.isOriginalDeclaration); 
   Expect.isTrue(reflect(new I()).type.isOriginalDeclaration);
 
   Expect.equals(reflectClass(A),
@@ -138,8 +138,8 @@
                    reflect(new F<num>()).type.originalDeclaration);
   Expect.equals(reflect(new G()).type,
                 reflect(new G()).type.originalDeclaration);
-  Expect.notEquals(reflect(new H()).type, /// 01: ok
-                   reflect(new H()).type.originalDeclaration); /// 01: ok
+  Expect.notEquals(reflect(new H()).type, 
+                   reflect(new H()).type.originalDeclaration); 
   Expect.equals(reflect(new I()).type,
                 reflect(new I()).type.originalDeclaration);
 
diff --git a/tests/lib/mirrors/initializing_formals_test.dart b/tests/lib/mirrors/initializing_formals_test.dart
index 3afb39d..2729524 100644
--- a/tests/lib/mirrors/initializing_formals_test.dart
+++ b/tests/lib/mirrors/initializing_formals_test.dart
@@ -75,7 +75,7 @@
   mm = reflectClass(Class).declarations[#Class.generic];
   pm = mm.parameters.single;
   Expect.equals(#tField, pm.simpleName);
-  Expect.equals(reflectClass(Class).typeVariables.single, pm.type);  /// 02: ok
+  Expect.equals(reflectClass(Class).typeVariables.single, pm.type);  
   Expect.isFalse(pm.isNamed);  /// 01: ok
   Expect.isFalse(pm.isFinal);  /// 01: ok
   Expect.isFalse(pm.isOptional);  /// 01: ok
@@ -111,7 +111,7 @@
   mm = reflectClass(Class).declarations[#Class.withVar];
   pm = mm.parameters.single;
   Expect.equals(#intField, pm.simpleName);
-  Expect.equals(reflectClass(int), pm.type);  // N.B.   /// 02: ok
+  Expect.equals(reflectClass(int), pm.type);
   Expect.isFalse(pm.isNamed);  /// 01: ok
   Expect.isFalse(pm.isFinal);  /// 01: ok
   Expect.isFalse(pm.isOptional);  /// 01: ok
diff --git a/tests/lib/mirrors/private_symbol_test.dart b/tests/lib/mirrors/private_symbol_test.dart
index 156381a..be4f5fe 100644
--- a/tests/lib/mirrors/private_symbol_test.dart
+++ b/tests/lib/mirrors/private_symbol_test.dart
@@ -7,7 +7,7 @@
 import 'dart:mirrors';
 import 'package:expect/expect.dart';
 
-typedef int _F(int);
+typedef int _F(int i);
 
 class _C<_T> {
   get g {}
diff --git a/tests/lib/typed_data/int32x4_bigint_test.dart b/tests/lib/typed_data/int32x4_bigint_test.dart
new file mode 100644
index 0000000..539b23f
--- /dev/null
+++ b/tests/lib/typed_data/int32x4_bigint_test.dart
@@ -0,0 +1,16 @@
+// 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 tag to be able to run in html test framework.
+library int32x4_bigint_test;
+
+import 'package:expect/expect.dart';
+import 'dart:typed_data';
+
+main() {
+  var n = 18446744073709551617;
+  var x = new Int32x4(n, 0, 0, 0);
+  Expect.equals(x.x, 1);
+}
diff --git a/tests/standalone/io/file_system_watcher_test.dart b/tests/standalone/io/file_system_watcher_test.dart
index 2cc97b7..a28d7ed 100644
--- a/tests/standalone/io/file_system_watcher_test.dart
+++ b/tests/standalone/io/file_system_watcher_test.dart
@@ -86,6 +86,8 @@
 
 
 void testWatchMoveFile() {
+  // Mac OS doesn't report move events.
+  if (Platform.isMacOS) return;
   var dir = Directory.systemTemp.createTempSync('dart_file_system_watcher');
   var file = new File(join(dir.path, 'file'));
   file.createSync();
diff --git a/tests/standalone/io/http_cookie_date_test.dart b/tests/standalone/io/http_cookie_date_test.dart
index 56bee7a..08288b6 100644
--- a/tests/standalone/io/http_cookie_date_test.dart
+++ b/tests/standalone/io/http_cookie_date_test.dart
@@ -2,17 +2,38 @@
 // for 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 dart.io;
+
 import "package:expect/expect.dart";
 import "dart:async";
-import "dart:math";
 import "dart:collection";
+import "dart:convert";
+import "dart:math";
+import "dart:typed_data";
+import "dart:isolate";
 
+part "../../../sdk/lib/io/bytes_builder.dart";
 part "../../../sdk/lib/io/common.dart";
-part "../../../sdk/lib/io/io_sink.dart";
+part "../../../sdk/lib/io/crypto.dart";
+part "../../../sdk/lib/io/data_transformer.dart";
+part "../../../sdk/lib/io/directory.dart";
+part "../../../sdk/lib/io/directory_impl.dart";
+part "../../../sdk/lib/io/file.dart";
+part "../../../sdk/lib/io/file_impl.dart";
+part "../../../sdk/lib/io/file_system_entity.dart";
+part "../../../sdk/lib/io/link.dart";
 part "../../../sdk/lib/io/http.dart";
 part "../../../sdk/lib/io/http_impl.dart";
-part "../../../sdk/lib/io/http_parser.dart";
 part "../../../sdk/lib/io/http_date.dart";
+part "../../../sdk/lib/io/http_parser.dart";
+part "../../../sdk/lib/io/http_headers.dart";
+part "../../../sdk/lib/io/http_session.dart";
+part "../../../sdk/lib/io/io_service.dart";
+part "../../../sdk/lib/io/io_sink.dart";
+part "../../../sdk/lib/io/platform.dart";
+part "../../../sdk/lib/io/platform_impl.dart";
+part "../../../sdk/lib/io/secure_socket.dart";
+part "../../../sdk/lib/io/secure_server_socket.dart";
 part "../../../sdk/lib/io/socket.dart";
 
 void testParseHttpCookieDate() {
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index 87dd27b..d1d261f 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -2,18 +2,38 @@
 // for 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:async';
-import 'dart:math';
-import 'dart:collection';
+library dart.io;
 
-part '../../../sdk/lib/io/common.dart';
-part "../../../sdk/lib/io/io_sink.dart";
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:collection";
+import "dart:convert";
+import "dart:math";
+import "dart:typed_data";
+import "dart:isolate";
+
+part "../../../sdk/lib/io/bytes_builder.dart";
+part "../../../sdk/lib/io/common.dart";
+part "../../../sdk/lib/io/crypto.dart";
+part "../../../sdk/lib/io/data_transformer.dart";
+part "../../../sdk/lib/io/directory.dart";
+part "../../../sdk/lib/io/directory_impl.dart";
+part "../../../sdk/lib/io/file.dart";
+part "../../../sdk/lib/io/file_impl.dart";
+part "../../../sdk/lib/io/file_system_entity.dart";
+part "../../../sdk/lib/io/link.dart";
 part "../../../sdk/lib/io/http.dart";
-part "../../../sdk/lib/io/http_date.dart";
-part "../../../sdk/lib/io/http_headers.dart";
 part "../../../sdk/lib/io/http_impl.dart";
+part "../../../sdk/lib/io/http_date.dart";
 part "../../../sdk/lib/io/http_parser.dart";
+part "../../../sdk/lib/io/http_headers.dart";
+part "../../../sdk/lib/io/http_session.dart";
+part "../../../sdk/lib/io/io_service.dart";
+part "../../../sdk/lib/io/io_sink.dart";
+part "../../../sdk/lib/io/platform.dart";
+part "../../../sdk/lib/io/platform_impl.dart";
+part "../../../sdk/lib/io/secure_socket.dart";
+part "../../../sdk/lib/io/secure_server_socket.dart";
 part "../../../sdk/lib/io/socket.dart";
 
 void testMultiValue() {
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index c35fcfb..2c5e508 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -2,21 +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.
 
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'dart:math';
-import 'dart:typed_data';
-import 'dart:isolate';
-import 'dart:collection';
+library dart.io;
 
-part '../../../sdk/lib/io/common.dart';
-part '../../../sdk/lib/io/io_sink.dart';
-part '../../../sdk/lib/io/http.dart';
-part '../../../sdk/lib/io/http_date.dart';
-part '../../../sdk/lib/io/http_impl.dart';
-part '../../../sdk/lib/io/http_headers.dart';
-part '../../../sdk/lib/io/http_parser.dart';
-part '../../../sdk/lib/io/socket.dart';
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:collection";
+import "dart:convert";
+import "dart:math";
+import "dart:typed_data";
+import "dart:isolate";
+
+part "../../../sdk/lib/io/bytes_builder.dart";
+part "../../../sdk/lib/io/common.dart";
+part "../../../sdk/lib/io/crypto.dart";
+part "../../../sdk/lib/io/data_transformer.dart";
+part "../../../sdk/lib/io/directory.dart";
+part "../../../sdk/lib/io/directory_impl.dart";
+part "../../../sdk/lib/io/file.dart";
+part "../../../sdk/lib/io/file_impl.dart";
+part "../../../sdk/lib/io/file_system_entity.dart";
+part "../../../sdk/lib/io/link.dart";
+part "../../../sdk/lib/io/http.dart";
+part "../../../sdk/lib/io/http_impl.dart";
+part "../../../sdk/lib/io/http_date.dart";
+part "../../../sdk/lib/io/http_parser.dart";
+part "../../../sdk/lib/io/http_headers.dart";
+part "../../../sdk/lib/io/http_session.dart";
+part "../../../sdk/lib/io/io_service.dart";
+part "../../../sdk/lib/io/io_sink.dart";
+part "../../../sdk/lib/io/platform.dart";
+part "../../../sdk/lib/io/platform_impl.dart";
+part "../../../sdk/lib/io/secure_socket.dart";
+part "../../../sdk/lib/io/secure_server_socket.dart";
+part "../../../sdk/lib/io/socket.dart";
 
 class HttpParserTest {
   static void runAllTests() {
diff --git a/tests/standalone/io/resolve_symbolic_links_test.dart b/tests/standalone/io/resolve_symbolic_links_test.dart
index 252e65f..690cbc5 100644
--- a/tests/standalone/io/resolve_symbolic_links_test.dart
+++ b/tests/standalone/io/resolve_symbolic_links_test.dart
@@ -23,7 +23,6 @@
   asyncTest(() => testDir(join(testsDir, 'standalone', 'io')));
   asyncTest(() => testDir(join(testsDir, 'lib', '..', 'standalone', 'io')));
   // Test a relative path.
-  asyncTest(() => testDir('.'));
   if (Platform.isWindows) {
     asyncTest(() =>testFile(join('\\\\?\\$testsDir', 'standalone', 'io',
                                  'resolve_symbolic_links_test.dart')));
@@ -37,7 +36,8 @@
          testFile(join(temp, 'link1', 'file2')),
          testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
          testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
-         testLink(join(temp, 'link1'))]))
+         testLink(join(temp, 'link1')),
+         testDir('.')]))
     .then((_) {
       if (Platform.isWindows) {
         // Windows applies '..' to a link without resolving the link first.
diff --git a/tests/standalone/io/socket_test.dart b/tests/standalone/io/socket_test.dart
index beec587..56a76bb 100644
--- a/tests/standalone/io/socket_test.dart
+++ b/tests/standalone/io/socket_test.dart
@@ -210,8 +210,22 @@
   });
 }
 
-main() {
+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();
@@ -224,5 +238,5 @@
   testConnectStreamDataClose(false);
   testConnectStreamDataCloseCancel(true);
   testConnectStreamDataCloseCancel(false);
-  asyncEnd();
+  testCloseWriteNoListen();
 }
diff --git a/tests/standalone/io/test_harness_analyzer_test.dart b/tests/standalone/io/test_harness_analyzer_test.dart
new file mode 100644
index 0000000..f2a2b40
--- /dev/null
+++ b/tests/standalone/io/test_harness_analyzer_test.dart
@@ -0,0 +1,11 @@
+// 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 '../../../tools/test.dart' as test_dart;
+import '../../../tools/testing/dart/launch_browser.dart' as launch_browser;
+
+// The purpose of this test is to run the analyzer on it and make sure our
+// testing scripts are free of warnings/errors.
+
+void main() {}
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index 5b540af..4b2fe2a 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -12,7 +12,7 @@
 import "../../../tools/testing/dart/test_options.dart";
 import "process_test_util.dart";
 
-final DEFAULT_TIMEOUT = 2;
+final DEFAULT_TIMEOUT = 10;
 final LONG_TIMEOUT = 30;
 
 class TestController {
@@ -140,8 +140,8 @@
         throw "This test always fails, to test the test scripts.";
         break;
       case 'timeout':
-        // Run for 10 seconds, then exit.  This tests a 2 second timeout.
-        new Timer(new Duration(seconds: 10), (){ });
+        // This process should be killed by the test after DEFAULT_TIMEOUT
+        new Timer(new Duration(hours: 42), (){ });
         break;
       default:
         throw "Unknown option ${arguments[0]} passed to test_runner_test";
diff --git a/tests/standalone/io/web_socket_protocol_processor_test.dart b/tests/standalone/io/web_socket_protocol_processor_test.dart
index ff5de75..b14a37d 100644
--- a/tests/standalone/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone/io/web_socket_protocol_processor_test.dart
@@ -2,21 +2,40 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "dart:convert";
-import "dart:math";
-import "dart:async";
-import "dart:collection";
-import "dart:typed_data";
-import "dart:isolate";
+library dart.io;
 
 import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
+import "dart:async";
+import "dart:collection";
+import "dart:convert";
+import "dart:math";
+import "dart:typed_data";
+import "dart:isolate";
 
-part '../../../sdk/lib/io/common.dart';
-part "../../../sdk/lib/io/http.dart";
 part "../../../sdk/lib/io/bytes_builder.dart";
+part "../../../sdk/lib/io/common.dart";
+part "../../../sdk/lib/io/crypto.dart";
+part "../../../sdk/lib/io/data_transformer.dart";
+part "../../../sdk/lib/io/directory.dart";
+part "../../../sdk/lib/io/directory_impl.dart";
+part "../../../sdk/lib/io/file.dart";
+part "../../../sdk/lib/io/file_impl.dart";
+part "../../../sdk/lib/io/file_system_entity.dart";
+part "../../../sdk/lib/io/link.dart";
+part "../../../sdk/lib/io/http.dart";
+part "../../../sdk/lib/io/http_impl.dart";
+part "../../../sdk/lib/io/http_date.dart";
+part "../../../sdk/lib/io/http_parser.dart";
+part "../../../sdk/lib/io/http_headers.dart";
+part "../../../sdk/lib/io/http_session.dart";
+part "../../../sdk/lib/io/io_service.dart";
 part "../../../sdk/lib/io/io_sink.dart";
-part "../../../sdk/lib/io/string_transformer.dart";
+part "../../../sdk/lib/io/platform.dart";
+part "../../../sdk/lib/io/platform_impl.dart";
+part "../../../sdk/lib/io/secure_socket.dart";
+part "../../../sdk/lib/io/secure_server_socket.dart";
+part "../../../sdk/lib/io/socket.dart";
 part "../../../sdk/lib/io/websocket.dart";
 part "../../../sdk/lib/io/websocket_impl.dart";
 
diff --git a/tests/standalone/io/web_socket_protocol_test.dart b/tests/standalone/io/web_socket_protocol_test.dart
new file mode 100644
index 0000000..e81cc27
--- /dev/null
+++ b/tests/standalone/io/web_socket_protocol_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=
+// VMOptions=--short_socket_read
+// VMOptions=--short_socket_write
+// VMOptions=--short_socket_read --short_socket_write
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+
+
+testEmptyProtocol() {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    server.listen((request) {
+      WebSocketTransformer.upgrade(request).then((websocket) {
+        websocket.close();
+      });
+    });
+    WebSocket.connect("ws://127.0.0.1:${server.port}/",
+                      protocols: []).then((client) {
+      Expect.isNull(client.protocol);
+      client.close();
+      server.close();
+    });
+  });
+}
+
+
+testProtocol(List<String> protocols, String used) {
+  selector(List<String> receivedProtocols) {
+    Expect.listEquals(protocols, receivedProtocols);
+    return used;
+  }
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    server.listen((request) {
+      WebSocketTransformer.upgrade(request,
+                                   protocolSelector: selector)
+        .then((websocket) {
+          Expect.equals(used, websocket.protocol);
+          websocket.close();
+        });
+    });
+    WebSocket.connect("ws://127.0.0.1:${server.port}/",
+                      protocols: protocols).then((client) {
+      Expect.equals(used, client.protocol);
+      client.close();
+      server.close();
+    });
+  });
+}
+
+
+testProtocolHandler() {
+  // Test throwing an error.
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    server.listen((request) {
+      selector(List<String> receivedProtocols) {
+        throw "error";
+      }
+      WebSocketTransformer.upgrade(request,
+                                   protocolSelector: selector)
+        .then((websocket) {
+          Expect.fail('error expected');
+        }, onError: (error) {
+          Expect.equals('error', error);
+        });
+    });
+    WebSocket.connect("ws://127.0.0.1:${server.port}/",
+                      protocols: ["v1.example.com"])
+      .then((client) {
+        Expect.fail('error expected');
+      }, onError: (error) {
+        server.close();
+      });
+  });
+
+  // Test returning another protocol.
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    server.listen((request) {
+      selector(List<String> receivedProtocols) => "v2.example.com";
+      WebSocketTransformer.upgrade(request,
+                                   protocolSelector: selector)
+        .then((websocket) {
+          Expect.fail('error expected');
+        }, onError: (error) {
+          Expect.isTrue(error is WebSocketException);
+        });
+    });
+    WebSocket.connect("ws://127.0.0.1:${server.port}/",
+                      protocols: ["v1.example.com"])
+      .then((client) {
+        Expect.fail('error expected');
+      }, onError: (error) {
+        server.close();
+      });
+  });
+}
+
+
+void main() {
+  testEmptyProtocol();
+  testProtocol(["v1.example.com", "v2.example.com"], "v1.example.com");
+  testProtocol(["v1.example.com", "v2.example.com"], "v2.example.com");
+  testProtocolHandler();
+}
+
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 7bf4ccf..570c988 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -56,43 +56,16 @@
 issue14236_test: Skip # Issue 14236 Script snapshots do not work in the browser.
 
 
-[ $compiler == dartanalyzer ]
+[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 javascript_int_overflow_literal_test/01: fail, ok
 issue14236_test: Skip # Analyzer can't handle Script snapshots.
 
 # test issue https://code.google.com/p/dart/issues/detail?id=11518
 io/file_constructor_test: fail
 
-# The dart:io library is created at build time from separate files, and
-# there is no language-spec compatible way to run unit tests on the private
-# members and methods of dart:io.
-# Dart analyzer spots the misuse of 'part' directives in these unit tests.
-io/http_headers_test: Skip
-io/http_cookie_date_test: Skip
-io/http_parser_test: Skip
-io/web_socket_protocol_processor_test: Skip
-
 # This is runtime test.
 io/process_exit_negative_test: Skip
 
-[ $compiler == dart2analyzer ]
-javascript_int_overflow_literal_test/01: fail, ok
-issue14236_test: Skip # Analyzer can't handle Script snapshots.
-
-# test issue https://code.google.com/p/dart/issues/detail?id=11518
-io/file_constructor_test: fail
-
-# The dart:io library is created at build time from separate files, and
-# there is no language-spec compatible way to run unit tests on the private
-# members and methods of dart:io.
-# Dart analyzer spots the misuse of 'part' directives in these unit tests.
-io/http_headers_test: Skip
-io/http_cookie_date_test: Skip
-io/http_parser_test: Skip
-io/web_socket_protocol_processor_test: Skip
-
-# This is runtime test.
-io/process_exit_negative_test: Skip
 
 [ $compiler == dart2js ]
 number_identity_test: Skip # Bigints and int/double diff. not supported.
@@ -174,9 +147,7 @@
 io/process_invalid_arguments_test: StaticWarning
 io/raw_secure_server_socket_argument_test: StaticWarning
 io/secure_socket_argument_test: StaticWarning
-io/skipping_dart2js_compilations_test: CompileTimeError, StaticWarning
 io/stdout_bad_argument_test: StaticWarning
-io/test_runner_test: CompileTimeError, StaticWarning
 package/package1_test: StaticWarning
 package/package_test: StaticWarning
 typed_data_test: StaticWarning
diff --git a/tests/standalone/vmservice/isolate_class_test.dart b/tests/standalone/vmservice/isolate_class_test.dart
index 086ae5e..9650443 100644
--- a/tests/standalone/vmservice/isolate_class_test.dart
+++ b/tests/standalone/vmservice/isolate_class_test.dart
@@ -28,10 +28,10 @@
   onRequestCompleted(Map reply) {
     Expect.equals('Library', reply['type']);
     Expect.equals('isolate_stacktrace_command_script', reply['name']);
-    Expect.equals(2, reply['classes'].length);
-    Expect.equals('@Class', reply['classes'][1]['type']);
-    Expect.equals('C', reply['classes'][1]['name']);
-    _classId = reply['classes'][1]['id'];
+    Expect.equals(1, reply['classes'].length);
+    Expect.equals('@Class', reply['classes'][0]['type']);
+    Expect.equals('C', reply['classes'][0]['name']);
+    _classId = reply['classes'][0]['id'];
   }
 }
 
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index aad4e49..b66f951 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -74,6 +74,9 @@
 }
 class JSFunction {}
 class JSInt {}
+class JSPositiveInt {}
+class JSUInt31 {}
+class JSUInt32 {}
 class JSDouble {}
 class JSNumber {}
 class JSNull {}
diff --git a/tools/VERSION b/tools/VERSION
index 5e01d86..23e911a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,5 +1,5 @@
 CHANNEL dev
 MAJOR 1
 MINOR 0
-BUILD 1
-PATCH 3
+BUILD 2
+PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 7f730cb..0ed83e6 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -257,47 +257,6 @@
       TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
                extras_flags, arch)
 
-
-def _DeleteTempWebdriverProfiles(directory):
-  """Find all the firefox profiles in a particular directory and delete them."""
-  for f in os.listdir(directory):
-    item = os.path.join(directory, f)
-    if os.path.isdir(item) and (f.startswith('tmp') or f.startswith('opera')):
-      subprocess.Popen('rm -rf %s' % item, shell=True)
-
-
-def CleanUpTemporaryFiles(system, browser):
-  """For some browser (selenium) tests, the browser creates a temporary profile
-  on each browser session start. On Windows, generally these files are
-  automatically deleted when all python processes complete. However, since our
-  buildbot slave script also runs on python, we never get the opportunity to
-  clear out the temp files, so we do so explicitly here. Our batch browser
-  testing will make this problem occur much less frequently, but will still
-  happen eventually unless we do this.
-
-  This problem also occurs with batch tests in Firefox. For some reason selenium
-  automatically deletes the temporary profiles for Firefox for one browser,
-  but not multiple ones when we have many open batch tasks running. This
-  behavior has not been reproduced outside of the buildbots.
-
-  Args:
-     - system: either 'linux', 'mac', 'windows'
-     - browser: one of the browsers, see GetBuildInfo
-  """
-  if system == 'windows':
-    temp_dir = 'C:\\Users\\chrome-bot\\AppData\\Local\\Temp'
-    for name in os.listdir(temp_dir):
-      fullname = os.path.join(temp_dir, name)
-      if os.path.isdir(fullname):
-        shutil.rmtree(fullname, ignore_errors=True)
-  elif browser == 'ff' or 'opera':
-    # Note: the buildbots run as root, so we can do this without requiring a
-    # password. The command won't actually work on regular machines without
-    # root permissions.
-    _DeleteTempWebdriverProfiles('/tmp')
-    _DeleteTempWebdriverProfiles('/var/tmp')
-
-
 def GetHasHardCodedCheckedMode(build_info):
   # TODO(ricow): We currently run checked mode tests on chrome on linux and
   # on the slow (all) IE windows bots. This is a hack and we should use the
@@ -364,9 +323,6 @@
                  build_info.test_set, build_info.arch,
                  compiler=build_info.compiler)
 
-  if build_info.runtime != 'd8':
-    CleanUpTemporaryFiles(build_info.system, build_info.runtime)
-
 
 def BuildCompiler(build_info):
   """
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index 38433dd..4248459 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -9,21 +9,34 @@
 import "dart:io";
 import "dart:async";
 
+import "ddbg/lib/commando.dart";
+
+class TargetIsolate {
+  int id;
+  // The location of the last paused event.
+  Map pausedLocation = null;
+
+  TargetIsolate(this.id);
+  bool get isPaused => pausedLocation != null;
+}
+
+Map<int, TargetIsolate> targetIsolates= new Map<int, TargetIsolate>();
 
 Map<int, Completer> outstandingCommands;
 
 Socket vmSock;
 String vmData;
-var stdinSubscription;
+Commando cmdo;
 var vmSubscription;
 int seqNum = 0;
-int isolate_id = -1;
+
+Process targetProcess;
 
 final verbose = false;
 final printMessages = false;
 
-// The location of the last paused event.
-Map pausedLocation = null;
+TargetIsolate currentIsolate;
+TargetIsolate mainIsolate;
 
 
 void printHelp() {
@@ -51,21 +64,29 @@
   tok <lib_id> <script_url> Get line and token table of script in library
   epi <none|all|unhandled>  Set exception pause info
   li List ids of all isolates in the VM
+  sci <id>  Set current target isolate
   i <id> Interrupt execution of given isolate id
   h   Print help
 """);
 }
 
 
+String formatLocation(Map location) {
+  if (location == null) return "";
+  var fileName = location["url"].split("/").last;
+  return "file: $fileName lib: ${location['libraryId']} token: ${location['tokenOffset']}";
+}
+
+
 void quitShell() {
   vmSubscription.cancel();
   vmSock.close();
-  stdinSubscription.cancel();
+  cmdo.done();
 }
 
 
 Future sendCmd(Map<String, dynamic> cmd) {
-  var completer = new Completer();
+  var completer = new Completer.sync();
   int id = cmd["id"];
   outstandingCommands[id] = completer;
   if (verbose) {
@@ -75,6 +96,34 @@
   return completer.future;
 }
 
+
+bool checkCurrentIsolate() {
+  if (currentIsolate != null) {
+    return true;
+  }
+  print("Need valid current isolate");
+  return false;
+}
+
+
+bool checkPaused() {
+  if (!checkCurrentIsolate()) return false;
+  if (currentIsolate.isPaused) return true;
+  print("Current isolate must be paused");
+  return false;
+}
+
+typedef void HandlerType(Map response);
+
+HandlerType showPromptAfter(void handler(Map response)) {
+  // Hide the command prompt immediately.
+  return (response) {
+    handler(response);
+    cmdo.show();
+  };
+}
+
+
 void processCommand(String cmdLine) {
   
   void huh() {
@@ -82,32 +131,37 @@
   }
 
   seqNum++;
+  cmdLine = cmdLine.trim();
   var args = cmdLine.split(' ');
   if (args.length == 0) {
     return;
   }
   var command = args[0];
-  var simple_commands =
+  var resume_commands =
       { 'r':'resume', 's':'stepOver', 'si':'stepInto', 'so':'stepOut'};
-  if (simple_commands[command] != null) {
+  if (resume_commands[command] != null) {
+    if (!checkPaused()) return;
     var cmd = { "id": seqNum,
-                "command": simple_commands[command],
-                "params": { "isolateId" : isolate_id } };
-    sendCmd(cmd).then((result) => handleGenericResponse(result));
+                "command": resume_commands[command],
+                "params": { "isolateId" : currentIsolate.id } };
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleResumedResponse));
   } else if (command == "bt") {
     var cmd = { "id": seqNum,
                 "command": "getStackTrace",
-                "params": { "isolateId" : isolate_id } };
-    sendCmd(cmd).then((result) => handleStackTraceResponse(result));
+                "params": { "isolateId" : currentIsolate.id } };
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleStackTraceResponse));
   } else if (command == "ll") {
     var cmd = { "id": seqNum,
                 "command": "getLibraries",
-                "params": { "isolateId" : isolate_id } };
-    sendCmd(cmd).then((result) => handleGetLibraryResponse(result));
+                "params": { "isolateId" : currentIsolate.id } };
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetLibraryResponse));
   } else if (command == "sbp" && args.length >= 2) {
     var url, line;
-    if (args.length == 2 && pausedLocation != null) {
-      url = pausedLocation["url"];
+    if (args.length == 2 && currentIsolate.pausedLocation != null) {
+      url = currentIsolate.pausedLocation["url"];
       assert(url != null);
       line = int.parse(args[1]);
     } else {
@@ -116,22 +170,25 @@
     }
     var cmd = { "id": seqNum,
                 "command": "setBreakpoint",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "url": url,
                             "line": line }};
-    sendCmd(cmd).then((result) => handleSetBpResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleSetBpResponse));
   } else if (command == "rbp" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "removeBreakpoint",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "breakpointId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGenericResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
   } else if (command == "ls" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "getScriptURLs",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "libraryId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGetScriptsResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetScriptsResponse));
   } else if (command == "eval" && args.length > 3) {
     var expr = args.getRange(3, args.length).join(" ");
     var target = args[1];
@@ -147,86 +204,106 @@
     }
     var cmd = { "id": seqNum,
                 "command": "evaluateExpr",
-                "params": { "isolateId": isolate_id,
+                "params": { "isolateId": currentIsolate.id,
                             target: int.parse(args[2]),
                             "expression": expr } };
-    sendCmd(cmd).then((result) => handleEvalResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleEvalResponse));
   } else if (command == "po" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "getObjectProperties",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "objectId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGetObjPropsResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetObjPropsResponse));
   } else if (command == "pl" && args.length >= 3) {
-     var cmd;
-     if (args.length == 3) {
-       cmd = { "id": seqNum,
-               "command": "getListElements",
-               "params": { "isolateId" : isolate_id,
-                           "objectId": int.parse(args[1]),
-                           "index": int.parse(args[2]) } };
+    var cmd;
+    if (args.length == 3) {
+      cmd = { "id": seqNum,
+              "command": "getListElements",
+              "params": { "isolateId" : currentIsolate.id,
+                          "objectId": int.parse(args[1]),
+                          "index": int.parse(args[2]) } };
     } else {
-       cmd = { "id": seqNum,
-               "command": "getListElements",
-               "params": { "isolateId" : isolate_id,
-                           "objectId": int.parse(args[1]),
-                           "index": int.parse(args[2]),
-                           "length": int.parse(args[3]) } };
+      cmd = { "id": seqNum,
+              "command": "getListElements",
+              "params": { "isolateId" : currentIsolate.id,
+                          "objectId": int.parse(args[1]),
+                          "index": int.parse(args[2]),
+                          "length": int.parse(args[3]) } };
     }
-    sendCmd(cmd).then((result) => handleGetListResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetListResponse));
   } else if (command == "pc" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "getClassProperties",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "classId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGetClassPropsResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetClassPropsResponse));
   } else if (command == "plib" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "getLibraryProperties",
-                "params": {"isolateId" : isolate_id,
+                "params": {"isolateId" : currentIsolate.id,
                            "libraryId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGetLibraryPropsResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetLibraryPropsResponse));
   } else if (command == "slib" && args.length == 3) {
     var cmd = { "id": seqNum,
                 "command": "setLibraryProperties",
-                "params": {"isolateId" : isolate_id,
+                "params": {"isolateId" : currentIsolate.id,
                            "libraryId": int.parse(args[1]),
                            "debuggingEnabled": args[2] } };
-    sendCmd(cmd).then((result) => handleSetLibraryPropsResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleSetLibraryPropsResponse));
   } else if (command == "pg" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "getGlobalVariables",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "libraryId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGetGlobalVarsResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetGlobalVarsResponse));
   } else if (command == "gs" && args.length == 3) {
     var cmd = { "id": seqNum,
                 "command":  "getScriptSource",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "libraryId": int.parse(args[1]),
                             "url": args[2] } };
-    sendCmd(cmd).then((result) => handleGetSourceResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetSourceResponse));
   } else if (command == "tok" && args.length == 3) {
     var cmd = { "id": seqNum,
                 "command":  "getLineNumberTable",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "libraryId": int.parse(args[1]),
                             "url": args[2] } };
-    sendCmd(cmd).then((result) => handleGetLineTableResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetLineTableResponse));
   } else if (command == "epi" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command":  "setPauseOnException",
-                "params": { "isolateId" : isolate_id,
+                "params": { "isolateId" : currentIsolate.id,
                             "exceptions": args[1] } };
-    sendCmd(cmd).then((result) => handleGenericResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
   } else if (command == "li") {
     var cmd = { "id": seqNum, "command": "getIsolateIds" };
-    sendCmd(cmd).then((result) => handleGetIsolatesResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGetIsolatesResponse));
+  } else if (command == "sci" && args.length == 2) {
+    var id = int.parse(args[1]);
+    if (targetIsolates[id] != null) {
+      currentIsolate = targetIsolates[id];
+      print("Setting current target isolate to $id");
+    } else {
+      print("$id is not a valid isolate id");
+    }
   } else if (command == "i" && args.length == 2) {
     var cmd = { "id": seqNum,
                 "command": "interrupt",
                 "params": { "isolateId": int.parse(args[1]) } };
-    sendCmd(cmd).then((result) => handleGenericResponse(result));
+    cmdo.hide();
+    sendCmd(cmd).then(showPromptAfter(handleGenericResponse));
   } else if (command == "q") {
     quitShell();
   } else if (command == "h") {
@@ -249,10 +326,7 @@
   } else if (kind == "object") {
     return "(obj, id $id) $text";
   } else if (kind == "function") {
-    var location = value['location'] != null
-        ? ", file '${value['location']['url']}'"
-          ", token pos ${value['location']['tokenOffset']}"
-        : "";
+    var location = formatLocation(value['location']);
     var name = value['name'];
     var signature = value['signature'];
     return "(closure ${name}${signature} $location)";
@@ -269,7 +343,7 @@
 }
 
 
-handleGetObjPropsResponse(response) {
+handleGetObjPropsResponse(Map response) {
   Map props = response["result"];
   int class_id = props["classId"];
   if (class_id == -1) {
@@ -283,7 +357,7 @@
   }
 }
 
-handleGetListResponse(response) {
+handleGetListResponse(Map response) {
   Map result = response["result"];
   if (result["elements"] != null) {
     // List slice.
@@ -304,7 +378,7 @@
 }
 
 
-handleGetClassPropsResponse(response) {
+handleGetClassPropsResponse(Map response) {
   Map props = response["result"];
   assert(props["name"] != null);
   int libId = props["libraryId"];
@@ -320,7 +394,7 @@
 }
 
 
-handleGetLibraryPropsResponse(response) {
+handleGetLibraryPropsResponse(Map response) {
   Map props = response["result"];
   assert(props["url"] != null);
   print("  library url: ${props["url"]}");
@@ -345,14 +419,14 @@
 }
 
 
-handleSetLibraryPropsResponse(response) {
+handleSetLibraryPropsResponse(Map response) {
   Map props = response["result"];
   assert(props["debuggingEnabled"] != null);
   print("  debugging enabled: ${props["debuggingEnabled"]}");
 }
 
 
-handleGetGlobalVarsResponse(response) {
+handleGetGlobalVarsResponse(Map response) {
   List globals = response["result"]["globals"];
   for (int i = 0; i < globals.length; i++) {
     printNamedObject(globals[i]);
@@ -360,27 +434,42 @@
 }
 
 
-handleGetSourceResponse(response) {
+handleGetSourceResponse(Map response) {
   Map result = response["result"];
   String source = result["text"];
   print("Source text:\n$source\n--------");
 }
 
 
-handleGetLineTableResponse(response) {
+handleGetLineTableResponse(Map response) {
   Map result = response["result"];
   var info = result["lines"];
   print("Line info table:\n$info");
 }
 
 
-handleGetIsolatesResponse(response) {
+void handleGetIsolatesResponse(Map response) {
   Map result = response["result"];
-  print("Isolates: ${result["isolateIds"]}");
+  List ids = result["isolateIds"];
+  assert(ids != null);
+  print("List of isolates:");
+  for (int id in ids) {
+    TargetIsolate isolate = targetIsolates[id];
+    var state = (isolate != null) ? "running" : "<unknown isolate>";
+    if (isolate != null && isolate.isPaused) {
+      var loc = formatLocation(isolate.pausedLocation);
+      state = "paused at $loc";
+    }
+    var marker = " ";
+    if (currentIsolate != null && id == currentIsolate.id) {
+      marker = "*";
+    }
+    print("$marker $id $state");
+  }
 }
 
 
-void handleGetLibraryResponse(response) {
+void handleGetLibraryResponse(Map response) {
   Map result = response["result"];
   List libs = result["libraries"];
   print("Loaded libraries:");
@@ -391,7 +480,7 @@
 }
 
 
-void handleGetScriptsResponse(response) {
+void handleGetScriptsResponse(Map response) {
   Map result = response["result"];
   List urls = result["urls"];
   print("Loaded scripts:");
@@ -401,13 +490,13 @@
 }
 
 
-void handleEvalResponse(response) {
+void handleEvalResponse(Map response) {
   Map result = response["result"];
   print(remoteObject(result));
 }
 
 
-void handleSetBpResponse(response) {
+void handleSetBpResponse(Map response) {
   Map result = response["result"];
   var id = result["breakpointId"];
   assert(id != null);
@@ -415,14 +504,23 @@
 }
 
 
-void handleGenericResponse(response) {
+void handleGenericResponse(Map response) {
   if (response["error"] != null) {
     print("Error: ${response["error"]}");
   }
 }
 
+void handleResumedResponse(Map response) {
+  if (response["error"] != null) {
+    print("Error: ${response["error"]}");
+    return;
+  }
+  assert(currentIsolate != null);
+  currentIsolate.pausedLocation = null;
+}
 
-void handleStackTraceResponse(response) {
+
+void handleStackTraceResponse(Map response) {
   Map result = response["result"];
   List callFrames = result["callFrames"];
   assert(callFrames != null);
@@ -432,10 +530,8 @@
 
 void printStackFrame(frame_num, Map frame) {
   var fname = frame["functionName"];
-  var libId = frame["location"]["libraryId"];
-  var url = frame["location"]["url"];
-  var toff = frame["location"]["tokenOffset"];
-  print("$frame_num  $fname (url: $url token: $toff lib: $libId)");
+  var loc = formatLocation(frame["location"]);
+  print("$frame_num  $fname ($loc)");
   List locals = frame["locals"];
   for (int i = 0; i < locals.length; i++) {
     printNamedObject(locals[i]);
@@ -453,23 +549,65 @@
 void handlePausedEvent(msg) {
   assert(msg["params"] != null);
   var reason = msg["params"]["reason"];
-  isolate_id = msg["params"]["isolateId"];
-  assert(isolate_id != null);
-  pausedLocation = msg["params"]["location"];
-  assert(pausedLocation != null);
+  int isolateId = msg["params"]["isolateId"];
+  assert(isolateId != null);
+  var isolate = targetIsolates[isolateId];
+  assert(isolate != null);
+  assert(!isolate.isPaused);
+  var location = msg["params"]["location"];;
+  assert(location != null);
+  isolate.pausedLocation = location;
   if (reason == "breakpoint") {
-    print("Isolate $isolate_id paused on breakpoint");
-    print("location: $pausedLocation");
+    print("Isolate $isolateId paused on breakpoint");
+    print("location: ${formatLocation(location)}");
   } else if (reason == "interrupted") {
-    print("Isolate $isolate_id paused due to an interrupt");
+    print("Isolate $isolateId paused due to an interrupt");
+    print("location: ${formatLocation(location)}");
   } else {
     assert(reason == "exception");
     var excObj = msg["params"]["exception"];
-    print("Isolate $isolate_id paused on exception");
+    print("Isolate $isolateId paused on exception");
     print(remoteObject(excObj));
   }
 }
 
+void handleIsolateEvent(msg) {
+  Map params = msg["params"];
+  assert(params != null);
+  var isolateId = params["id"];
+  var reason = params["reason"];
+  if (reason == "created") {
+    print("Isolate $isolateId has been created.");
+    assert(targetIsolates[isolateId] == null);
+    targetIsolates[isolateId] = new TargetIsolate(isolateId);
+    if (mainIsolate == null) {
+      mainIsolate = targetIsolates[isolateId];
+      currentIsolate = mainIsolate;
+      print("Current isolate set to ${currentIsolate.id}.");
+    }
+  } else {
+    assert(reason == "shutdown");
+    var isolate = targetIsolates.remove(isolateId);
+    assert(isolate != null);
+    if (isolate == mainIsolate) {
+      mainIsolate = null;
+      print("Main isolate ${isolate.id} has terminated.");
+    } else {
+      print("Isolate ${isolate.id} has terminated.");
+    }
+    if (isolate == currentIsolate) {
+      currentIsolate = mainIsolate;
+      if (currentIsolate == null && !targetIsolates.isEmpty) {
+        currentIsolate = targetIsolates.first;
+      }
+      if (currentIsolate != null) {
+        print("Setting current isolate to ${currentIsolate.id}.");
+      } else {
+        print("All isolates have terminated.");
+      }
+    }
+  }
+}
 
 void processVmMessage(String jsonString) {
   var msg = JSON.decode(jsonString);
@@ -477,33 +615,41 @@
     return;
   }
   var event = msg["event"];
+  if (event == "isolate") {
+    cmdo.hide();
+    handleIsolateEvent(msg);
+    cmdo.show();
+    return;
+  }
   if (event == "paused") {
+    cmdo.hide();
     handlePausedEvent(msg);
+    cmdo.show();
     return;
   }
   if (event == "breakpointResolved") {
     Map params = msg["params"];
     assert(params != null);
-    print("BP ${params["breakpointId"]} resolved and "
-          "set at line ${params["line"]}.");
-    return;
-  }
-  if (event == "isolate") {
-    Map params = msg["params"];
-    assert(params != null);
-    print("Isolate ${params["id"]} has been ${params["reason"]}.");
+    var isolateId = params["isolateId"];
+    var location = formatLocation(params["location"]);
+    cmdo.hide();
+    print("BP ${params["breakpointId"]} resolved in isolate $isolateId"
+          " at $location.");
+    cmdo.show();
     return;
   }
   if (msg["id"] != null) {
     var id = msg["id"];
     if (outstandingCommands.containsKey(id)) {
+      var completer = outstandingCommands.remove(id);
       if (msg["error"] != null) {
         print("VM says: ${msg["error"]}");
+        // TODO(turnidge): Rework how hide/show happens.  For now we
+        // show here explicitly.
+        cmdo.show();
       } else {
-        var completer = outstandingCommands[id];
         completer.complete(msg);
       }
-      outstandingCommands.remove(id);
     }
   }
 }
@@ -608,6 +754,30 @@
   return 0;
 }
 
+List<String> debuggerCommandCompleter(List<String> commandParts) {
+  List<String> completions = new List<String>();
+
+  // TODO(turnidge): Have a global command table and use it to for
+  // help messages, command completion, and command dispatching.  For now
+  // we hardcode the list here.
+  //
+  // TODO(turnidge): Implement completion for arguments as well.
+  List<String> allCommands = ['q', 'bt', 'r', 's', 'so', 'si', 'sbp', 'rbp',
+                              'po', 'eval', 'pl', 'pc', 'll', 'plib', 'slib',
+                              'pg', 'ls', 'gs', 'tok', 'epi', 'li', 'i', 'h'];
+
+  // Completion of first word in the command.
+  if (commandParts.length == 1) {
+    String prefix = commandParts.last;
+    for (String command in allCommands) {
+      if (command.startsWith(prefix)) {
+        completions.add(command);
+      }
+    } 
+  }
+
+  return completions;
+}
 
 void debuggerMain() {
   outstandingCommands = new Map<int, Completer>();
@@ -628,20 +798,46 @@
           // TODO(floitsch): do we want to print the stack trace?
           quitShell();
         });
-    stdinSubscription = stdin.transform(UTF8.decoder)
-                             .transform(new LineSplitter())
-                             .listen((String line) => processCommand(line));
+    cmdo = new Commando(stdin, stdout, processCommand,
+                        completer : debuggerCommandCompleter);
   });
 }
 
-void main(List<String> arguments) {
-  if (arguments.length > 0) {
-    arguments = <String>['--debug', '--verbose_debug']..addAll(arguments);
-    Process.start(Platform.executable, arguments).then((Process process) {
-      process.stdin.close();
-      process.exitCode.then((int exitCode) {
-        print('${arguments.join(" ")} exited with $exitCode');
-      });
+void main(List<String> args) {
+  if (args.length > 0) {
+    if (verbose) {
+      args = <String>['--debug', '--verbose_debug']..addAll(args);
+    } else {
+      args = <String>['--debug']..addAll(args);
+    }
+    Process.start(Platform.executable, args).then((Process process) {
+        targetProcess = process;
+        process.stdin.close();
+
+        // TODO(turnidge): For now we only show full lines of output
+        // from the debugged process.  Should show each character.
+        process.stdout
+            .transform(UTF8.decoder)
+            .transform(new LineSplitter())
+            .listen((String line) {
+                // Hide/show command prompt across asynchronous output.
+                if (cmdo != null) {
+                  cmdo.hide();
+                }
+                print("$line");
+                if (cmdo != null) {
+                  cmdo.show();
+                }
+              });
+
+        process.exitCode.then((int exitCode) {
+            if (exitCode == 0) {
+              print('Program exited normally.');
+            } else {
+              print('Program exited with code $exitCode.');
+            }
+          });
+
       debuggerMain();
     });
   } else {
diff --git a/tools/ddbg/lib/commando.dart b/tools/ddbg/lib/commando.dart
new file mode 100644
index 0000000..cb1fef2
--- /dev/null
+++ b/tools/ddbg/lib/commando.dart
@@ -0,0 +1,712 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import 'terminfo.dart';
+
+typedef List<String> CommandCompleter(List<String> commandParts);
+
+class Commando {
+  // Ctrl keys
+  static const runeCtrlA   = 0x01;
+  static const runeCtrlB   = 0x02;
+  static const runeCtrlD   = 0x04;
+  static const runeCtrlE   = 0x05;
+  static const runeCtrlF   = 0x06;
+  static const runeTAB     = 0x09;
+  static const runeNewline = 0x0a;
+  static const runeCtrlK   = 0x0b;
+  static const runeCtrlL   = 0x0c;
+  static const runeCtrlN   = 0x0e;
+  static const runeCtrlP   = 0x10;
+  static const runeCtrlU   = 0x15;
+  static const runeCtrlY   = 0x19;
+  static const runeESC     = 0x1b;
+  static const runeSpace   = 0x20;
+  static const runeDEL     = 0x7F;
+
+  Commando(this._stdin,
+           this._stdout,
+           this._handleCommand,
+           {this.prompt : '> ', this.completer : null}) {
+    _stdin.echoMode = false;
+    _stdin.lineMode = false;
+    _screenWidth = _term.cols - 1;
+    _writePrompt();
+    _stdinSubscription =
+        _stdin.transform(UTF8.decoder).listen(_handleText, onDone:done);
+  }
+
+  void _handleText(String text) {
+    try {
+      if (!_promptShown) {
+        _bufferedInput.write(text);
+        return;
+      }
+
+      var runes = text.runes.toList();
+      var pos = 0;
+      while (pos < runes.length) {
+        if (!_promptShown) {
+          // A command was processed which hid the prompt.  Buffer
+          // the rest of the input.
+          //
+          // TODO(turnidge): Here and elsewhere in the file I pass
+          // runes to String.fromCharCodes.  Does this work?
+          _bufferedInput.write(
+              new String.fromCharCodes(runes.skip(pos)));
+          return;
+        }
+
+        var rune = runes[pos];
+
+        // Count consecutive tabs because double-tab is meaningful.
+        if (rune == runeTAB) {
+          _tabCount++;
+        } else {
+          _tabCount = 0;
+        }
+
+        if (_isControlRune(rune)) {
+          pos += _handleControlSequence(runes, pos);
+        } else {
+          pos += _handleRegularSequence(runes, pos);
+        }
+      }
+    } catch(e, trace) {
+      stderr.writeln('\nUnexpected exception: $e');
+      stderr.writeln(trace);
+      stderr.close().then((_) {
+          done();
+        });
+    }
+  }
+
+  int _handleControlSequence(List<int> runes, int pos) {
+    var runesConsumed = 1;  // Most common result.
+    var char = runes[pos];
+    switch (char) {
+      case runeCtrlA:
+        _home();
+        break;
+           
+      case runeCtrlB:
+        _leftArrow();
+        break;
+
+      case runeCtrlD:
+        if (_currentLine.length == 0) {
+          // ^D on an empty line means quit.
+          _stdout.writeln();
+          done();
+        } else {
+          _delete();
+        }
+        break;
+           
+      case runeCtrlE:
+        _end();
+        break;
+           
+      case runeCtrlF:
+        _rightArrow();
+        break;
+
+      case runeTAB:
+        if (_complete(_tabCount > 1)) {
+          _tabCount = 0;
+        }
+        break;
+      
+      case runeNewline:
+        _newline();
+        break;
+      
+      case runeCtrlK:
+        _kill();
+        break;
+           
+      case runeCtrlL:
+        _clearScreen();
+        break;
+           
+      case runeCtrlN:
+        _historyNext();
+        break;
+
+      case runeCtrlP:
+        _historyPrevious();
+        break;
+
+      case runeCtrlU:
+        _clearLine();
+        break;
+           
+      case runeCtrlY:
+        _yank();
+        break;
+           
+      case runeESC:
+        // Check to see if this is an arrow key.
+        if (pos + 2 < runes.length &&  // must be a 3 char sequence.
+            runes[pos + 1] == 0x5b) {  // second char must be '['.
+          switch (runes[pos + 2]) {
+            case 0x41:  // ^[[A = up arrow
+              _historyPrevious();
+              runesConsumed = 3;
+              break;
+
+            case 0x42:  // ^[[B = down arrow
+              _historyNext();
+              runesConsumed = 3;
+              break;
+
+            case 0x43:  // ^[[C = right arrow
+              _rightArrow();
+              runesConsumed = 3;
+              break;
+        
+            case 0x44:  // ^[[D = left arrow
+              _leftArrow();
+              runesConsumed = 3;
+              break;
+
+            default:
+              // Ignore the escape character.
+              break;
+          }
+        }
+        break;
+
+      case runeDEL:
+        _backspace();
+        break;
+
+      default:
+        // Ignore the escape character.
+        break;
+    }
+    return runesConsumed;
+  }
+
+  int _handleRegularSequence(List<int> runes, int pos) {
+    var len = pos + 1;
+    while (len < runes.length && !_isControlRune(runes[len])) {
+      len++;
+    }
+    _addChars(runes.getRange(pos, len));
+    return len;
+  }
+
+  bool _isControlRune(int char) {
+    return (char >= 0x00 && char < 0x20) || (char == 0x7f);
+  }
+
+  void done() {
+    _stdin.echoMode = true;
+    _stdin.lineMode = true;
+    _stdinSubscription.cancel();
+  }
+
+  void _writePromptAndLine() {
+    _writePrompt();
+    var pos = _writeRange(_currentLine, 0, _currentLine.length);
+    _cursorPos = _move(pos, _cursorPos);
+  }
+
+  void _writePrompt() {
+    _stdout.write(prompt);
+  }
+
+  void _addChars(Iterable<int> chars) {
+    var newLine = [];
+    newLine..addAll(_currentLine.take(_cursorPos))
+           ..addAll(chars)
+           ..addAll(_currentLine.skip(_cursorPos));
+    _update(newLine, (_cursorPos + chars.length));
+  }
+
+  void _backspace() {
+    if (_cursorPos == 0) {
+      return;
+    }
+
+    var newLine = [];
+    newLine..addAll(_currentLine.take(_cursorPos - 1))
+           ..addAll(_currentLine.skip(_cursorPos));
+    _update(newLine, (_cursorPos - 1));
+  }
+
+  void _delete() {
+    if (_cursorPos == _currentLine.length) {
+      return;
+    }
+
+    var newLine = [];
+    newLine..addAll(_currentLine.take(_cursorPos))
+           ..addAll(_currentLine.skip(_cursorPos + 1));
+    _update(newLine, _cursorPos);
+  }
+
+  void _home() {
+    _updatePos(0);
+  }
+
+  void _end() {
+    _updatePos(_currentLine.length);
+  }
+
+  void _clearScreen() {
+    _stdout.write(_term.clear);
+    _writePromptAndLine();
+  }
+
+  void _kill() {
+    var newLine = [];
+    newLine.addAll(_currentLine.take(_cursorPos));
+    _killBuffer = _currentLine.skip(_cursorPos).toList();
+    _update(newLine, _cursorPos);
+  }
+
+  void _clearLine() {
+    _update([], 0);
+  }
+
+  void _yank() {
+    var newLine = [];
+    newLine..addAll(_currentLine.take(_cursorPos))
+           ..addAll(_killBuffer)
+           ..addAll(_currentLine.skip(_cursorPos));
+    _update(newLine, (_cursorPos + _killBuffer.length));
+  }
+
+  static String _trimLeadingSpaces(String line) {
+    bool _isSpace(int rune) {
+      return rune == runeSpace;
+    }
+    return new String.fromCharCodes(line.runes.skipWhile(_isSpace));
+  }
+
+  static String _sharedPrefix(String one, String two) {
+    var len = min(one.length, two.length);
+    var runesOne = one.runes.toList();
+    var runesTwo = two.runes.toList();
+    var pos;
+    for (pos = 0; pos < len; pos++) {
+      if (runesOne[pos] != runesTwo[pos]) {
+        break;
+      }
+    }
+    var shared =  new String.fromCharCodes(runesOne.take(pos));
+    return shared;
+  }
+
+  bool _complete(bool showCompletions) {
+    if (completer == null) {
+      return false;
+    }
+
+    var linePrefix = _currentLine.take(_cursorPos).toList();
+    List<String> commandParts =
+        _trimLeadingSpaces(new String.fromCharCodes(linePrefix)).split(' ');
+    List<String> completionList = completer(commandParts);
+    var completion = '';
+
+    if (completionList.length == 0) {
+      // The current line admits no possible completion.
+      return false;
+
+    } else if (completionList.length == 1) {
+      // There is a single, non-ambiguous completion for the current line.
+      completion = completionList[0];
+
+      // If we are at the end of the line, add a space to signal that
+      // the completion is unambiguous.
+      if (_currentLine.length == _cursorPos) {
+        completion = completion + ' ';
+      }
+    } else {
+      // There are ambiguous completions. Find the longest common
+      // shared prefix of all of the completions.
+      completion = completionList.fold(completionList[0], _sharedPrefix);
+    }
+
+    var lastWord = commandParts.last;
+    if (completion == lastWord) {
+      // The completion does not add anything.
+      if (showCompletions) {
+        // User hit double-TAB.  Show them all possible completions.
+        _move(_cursorPos, _currentLine.length);
+        _stdout.writeln();
+        _stdout.writeln(completionList);
+        _writePromptAndLine();
+      }
+      return false;
+    } else {
+      // Apply the current completion.
+      var completionRunes = completion.runes.toList();
+
+      var newLine = [];
+      newLine..addAll(linePrefix)
+             ..addAll(completionRunes.skip(lastWord.length))
+             ..addAll(_currentLine.skip(_cursorPos));
+      _update(newLine, _cursorPos + completionRunes.length - lastWord.length);
+      return true;
+    }
+  }
+
+  void _newline() {
+    _addLineToHistory(_currentLine);
+    _linePos = _lines.length;
+
+    _end();
+    _stdout.writeln();
+
+    // Call the user's command handler.
+    _handleCommand(new String.fromCharCodes(_currentLine));
+    
+    _currentLine = [];
+    _cursorPos = 0;
+    _linePos = _lines.length;
+    if (_promptShown) {
+      _writePrompt();
+    }
+  }
+
+  void _leftArrow() {
+    _updatePos(_cursorPos - 1);
+  }
+
+  void _rightArrow() {
+    _updatePos(_cursorPos + 1);
+  }
+
+  void _addLineToHistory(List<int> line) {
+    if (_tempLineAdded) {
+      _lines.removeLast();
+      _tempLineAdded = false;
+    }
+    if (line.length > 0) {
+      _lines.add(line);
+    }
+  }
+
+  void _addTempLineToHistory(List<int> line) {
+    _lines.add(line);
+    _tempLineAdded = true;
+  }
+
+  void _replaceHistory(List<int> line, int linePos) {
+    _lines[linePos] = line;
+  }
+
+  void _historyPrevious() {
+    if (_linePos == 0) {
+      return;
+    }
+
+    if (_linePos == _lines.length) {
+      // The current in-progress line gets temporarily stored in history.
+      _addTempLineToHistory(_currentLine);
+    } else {
+      // Any edits get committed to history.
+      _replaceHistory(_currentLine, _linePos);
+    }
+
+    _linePos -= 1;
+    var line = _lines[_linePos];
+    _update(line, line.length);
+  }
+
+  void _historyNext() {
+    // For the very first command, _linePos (0) will exceed
+    // (_lines.length - 1) (-1) so we use a ">=" here instead of an "==".
+    if (_linePos >= (_lines.length - 1)) {
+      return;
+    }
+
+    // Any edits get committed to history.
+    _replaceHistory(_currentLine, _linePos);
+
+    _linePos += 1;
+    var line = _lines[_linePos];
+    _update(line, line.length);
+  }
+
+  void _updatePos(int newCursorPos) {
+    if (newCursorPos < 0) {
+      return;
+    }
+    if (newCursorPos > _currentLine.length) {
+      return;
+    }
+
+    _cursorPos = _move(_cursorPos, newCursorPos);
+  }
+
+  void _update(List<int> newLine, int newCursorPos) {
+    var pos = _cursorPos;
+    var diffPos;
+    var sharedLen = min(_currentLine.length, newLine.length);
+
+    // Find first difference.
+    for (diffPos = 0; diffPos < sharedLen; diffPos++) {
+      if (_currentLine[diffPos] != newLine[diffPos]) {
+        break;
+      }
+    }
+
+    // Move the cursor to where the difference begins.
+    pos = _move(pos, diffPos);
+
+    // Write the new text.
+    pos = _writeRange(newLine, pos, newLine.length);
+
+    // Clear any extra characters at the end.
+    pos = _clearRange(pos, _currentLine.length);
+
+    // Move the cursor back to the input point.
+    _cursorPos = _move(pos, newCursorPos);
+    _currentLine = newLine;    
+  }
+  
+  void hide() {
+    if (!_promptShown) {
+      return;
+    }
+    _promptShown = false;
+    // We need to erase everything, including the prompt.
+    var curLine = _getLine(_cursorPos);
+    var lastLine = _getLine(_currentLine.length);
+
+    // Go to last line.
+    if (curLine < lastLine) {
+      for (var i = 0; i < (lastLine - curLine); i++) {
+        // This moves us to column 0.
+        _stdout.write(_term.cursorDown);
+      }
+      curLine = lastLine;
+    } else {
+      // Move to column 0.
+      _stdout.write('\r');
+    }
+
+    // Work our way up, clearing lines.
+    while (true) {
+      _stdout.write(_term.clrEOL);
+      if (curLine > 0) {
+        _stdout.write(_term.cursorUp);
+      } else {
+        break;
+      }
+    }
+  }
+
+  void show() {
+    if (_promptShown) {
+      return;
+    }
+    _promptShown = true;
+    _writePromptAndLine();
+
+    // If input was buffered while the prompt was hidden, process it
+    // now.
+    if (!_bufferedInput.isEmpty) {
+      var input = _bufferedInput.toString();
+      _bufferedInput.clear();
+      _handleText(input);
+    }
+  }
+
+  int _writeRange(List<int> text, int pos, int writeToPos) {
+    if (pos >= writeToPos) {
+      return pos;
+    }
+    while (pos < writeToPos) {
+      var margin = _nextMargin(pos);
+      var limit = min(writeToPos, margin);
+      _stdout.write(new String.fromCharCodes(text.getRange(pos, limit)));
+      pos = limit;
+      if (pos == margin) {
+        _stdout.write('\n');
+      }
+    }
+    return pos;
+  }
+
+  int _clearRange(int pos, int clearToPos) {
+    if (pos >= clearToPos) {
+      return pos;
+    }
+    while (true) {
+      var limit = _nextMargin(pos);
+      _stdout.write(_term.clrEOL);
+      if (limit >= clearToPos) {
+        return pos;
+      }
+      _stdout.write('\n');
+      pos = limit;
+    }
+  }
+
+  int _move(int pos, int newPos) {
+    if (pos == newPos) {
+      return pos;
+    }
+
+    var curCol = _getCol(pos);
+    var curLine = _getLine(pos);
+    var newCol = _getCol(newPos);
+    var newLine = _getLine(newPos);
+
+    if (curLine > newLine) {
+      for (var i = 0; i < (curLine - newLine); i++) {
+        _stdout.write(_term.cursorUp);
+      }
+    }
+    if (curLine < newLine) {
+      for (var i = 0; i < (newLine - curLine); i++) {
+        _stdout.write(_term.cursorDown);
+      }
+
+      // Moving down resets column to zero, oddly.
+      curCol = 0;
+    }
+    if (curCol > newCol) {
+      for (var i = 0; i < (curCol - newCol); i++) {
+        _stdout.write(_term.cursorBack);
+      }
+    }
+    if (curCol < newCol) {
+      for (var i = 0; i < (newCol - curCol); i++) {
+        _stdout.write(_term.cursorForward);
+      }
+    }
+
+    return newPos;
+  }
+        
+  int _nextMargin(int pos) {
+    var truePos = pos + prompt.length;
+    var curLine = _getLine(pos);
+    return ((truePos ~/ _screenWidth) + 1) * _screenWidth - prompt.length;
+  }
+
+  int _getLine(int pos) {
+    var truePos = pos + prompt.length;
+    return truePos ~/ _screenWidth;
+  }
+
+  int _getCol(int pos) {
+    var truePos = pos + prompt.length;
+    return truePos % _screenWidth;
+  }
+
+  Stdin _stdin;
+  StreamSubscription _stdinSubscription;
+  IOSink _stdout;
+  final _handleCommand;
+  final String prompt;
+  bool _promptShown = true;
+  final CommandCompleter completer;
+  TermInfo _term = new TermInfo();
+
+  // TODO(turnidge): Update screenwidth when we clear the screen.  See
+  // if we can get screen resize events too.
+  int _screenWidth;
+  List<int> _currentLine = [];  // A list of runes.
+  StringBuffer _bufferedInput = new StringBuffer();
+  List<List<int>> _lines = [];
+
+  // When using the command history, the current line is temporarily
+  // added to the history to allow the user to return to it.  This
+  // values tracks whether the history has a temporary line at the end.
+  bool _tempLineAdded = false;
+  int _linePos = 0;
+  int _cursorPos = 0;
+  int _tabCount = 0;
+  List<int> _killBuffer = [];
+}
+
+
+// Demo code.
+
+
+List<String> _myCompleter(List<String> commandTokens) {
+  List<String> completions = new List<String>();
+
+  // First word completions.
+  if (commandTokens.length <= 1) {
+    String prefix = '';
+    if (commandTokens.length == 1) {
+      prefix = commandTokens.first;
+    }
+    if ('quit'.startsWith(prefix)) {
+      completions.add('quit');
+    }
+    if ('help'.startsWith(prefix)) {
+      completions.add('help');
+    }
+    if ('happyface'.startsWith(prefix)) {
+      completions.add('happyface');
+    }
+  }
+
+  // Complete 'foobar' or 'gondola' anywhere in string.
+  String lastWord = commandTokens.last;
+  if ('foobar'.startsWith(lastWord)) {
+    completions.add('foobar');
+  }
+  if ('gondola'.startsWith(lastWord)) {
+    completions.add('gondola');
+  }
+
+  return completions;
+}
+
+
+int _helpCount = 0;
+Commando cmdo;
+
+
+void _handleCommand(String rawCommand) {
+  String command = rawCommand.trim();
+  if (command == 'quit') {
+    cmdo.done();
+  } else if (command == 'help') {
+    switch (_helpCount) {
+      case 0:
+        print('I will not help you.');
+        break;
+      case 1:
+        print('I mean it.');
+        break;
+      case 2:
+        print('Seriously.');
+        break;
+      case 100:
+        print('Well now.');
+        break;
+      default:
+        print("Okay.  Type 'quit' to quit");
+        break;
+    }
+    _helpCount++;
+  } else if (command == 'happyface') {
+    print(':-)');
+  } else {
+    print('Received command($command)');
+  }
+}
+
+
+void main() {
+  stdout.writeln('[Commando demo]');
+  cmd = new Commando(stdin, stdout, _handleCommand,
+                     completer:_myCompleter);
+}
diff --git a/tools/ddbg/lib/terminfo.dart b/tools/ddbg/lib/terminfo.dart
new file mode 100644
index 0000000..4521031
--- /dev/null
+++ b/tools/ddbg/lib/terminfo.dart
@@ -0,0 +1,57 @@
+// 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:convert';
+import 'dart:io';
+
+int _tputGetInteger(String capName) {
+  var result = Process.runSync('tput',  ['$capName'], stdoutEncoding:UTF8);
+  if (result.exitCode != 0) {
+    return 0;
+  }
+  return int.parse(result.stdout);
+}
+
+String _tputGetSequence(String capName) {
+  var result = Process.runSync('tput',  ['$capName'], stdoutEncoding:UTF8);
+  if (result.exitCode != 0) {
+    return '';
+  }
+  return result.stdout;
+}
+
+class TermInfo {
+  TermInfo() {
+    resize();
+  }
+
+  int get lines => _lines;
+  int get cols => _cols;
+
+  int _lines;
+  int _cols;
+
+  void resize() {
+    _lines = _tputGetInteger('lines');
+    _cols = _tputGetInteger('cols');
+  }
+
+  // Back one character.
+  final String cursorBack = _tputGetSequence('cub1');
+
+  // Forward one character.
+  final String cursorForward = _tputGetSequence('cuf1');
+
+  // Up one character.
+  final String cursorUp = _tputGetSequence('cuu1');
+
+  // Down one character.
+  final String cursorDown = _tputGetSequence('cud1');
+
+  // Clear to end of line.
+  final String clrEOL = _tputGetSequence('el');
+
+  // Clear screen and home cursor.
+  final String clear = _tputGetSequence('clear');
+}
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index 5cf230b..75c699c 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -387,6 +387,11 @@
 
   static String addTrailingDot(String str) => '${str}.';
 
+  static String demangle(String str) {
+    var atPos = str.indexOf('@');
+    return atPos == -1 ? str : str.substring(0, atPos);
+  }
+
   static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;
 
   static bool _isBuiltinType(ClassMirror cls) {
diff --git a/tools/publish_barback.py b/tools/publish_barback.py
index a4b9c3d..87752b0 100755
--- a/tools/publish_barback.py
+++ b/tools/publish_barback.py
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# 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.
 #
@@ -31,24 +31,21 @@
   HOME = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
   BARBACK = os.path.join(HOME, 'pkg', 'barback')
 
-  (channel, major, minor, build, patch) = utils.ReadVersionFile()
+  (channel, major, minor, service, qualifier) = utils.ReadVersionFile()
+  major = int(major)
+  minor = int(minor)
+  service = int(service)
 
   # The bleeding_edge branch has a fixed version number of 0.1.x.y. Don't allow
   # users to publish packages from there.
   if (major == 0 and minor <= 1) or channel == 'be':
     print 'Error: Do not run this script from a bleeding_edge checkout.'
-    return -1
+    #return -1
 
   # Convert the version to semver syntax.
-  # TODO(rnystrom): Change this when the SDK's version numbering scheme is
-  # decided.
-  if patch != 0:
-    version = '%d.%d.%d+%d' % (major, minor, build, patch)
-  else:
-    version = '%d.%d.%d' % (major, minor, build)
+  version = '%d.%d.%d+%s' % (major, minor, service, qualifier)
 
-  # Copy the package to a temp directory so we can fill in the versions in its
-  # pubspec.
+  # Copy the package to a temp directory so we can fill in its pubspec.
   tmpDir = tempfile.mkdtemp()
   shutil.copytree(os.path.join(HOME, BARBACK), os.path.join(tmpDir, 'barback'))
 
@@ -58,16 +55,21 @@
 
   # Fill in the SDK version constraint. It pins barback to the current version
   # of the SDK with a small amount of wiggle room for hotfixes.
-  if major < 1:
-    # No breaking changes until after 1.0.
-    # TODO(rnystrom): Remove this once 1.0 has shipped.
-    constraint = '>=%d.%d.%d <1.1.0' % (major, minor, build)
-  else:
-    constraint = '>=%d.%d.%d <%d.%d.0' % (major, minor, build, major, minor + 1)
+  constraint = '>=%d.%d.%d <%d.%d.0' % (major, minor, service, major, minor + 1)
 
   # Fill in the SDK version constraint.
   pubspec = pubspec.replace('$SDK_CONSTRAINT$', constraint)
 
+  # Give barback a new version that roughly mirrors the SDK, like so:
+  # SDK 1.2.3+4 --> barback 0.12.3+4.
+  barback_version = 'version: 0.%d.%d+%s # Set by publish_barback.py.' % (
+      10 + minor, service, qualifier)
+  pubspec = pubspec.replace(
+      'version: 0.9.0 # Replaced by publish_barback.py. Do not edit.',
+      barback_version)
+
+  return
+
   with open(pubspecPath, 'w') as pubspecFile:
     pubspecFile.write(pubspec)
 
diff --git a/tools/test.dart b/tools/test.dart
index 4d71459..c96084d 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -178,7 +178,9 @@
     for (String key in selectors.keys) {
       if (key == 'co19') {
         testSuites.add(new Co19TestSuite(conf));
-      } else if (conf['runtime'] == 'vm' && key == 'vm') {
+      } else if (conf['compiler'] == 'none' &&
+                 conf['runtime'] == 'vm' &&
+                 key == 'vm') {
         // vm tests contain both cc tests (added here) and dart tests (added
         // in [TEST_SUITE_DIRECTORIES]).
         testSuites.add(new VMTestSuite(conf));
@@ -282,10 +284,10 @@
   return completer.future;
 }
 
-void main() {
+void main(List<String> arguments) {
   deleteTemporaryDartDirectories().then((_) {
     var optionsParser = new TestOptionsParser();
-    var configurations = optionsParser.parse(new Options().arguments);
+    var configurations = optionsParser.parse(arguments);
     if (configurations != null && configurations.length > 0) {
       testConfigurations(configurations);
     }
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index 940d47c..6a2fc4a 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -205,7 +205,7 @@
    */
   Future adbRoot() {
     var adbRootCompleter = new Completer();
-    return _adbCommand(['root']).then((_) {
+    _adbCommand(['root']).then((_) {
       // TODO: Figure out a way to wait until the adb daemon was restarted in
       // 'root mode' on the device.
       new Timer(_adbServerStartupTime, () => adbRootCompleter.complete(true));
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index 8cdc3cd..501f765 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -315,7 +315,7 @@
         // Get the version and log that.
         return getVersion().then((version) {
           _logEvent("Got version: $version");
-          return new Directory('').createTemp().then((userDir) {
+          return Directory.systemTemp.createTemp().then((userDir) {
             _cleanup = () { userDir.deleteSync(recursive: true); };
             _createLaunchHTML(userDir.path, url);
             var args = ["${userDir.path}/launch.html"];
@@ -379,7 +379,7 @@
       if (!success) return false;
       _logEvent("Got version: $_version");
 
-      return new Directory('').createTemp().then((userDir) {
+      return Directory.systemTemp.createTemp().then((userDir) {
         _cleanup = () { userDir.deleteSync(recursive: true); };
         var args = ["--user-data-dir=${userDir.path}", url,
                     "--disable-extensions", "--disable-popup-blocking",
@@ -608,7 +608,7 @@
       version = versionResult.stdout;
       _logEvent("Got version: $version");
 
-      return new Directory('').createTemp().then((userDir) {
+      return Directory.systemTemp.createTemp().then((userDir) {
         _createPreferenceFile(userDir.path);
         _cleanup = () { userDir.deleteSync(recursive: true); };
         var args = ["-profile", "${userDir.path}",
@@ -854,7 +854,7 @@
       // We don't do anything, this browser is currently being killed and
       // replaced. The browser here can be null if we decided to kill the
       // browser.
-    } else if (status.currentTest != null && status.currentTest.id != testId) {
+    } else if (status.currentTest != null && status.currentTest.id == testId) {
       status.currentTest.lastKnownMessage = output;
     }
   }
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 9348763..5a55119 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -6,7 +6,6 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:isolate';
 import 'test_suite.dart';  // For TestUtils.
 // TODO(efortuna): Rewrite to not use the args library and simply take an
 // expected number of arguments, so test.dart doesn't rely on the args library?
@@ -38,7 +37,7 @@
 // http://host:port/root_packages/X -> $BuildDir/packages/X
 // Issue: 8368
 
-main() {
+main(List<String> arguments) {
   /** Convenience method for local testing. */
   var parser = new ArgParser();
   parser.addOption('port', abbr: 'p',
@@ -57,14 +56,14 @@
   parser.addOption('runtime', help: 'The runtime we are using (for csp flags).',
       defaultsTo: 'none');
 
-  var args = parser.parse(new Options().arguments);
+  var args = parser.parse(arguments);
   if (args['help']) {
     print(parser.getUsage());
   } else {
     // Pretend we're running test.dart so that TestUtils doesn't get confused
     // about the "current directory." This is only used if we're trying to run
     // this file independently for local testing.
-    TestUtils.testScriptPath = new Path(new Options().script)
+    TestUtils.testScriptPath = new Path(Platform.script.path)
         .directoryPath
         .join(new Path('../../test.dart'))
         .canonicalize()
diff --git a/tools/testing/dart/launch_browser.dart b/tools/testing/dart/launch_browser.dart
index 0b752d3..269d151 100644
--- a/tools/testing/dart/launch_browser.dart
+++ b/tools/testing/dart/launch_browser.dart
@@ -20,14 +20,13 @@
   print("Supported browsers: ${Browser.SUPPORTED_BROWSERS}");
 }
 
-void main() {
-  var args = new Options().arguments;
-  if (args.length != 2) {
+void main(List<String> arguments) {
+  if (arguments.length != 2) {
     print("Wrong number of arguments, please pass in exactly two arguments");
     printHelp();
     return;
   }
-  var name = args[0];
+  var name = arguments[0];
 
   if (!Browser.supportedBrowser(name)) {
     print("Specified browser not supported");
@@ -37,5 +36,5 @@
 
   var executable = Locations.getBrowserLocation(name, {});
   var browser = new Browser.byName(name, executable);
-  browser.start(args[1]);
+  browser.start(arguments[1]);
 }
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index e61f21b..5541564 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -276,5 +276,5 @@
   if (!dir.existsSync()) {
     dir.createSync();
   }
-  return new Path(new File(path).fullPathSync());
+  return new Path(new File(path).absolute.path);
 }
diff --git a/tools/testing/dart/record_and_replay.dart b/tools/testing/dart/record_and_replay.dart
index 90af781..f60be45 100644
--- a/tools/testing/dart/record_and_replay.dart
+++ b/tools/testing/dart/record_and_replay.dart
@@ -6,7 +6,6 @@
 
 import 'dart:io';
 import 'dart:convert';
-import 'dart:convert';
 
 import 'test_runner.dart';
 import 'utils.dart' show Path;
diff --git a/tools/testing/dart/test_controller.js b/tools/testing/dart/test_controller.js
index 1b03546..806a7f9 100644
--- a/tools/testing/dart/test_controller.js
+++ b/tools/testing/dart/test_controller.js
@@ -34,7 +34,7 @@
 var recordedEventList = [];
 var timestampOfFirstEvent = null;
 
-var STATUS_UPDATE_INTERVALL = 5000; // Every 10 seconds.
+var STATUS_UPDATE_INTERVALL = 10000;
 
 function getCurrentTimestamp() {
   if (timestampOfFirstEvent == null) {
@@ -74,9 +74,7 @@
 function printToConsole(message) {
   var consoleAvailable = typeof console === 'object';
 
-  if (!consoleAvailable) {
-    printToDOM(message);
-  } else {
+  if (consoleAvailable) {
     console.log(message);
   }
 }
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index feda5b9..48f1310 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -5,7 +5,6 @@
 library test_options_parser;
 
 import "dart:io";
-import "dart:math";
 import "drt_updater.dart";
 import "test_suite.dart";
 
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 80b00a0..ea31bfc 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -7,7 +7,6 @@
 import "dart:async";
 import "dart:io";
 import "dart:io" as io;
-import "http_server.dart" as http_server;
 import "status_file_parser.dart";
 import "test_runner.dart";
 import "test_suite.dart";
@@ -323,17 +322,9 @@
 class LeftOverTempDirPrinter extends EventListener {
   final MIN_NUMBER_OF_TEMP_DIRS = 50;
 
-  static Directory _getTemporaryDirectory() {
-    // Dir will be located in the system temporary directory.
-    var dir = new Directory('').createTempSync();
-    var path = new Path(dir.path).directoryPath;
-    dir.deleteSync();
-    return new Directory(path.toNativePath());
-  }
-
   static RegExp _getTemporaryDirectoryRegexp() {
     // These are the patterns of temporary directory names created by
-    // 'Directory.createTempSync()' on linux/macos and windows.
+    // 'Directory.systemTemp.createTemp()' on linux/macos and windows.
     if (['macos', 'linux'].contains(Platform.operatingSystem)) {
       return new RegExp(r'^temp_dir1_......$');
     } else {
@@ -343,7 +334,7 @@
 
   static Stream<Directory> getLeftOverTemporaryDirectories() {
     var regExp = _getTemporaryDirectoryRegexp();
-    return _getTemporaryDirectory().list().where(
+    return Directory.systemTemp.list().where(
         (FileSystemEntity fse) {
           if (fse is Directory) {
             if (regExp.hasMatch(new Path(fse.path).filename)) {
@@ -359,7 +350,7 @@
       if (count > MIN_NUMBER_OF_TEMP_DIRS) {
         DebugLogger.warning("There are ${count} directories "
                             "in the system tempdir "
-                            "('${_getTemporaryDirectory().path}')! "
+                            "('${Directory.systemTemp.path}')! "
                             "Maybe left over directories?\n");
       }
     }).catchError((error) {
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index e5205b1..38f500b 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -700,6 +700,12 @@
 }
 
 class BrowserCommandOutputImpl extends CommandOutputImpl {
+  // Although tests are reported as passing, content shell sometimes exits with
+  // a nonzero exitcode which makes our dartium builders extremely falky.
+  // See: http://dartbug.com/15139.
+  static int WHITELISTED_CONTENTSHELL_EXITCODE = -1073740022;
+  static bool isWindows = io.Platform.operatingSystem == 'windows';
+
   bool _failedBecauseOfMissingXDisplay;
 
   BrowserCommandOutputImpl(
@@ -832,7 +838,9 @@
         DebugLogger.warning(message);
         diagnostics.add(message);
       }
-      return (exitCode != 0 && !hasCrashed);
+      return (!hasCrashed &&
+              exitCode != 0 &&
+              (!isWindows || exitCode != WHITELISTED_CONTENTSHELL_EXITCODE));
     }
     DebugLogger.warning("Couldn't find 'Content-Type: text/plain' in output. "
                         "($command).");
@@ -1247,8 +1255,10 @@
   static const DART2JS_EXITCODE_CRASH = 253;
 
   CompilationCommandOutputImpl(Command command, int exitCode, bool timedOut,
-      List<int> stdout, List<int> stderr, Duration time)
-      : super(command, exitCode, timedOut, stdout, stderr, time, false);
+      List<int> stdout, List<int> stderr, Duration time,
+      bool compilationSkipped)
+      : super(command, exitCode, timedOut, stdout, stderr, time,
+              compilationSkipped);
 
   Expectation result(TestCase testCase) {
     // Handle general crash/timeout detection.
@@ -1334,7 +1344,7 @@
         command, exitCode, timedOut, stdout, stderr, time);
   } else if (command is CompilationCommand) {
     return new CompilationCommandOutputImpl(
-        command, exitCode, timedOut, stdout, stderr, time);
+        command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
   } else if (command is JSCommandlineCommand) {
     return new JsCommandlineOutputImpl(
         command, exitCode, timedOut, stdout, stderr, time);
@@ -2314,7 +2324,57 @@
         });
     }
 
+    var testCaseEnqueuer;
     void setupForRunning(TestCaseEnqueuer testCaseEnqueuer) {
+      Timer _debugTimer;
+      // If we haven't seen a single test finishing during a 10 minute period
+      // something is definitly wrong, so we dump the debugging information.
+      final debugTimerDuration = const Duration(minutes: 10);
+
+      void cancelDebugTimer() {
+        if (_debugTimer != null) {
+          _debugTimer.cancel();
+        }
+      }
+
+      void resetDebugTimer() {
+        cancelDebugTimer();
+        _debugTimer = new Timer(debugTimerDuration, () {
+          print("The debug timer of test.dart expired. Please report this issue"
+                " to ricow/kustermann and provide the following information:");
+          print("");
+          _graph.DumpCounts();
+          print("");
+          var unfinishedNodeStates = [
+              dgraph.NodeState.Initialized,
+              dgraph.NodeState.Waiting,
+              dgraph.NodeState.Enqueuing,
+              dgraph.NodeState.Processing];
+
+          for (var nodeState in unfinishedNodeStates) {
+            if (_graph.stateCount(nodeState) > 0) {
+              print("Commands in state '$nodeState':");
+              print("=================================");
+              print("");
+              for (var node in _graph.nodes) {
+                if (node.state == nodeState) {
+                  var command = node.userData;
+                  var testCases = testCaseEnqueuer.command2testCases[command];
+                  print("  Command: $command");
+                  for (var testCase in testCases) {
+                    print("    Enqueued by: ${testCase.configurationString} "
+                          "-- ${testCase.displayName}");
+                  }
+                  print("");
+                }
+              }
+              print("");
+              print("");
+            }
+          }
+        });
+      }
+
       bool recording = recordingOutputFile != null;
       bool replaying = recordedInputFile != null;
 
@@ -2349,6 +2409,8 @@
           new TestCaseCompleter(_graph, testCaseEnqueuer, commandQueue);
       testCaseCompleter.finishedTestCases.listen(
           (TestCase finishedTestCase) {
+            resetDebugTimer();
+
             // If we're recording, we don't report any TestCases to listeners.
             if (!recording) {
               eventFinishedTestCase(finishedTestCase);
@@ -2357,12 +2419,17 @@
           onDone: () {
             // Wait until the commandQueue/execturo is done (it may need to stop
             // batch runners, browser controllers, ....)
-            commandQueue.done.then((_) => eventAllTestsDone());
+            commandQueue.done.then((_) {
+              cancelDebugTimer();
+              eventAllTestsDone();
+            });
           });
+
+      resetDebugTimer();
     }
 
     // Build up the dependency graph
-    var testCaseEnqueuer = new TestCaseEnqueuer(_graph, (TestCase newTestCase) {
+    testCaseEnqueuer = new TestCaseEnqueuer(_graph, (TestCase newTestCase) {
       eventTestAdded(newTestCase);
     });
 
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 1d4c4dc..867d374 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -17,7 +17,6 @@
 import "dart:async";
 import "dart:convert" show LineSplitter, UTF8;
 import "dart:io";
-import "dart:isolate";
 import "drt_updater.dart";
 import "multitest.dart";
 import "status_file_parser.dart";
@@ -327,45 +326,16 @@
 }
 
 
-void ccTestLister() {
-  port.receive((String runnerPath, SendPort replyTo) {
-    Future processFuture = Process.start(runnerPath, ["--list"]);
-    processFuture.then((Process p) {
-      // Drain stderr to not leak resources.
-      p.stderr.listen((_) { });
-      Stream<String> stdoutStream =
-          p.stdout.transform(UTF8.decoder)
-                  .transform(new LineSplitter());
-      var streamDone = false;
-      var processExited = false;
-      checkDone() {
-        if (streamDone && processExited) {
-          replyTo.send("");
-        }
-      }
-      stdoutStream.listen((String line) {
-        replyTo.send(line);
-      },
-      onDone: () {
-        streamDone = true;
-        checkDone();
-      });
-
-      p.exitCode.then((code) {
-        if (code < 0) {
-          print("Failed to list tests: $runnerPath --list");
-          replyTo.send("");
-        } else {
-          processExited = true;
-          checkDone();
-        }
-      });
-      port.close();
-    }).catchError((e) {
-      print("Failed to list tests: $runnerPath --list");
-      replyTo.send("");
-      return true;
-    });
+Future<Iterable<String>> ccTestLister(String runnerPath) {
+  return Process.run(runnerPath, ["--list"]).then((ProcessResult result) {
+    if (result.exitCode != 0) {
+      throw "Failed to list tests: '$runnerPath --list'. "
+            "Process exited with ${result.exitCode}";
+    }
+    return result.stdout
+      .split('\n')
+      .map((line) => line.trim())
+      .where((name) => name.length > 0);
   });
 }
 
@@ -385,7 +355,6 @@
   final String dartDir;
   List<String> statusFilePaths;
   VoidFunction doDone;
-  ReceivePort receiveTestName;
   TestExpectations testExpectations;
 
   CCTestSuite(Map configuration,
@@ -409,30 +378,21 @@
     }
   }
 
-  void testNameHandler(String testName, ignore) {
-    if (testName == "") {
-      receiveTestName.close();
+  void testNameHandler(String testName) {
+    // Only run the tests that match the pattern. Use the name
+    // "suiteName/testName" for cc tests.
+    String constructedName = '$suiteName/$testPrefix$testName';
 
-      if (doDone != null) doDone();
-    } else {
-      // Only run the tests that match the pattern. Use the name
-      // "suiteName/testName" for cc tests.
-      String constructedName = '$suiteName/$testPrefix$testName';
+    var expectations = testExpectations.expectations(
+        '$testPrefix$testName');
 
-      var expectations = testExpectations.expectations(
-          '$testPrefix$testName');
+    var args = TestUtils.standardOptions(configuration);
+    args.add(testName);
 
-      var args = TestUtils.standardOptions(configuration);
-      args.add(testName);
-
-      var command = CommandBuilder.instance.getCommand(
-          'run_vm_unittest', targetRunnerPath, args, configurationDir);
-      enqueueNewTestCase(
-          new TestCase(constructedName,
-                       [command],
-                       configuration,
-                       expectations));
-    }
+    var command = CommandBuilder.instance.getCommand(
+        'run_vm_unittest', targetRunnerPath, args, configurationDir);
+    enqueueNewTestCase(
+        new TestCase(constructedName, [command], configuration, expectations));
   }
 
   void forEachTest(Function onTest, Map testCache, [VoidFunction onDone]) {
@@ -443,10 +403,13 @@
     void statusFileRead() {
       filesRead++;
       if (filesRead == statusFilePaths.length) {
-        receiveTestName = new ReceivePort();
-        var port = spawnFunction(ccTestLister);
-        port.send(hostRunnerPath, receiveTestName.toSendPort());
-        receiveTestName.receive(testNameHandler);
+        ccTestLister(hostRunnerPath).then((Iterable<String> names) {
+          names.forEach(testNameHandler);
+          onDone();
+        }).catchError((error) {
+          print("Fatal error occured: $error");
+          exit(1);
+        });
       }
     }
 
@@ -540,8 +503,7 @@
    * The [StandardTestSuite] also optionally takes a list of servers that have
    * been started up by the test harness, to be used by browser tests.
    */
-  factory StandardTestSuite.forDirectory(
-      Map configuration, Path directory) {
+  factory StandardTestSuite.forDirectory(Map configuration, Path directory) {
     final name = directory.filename;
 
     return new StandardTestSuite(configuration,
@@ -1233,7 +1195,7 @@
         .append(testUniqueName);
 
     TestUtils.mkdirRecursive(new Path('.'), generatedTestPath);
-    return new File(generatedTestPath.toNativePath()).fullPathSync()
+    return new File(generatedTestPath.toNativePath()).absolute.path
         .replaceAll('\\', '/');
   }
 
@@ -1533,24 +1495,9 @@
 
     bool hasCompileError = contents.contains("@compile-error");
     bool hasRuntimeError = contents.contains("@runtime-error");
-    bool hasDynamicTypeError = contents.contains("@dynamic-type-error");
     bool hasStaticWarning = contents.contains("@static-warning");
     bool isMultitest = multiTestRegExp.hasMatch(contents);
 
-    if (hasDynamicTypeError) {
-      // TODO(ahe): Remove this warning when co19 no longer uses this tag.
-
-      // @dynamic-type-error has been replaced by tests that use
-      // tests/co19/src/Utils/dynamic_check.dart to dynamically detect
-      // if a test is running in checked mode or not and change its
-      // expectations accordingly.
-
-      // Using stderr.writeString to avoid breaking dartc/junit_tests
-      // which parses the output of the --list option.
-      stderr.writeln(
-          "Warning: deprecated @dynamic-type-error tag used in $filePath");
-    }
-
     return {
       "vmOptions": <List>[[]],
       "sharedOptions": <String>[],
@@ -1724,10 +1671,11 @@
     updatedConfiguration['timeout'] *= 3;
     var command = CommandBuilder.instance.getCommand(
         'junit_test', 'java', args, configurationDir);
-    enqueueNewTestCase(new TestCase(suiteName,
-                                   [command],
-                                   updatedConfiguration,
-                                   new Set<String>.from([PASS])));
+    enqueueNewTestCase(
+        new TestCase(suiteName,
+                     [command],
+                     updatedConfiguration,
+                     new Set<Expectation>.from([Expectation.PASS])));
     doDone();
   }
 
@@ -1780,7 +1728,7 @@
    * the main script using 'test_suite.dart' is not there, the main
    * script must set this to '.../dart/tools/test.dart'.
    */
-  static String testScriptPath = new Options().script;
+  static String testScriptPath = new Path(Platform.script.path).toNativePath();
   static LastModifiedCache lastModifiedCache = new LastModifiedCache();
   static Path currentWorkingDirectory =
       new Path(Directory.current.path);
@@ -1862,7 +1810,7 @@
 
   static Path dartDir() {
     File scriptFile = new File(testScriptPath);
-    Path scriptPath = new Path(scriptFile.fullPathSync());
+    Path scriptPath = new Path(scriptFile.absolute.path);
     return scriptPath.directoryPath.directoryPath;
   }
 
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index fb71f3f..ab81b51 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -4,7 +4,6 @@
 
 library utils;
 
-import 'dart:async';
 import 'dart:io';
 import 'dart:math' show min;
 import 'dart:convert';
diff --git a/tools/upload_sdk.py b/tools/upload_sdk.py
deleted file mode 100644
index 67f7131..0000000
--- a/tools/upload_sdk.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2011 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.
-
-# This zips the SDK and uploads it to Google Storage when run on a buildbot.
-#
-# Usage: upload_sdk.py path_to_sdk
-
-import os
-import os.path
-import platform
-import subprocess
-import sys
-import utils
-
-
-GSUTIL = utils.GetBuildbotGSUtilPath()
-HAS_SHELL = False
-if platform.system() == 'Windows':
-  HAS_SHELL = True
-GS_SITE = 'gs://'
-GS_DIR = 'dart-dump-render-tree'
-GS_SDK_DIR = 'sdk'
-SDK_LOCAL_ZIP = "dart-sdk.zip"
-SDK_LOCAL_TARGZ = "dart-sdk.tar.gz"
-
-def ExecuteCommand(cmd):
-  """Execute a command in a subprocess.
-  """
-  print 'Executing: ' + ' '.join(cmd)
-  pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-      shell=HAS_SHELL)
-  output = pipe.communicate()
-  if pipe.returncode != 0:
-    print 'Execution failed: ' + str(output)
-  return (pipe.returncode, output)
-
-
-def UploadArchive(source, target):
-  """Upload an archive zip file to Google storage.
-  """
-  # Upload file.
-  cmd = [GSUTIL, 'cp', source, target]
-  (status, output) = ExecuteCommand(cmd)
-  if status != 0:
-    return status
-  print 'Uploaded: ' + output[0]
-
-  cmd = [GSUTIL, 'setacl', 'public-read', target]
-  (status, output) = ExecuteCommand(cmd)
-  return status
-
-
-def Usage(progname):
-  sys.stderr.write('Usage: %s path_to_sdk\n' % progname)
-
-
-def main(argv):
-  #allow local editor builds to deploy to a different bucket
-  if os.environ.has_key('DART_LOCAL_BUILD'):
-    gsdir = os.environ['DART_LOCAL_BUILD']
-  else:
-    gsdir = GS_DIR
-    
-  if not os.path.exists(argv[1]):
-    sys.stderr.write('Path not found: %s\n' % argv[1])
-    Usage(argv[0])
-    return 1
-
-  if not os.path.exists(GSUTIL):
-    #TODO: Determine where we are running, if we're running on a buildbot we
-    #should fail with a message.  
-    #If we are not on a buildbot then fail silently. 
-    utils.Touch(os.path.join(argv[1], 'upload.stamp'))
-    exit(0)
-  
-  revision = utils.GetSVNRevision()
-  if revision is None:
-    sys.stderr.write('Unable to find SVN revision.\n')
-    return 1
-
-  os.chdir(os.path.dirname(argv[1]))
-
-  if (os.path.basename(os.path.dirname(argv[1])) ==
-      utils.GetBuildConf('release', 'ia32')):
-    sdk_suffix = ''
-  else:
-    sdk_suffix = '-debug'
-  # TODO(dgrove) - deal with architectures that are not ia32.
-  sdk_file_zip = 'dart-%s-%s%s.zip' % (utils.GuessOS(), revision, sdk_suffix)
-  sdk_file_targz = 'dart-%s-%s%s.tar.gz' % (utils.GuessOS(), revision,
-      sdk_suffix)
-  if (os.path.exists(SDK_LOCAL_ZIP)):
-    os.remove(SDK_LOCAL_ZIP)
-  if (os.path.exists(SDK_LOCAL_TARGZ)):
-    os.remove(SDK_LOCAL_TARGZ)
-  if platform.system() == 'Windows':
-    # Windows does not have zip. We use the 7 zip utility in third party.
-    ExecuteCommand([os.path.join('..', 'third_party', '7zip', '7za'), 'a',
-        '-tzip', SDK_LOCAL_ZIP, os.path.basename(argv[1])])
-  else:
-    ExecuteCommand(['zip', '-yr', SDK_LOCAL_ZIP, os.path.basename(argv[1])])
-    ExecuteCommand(['tar', 'czf', SDK_LOCAL_TARGZ, os.path.basename(argv[1])])
-  UploadArchive(SDK_LOCAL_ZIP,
-                GS_SITE + '/'.join([gsdir, GS_SDK_DIR, sdk_file_zip]))
-  if (os.path.exists(SDK_LOCAL_TARGZ)):
-    UploadArchive(SDK_LOCAL_TARGZ,
-                GS_SITE + '/'.join([gsdir, GS_SDK_DIR, sdk_file_targz]))
-  latest_name_zip = 'dart-%s-latest%s.zip' % (utils.GuessOS(), sdk_suffix)
-  latest_name_targz = 'dart-%s-latest%s.tar.gz' % (utils.GuessOS(), sdk_suffix)
-  UploadArchive(SDK_LOCAL_ZIP,
-                GS_SITE + '/'.join([gsdir, GS_SDK_DIR, latest_name_zip]))
-  if (os.path.exists(SDK_LOCAL_TARGZ)):
-    UploadArchive(SDK_LOCAL_TARGZ,
-                GS_SITE + '/'.join([gsdir, GS_SDK_DIR, latest_name_targz]))
-  utils.Touch('upload.stamp')
-
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv))
diff --git a/tools/utils.py b/tools/utils.py
index ab83b46..89da10f 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -455,6 +455,17 @@
     os.utime(name, None)
 
 
+def ExecuteCommand(cmd):
+  """Execute a command in a subprocess."""
+  print 'Executing: ' + ' '.join(cmd)
+  pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+      shell=IsWindows())
+  output = pipe.communicate()
+  if pipe.returncode != 0:
+    raise Exception('Execution failed: ' + str(output))
+  return (pipe.returncode, output)
+
+
 def DartBinary():
   tools_dir = os.path.dirname(os.path.realpath(__file__))
   dart_binary_prefix = os.path.join(tools_dir, 'testing', 'bin')