Version 0.8.1.0 .

svn merge -r 28200:28280  https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@28283 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index be03c50..c136b7a 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -376,6 +376,10 @@
     elements.sort(compare);
   }
 
+  void shuffle() {
+    elements.shuffle();
+  }
+
   int indexOf(E element, [int start = 0]) {
     return elements.indexOf(element, start);
   }
@@ -583,4 +587,4 @@
   String group(int i) => _match[i];
   int start() => _match.start;
   int end() => _match.end;
-}
\ No newline at end of file
+}
diff --git a/pkg/analyzer_experimental/test/utils.dart b/pkg/analyzer_experimental/test/utils.dart
index 637fe0c..df22ff8 100644
--- a/pkg/analyzer_experimental/test/utils.dart
+++ b/pkg/analyzer_experimental/test/utils.dart
@@ -38,7 +38,8 @@
 ///
 /// Returns the return value of [fn].
 dynamic withTempDir(fn(String path)) {
-  var tempDir = new Directory('').createTempSync().path;
+  var tempDir =
+      Directory.systemTemp.createTempSync('analyzer_experimental_').path;
   try {
     return fn(tempDir);
   } finally {
diff --git a/pkg/barback/lib/src/transform_logger.dart b/pkg/barback/lib/src/transform_logger.dart
index 131be29..e68573a 100644
--- a/pkg/barback/lib/src/transform_logger.dart
+++ b/pkg/barback/lib/src/transform_logger.dart
@@ -14,6 +14,14 @@
 
   TransformLogger(this._shouldPrint);
 
+  /// Logs an informative message.
+  ///
+  /// If present, [span] indicates the location in the input asset that caused
+  /// the message.
+  void info(String message, [Span span]) {
+    _printMessage('info', message, span);
+  }
+
   /// Logs a warning message.
   ///
   /// If present, [span] indicates the location in the input asset that caused
@@ -34,7 +42,7 @@
   // TODO(sigmund,rnystrom): do something better than printing.
   _printMessage(String prefix, String message, Span span) {
     if (!_shouldPrint) return;
-    print(span == null ? '$prefix $message'
+    print(span == null ? '$prefix: $message'
         : '$prefix ${span.getLocationMessage(message)}');
   }
 }
diff --git a/pkg/barback/test/asset_test.dart b/pkg/barback/test/asset_test.dart
index 5563ebf..74f459e 100644
--- a/pkg/barback/test/asset_test.dart
+++ b/pkg/barback/test/asset_test.dart
@@ -27,7 +27,7 @@
 
   setUp(() {
     // Create a temp file we can use for assets.
-    tempDir = new Directory("").createTempSync();
+    tempDir = Directory.systemTemp.createTempSync('barback_asset_test_');
     binaryFilePath = pathos.join(tempDir.path, "file.bin");
     new File(binaryFilePath).writeAsBytesSync(binaryContents);
 
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
index 19824cf..a91ff69 100644
--- a/pkg/custom_element/lib/custom_element.dart
+++ b/pkg/custom_element/lib/custom_element.dart
@@ -481,7 +481,7 @@
   @deprecated
   int get clientWidth => client.width;
 
-  Rect get client => host.client;
+  Rectangle get client => host.client;
 
   @deprecated
   int get offsetHeight => offset.height;
@@ -495,7 +495,7 @@
   @deprecated
   int get offsetWidth => offset.width;
 
-  Rect get offset => host.offset;
+  Rectangle get offset => host.offset;
 
   int get scrollHeight => host.scrollHeight;
 
@@ -509,9 +509,9 @@
 
   int get scrollWidth => host.scrollWidth;
 
-  Rect getBoundingClientRect() => host.getBoundingClientRect();
+  Rectangle getBoundingClientRect() => host.getBoundingClientRect();
 
-  List<Rect> getClientRects() => host.getClientRects();
+  List<Rectangle> getClientRects() => host.getClientRects();
 
   List<Node> getElementsByClassName(String name) =>
       host.getElementsByClassName(name);
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index dd4044e..5f9949e 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -1,36 +1,30 @@
 library single_library_test;
 
-import 'dart:io'; 
+import 'dart:io';
 
 import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
 
 import '../lib/docgen.dart';
 
-main() {
-  group('Generate docs for', () {
-    test('one simple file.', () {
-      var temporaryDir = Directory.createSystemTempSync('single_library_');
-      var fileName = path.join(temporaryDir.path, 'temp.dart');
-      var file = new File(fileName);
-      file.writeAsStringSync('''
+const String DART_LIBRARY = '''
   library test;
   /**
    * Doc comment for class [A].
-   * 
+   *
    * Multiline Test
    */
   /*
    * Normal comment for class A.
    */
   class A {
-    
+
     int _someNumber;
-    
+
     A() {
       _someNumber = 12;
     }
-    
+
     /**
      * Test for linking to parameter [A]
      */
@@ -38,30 +32,37 @@
       print(A);
     }
   }
-  
+
   main() {
     A a = new A();
     a.doThis(5);
   }
-      ''');
-      
+''';
+
+main() {
+  group('Generate docs for', () {
+    test('one simple file.', () {
+      var temporaryDir = Directory.systemTemp.createTempSync('single_library_');
+      var fileName = path.join(temporaryDir.path, 'temp.dart');
+      var file = new File(fileName);
+      file.writeAsStringSync(DART_LIBRARY);
       getMirrorSystem([fileName])
         .then(expectAsync1((mirrorSystem) {
-          var testLibraryUri = new Uri(scheme: 'file', 
+          var testLibraryUri = new Uri(scheme: 'file',
               path: path.absolute(fileName));
           var library = generateLibrary(mirrorSystem.libraries[testLibraryUri]);
           expect(library is Library, isTrue);
-          
+
           var classTypes = library.classes;
           expect(classTypes is ClassGroup, isTrue);
-          
+
           var classes = [];
           classes.addAll(classTypes.classes.values);
           classes.addAll(classTypes.errors.values);
           expect(classes.every((e) => e is Class), isTrue);
-          
+
           expect(classTypes.typedefs.values.every((e) => e is Typedef), isTrue);
-          
+
           var classMethodTypes = [];
           classes.forEach((e) {
             classMethodTypes.add(e.methods);
@@ -78,16 +79,16 @@
             classMethods.addAll(e.regularMethods.values);
           });
           expect(classMethods.every((e) => e is Method), isTrue);
-          
+
           var methodParameters = [];
-          classMethods.forEach((e) { 
+          classMethods.forEach((e) {
             methodParameters.addAll(e.parameters.values);
           });
           expect(methodParameters.every((e) => e is Parameter), isTrue);
-          
+
           var functionTypes = library.functions;
           expect(functionTypes is MethodGroup, isTrue);
-          
+
           var functions = [];
           functions.addAll(functionTypes.setters.values);
           functions.addAll(functionTypes.getters.values);
@@ -95,35 +96,35 @@
           functions.addAll(functionTypes.operators.values);
           functions.addAll(functionTypes.regularMethods.values);
           expect(functions.every((e) => e is Method), isTrue);
-          
+
           var functionParameters = [];
           functions.forEach((e) {
-            functionParameters.addAll(e.parameters.values); 
+            functionParameters.addAll(e.parameters.values);
           });
           expect(functionParameters.every((e) => e is Parameter), isTrue);
-    
+
           var variables = library.variables.values;
           expect(variables.every((e) => e is Variable), isTrue);
-          
-          /// Testing fixReference 
+
+          /// Testing fixReference
           // Testing Doc comment for class [A].
           var libraryMirror = mirrorSystem.libraries[testLibraryUri];
           var classMirror = libraryMirror.classes.values.first;
-          var classDocComment = fixReference('A', libraryMirror, 
+          var classDocComment = fixReference('A', libraryMirror,
               classMirror, null).children.first.text;
           expect(classDocComment == 'test.A', isTrue);
-          
+
           // Test for linking to parameter [A]
           var methodMirror = classMirror.methods['doThis'];
           var methodParameterDocComment = fixReference('A', libraryMirror,
               classMirror, methodMirror).children.first.text;
           expect(methodParameterDocComment == 'test.A.doThis#A', isTrue);
-          
+
           // Testing trying to refer to doThis function
-          var methodDocComment = fixReference('doThis', libraryMirror, 
+          var methodDocComment = fixReference('doThis', libraryMirror,
               classMirror, methodMirror).children.first.text;
           expect(methodDocComment == 'test.A.doThis', isTrue);
-          
+
           // Testing something with no reference
           var libraryDocComment = fixReference('foobar', libraryMirror,
               classMirror, methodMirror).children.first.text;
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index c42b810..7467d5f 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -216,7 +216,7 @@
   group('in a temp directory', () {
     var tempDir;
     setUp(() {
-      tempDir = new Directory('').createTempSync();
+      tempDir = Directory.systemTemp.createTempSync('http_test_');
     });
 
     tearDown(() => tempDir.deleteSync(recursive: true));
diff --git a/pkg/http_server/test/virtual_directory_test.dart b/pkg/http_server/test/virtual_directory_test.dart
index 4b59f2c..9d38e68 100644
--- a/pkg/http_server/test/virtual_directory_test.dart
+++ b/pkg/http_server/test/virtual_directory_test.dart
@@ -16,7 +16,7 @@
   group('serve-root', () {
     test('dir-exists', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var virDir = new VirtualDirectory(dir.path);
 
         virDir.serve(server);
@@ -31,7 +31,7 @@
 
     test('dir-not-exists', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         dir.deleteSync();
         var virDir = new VirtualDirectory(dir.path);
 
@@ -49,7 +49,7 @@
     group('top-level', () {
       test('file-exists', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var file = new File('${dir.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
@@ -65,7 +65,7 @@
 
       test('file-not-exists', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var virDir = new VirtualDirectory(dir.path);
 
           virDir.serve(server);
@@ -82,7 +82,7 @@
     group('in-dir', () {
       test('file-exists', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var dir2 = new Directory('${dir.path}/dir')..createSync();
           var file = new File('${dir2.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
@@ -99,7 +99,7 @@
 
       test('file-not-exists', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var dir2 = new Directory('${dir.path}/dir')..createSync();
           var file = new File('${dir.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
@@ -120,7 +120,7 @@
     group('top-level', () {
       test('simple', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var virDir = new VirtualDirectory(dir.path);
           virDir.allowDirectoryListing = true;
 
@@ -136,7 +136,7 @@
 
       test('files', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var virDir = new VirtualDirectory(dir.path);
           for (int i = 0; i < 10; i++) {
             new File('${dir.path}/$i').createSync();
@@ -155,7 +155,7 @@
 
       test('dirs', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var virDir = new VirtualDirectory(dir.path);
           for (int i = 0; i < 10; i++) {
             new Directory('${dir.path}/$i').createSync();
@@ -175,7 +175,8 @@
       if (!Platform.isWindows) {
         test('recursive-link', () {
           expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir = new Directory('').createTempSync();
+            var dir =
+                Directory.systemTemp.createTempSync('http_server_virtual_');
             var link = new Link('${dir.path}/recursive')..createSync('.');
             var virDir = new VirtualDirectory(dir.path);
             virDir.allowDirectoryListing = true;
@@ -207,7 +208,7 @@
     group('custom', () {
       test('simple', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var virDir = new VirtualDirectory(dir.path);
           virDir.allowDirectoryListing = true;
           virDir.setDirectoryHandler((dir2, request) {
@@ -234,7 +235,8 @@
       group('follow-links', () {
         test('dir-link', () {
           expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir = new Directory('').createTempSync();
+            var dir =
+                Directory.systemTemp.createTempSync('http_server_virtual_');
             var dir2 = new Directory('${dir.path}/dir2')..createSync();
             var link = new Link('${dir.path}/dir3')..createSync('dir2');
             var file = new File('${dir2.path}/file')..createSync();
@@ -253,7 +255,8 @@
 
         test('root-link', () {
           expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir = new Directory('').createTempSync();
+            var dir =
+                Directory.systemTemp.createTempSync('http_server_virtual_');
             var link = new Link('${dir.path}/dir3')..createSync('.');
             var file = new File('${dir.path}/file')..createSync();
             var virDir = new VirtualDirectory(dir.path);
@@ -272,7 +275,8 @@
         group('bad-links', () {
           test('absolute-link', () {
             expect(HttpServer.bind('localhost', 0).then((server) {
-              var dir = new Directory('').createTempSync();
+              var dir =
+                  Directory.systemTemp.createTempSync('http_server_virtual_');
               var file = new File('${dir.path}/file')..createSync();
               var link = new Link('${dir.path}/dir3')
                   ..createSync('${dir.path}/file');
@@ -296,7 +300,8 @@
 
           test('relative-parent-link', () {
             expect(HttpServer.bind('localhost', 0).then((server) {
-              var dir = new Directory('').createTempSync();
+              var dir =
+                  Directory.systemTemp.createTempSync('http_server_virtual_');
               var name = basename(dir.path);
               var file = new File('${dir.path}/file')..createSync();
               var link = new Link('${dir.path}/dir3')
@@ -324,7 +329,8 @@
       group('not-follow-links', () {
         test('dir-link', () {
           expect(HttpServer.bind('localhost', 0).then((server) {
-            var dir = new Directory('').createTempSync();
+            var dir =
+                Directory.systemTemp.createTempSync('http_server_virtual_');
             var dir2 = new Directory('${dir.path}/dir2')..createSync();
             var link = new Link('${dir.path}/dir3')..createSync('dir2');
             var file = new File('${dir2.path}/file')..createSync();
@@ -348,7 +354,7 @@
     group('file', () {
       test('file-exists', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var file = new File('${dir.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
@@ -373,7 +379,7 @@
 
       test('file-changes', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var file = new File('${dir.path}/file')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
@@ -405,7 +411,7 @@
     group('mime-type', () {
       test('from-path', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var file = new File('${dir.path}/file.jpg')..createSync();
           var virDir = new VirtualDirectory(dir.path);
 
@@ -422,7 +428,7 @@
 
       test('from-magic-number', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-          var dir = new Directory('').createTempSync();
+          var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           var file = new File('${dir.path}/file.jpg')..createSync();
           file.writeAsBytesSync(
               [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
@@ -444,7 +450,7 @@
   group('error-page', () {
     test('default', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var virDir = new VirtualDirectory(dir.path);
         dir.deleteSync();
 
@@ -459,7 +465,7 @@
 
     test('custom', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var virDir = new VirtualDirectory(dir.path);
         dir.deleteSync();
 
@@ -481,7 +487,7 @@
   group('escape-root', () {
     test('escape1', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
 
@@ -497,7 +503,7 @@
 
     test('escape2', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         new Directory('${dir.path}/dir').createSync();
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
@@ -516,7 +522,7 @@
   group('url-decode', () {
     test('with-space', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var file = new File('${dir.path}/my file')..createSync();
         var virDir = new VirtualDirectory(dir.path);
 
@@ -532,7 +538,7 @@
 
     test('encoded-space', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var file = new File('${dir.path}/my file')..createSync();
         var virDir = new VirtualDirectory(dir.path);
 
@@ -548,7 +554,7 @@
 
     test('encoded-path-separator', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         new Directory('${dir.path}/a').createSync();
         new Directory('${dir.path}/a/b').createSync();
         new Directory('${dir.path}/a/b/c').createSync();
@@ -567,7 +573,7 @@
 
     test('encoded-null', () {
       expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
         var virDir = new VirtualDirectory(dir.path);
         virDir.allowDirectoryListing = true;
 
@@ -584,7 +590,7 @@
     testEncoding(name, expected, [bool create = true]) {
       test('encode-$name', () {
         expect(HttpServer.bind('localhost', 0).then((server) {
-        var dir = new Directory('').createTempSync();
+        var dir = Directory.systemTemp.createTempSync('http_server_virtual_');
           if (create) new File('${dir.path}/$name').createSync();
           var virDir = new VirtualDirectory(dir.path);
           virDir.allowDirectoryListing = true;
diff --git a/pkg/pkg.status b/pkg/pkg.status
index d5c5205..7fed36f 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -240,3 +240,7 @@
 
 [ $compiler == none && $runtime == vm && $checked ]
 intl/test/message_extraction/failed_extraction_test: Pass, Fail # Issue 13543
+
+[ $compiler == none && $runtime == dartium ]
+source_maps/test/parser_test: Pass, Timeout # Issue 13719: Please triage this failure.
+
diff --git a/pkg/polymer/lib/platform.dart b/pkg/polymer/lib/platform.dart
index 5dc5c3e..f6c475a 100644
--- a/pkg/polymer/lib/platform.dart
+++ b/pkg/polymer/lib/platform.dart
@@ -11,6 +11,7 @@
 // belong in html's Platform instead?
 library polymer.platform;
 
+import 'dart:async' show Completer;
 import 'dart:html' show Text, MutationObserver;
 import 'dart:collection' show Queue;
 import 'package:observe/src/microtask.dart' show performMicrotaskCheckpoint;
diff --git a/pkg/scheduled_test/lib/descriptor.dart b/pkg/scheduled_test/lib/descriptor.dart
index 6692591..0004236 100644
--- a/pkg/scheduled_test/lib/descriptor.dart
+++ b/pkg/scheduled_test/lib/descriptor.dart
@@ -46,7 +46,9 @@
 ///       setUp(() {
 ///         var tempDir;
 ///         schedule(() {
-///           return new Directory('').createTemp().then((dir) {
+///           return Directory.systemTemp
+///                           .createTemp('my_temp_dir_')
+///                           .then((dir) {
 ///             tempDir = dir;
 ///             d.defaultRoot = tempDir.path;
 ///           });
diff --git a/pkg/scheduled_test/test/descriptor/utils.dart b/pkg/scheduled_test/test/descriptor/utils.dart
index bd9ae57..9674469 100644
--- a/pkg/scheduled_test/test/descriptor/utils.dart
+++ b/pkg/scheduled_test/test/descriptor/utils.dart
@@ -16,7 +16,7 @@
 
 void scheduleSandbox() {
   schedule(() {
-    return new Directory('').createTemp().then((dir) {
+    return Directory.systemTemp.createTemp('descriptor_sandbox_').then((dir) {
       sandbox = dir.path;
       d.defaultRoot = sandbox;
     });
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index 92ebfad..f937ae8 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -357,10 +357,10 @@
 }
 
 ScheduledProcess startDartProcess(String script) {
-  var tempDir = schedule(() {
-    return new Directory('').createTemp().then((dir) => dir.path);
-  }, 'create temp dir');
-
+  var tempDir = schedule(() => Directory.systemTemp
+                                        .createTemp('scheduled_process_test_')
+                                        .then((dir) => dir.path),
+                         'create temp dir');
   var dartPath = schedule(() {
     return tempDir.then((dir) {
       var utilsPath = path.absolute(path.join(Platform.script, 'utils.dart'));
diff --git a/pkg/third_party/html5lib/lib/src/list_proxy.dart b/pkg/third_party/html5lib/lib/src/list_proxy.dart
index 99adb3f..786e393 100644
--- a/pkg/third_party/html5lib/lib/src/list_proxy.dart
+++ b/pkg/third_party/html5lib/lib/src/list_proxy.dart
@@ -51,6 +51,7 @@
   void addLast(E value) { add(value); }
   void addAll(Iterable<E> collection) { _list.addAll(collection); }
   void sort([int compare(E a, E b)]) { _list.sort(compare); }
+  void shuffle() { _list.shuffle(); }
 
   int indexOf(E element, [int start = 0]) => _list.indexOf(element, start);
   int lastIndexOf(E element, [int start]) => _list.lastIndexOf(element, start);
diff --git a/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart b/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
index b94a0c4..2388ccb 100644
--- a/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
+++ b/pkg/unmodifiable_collection/lib/unmodifiable_collection.dart
@@ -54,11 +54,12 @@
 
   Map<int, E> asMap() => _source.asMap();
 
-
   void operator []=(int index, E value) { _source[index] = value; }
 
   void sort([int compare(E a, E b)]) { _source.sort(compare); }
 
+  void shuffle() { _source.shuffle(); }
+
   void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
     _source.setRange(start, end, iterable, skipCount);
   }
@@ -154,7 +155,7 @@
 /**
  * An unmodifiable set.
  *
- * An UnmodifiableSetView contains a [Set] object and ensures 
+ * An UnmodifiableSetView contains a [Set] object and ensures
  * that it does not change.
  * Methods that would change the set,
  * such as [add] and [remove], throw an [UnsupportedError].
@@ -230,7 +231,7 @@
 /**
  * An unmodifiable map.
  *
- * An UnmodifiableMapView contains a [Map] object and ensures 
+ * An UnmodifiableMapView contains a [Map] object and ensures
  * that it does not change.
  * Methods that would change the map,
  * such as [addAll] and [remove], throw an [UnsupportedError].
diff --git a/pkg/utf/lib/utf.dart b/pkg/utf/lib/utf.dart
index 164c340..002287a 100644
--- a/pkg/utf/lib/utf.dart
+++ b/pkg/utf/lib/utf.dart
@@ -3,12 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * Support for encoding and decoding Unicode characters in UTF-8, UTF-16, and 
+ * Support for encoding and decoding Unicode characters in UTF-8, UTF-16, and
  * UTF-32.
  */
 library utf;
+
 import "dart:async";
 import "dart:collection";
+
 part "utf_stream.dart";
 part "utf8.dart";
 part "utf16.dart";
diff --git a/pkg/utf/lib/utf16.dart b/pkg/utf/lib/utf16.dart
index 3518bbb..7de9e61 100644
--- a/pkg/utf/lib/utf16.dart
+++ b/pkg/utf/lib/utf16.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart.utf;
+part of utf;
 
 /**
  * Decodes the UTF-16 bytes as an iterable. Thus, the consumer can only convert
diff --git a/pkg/utf/lib/utf32.dart b/pkg/utf/lib/utf32.dart
index acd465c..885ed94 100644
--- a/pkg/utf/lib/utf32.dart
+++ b/pkg/utf/lib/utf32.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart.utf;
+part of utf;
 
 /**
  * Decodes the UTF-32 bytes as an iterable. Thus, the consumer can only convert
@@ -70,7 +70,7 @@
 String decodeUtf32be(
     List<int> bytes, [int offset = 0, int length, bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) =>
-  new String.fromCharCodes((new Utf32beBytesDecoder(bytes, offset, length, 
+  new String.fromCharCodes((new Utf32beBytesDecoder(bytes, offset, length,
     stripBom, replacementCodepoint)).decodeRest());
 
 /**
diff --git a/pkg/utf/lib/utf8.dart b/pkg/utf/lib/utf8.dart
index 7543865..36288d9 100644
--- a/pkg/utf/lib/utf8.dart
+++ b/pkg/utf/lib/utf8.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart.utf;
+part of utf;
 
 const int _UTF8_ONE_BYTE_MAX = 0x7f;
 const int _UTF8_TWO_BYTE_MAX = 0x7ff;
diff --git a/pkg/utf/lib/utf_stream.dart b/pkg/utf/lib/utf_stream.dart
index 8440313..cfc57b9 100644
--- a/pkg/utf/lib/utf_stream.dart
+++ b/pkg/utf/lib/utf_stream.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart.utf;
+part of utf;
 
 abstract class _StringDecoder
     extends StreamEventTransformer<List<int>, String> {
diff --git a/pkg/watcher/test/utils.dart b/pkg/watcher/test/utils.dart
index 656ddf8..28d57b0 100644
--- a/pkg/watcher/test/utils.dart
+++ b/pkg/watcher/test/utils.dart
@@ -46,7 +46,7 @@
 ///
 /// This should usually be called by [setUp].
 void createSandbox() {
-  var dir = new Directory("").createTempSync();
+  var dir = Directory.systemTemp.createTempSync('watcher_test_');
   _sandboxDir = dir.path;
 
   _mockFileModificationTimes = new Map<String, int>();
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 48c10fb..eee4430 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -27,7 +27,8 @@
   V(Directory_Create, 1)                                                       \
   V(Directory_Current, 0)                                                      \
   V(Directory_SetCurrent, 1)                                                   \
-  V(Directory_CreateTemp, 2)                                                   \
+  V(Directory_SystemTemp, 0)                                                   \
+  V(Directory_CreateTemp, 1)                                                   \
   V(Directory_Delete, 2)                                                       \
   V(Directory_Rename, 2)                                                       \
   V(Directory_List, 3)                                                         \
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index eabd4f3..9d33706 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -485,7 +485,8 @@
       if (DartUtils::IsDartIOLibURL(url_string)) {
         return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
       }
-      return Dart_Error("Do not know how to load '%s'", url_string);
+      return Dart_Error("The built-in library '%s' is not available"
+                        " on the stand-alone VM.\n", url_string);
     } else {
       ASSERT(tag == Dart_kSourceTag);
       return Dart_Error("Unable to load source '%s' ", url_string);
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 6aa4d09..10c53b9 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -76,16 +76,22 @@
 }
 
 
+void FUNCTION_NAME(Directory_SystemTemp)(
+    Dart_NativeArguments args) {
+  char* result = Directory::SystemTemp();
+  Dart_SetReturnValue(args, DartUtils::NewString(result));
+  free(result);
+}
+
+
 void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) {
   Dart_Handle path = Dart_GetNativeArgument(args, 0);
-  Dart_Handle system = Dart_GetNativeArgument(args, 1);
   if (!Dart_IsString(path)) {
     Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(
-        "Template argument of CreateSystemTempSync is not a String"));
+        "Prefix argument of CreateSystemTempSync is not a String"));
     return;
   }
-  char* result = Directory::CreateTemp(DartUtils::GetStringValue(path),
-                                       DartUtils::GetBooleanValue(system));
+  char* result = Directory::CreateTemp(DartUtils::GetStringValue(path));
   if (result != NULL) {
     Dart_SetReturnValue(args, DartUtils::NewString(result));
     free(result);
@@ -195,23 +201,7 @@
 CObject* Directory::CreateTempRequest(const CObjectArray& request) {
   if (request.Length() == 1 && request[0]->IsString()) {
     CObjectString path(request[0]);
-    char* result = Directory::CreateTemp(path.CString(), false);
-    if (result != NULL) {
-      CObject* temp_dir = new CObjectString(CObject::NewString(result));
-      free(result);
-      return temp_dir;
-    } else {
-      return CObject::NewOSError();
-    }
-  }
-  return CObject::IllegalArgumentError();
-}
-
-
-CObject* Directory::CreateSystemTempRequest(const CObjectArray& request) {
-  if (request.Length() == 1 && request[0]->IsString()) {
-    CObjectString path(request[0]);
-    char* result = Directory::CreateTemp(path.CString(), true);
+    char* result = Directory::CreateTemp(path.CString());
     if (result != NULL) {
       CObject* temp_dir = new CObjectString(CObject::NewString(result));
       free(result);
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 57302a2..fd78e80 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -257,7 +257,8 @@
   static char* Current();
   static bool SetCurrent(const char* path);
   static bool Create(const char* path);
-  static char* CreateTemp(const char* const_template, bool system);
+  static char* SystemTemp();
+  static char* CreateTemp(const char* path);
   static bool Delete(const char* path, bool recursive);
   static bool Rename(const char* path, const char* new_path);
 
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index 6a2646a..7dd450a 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -382,34 +382,34 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template, bool system) {
-  // Returns a new, unused directory name, modifying the contents of
-  // dir_template.  Creates the directory with the permissions specified
+char* Directory::SystemTemp() {
+  // Android does not have a /tmp directory. A partial substitute,
+  // suitable for bring-up work and tests, is to create a tmp
+  // directory in /data/local/tmp.
+  //
+  // TODO(4413): In the long run, when running in an application we should
+  // probably use the appropriate directory from the Android API,
+  // probably what File.createTempFile uses.
+#define ANDROID_TEMP_DIR "/data/local/tmp"
+  struct stat st;
+  if (stat(ANDROID_TEMP_DIR, &st) != 0) {
+    mkdir(ANDROID_TEMP_DIR, 0777);
+  }
+  return strdup(ANDROID_TEMP_DIR);
+}
+
+
+char* Directory::CreateTemp(const char* prefix) {
+  // Returns a new, unused directory name, adding characters to the end
+  // of prefix.  Creates the directory with the permissions specified
   // by the process umask.
   // The return value must be freed by the caller.
   PathBuffer path;
-  if (system) {
-    // Android does not have a /tmp directory. A partial substitute,
-    // suitable for bring-up work and tests, is to create a tmp
-    // directory in /data/local/tmp.
-    //
-    // TODO(4413): In the long run, when running in an application we should
-    // probably use the appropriate directory from the Android API,
-    // probably what File.createTempFile uses.
-    #define ANDROID_TEMP_DIR "/data/local/tmp"
-    struct stat st;
-    if (stat(ANDROID_TEMP_DIR, &st) != 0) {
-      mkdir(ANDROID_TEMP_DIR, 0777);
-    }
-    path.Add(ANDROID_TEMP_DIR "/");
-  }
-
-  path.Add(const_template);
+  path.Add(prefix);
   if (!path.Add("XXXXXX")) {
     // Pattern has overflowed.
     return NULL;
   }
-
   char* result;
   do {
     result = MakeTempDirectory(path.AsString());
@@ -417,11 +417,7 @@
   if (result == NULL) {
     return NULL;
   }
-  int length = strnlen(path.AsString(), PATH_MAX);
-  result = static_cast<char*>(malloc(length + 1));
-  strncpy(result, path.AsString(), length);
-  result[length] = '\0';
-  return result;
+  return strdup(result);
 }
 
 
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index e12dbfd..c26289c 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -373,27 +373,31 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template, bool system) {
-  // Returns a new, unused directory name, modifying the contents of
-  // dir_template.  Creates the directory with the permissions specified
+char* Directory::SystemTemp() {
+  const char* temp_dir = getenv("TMPDIR");
+  if (temp_dir == NULL) {
+    temp_dir = getenv("TMP");
+  }
+  if (temp_dir == NULL) {
+    temp_dir = "/tmp";
+  }
+  char* result = strdup(temp_dir);
+  // Remove any trailing slash.
+  int length = strlen(result);
+  if (length > 1 && result[length - 1] == '/') {
+    result[length - 1] = '\0';
+  }
+  return result;
+}
+
+
+char* Directory::CreateTemp(const char* prefix) {
+  // Returns a new, unused directory name, adding characters to the end
+  // of prefix.  Creates the directory with the permissions specified
   // by the process umask.
   // The return value must be freed by the caller.
   PathBuffer path;
-  if (system) {
-    const char* temp_dir = getenv("TMPDIR");
-    if (temp_dir == NULL) {
-      temp_dir = getenv("TMP");
-    }
-    if (temp_dir != NULL) {
-      path.Add(temp_dir);
-      if (temp_dir[strlen(temp_dir) - 1] != '/') {
-        path.Add("/");
-      }
-    } else {
-      path.Add("/tmp/");
-    }
-  }
-  path.Add(const_template);
+  path.Add(prefix);
   if (!path.Add("XXXXXX")) {
     // Pattern has overflowed.
     return NULL;
@@ -405,11 +409,7 @@
   if (result == NULL) {
     return NULL;
   }
-  int length = strnlen(path.AsString(), PATH_MAX);
-  result = static_cast<char*>(malloc(length + 1));
-  strncpy(result, path.AsString(), length);
-  result[length] = '\0';
-  return result;
+  return strdup(result);
 }
 
 
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index 5757a9c..074647f 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -361,27 +361,31 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template, bool system) {
-  // Returns a new, unused directory name, modifying the contents of
-  // dir_template.  Creates the directory with the permissions specified
+char* Directory::SystemTemp() {
+  const char* temp_dir = getenv("TMPDIR");
+  if (temp_dir == NULL) {
+    temp_dir = getenv("TMP");
+  }
+  if (temp_dir == NULL) {
+    temp_dir = "/tmp";
+  }
+  char* result = strdup(temp_dir);
+  // Remove any trailing slash.
+  int length = strlen(result);
+  if (length > 1 && result[length - 1] == '/') {
+    result[length - 1] = '\0';
+  }
+  return result;
+}
+
+
+char* Directory::CreateTemp(const char* prefix) {
+  // Returns a new, unused directory name, adding characters to the end
+  // of prefix.  Creates the directory with the permissions specified
   // by the process umask.
   // The return value must be freed by the caller.
   PathBuffer path;
-  if (system) {
-    const char* temp_dir = getenv("TMPDIR");
-    if (temp_dir == NULL) {
-      temp_dir = getenv("TMP");
-    }
-    if (temp_dir != NULL) {
-      path.Add(temp_dir);
-      if (temp_dir[strlen(temp_dir) - 1] != '/') {
-        path.Add("/");
-      }
-    } else {
-      path.Add("/tmp/");
-    }
-  }
-  path.Add(const_template);
+  path.Add(prefix);
   if (!path.Add("XXXXXX")) {
     // Pattern has overflowed.
     return NULL;
@@ -393,11 +397,7 @@
   if (result == NULL) {
     return NULL;
   }
-  int length = strlen(path.AsString());
-  result = static_cast<char*>(malloc(length + 1));
-  strncpy(result, path.AsString(), length);
-  result[length] = '\0';
-  return result;
+  return strdup(result);
 }
 
 
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index f5961b9..f3d0dab 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -5,8 +5,8 @@
 patch class _Directory {
   /* patch */ static _current() native "Directory_Current";
   /* patch */ static _setCurrent(path) native "Directory_SetCurrent";
-  /* patch */ static _createTemp(String template, bool system)
-      native "Directory_CreateTemp";
+  /* patch */ static _createTemp(String path) native "Directory_CreateTemp";
+  /* patch */ static String _systemTemp() native "Directory_SystemTemp";
   /* patch */ static int _exists(String path) native "Directory_Exists";
   /* patch */ static _create(String path) native "Directory_Create";
   /* patch */ static _deleteNative(String path, bool recursive)
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index c72f4ef..e3e390f 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -383,21 +383,23 @@
 }
 
 
-char* Directory::CreateTemp(const char* const_template, bool system) {
-  // Returns a new, unused directory name, modifying the contents of
-  // dir_template.  Creates this directory, with a default security
+char* Directory::SystemTemp() {
+  PathBuffer path;
+  path.Reset(GetTempPathW(MAX_PATH, path.AsStringW()) - 1);  // Remove \ at end.
+  return path.AsString();
+}
+
+
+char* Directory::CreateTemp(const char* prefix) {
+  // Returns a new, unused directory name, adding characters to the
+  // end of prefix.
+  // Creates this directory, with a default security
   // descriptor inherited from its parent directory.
   // The return value must be freed by the caller.
   PathBuffer path;
-  if (system) {
-    path.Reset(GetTempPathW(MAX_PATH, path.AsStringW()));
-    if (path.length() == 0) {
-      return NULL;
-    }
-  }
-  const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
-  path.AddW(system_template);
-  free(const_cast<wchar_t*>(system_template));
+  const wchar_t* system_prefix = StringUtils::Utf8ToWide(prefix);
+  path.AddW(system_prefix);
+  free(const_cast<wchar_t*>(system_prefix));
 
   // Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36.
   if (path.length() > MAX_PATH - 36) {
diff --git a/runtime/bin/io_service.h b/runtime/bin/io_service.h
index 8c1ba9f..d9e8c45 100644
--- a/runtime/bin/io_service.h
+++ b/runtime/bin/io_service.h
@@ -47,12 +47,11 @@
   V(Directory, Delete, 30)                                                     \
   V(Directory, Exists, 31)                                                     \
   V(Directory, CreateTemp, 32)                                                 \
-  V(Directory, CreateSystemTemp, 33)                                           \
-  V(Directory, ListStart, 34)                                                  \
-  V(Directory, ListNext, 35)                                                   \
-  V(Directory, ListStop, 36)                                                   \
-  V(Directory, Rename, 37)                                                     \
-  V(SSLFilter, ProcessFilter, 38)
+  V(Directory, ListStart, 33)                                                  \
+  V(Directory, ListNext, 34)                                                   \
+  V(Directory, ListStop, 35)                                                   \
+  V(Directory, Rename, 36)                                                     \
+  V(SSLFilter, ProcessFilter, 37)
 
 #define DECLARE_REQUEST(type, method, id)                                      \
   k##type##method##Request = id,
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 92e08ac..eae320d 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -630,6 +630,8 @@
   Dart_ExitScope();
   Dart_ShutdownIsolate();
 
+  Dart_Cleanup();
+
   return exit_code;
 }
 
@@ -799,8 +801,6 @@
     result = Dart_CreateScriptSnapshot(&buffer, &size);
     if (Dart_IsError(result)) {
       Log::PrintErr("%s\n", Dart_GetError(result));
-      Dart_ExitScope();
-      Dart_ShutdownIsolate();
       return DartErrorExit(result);
     }
 
@@ -875,6 +875,8 @@
   // Terminate process exit-code handler.
   Process::TerminateExitCodeHandler();
 
+  Dart_Cleanup();
+
   // Free copied argument strings if converted.
   if (argv_converted) {
     for (int i = 0; i < argc; i++) free(argv[i]);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 9f4969e..bcd3474 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -750,6 +750,13 @@
     Dart_FileCloseCallback file_close);
 
 /**
+ * Cleanup state in the VM before process termination.
+ *
+ * \return True if cleanup is successful.
+ */
+DART_EXPORT bool Dart_Cleanup();
+
+/**
  * Sets command line flags. Should be called before Dart_Initialize.
  *
  * \param argc The length of the arguments array.
@@ -1822,6 +1829,30 @@
                                            Dart_Handle* arguments);
 
 /**
+ * Invokes a Generative Constructor on an object that was previously
+ * allocated using Dart_Allocate.
+ *
+ * The 'target' parameter must be an object.
+ *
+ * This function ignores visibility (leading underscores in names).
+ *
+ * May generate an unhandled exception error.
+ *
+ * \param target An object.
+ * \param name The name of the constructor to invoke.
+ * \param number_of_arguments Size of the arguments array.
+ * \param arguments An array of arguments to the function.
+ *
+ * \return If the constructor is called and completes
+ *   successfully, then the object is returned. If an error
+ *   occurs during execution, then an error handle is returned.
+ */
+DART_EXPORT Dart_Handle Dart_InvokeConstructor(Dart_Handle object,
+                                               Dart_Handle name,
+                                               int number_of_arguments,
+                                               Dart_Handle* arguments);
+
+/**
  * Gets the value of a field.
  *
  * The 'container' parameter may be an object, type, or library.  If
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 89ddce5..fe9a15b 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -202,6 +202,10 @@
     IterableMixinWorkaround.sortList(this, compare);
   }
 
+  void shuffle() {
+    IterableMixinWorkaround.shuffleList(this);
+  }
+
   int indexOf(Object element, [int start = 0]) {
     return Arrays.indexOf(this, element, start, this.length);
   }
@@ -456,6 +460,11 @@
         "Cannot modify an immutable array");
   }
 
+  void shuffle() {
+    throw new UnsupportedError(
+        "Cannot modify an immutable array");
+  }
+
   String toString() {
     return IterableMixinWorkaround.toStringIterable(this, '[', ']');
   }
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index b1f1ccb..2a0ec88 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -336,6 +336,10 @@
     IterableMixinWorkaround.sortList(this, compare);
   }
 
+  void shuffle() {
+    IterableMixinWorkaround.shuffleList(this);
+  }
+
   String toString() {
     return IterableMixinWorkaround.toStringIterable(this, '[', ']');
   }
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 754aa5f..f6cb310 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1064,18 +1064,6 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(InstanceMirror_identityHash, 1) {
-  GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
-  ObjectStore* object_store = isolate->object_store();
-  const Class& cls = Class::Handle(isolate, object_store->object_class());
-  const Function& function =
-      Function::Handle(isolate, cls.LookupDynamicFunction(Symbols::hashCode()));
-  const Array& args = Array::Handle(isolate, Array::New(1));
-  args.SetAt(0, reflectee);
-  return DartEntry::InvokeFunction(function, args);
-}
-
-
 DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) {
   // Argument 0 is the mirror, which is unused by the native. It exists
   // because this native is an instance method in order to be polymorphic
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index e20aa88..858b2ee 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -302,21 +302,11 @@
   }
 
   int get hashCode {
-    // If the reflectee is a double or bignum, use the base hashCode to preserve
-    // the illusion that boxed numbers with the same value are identical. If the
-    // reflectee is a Smi, use the base hashCode because Object.hashCode does
-    // not work for non-heap objects. Otherwise, use Object.hashCode to maintain
-    // correctness even if a user-defined hashCode returns different values for
-    // successive invocations.
-    var h = _reflectee is num ? _reflectee.hashCode : _identityHash(_reflectee);
     // Avoid hash collisions with the reflectee. This constant is in Smi range
     // and happens to be the inner padding from RFC 2104.
-    return h ^ 0x36363636;
+    return identityHashCode(_reflectee) ^ 0x36363636;
   }
 
-  static _identityHash(reflectee)
-      native "InstanceMirror_identityHash";
-
   // Override to include the receiver in the arguments.
   InstanceMirror invoke(Symbol memberName,
                         List positionalArguments,
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 0f10690..9e2a114 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -407,7 +407,11 @@
   }
 
   void sort([int compare(num a, num b)]) {
-    return IterableMixinWorkaround.sortList(this, compare);
+    IterableMixinWorkaround.sortList(this, compare);
+  }
+
+  void shuffle() {
+    IterableMixinWorkaround.shuffleList(this);
   }
 
   int indexOf(element, [int start = 0]) {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 48844b2..cd51087 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -256,7 +256,6 @@
   V(Mirrors_makeLocalTypeMirror, 1)                                            \
   V(Mirrors_makeLocalMirrorSystem, 0)                                          \
   V(MirrorReference_equals, 2)                                                 \
-  V(InstanceMirror_identityHash, 1)                                            \
   V(InstanceMirror_invoke, 5)                                                  \
   V(InstanceMirror_invokeGetter, 3)                                            \
   V(InstanceMirror_invokeSetter, 4)                                            \
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index 1e8835a..4873371 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -50,6 +50,8 @@
     delete observers_[i];
   }
   free(observers_);
+  observers_length_ = 0;
+  observers_ = NULL;
 }
 
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index af17f5e..e81438f 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -74,7 +74,6 @@
 };
 
 
-// TODO(turnidge): We should add a corresponding Dart::Cleanup.
 const char* Dart::InitOnce(Dart_IsolateCreateCallback create,
                            Dart_IsolateInterruptCallback interrupt,
                            Dart_IsolateUnhandledExceptionCallback unhandled,
@@ -144,6 +143,37 @@
 }
 
 
+const char* Dart::Cleanup() {
+#if 0
+  // Ideally we should shutdown the VM isolate here, but the thread pool
+  // shutdown does not seem to ensure that all the threads have stopped
+  // execution before it terminates, this results in racing isolates.
+  if (vm_isolate_ == NULL) {
+    return "VM already terminated.";
+  }
+
+  ASSERT(Isolate::Current() == NULL);
+
+  delete thread_pool_;
+  thread_pool_ = NULL;
+
+  // Set the VM isolate as current isolate.
+  Isolate::SetCurrent(vm_isolate_);
+
+  // There is a planned and known asymmetry here: We exit one scope for the VM
+  // isolate to account for the scope that was entered in Dart_InitOnce.
+  Dart_ExitScope();
+
+  ShutdownIsolate();
+  vm_isolate_ = NULL;
+#endif
+
+  CodeObservers::DeleteAll();
+
+  return NULL;
+}
+
+
 Isolate* Dart::CreateIsolate(const char* name_prefix) {
   // Create a new isolate.
   Isolate* isolate = Isolate::Init(name_prefix);
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index d1c592a..edb18ad 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -28,6 +28,7 @@
       Dart_FileReadCallback file_read,
       Dart_FileWriteCallback file_write,
       Dart_FileCloseCallback file_close);
+  static const char* Cleanup();
 
   static Isolate* CreateIsolate(const char* name_prefix);
   static RawError* InitializeIsolate(const uint8_t* snapshot, void* data);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 680476e..44d8274 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -761,10 +761,23 @@
   return true;
 }
 
+
+DART_EXPORT bool Dart_Cleanup() {
+  CHECK_NO_ISOLATE(Isolate::Current());
+  const char* err_msg = Dart::Cleanup();
+  if (err_msg != NULL) {
+    OS::PrintErr("Dart_Cleanup: %s\n", err_msg);
+    return false;
+  }
+  return true;
+}
+
+
 DART_EXPORT bool Dart_SetVMFlags(int argc, const char** argv) {
   return Flags::ProcessCommandLineFlags(argc, argv);
 }
 
+
 DART_EXPORT bool Dart_IsVMFlagSet(const char* flag_name) {
   if (Flags::Lookup(flag_name) != NULL) {
     return true;
@@ -2974,6 +2987,115 @@
 }
 
 
+static Dart_Handle SetupArguments(Isolate* isolate,
+                                  int num_args,
+                                  Dart_Handle* arguments,
+                                  int extra_args,
+                                  Array* args) {
+  // Check for malformed arguments in the arguments list.
+  *args = Array::New(num_args + extra_args);
+  Object& arg = Object::Handle(isolate);
+  for (int i = 0; i < num_args; i++) {
+    arg = Api::UnwrapHandle(arguments[i]);
+    if (!arg.IsNull() && !arg.IsInstance()) {
+      *args = Array::null();
+      if (arg.IsError()) {
+        return Api::NewHandle(isolate, arg.raw());
+      } else {
+        return Api::NewError(
+            "%s expects arguments[%d] to be an Instance handle.",
+            "Dart_Invoke", i);
+      }
+    }
+    args->SetAt((i + extra_args), arg);
+  }
+  return Api::Success();
+}
+
+
+DART_EXPORT Dart_Handle Dart_InvokeConstructor(Dart_Handle object,
+                                               Dart_Handle name,
+                                               int number_of_arguments,
+                                               Dart_Handle* arguments) {
+  Isolate* isolate = Isolate::Current();
+  DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
+
+  if (number_of_arguments < 0) {
+    return Api::NewError(
+        "%s expects argument 'number_of_arguments' to be non-negative.",
+        CURRENT_FUNC);
+  }
+  const String& constructor_name = Api::UnwrapStringHandle(isolate, name);
+  if (constructor_name.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, name, String);
+  }
+  const Instance& instance = Api::UnwrapInstanceHandle(isolate, object);
+  if (instance.IsNull()) {
+    RETURN_TYPE_ERROR(isolate, object, Instance);
+  }
+
+  // Since we have allocated an object it would mean that all classes
+  // are finalized and hence it is not necessary to call
+  // Api::CheckIsolateState.
+  // TODO(asiva): How do we ensure that a constructor is not called more than
+  // once for the same object.
+
+  // Construct name of the constructor to invoke.
+  const Type& type_obj = Type::Handle(isolate, instance.GetType());
+  const Class& cls = Class::Handle(isolate, type_obj.type_class());
+  const String& class_name = String::Handle(isolate, cls.Name());
+  const Array& strings = Array::Handle(Array::New(3));
+  strings.SetAt(0, class_name);
+  strings.SetAt(1, Symbols::Dot());
+  strings.SetAt(2, constructor_name);
+  const String& dot_name = String::Handle(isolate, String::ConcatAll(strings));
+  const AbstractTypeArguments& type_arguments =
+    AbstractTypeArguments::Handle(isolate, type_obj.arguments());
+  const Function& constructor =
+    Function::Handle(isolate, cls.LookupFunctionAllowPrivate(dot_name));
+  const int extra_args = 2;
+  if (!constructor.IsNull() &&
+      constructor.IsConstructor() &&
+      constructor.AreValidArgumentCounts(number_of_arguments + extra_args,
+                                         0,
+                                         NULL)) {
+    // Create the argument list.
+    // Constructors get the uninitialized object and a constructor phase.
+    if (!type_arguments.IsNull()) {
+      // The type arguments will be null if the class has no type
+      // parameters, in which case the following call would fail
+      // because there is no slot reserved in the object for the
+      // type vector.
+      instance.SetTypeArguments(type_arguments);
+    }
+    Dart_Handle result;
+    Array& args = Array::Handle(isolate);
+    result = SetupArguments(isolate,
+                            number_of_arguments,
+                            arguments,
+                            extra_args,
+                            &args);
+    if (!::Dart_IsError(result)) {
+      args.SetAt(0, instance);
+      args.SetAt(1, Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll)));
+      const Object& retval = Object::Handle(
+          isolate,
+          DartEntry::InvokeFunction(constructor, args));
+      if (retval.IsError()) {
+        result = Api::NewHandle(isolate, retval.raw());
+      } else {
+        result = Api::NewHandle(isolate, instance.raw());
+      }
+    }
+    return result;
+  }
+  return Api::NewError(
+      "%s expects argument 'name' to be a valid constructor.",
+      CURRENT_FUNC);
+}
+
+
 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
                                     Dart_Handle name,
                                     int number_of_arguments,
@@ -2995,27 +3117,8 @@
   if (obj.IsError()) {
     return target;
   }
-
-  // Check for malformed arguments in the arguments list.
-  intptr_t num_receiver =
-      (obj.IsNull() || (obj.IsInstance() && !obj.IsType())) ? 1 : 0;
-  const Array& args =
-      Array::Handle(isolate, Array::New(number_of_arguments + num_receiver));
-  Object& arg = Object::Handle(isolate);
-  for (int i = 0; i < number_of_arguments; i++) {
-    arg = Api::UnwrapHandle(arguments[i]);
-    if (!arg.IsNull() && !arg.IsInstance()) {
-      if (arg.IsError()) {
-        return Api::NewHandle(isolate, arg.raw());
-      } else {
-        return Api::NewError(
-            "%s expects arguments[%d] to be an Instance handle.",
-            CURRENT_FUNC, i);
-      }
-    }
-    args.SetAt((i + num_receiver), arg);
-  }
-
+  Dart_Handle result;
+  Array& args = Array::Handle(isolate);
   if (obj.IsType()) {
     // Finalize all classes.
     Dart_Handle state = Api::CheckIsolateState(isolate);
@@ -3038,9 +3141,17 @@
                            cls_name.ToCString(),
                            function_name.ToCString());
     }
-    return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
-
+    // Setup args and check for malformed arguments in the arguments list.
+    result = SetupArguments(isolate, number_of_arguments, arguments, 0, &args);
+    if (!::Dart_IsError(result)) {
+      result = Api::NewHandle(isolate,
+                              DartEntry::InvokeFunction(function, args));
+    }
+    return result;
   } else if (obj.IsNull() || obj.IsInstance()) {
+    // Since we have allocated an object it would mean that all classes
+    // are finalized and hence it is not necessary to call
+    // Api::CheckIsolateState.
     Instance& instance = Instance::Handle(isolate);
     instance ^= obj.raw();
     ArgumentsDescriptor args_desc(
@@ -3048,18 +3159,33 @@
     const Function& function = Function::Handle(
         isolate,
         Resolver::ResolveDynamic(instance, function_name, args_desc));
-    args.SetAt(0, instance);
     if (function.IsNull()) {
-      const Array& args_descriptor =
+      // Setup args and check for malformed arguments in the arguments list.
+      result = SetupArguments(isolate,
+                              number_of_arguments,
+                              arguments,
+                              1,
+                              &args);
+      if (!::Dart_IsError(result)) {
+        args.SetAt(0, instance);
+        const Array& args_descriptor =
           Array::Handle(ArgumentsDescriptor::New(args.Length()));
-      return Api::NewHandle(isolate,
-                            DartEntry::InvokeNoSuchMethod(instance,
-                                                          function_name,
-                                                          args,
-                                                          args_descriptor));
+        result = Api::NewHandle(isolate,
+                                DartEntry::InvokeNoSuchMethod(instance,
+                                                              function_name,
+                                                              args,
+                                                              args_descriptor));
+      }
+      return result;
     }
-    return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
-
+    // Setup args and check for malformed arguments in the arguments list.
+    result = SetupArguments(isolate, number_of_arguments, arguments, 1, &args);
+    if (!::Dart_IsError(result)) {
+      args.SetAt(0, instance);
+      result = Api::NewHandle(isolate,
+                              DartEntry::InvokeFunction(function, args));
+    }
+    return result;
   } else if (obj.IsLibrary()) {
     // Check whether class finalization is needed.
     const Library& lib = Library::Cast(obj);
@@ -3089,8 +3215,13 @@
                            function_name.ToCString(),
                            error_message.ToCString());
     }
-    return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
-
+    // Setup args and check for malformed arguments in the arguments list.
+    result = SetupArguments(isolate, number_of_arguments, arguments, 0, &args);
+    if (!::Dart_IsError(result)) {
+      result = Api::NewHandle(isolate,
+                              DartEntry::InvokeFunction(function, args));
+    }
+    return result;
   } else {
     return Api::NewError(
         "%s expects argument 'target' to be an object, type, or library.",
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index aa860ea..53da807 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -3844,12 +3844,12 @@
   EXPECT_EQ(7, int_value);
 
   // Allocate without a constructor.
-  result = Dart_Allocate(type);
-  EXPECT_VALID(result);
+  Dart_Handle obj = Dart_Allocate(type);
+  EXPECT_VALID(obj);
   instanceof = false;
-  EXPECT_VALID(Dart_ObjectIsType(result, type, &instanceof));
+  EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
   EXPECT(instanceof);
-  foo = Dart_GetField(result, NewString("foo"));
+  foo = Dart_GetField(obj, NewString("foo"));
   EXPECT(Dart_IsNull(foo));
 
   // Invoke the unnamed constructor with an empty string.
@@ -3863,6 +3863,19 @@
   EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
   EXPECT_EQ(7, int_value);
 
+  // Allocate object and invoke the unnamed constructor with an empty string.
+  obj = Dart_Allocate(type);
+  EXPECT_VALID(obj);
+  instanceof = false;
+  EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
+  EXPECT(instanceof);
+  result = Dart_InvokeConstructor(obj, NewString(""), 0, NULL);
+  EXPECT_VALID(result);
+  int_value = 0;
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
+  EXPECT_EQ(7, int_value);
+
   // Invoke a named constructor.
   result = Dart_New(type, NewString("named"), 1, args);
   EXPECT_VALID(result);
@@ -3873,6 +3886,19 @@
   EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
   EXPECT_EQ(11, int_value);
 
+  // Allocate object and invoke a named constructor.
+  obj = Dart_Allocate(type);
+  EXPECT_VALID(obj);
+  instanceof = false;
+  EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
+  EXPECT(instanceof);
+  result = Dart_InvokeConstructor(obj, NewString("named"), 1, args);
+  EXPECT_VALID(result);
+  int_value = 0;
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
+  EXPECT_EQ(11, int_value);
+
   // Invoke a hidden named constructor.
   result = Dart_New(type, NewString("_hidden"), 1, args);
   EXPECT_VALID(result);
@@ -3883,6 +3909,28 @@
   EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
   EXPECT_EQ(-11, int_value);
 
+  // Allocate object and invoke a hidden named constructor.
+  obj = Dart_Allocate(type);
+  EXPECT_VALID(obj);
+  instanceof = false;
+  EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
+  EXPECT(instanceof);
+  result = Dart_InvokeConstructor(obj, NewString("_hidden"), 1, args);
+  EXPECT_VALID(result);
+  int_value = 0;
+  foo = Dart_GetField(result, NewString("foo"));
+  EXPECT_VALID(Dart_IntegerToInt64(foo, &int_value));
+  EXPECT_EQ(-11, int_value);
+
+  // Allocate object and Invoke a constructor which throws an exception.
+  obj = Dart_Allocate(type);
+  EXPECT_VALID(obj);
+  instanceof = false;
+  EXPECT_VALID(Dart_ObjectIsType(obj, type, &instanceof));
+  EXPECT(instanceof);
+  result = Dart_InvokeConstructor(obj, NewString("exception"), 1, args);
+  EXPECT_ERROR(result, "ConstructorDeath");
+
   // Invoke a factory constructor.
   result = Dart_New(type, NewString("multiply"), 1, args);
   EXPECT_VALID(result);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 69199f0..4cb67db 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -970,13 +970,26 @@
                               temp_index(),
                               node->left()->token_pos());
     node->left()->Visit(&for_left);
-    EffectGraphVisitor for_right(owner(), temp_index());
-    node->right()->Visit(&for_right);
     EffectGraphVisitor empty(owner(), temp_index());
-    if (node->kind() == Token::kAND) {
-      Join(for_left, for_right, empty);
+    if (FLAG_enable_type_checks) {
+      ValueGraphVisitor for_right(owner(), temp_index());
+      node->right()->Visit(&for_right);
+      Value* right_value = for_right.value();
+      for_right.Do(new AssertBooleanInstr(node->right()->token_pos(),
+                                          right_value));
+      if (node->kind() == Token::kAND) {
+        Join(for_left, for_right, empty);
+      } else {
+        Join(for_left, empty, for_right);
+      }
     } else {
-      Join(for_left, empty, for_right);
+      EffectGraphVisitor for_right(owner(), temp_index());
+      node->right()->Visit(&for_right);
+      if (node->kind() == Token::kAND) {
+        Join(for_left, for_right, empty);
+      } else {
+        Join(for_left, empty, for_right);
+      }
     }
     return;
   }
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 83a631b..2a1a485 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -1163,7 +1163,8 @@
   Definition* last;
   if (optimizer.TryInlineRecognizedMethod(target,
                                           call_,
-                                          call_->ic_data(),
+                                          call_->instance_call()->token_pos(),
+                                          *call_->instance_call()->ic_data(),
                                           &entry, &last)) {
     // Create a graph fragment.
     InlineExitCollector* exit_collector =
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index b9f6bd4..f2d9c90 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -687,21 +687,6 @@
 }
 
 
-static intptr_t ReceiverClassId(InstanceCallInstr* call) {
-  if (!call->HasICData()) return kIllegalCid;
-
-  const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
-
-  if (ic_data.NumberOfChecks() != 1) return kIllegalCid;
-  ASSERT(ic_data.HasOneTarget());
-
-  Function& target = Function::Handle();
-  intptr_t class_id;
-  ic_data.GetOneClassCheckAt(0, &class_id, &target);
-  return class_id;
-}
-
-
 void FlowGraphOptimizer::AddCheckSmi(Definition* to_check,
                                      intptr_t deopt_id,
                                      Environment* deopt_environment,
@@ -715,19 +700,24 @@
 }
 
 
+Instruction* FlowGraphOptimizer::GetCheckClass(Definition* to_check,
+                                               const ICData& unary_checks,
+                                               intptr_t deopt_id) {
+  if ((unary_checks.NumberOfChecks() == 1) &&
+      (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
+    return new CheckSmiInstr(new Value(to_check), deopt_id);
+  }
+  return new CheckClassInstr(new Value(to_check), deopt_id, unary_checks);
+}
+
+
 void FlowGraphOptimizer::AddCheckClass(Definition* to_check,
                                        const ICData& unary_checks,
                                        intptr_t deopt_id,
                                        Environment* deopt_environment,
                                        Instruction* insert_before) {
   // Type propagation has not run yet, we cannot eliminate the check.
-  Instruction* check = NULL;
-  if ((unary_checks.NumberOfChecks() == 1) &&
-      (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
-    check = new CheckSmiInstr(new Value(to_check), deopt_id);
-  } else {
-    check = new CheckClassInstr(new Value(to_check), deopt_id, unary_checks);
-  }
+  Instruction* check = GetCheckClass(to_check, unary_checks, deopt_id);
   InsertBefore(insert_before, check, deopt_environment, Definition::kEffect);
 }
 
@@ -741,75 +731,19 @@
 }
 
 
-static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) {
-  ASSERT(ic_data.num_args_tested() > arg_n);
-  if (ic_data.NumberOfChecks() == 0) return false;
-  GrowableArray<intptr_t> class_ids;
-  Function& target = Function::Handle();
-  const intptr_t len = ic_data.NumberOfChecks();
-  for (intptr_t i = 0; i < len; i++) {
-    ic_data.GetCheckAt(i, &class_ids, &target);
-    if (class_ids[arg_n] != kSmiCid) return false;
+static bool ArgIsAlways(intptr_t cid,
+                        const ICData& ic_data,
+                        intptr_t arg_number) {
+  ASSERT(ic_data.num_args_tested() > arg_number);
+  const intptr_t num_checks = ic_data.NumberOfChecks();
+  if (num_checks == 0) return false;
+  for (intptr_t i = 0; i < num_checks; i++) {
+    if (ic_data.GetClassIdAt(i, arg_number) != cid) return false;
   }
   return true;
 }
 
 
-// Returns array classid to load from, array and index value
-
-intptr_t FlowGraphOptimizer::PrepareIndexedOp(InstanceCallInstr* call,
-                                              intptr_t class_id,
-                                              Definition** array,
-                                              Definition** index) {
-  // Insert class check and index smi checks and attach a copy of the
-  // original environment because the operation can still deoptimize.
-  AddReceiverCheck(call);
-  InsertBefore(call,
-               new CheckSmiInstr(new Value(*index), call->deopt_id()),
-               call->env(),
-               Definition::kEffect);
-
-  // Insert array length load and bounds check.
-  const bool is_immutable =
-      CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
-  LoadFieldInstr* length =
-      new LoadFieldInstr(new Value(*array),
-                         CheckArrayBoundInstr::LengthOffsetFor(class_id),
-                         Type::ZoneHandle(Type::SmiType()),
-                         is_immutable);
-  length->set_result_cid(kSmiCid);
-  length->set_recognized_kind(
-      LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
-  InsertBefore(call, length, NULL, Definition::kValue);
-  InsertBefore(call,
-               new CheckArrayBoundInstr(new Value(length),
-                                        new Value(*index),
-                                        call->deopt_id()),
-               call->env(),
-               Definition::kEffect);
-
-  if (class_id == kGrowableObjectArrayCid) {
-    // Insert data elements load.
-    LoadFieldInstr* elements =
-        new LoadFieldInstr(new Value(*array),
-                           GrowableObjectArray::data_offset(),
-                           Type::ZoneHandle(Type::DynamicType()));
-    elements->set_result_cid(kArrayCid);
-    InsertBefore(call, elements, NULL, Definition::kValue);
-    *array = elements;
-    return kArrayCid;
-  }
-  if (RawObject::IsExternalTypedDataClassId(class_id)) {
-    LoadUntaggedInstr* elements =
-        new LoadUntaggedInstr(new Value(*array),
-                              ExternalTypedData::data_offset());
-    InsertBefore(call, elements, NULL, Definition::kValue);
-    *array = elements;
-  }
-  return class_id;
-}
-
-
 static bool CanUnboxInt32() {
   // Int32/Uint32 can be unboxed if it fits into a smi or the platform
   // supports unboxed mints.
@@ -817,97 +751,144 @@
 }
 
 
-bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
-  const intptr_t class_id = ReceiverClassId(call);
-  ICData& value_check = ICData::ZoneHandle();
-  switch (class_id) {
-    case kArrayCid:
-    case kGrowableObjectArrayCid:
-      if (ArgIsAlwaysSmi(*call->ic_data(), 2)) {
-        value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
-      }
-      break;
-    case kTypedDataInt8ArrayCid:
-    case kTypedDataUint8ArrayCid:
-    case kTypedDataUint8ClampedArrayCid:
-    case kExternalTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ClampedArrayCid:
-    case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid:
-      // Check that value is always smi.
-      value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
-      if ((value_check.NumberOfChecks() != 1) ||
-          (value_check.GetReceiverClassIdAt(0) != kSmiCid)) {
-        return false;
-      }
-      break;
-    case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid: {
-      if (!CanUnboxInt32()) return false;
-      // Check that value is always smi or mint, if the platform has unboxed
-      // mints (ia32 with at least SSE 4.1).
-      value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
-      for (intptr_t i = 0; i < value_check.NumberOfChecks(); i++) {
-        intptr_t cid = value_check.GetReceiverClassIdAt(i);
-        if (FlowGraphCompiler::SupportsUnboxedMints()) {
-          if ((cid != kSmiCid) && (cid != kMintCid)) {
-            return false;
-          }
-        } else if (cid != kSmiCid) {
-          return false;
-        }
-      }
-      break;
-    }
-    case kTypedDataFloat32ArrayCid:
-    case kTypedDataFloat64ArrayCid: {
-      // Check that value is always double.
-      value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
-      if ((value_check.NumberOfChecks() != 1) ||
-          (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) {
-        return false;
-      }
-      break;
-    }
-    case kTypedDataFloat32x4ArrayCid: {
-      if (!ShouldInlineSimd()) {
-        return false;
-      }
-      // Check that value is always a Float32x4.
-      value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
-      if ((value_check.NumberOfChecks() != 1) ||
-          (value_check.GetReceiverClassIdAt(0) != kFloat32x4Cid)) {
-          return false;
-      }
-    }
-    break;
-    default:
-      // TODO(fschneider): Add support for other array types.
-      return false;
-  }
+static intptr_t MethodKindToCid(MethodRecognizer::Kind kind) {
+  switch (kind) {
+    case MethodRecognizer::kImmutableArrayGetIndexed:
+      return kImmutableArrayCid;
 
-  BuildStoreIndexed(call, value_check, class_id);
+    case MethodRecognizer::kObjectArrayGetIndexed:
+    case MethodRecognizer::kObjectArraySetIndexed:
+      return kArrayCid;
+
+    case MethodRecognizer::kGrowableArrayGetIndexed:
+    case MethodRecognizer::kGrowableArraySetIndexed:
+      return kGrowableObjectArrayCid;
+
+    case MethodRecognizer::kFloat32ArrayGetIndexed:
+    case MethodRecognizer::kFloat32ArraySetIndexed:
+      return kTypedDataFloat32ArrayCid;
+
+    case MethodRecognizer::kFloat64ArrayGetIndexed:
+    case MethodRecognizer::kFloat64ArraySetIndexed:
+      return kTypedDataFloat64ArrayCid;
+
+    case MethodRecognizer::kInt8ArrayGetIndexed:
+    case MethodRecognizer::kInt8ArraySetIndexed:
+      return kTypedDataInt8ArrayCid;
+
+    case MethodRecognizer::kUint8ArrayGetIndexed:
+    case MethodRecognizer::kUint8ArraySetIndexed:
+      return kTypedDataUint8ArrayCid;
+
+    case MethodRecognizer::kUint8ClampedArrayGetIndexed:
+    case MethodRecognizer::kUint8ClampedArraySetIndexed:
+      return kTypedDataUint8ClampedArrayCid;
+
+    case MethodRecognizer::kExternalUint8ArrayGetIndexed:
+    case MethodRecognizer::kExternalUint8ArraySetIndexed:
+      return kExternalTypedDataUint8ArrayCid;
+
+    case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
+    case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
+      return kExternalTypedDataUint8ClampedArrayCid;
+
+    case MethodRecognizer::kInt16ArrayGetIndexed:
+    case MethodRecognizer::kInt16ArraySetIndexed:
+      return kTypedDataInt16ArrayCid;
+
+    case MethodRecognizer::kUint16ArrayGetIndexed:
+    case MethodRecognizer::kUint16ArraySetIndexed:
+      return kTypedDataUint16ArrayCid;
+
+    case MethodRecognizer::kInt32ArrayGetIndexed:
+    case MethodRecognizer::kInt32ArraySetIndexed:
+      return kTypedDataInt32ArrayCid;
+
+    case MethodRecognizer::kUint32ArrayGetIndexed:
+    case MethodRecognizer::kUint32ArraySetIndexed:
+      return kTypedDataUint32ArrayCid;
+
+    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+    case MethodRecognizer::kFloat32x4ArraySetIndexed:
+      return kTypedDataFloat32x4ArrayCid;
+
+    default:
+      break;
+  }
+  return kIllegalCid;
+}
+
+
+bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
+  // Check for monomorphic IC data.
+  if (!call->HasICData()) return false;
+  const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
+  if (ic_data.NumberOfChecks() != 1) return false;
+  ASSERT(ic_data.HasOneTarget());
+
+  const Function& target = Function::Handle(ic_data.GetTargetAt(0));
+  TargetEntryInstr* entry;
+  Definition* last;
+  if (!TryInlineRecognizedMethod(target,
+                                 call,
+                                 call->token_pos(),
+                                 *call->ic_data(),
+                                 &entry, &last)) {
+    return false;
+  }
+  // Insert receiver class check.
+  AddReceiverCheck(call);
+  // Remove the original push arguments.
+  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+    PushArgumentInstr* push = call->PushArgumentAt(i);
+    push->ReplaceUsesWith(push->value()->definition());
+    push->RemoveFromGraph();
+  }
+  // Replace all uses of this definition with the result.
+  call->ReplaceUsesWith(last);
+  // Finally insert the sequence other definition in place of this one in the
+  // graph.
+  call->previous()->LinkTo(entry->next());
+  entry->UnuseAllInputs();  // Entry block is not in the graph.
+  last->LinkTo(call);
+  // Remove through the iterator.
+  ASSERT(current_iterator()->Current() == call);
+  current_iterator()->RemoveCurrentFromGraph();
+  call->set_previous(NULL);
+  call->set_next(NULL);
   return true;
 }
 
 
-void FlowGraphOptimizer::BuildStoreIndexed(InstanceCallInstr* call,
-                                           const ICData& value_check,
-                                           intptr_t class_id) {
+bool FlowGraphOptimizer::InlineSetIndexed(
+    MethodRecognizer::Kind kind,
+    const Function& target,
+    Instruction* call,
+    intptr_t token_pos,
+    const ICData* ic_data,
+    const ICData& value_check,
+    TargetEntryInstr** entry,
+    Definition** last) {
+  intptr_t array_cid = MethodKindToCid(kind);
+  ASSERT(array_cid != kIllegalCid);
+
   Definition* array = call->ArgumentAt(0);
   Definition* index = call->ArgumentAt(1);
   Definition* stored_value = call->ArgumentAt(2);
+
+  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
+                                call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(call);
+  Instruction* cursor = *entry;
   if (FLAG_enable_type_checks) {
     // Only type check for the value. A type check for the index is not
     // needed here because we insert a deoptimizing smi-check for the case
     // the index is not a smi.
-    const Function& target =
-        Function::ZoneHandle(call->ic_data()->GetTargetAt(0));
     const AbstractType& value_type =
         AbstractType::ZoneHandle(target.ParameterTypeAt(2));
     Definition* instantiator = NULL;
     Definition* type_args = NULL;
-    switch (class_id) {
+    switch (array_cid) {
       case kArrayCid:
       case kGrowableObjectArrayCid: {
         const Class& instantiator_class = Class::Handle(target.Owner());
@@ -917,7 +898,11 @@
             new LoadFieldInstr(new Value(array),
                                type_arguments_field_offset,
                                Type::ZoneHandle());  // No type.
-        InsertBefore(call, load_type_args, NULL, Definition::kValue);
+        cursor = flow_graph()->AppendTo(cursor,
+                                        load_type_args,
+                                        NULL,
+                                        Definition::kValue);
+
         instantiator = array;
         type_args = load_type_args;
         break;
@@ -936,15 +921,15 @@
       case kTypedDataFloat32ArrayCid:
       case kTypedDataFloat64ArrayCid: {
         type_args = instantiator = flow_graph_->constant_null();
-        ASSERT((class_id != kTypedDataFloat32ArrayCid &&
-                class_id != kTypedDataFloat64ArrayCid) ||
+        ASSERT((array_cid != kTypedDataFloat32ArrayCid &&
+                array_cid != kTypedDataFloat64ArrayCid) ||
                value_type.IsDoubleType());
         ASSERT(value_type.IsInstantiated());
         break;
       }
       case kTypedDataFloat32x4ArrayCid: {
         type_args = instantiator = flow_graph_->constant_null();
-        ASSERT((class_id != kTypedDataFloat32x4ArrayCid) ||
+        ASSERT((array_cid != kTypedDataFloat32x4ArrayCid) ||
                value_type.IsFloat32x4Type());
         ASSERT(value_type.IsInstantiated());
         break;
@@ -954,7 +939,7 @@
         UNREACHABLE();
     }
     AssertAssignableInstr* assert_value =
-        new AssertAssignableInstr(call->token_pos(),
+        new AssertAssignableInstr(token_pos,
                                   new Value(stored_value),
                                   new Value(instantiator),
                                   new Value(type_args),
@@ -964,10 +949,18 @@
     // must have a deoptimization id that is valid for lookup in the unoptimized
     // code.
     assert_value->deopt_id_ = call->deopt_id();
-    InsertBefore(call, assert_value, call->env(), Definition::kValue);
+    cursor = flow_graph()->AppendTo(cursor,
+                                    assert_value,
+                                    call->env(),
+                                    Definition::kValue);
   }
 
-  intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index);
+  array_cid = PrepareInlineIndexedOp(call,
+                                     array_cid,
+                                     &array,
+                                     index,
+                                     &cursor);
+
   // Check if store barrier is needed. Byte arrays don't need a store barrier.
   StoreBarrierType needs_store_barrier =
       (RawObject::IsTypedDataClassId(array_cid) ||
@@ -978,83 +971,40 @@
     // No store barrier needed because checked value is a smi, an unboxed mint,
     // an unboxed double, an unboxed Float32x4, or unboxed Uint32x4.
     needs_store_barrier = kNoStoreBarrier;
-    AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(),
-                  call);
+    Instruction* check =
+        GetCheckClass(stored_value, value_check, call->deopt_id());
+    cursor = flow_graph()->AppendTo(cursor,
+                                    check,
+                                    call->env(),
+                                    Definition::kEffect);
   }
 
   intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
-  Definition* array_op = new StoreIndexedInstr(new Value(array),
-                                               new Value(index),
-                                               new Value(stored_value),
-                                               needs_store_barrier,
-                                               index_scale,
-                                               array_cid,
-                                               call->deopt_id());
-  ReplaceCall(call, array_op);
-}
-
-
-static intptr_t MethodKindToCid(MethodRecognizer::Kind kind) {
-  switch (kind) {
-    case MethodRecognizer::kImmutableArrayGetIndexed:
-      return kImmutableArrayCid;
-
-    case MethodRecognizer::kObjectArrayGetIndexed:
-      return kArrayCid;
-
-    case MethodRecognizer::kGrowableArrayGetIndexed:
-      return kGrowableObjectArrayCid;
-
-    case MethodRecognizer::kFloat32ArrayGetIndexed:
-      return kTypedDataFloat32ArrayCid;
-
-    case MethodRecognizer::kFloat64ArrayGetIndexed:
-      return kTypedDataFloat64ArrayCid;
-
-    case MethodRecognizer::kInt8ArrayGetIndexed:
-      return kTypedDataInt8ArrayCid;
-
-    case MethodRecognizer::kUint8ArrayGetIndexed:
-      return kTypedDataUint8ArrayCid;
-
-    case MethodRecognizer::kUint8ClampedArrayGetIndexed:
-      return kTypedDataUint8ClampedArrayCid;
-
-    case MethodRecognizer::kExternalUint8ArrayGetIndexed:
-      return kExternalTypedDataUint8ArrayCid;
-
-    case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
-      return kExternalTypedDataUint8ClampedArrayCid;
-
-    case MethodRecognizer::kInt16ArrayGetIndexed:
-      return kTypedDataInt16ArrayCid;
-
-    case MethodRecognizer::kUint16ArrayGetIndexed:
-      return kTypedDataUint16ArrayCid;
-
-    case MethodRecognizer::kInt32ArrayGetIndexed:
-      return kTypedDataInt32ArrayCid;
-
-    case MethodRecognizer::kUint32ArrayGetIndexed:
-      return kTypedDataUint32ArrayCid;
-
-    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
-      return kTypedDataFloat32x4ArrayCid;
-
-    default:
-      break;
-  }
-  return kIllegalCid;
+  *last = new StoreIndexedInstr(new Value(array),
+                                new Value(index),
+                                new Value(stored_value),
+                                needs_store_barrier,
+                                index_scale,
+                                array_cid,
+                                call->deopt_id());
+  flow_graph()->AppendTo(cursor,
+                         *last,
+                         call->env(),
+                         Definition::kEffect);
+  return true;
 }
 
 
 bool FlowGraphOptimizer::TryInlineRecognizedMethod(const Function& target,
                                                    Instruction* call,
+                                                   intptr_t token_pos,
                                                    const ICData& ic_data,
                                                    TargetEntryInstr** entry,
                                                    Definition** last) {
+  ICData& value_check = ICData::ZoneHandle();
   MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target);
   switch (kind) {
+    // Recognized [] operators.
     case MethodRecognizer::kImmutableArrayGetIndexed:
     case MethodRecognizer::kObjectArrayGetIndexed:
     case MethodRecognizer::kGrowableArrayGetIndexed:
@@ -1067,91 +1017,152 @@
     case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
     case MethodRecognizer::kInt16ArrayGetIndexed:
     case MethodRecognizer::kUint16ArrayGetIndexed:
-      return TryInlineGetIndexed(kind, call, ic_data, entry, last);
+      return InlineGetIndexed(kind, call, ic_data, entry, last);
     case MethodRecognizer::kFloat32x4ArrayGetIndexed:
       if (!ShouldInlineSimd()) return false;
-      return TryInlineGetIndexed(kind, call, ic_data, entry, last);
+      return InlineGetIndexed(kind, call, ic_data, entry, last);
     case MethodRecognizer::kInt32ArrayGetIndexed:
     case MethodRecognizer::kUint32ArrayGetIndexed:
       if (!CanUnboxInt32()) return false;
-      return TryInlineGetIndexed(kind, call, ic_data, entry, last);
+      return InlineGetIndexed(kind, call, ic_data, entry, last);
+
+    // Recognized []= operators.
+    case MethodRecognizer::kObjectArraySetIndexed:
+    case MethodRecognizer::kGrowableArraySetIndexed:
+      if (ArgIsAlways(kSmiCid, ic_data, 2)) {
+        value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      }
+      return InlineSetIndexed(kind, target, call, token_pos,
+                              &ic_data, value_check, entry, last);
+    case MethodRecognizer::kInt8ArraySetIndexed:
+    case MethodRecognizer::kUint8ArraySetIndexed:
+    case MethodRecognizer::kUint8ClampedArraySetIndexed:
+    case MethodRecognizer::kExternalUint8ArraySetIndexed:
+    case MethodRecognizer::kExternalUint8ClampedArraySetIndexed:
+    case MethodRecognizer::kInt16ArraySetIndexed:
+    case MethodRecognizer::kUint16ArraySetIndexed:
+      if (!ArgIsAlways(kSmiCid, ic_data, 2)) return false;
+      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      return InlineSetIndexed(kind, target, call, token_pos,
+                              &ic_data, value_check, entry, last);
+    case MethodRecognizer::kInt32ArraySetIndexed:
+    case MethodRecognizer::kUint32ArraySetIndexed:
+      if (!CanUnboxInt32()) return false;
+      // Check that value is always smi or mint, if the platform has unboxed
+      // mints (ia32 with at least SSE 4.1).
+      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      if (FlowGraphCompiler::SupportsUnboxedMints()) {
+        if (!HasOnlySmiOrMint(value_check)) {
+          return false;
+        }
+      } else if (!HasOnlyOneSmi(value_check)) {
+        return false;
+      }
+      return InlineSetIndexed(kind, target, call, token_pos,
+                              &ic_data, value_check, entry, last);
+    case MethodRecognizer::kFloat32ArraySetIndexed:
+    case MethodRecognizer::kFloat64ArraySetIndexed:
+      // Check that value is always double.
+      if (!ArgIsAlways(kDoubleCid, ic_data, 2)) return false;
+      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      return InlineSetIndexed(kind, target, call, token_pos,
+                              &ic_data, value_check, entry, last);
+    case MethodRecognizer::kFloat32x4ArraySetIndexed:
+      if (!ShouldInlineSimd()) return false;
+      // Check that value is always a Float32x4.
+      if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) return false;
+      value_check = ic_data.AsUnaryClassChecksForArgNr(2);
+      return InlineSetIndexed(kind, target, call, token_pos,
+                              &ic_data, value_check, entry, last);
     default:
       return false;
   }
 }
 
 
-bool FlowGraphOptimizer::TryInlineGetIndexed(MethodRecognizer::Kind kind,
-                                             Instruction* call,
-                                             const ICData& ic_data,
-                                             TargetEntryInstr** entry,
-                                             Definition** last) {
-  intptr_t array_cid = MethodKindToCid(kind);
-  ASSERT(array_cid != kIllegalCid);
-
-  // Insert index smi checks and attach a copy of the
-  // original environment because the operation can still deoptimize.
-  Definition* array = call->ArgumentAt(0);
-  Definition* index = call->ArgumentAt(1);
-  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
-                                call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(call);
-
-  Instruction* cursor = *entry;
-  cursor = flow_graph()->AppendTo(cursor,
-                                  new CheckSmiInstr(new Value(index),
-                                                    call->deopt_id()),
-                                  call->env(),
-                                  Definition::kEffect);
+intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call,
+                                                    intptr_t array_cid,
+                                                    Definition** array,
+                                                    Definition* index,
+                                                    Instruction** cursor) {
+  // Insert index smi check.
+  *cursor = flow_graph()->AppendTo(*cursor,
+                                   new CheckSmiInstr(new Value(index),
+                                                     call->deopt_id()),
+                                   call->env(),
+                                   Definition::kEffect);
 
   // Insert array length load and bounds check.
   const bool is_immutable =
       CheckArrayBoundInstr::IsFixedLengthArrayType(array_cid);
   LoadFieldInstr* length =
-      new LoadFieldInstr(new Value(array),
+      new LoadFieldInstr(new Value(*array),
                          CheckArrayBoundInstr::LengthOffsetFor(array_cid),
                          Type::ZoneHandle(Type::SmiType()),
                          is_immutable);
   length->set_result_cid(kSmiCid);
   length->set_recognized_kind(
       LoadFieldInstr::RecognizedKindFromArrayCid(array_cid));
-  cursor = flow_graph()->AppendTo(cursor,
-                                  length,
-                                  NULL,
-                                  Definition::kValue);
+  *cursor = flow_graph()->AppendTo(*cursor,
+                                   length,
+                                   NULL,
+                                   Definition::kValue);
 
-  cursor = flow_graph()->AppendTo(cursor,
-                                  new CheckArrayBoundInstr(
-                                      new Value(length),
-                                      new Value(index),
-                                      call->deopt_id()),
-                                  call->env(),
-                                  Definition::kEffect);
+  *cursor = flow_graph()->AppendTo(*cursor,
+                                   new CheckArrayBoundInstr(
+                                       new Value(length),
+                                       new Value(index),
+                                       call->deopt_id()),
+                                   call->env(),
+                                   Definition::kEffect);
 
   if (array_cid == kGrowableObjectArrayCid) {
     // Insert data elements load.
     LoadFieldInstr* elements =
-        new LoadFieldInstr(new Value(array),
+        new LoadFieldInstr(new Value(*array),
                            GrowableObjectArray::data_offset(),
                            Type::ZoneHandle(Type::DynamicType()));
     elements->set_result_cid(kArrayCid);
-    cursor = flow_graph()->AppendTo(cursor,
-                                    elements,
-                                    NULL,
-                                    Definition::kValue);
+    *cursor = flow_graph()->AppendTo(*cursor,
+                                     elements,
+                                     NULL,
+                                     Definition::kValue);
     // Load from the data from backing store which is a fixed-length array.
-    array = elements;
+    *array = elements;
     array_cid = kArrayCid;
   } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
     LoadUntaggedInstr* elements =
-        new LoadUntaggedInstr(new Value(array),
+        new LoadUntaggedInstr(new Value(*array),
                               ExternalTypedData::data_offset());
-    cursor = flow_graph()->AppendTo(cursor,
-                                    elements,
-                                    NULL,
-                                    Definition::kValue);
-    array = elements;
+    *cursor = flow_graph()->AppendTo(*cursor,
+                                     elements,
+                                     NULL,
+                                     Definition::kValue);
+    *array = elements;
   }
+  return array_cid;
+}
+
+bool FlowGraphOptimizer::InlineGetIndexed(MethodRecognizer::Kind kind,
+                                          Instruction* call,
+                                          const ICData& ic_data,
+                                          TargetEntryInstr** entry,
+                                          Definition** last) {
+  intptr_t array_cid = MethodKindToCid(kind);
+  ASSERT(array_cid != kIllegalCid);
+
+  Definition* array = call->ArgumentAt(0);
+  Definition* index = call->ArgumentAt(1);
+  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
+                                call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(call);
+  Instruction* cursor = *entry;
+
+  array_cid = PrepareInlineIndexedOp(call,
+                                     array_cid,
+                                     &array,
+                                     index,
+                                     &cursor);
 
   intptr_t deopt_id = Isolate::kNoDeoptId;
   if ((array_cid == kTypedDataInt32ArrayCid) ||
@@ -1189,6 +1200,7 @@
   Definition* last;
   if (!TryInlineRecognizedMethod(target,
                                  call,
+                                 call->token_pos(),
                                  *call->ic_data(),
                                  &entry, &last)) {
     return false;
@@ -2963,7 +2975,7 @@
     AddReceiverCheck(instr);
   }
   StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
-  if (ArgIsAlwaysSmi(*instr->ic_data(), 1)) {
+  if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) {
     InsertBefore(instr,
                  new CheckSmiInstr(new Value(instr->ArgumentAt(1)),
                                    instr->deopt_id()),
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 1879186..ad3ab68 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -46,6 +46,7 @@
 
   bool TryInlineRecognizedMethod(const Function& target,
                                  Instruction* call,
+                                 intptr_t token_pos,
                                  const ICData& ic_data,
                                  TargetEntryInstr** entry,
                                  Definition** last);
@@ -72,20 +73,27 @@
 
   void SpecializePolymorphicInstanceCall(PolymorphicInstanceCallInstr* call);
 
-  intptr_t PrepareIndexedOp(InstanceCallInstr* call,
-                            intptr_t class_id,
-                            Definition** array,
-                            Definition** index);
   bool TryReplaceWithStoreIndexed(InstanceCallInstr* call);
-  void BuildStoreIndexed(InstanceCallInstr* call,
-                         const ICData& value_check,
-                         intptr_t class_id);
+  bool InlineSetIndexed(MethodRecognizer::Kind kind,
+                        const Function& target,
+                        Instruction* call,
+                        intptr_t token_pos,
+                        const ICData* ic_data,
+                        const ICData& value_check,
+                        TargetEntryInstr** entry,
+                        Definition** last);
   bool TryReplaceWithLoadIndexed(InstanceCallInstr* call);
-  bool TryInlineGetIndexed(MethodRecognizer::Kind kind,
-                           Instruction* call,
-                           const ICData& ic_data,
-                           TargetEntryInstr** entry,
-                           Definition** last);
+  bool InlineGetIndexed(MethodRecognizer::Kind kind,
+                        Instruction* call,
+                        const ICData& ic_data,
+                        TargetEntryInstr** entry,
+                        Definition** last);
+  intptr_t PrepareInlineIndexedOp(Instruction* call,
+                                  intptr_t array_cid,
+                                  Definition** array,
+                                  Definition* index,
+                                  Instruction** cursor);
+
 
   bool TryReplaceWithBinaryOp(InstanceCallInstr* call, Token::Kind op_kind);
   bool TryReplaceWithUnaryOp(InstanceCallInstr* call, Token::Kind op_kind);
@@ -130,6 +138,9 @@
                      intptr_t deopt_id,
                      Environment* deopt_environment,
                      Instruction* insert_before);
+  Instruction* GetCheckClass(Definition* to_check,
+                             const ICData& unary_checks,
+                             intptr_t deopt_id);
 
   // Insert a Smi check if needed.
   void AddCheckSmi(Definition* to_check,
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 50c4930..a75ba71 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1429,7 +1429,16 @@
         TypeArguments::Cast(constant_type_args->value());
     const AbstractType& new_dst_type = AbstractType::Handle(
         dst_type().InstantiateFrom(instantiator_type_args, NULL));
+    // If dst_type is instantiated to dynamic or Object, skip the test.
+    if (!new_dst_type.IsMalformed() && !new_dst_type.IsMalbounded() &&
+        (new_dst_type.IsDynamicType() || new_dst_type.IsObjectType())) {
+      return value()->definition();
+    }
     set_dst_type(AbstractType::ZoneHandle(new_dst_type.Canonicalize()));
+    if (FLAG_eliminate_type_checks &&
+        value()->Type()->IsAssignableTo(dst_type())) {
+      return value()->definition();
+    }
     ConstantInstr* null_constant = flow_graph->constant_null();
     instantiator_type_arguments()->BindTo(null_constant);
   }
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 35ca39c..e7cf253 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -136,21 +136,36 @@
   V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 1714792414)                       \
   V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1516924162)                       \
   V(_List, [], ObjectArrayGetIndexed, 1079829188)                              \
+  V(_List, []=, ObjectArraySetIndexed, 748954698)                              \
   V(_ImmutableList, [], ImmutableArrayGetIndexed, 25983597)                    \
   V(_GrowableList, [], GrowableArrayGetIndexed, 1686777561)                    \
+  V(_GrowableList, []=, GrowableArraySetIndexed, 327404102)                    \
   V(_Float32Array, [], Float32ArrayGetIndexed, 1225286513)                     \
+  V(_Float32Array, []=, Float32ArraySetIndexed, 1155155195)                    \
   V(_Float64Array, [], Float64ArrayGetIndexed, 871118335)                      \
+  V(_Float64Array, []=, Float64ArraySetIndexed, 214271306)                     \
   V(_Int8Array, [], Int8ArrayGetIndexed, 199925538)                            \
+  V(_Int8Array, []=, Int8ArraySetIndexed, 25452746)                            \
   V(_Uint8Array, [], Uint8ArrayGetIndexed, 502448555)                          \
+  V(_Uint8Array, []=, Uint8ArraySetIndexed, 182237960)                         \
   V(_Uint8ClampedArray, [], Uint8ClampedArrayGetIndexed, 1292893603)           \
+  V(_Uint8ClampedArray, []=, Uint8ClampedArraySetIndexed, 670971404)           \
   V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 1831383216)         \
+  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 1660673499)        \
   V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
     1831906095)                                                                \
+  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
+    19235519)                                                                  \
   V(_Int16Array, [], Int16ArrayGetIndexed, 1191799443)                         \
+  V(_Int16Array, []=, Int16ArraySetIndexed, 1182335435)                        \
   V(_Uint16Array, [], Uint16ArrayGetIndexed, 814177144)                        \
+  V(_Uint16Array, []=, Uint16ArraySetIndexed, 663508528)                       \
   V(_Int32Array, [], Int32ArrayGetIndexed, 787321640)                          \
+  V(_Int32Array, []=, Int32ArraySetIndexed, 1515238594)                        \
   V(_Uint32Array, [], Uint32ArrayGetIndexed, 1421922726)                       \
+  V(_Uint32Array, []=, Uint32ArraySetIndexed, 1980947178)                      \
   V(_Float32x4Array, [], Float32x4ArrayGetIndexed, 1901126825)                 \
+  V(_Float32x4Array, []=, Float32x4ArraySetIndexed, 1419416331)                \
 
 
 // A list of core function that should always be inlined.
@@ -4075,6 +4090,7 @@
         immutable_(immutable),
         recognized_kind_(MethodRecognizer::kUnknown),
         field_(NULL) {
+    ASSERT(offset_in_bytes >= 0);
     ASSERT(type.IsZoneHandle());  // May be null if field is not an instance.
     SetInputAt(0, instance);
   }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 0e6ad03..d8ab9a5 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -680,9 +680,6 @@
     api_state()->weak_persistent_handles().VisitHandles(&visitor);
 
     CompilerStats::Print();
-    // TODO(asiva): Move this code to Dart::Cleanup when we have that method
-    // as the cleanup for Dart::InitOnce.
-    CodeObservers::DeleteAll();
     if (FLAG_trace_isolates) {
       heap()->PrintSizes();
       megamorphic_cache_table()->PrintSizes();
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 22ec97e..5f805b2 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -3317,6 +3317,9 @@
   if (field->has_factory) {
     ErrorMsg("keyword 'factory' not allowed in field declaration");
   }
+  if (!field->has_static && field->has_const) {
+    ErrorMsg(field->name_pos, "instance field may not be 'const'");
+  }
   if (members->FieldNameExists(*field->name, !field->has_final)) {
     ErrorMsg(field->name_pos,
              "field or method '%s' already defined", field->name->ToCString());
diff --git a/sdk/lib/_collection_dev/collection_dev.dart b/sdk/lib/_collection_dev/collection_dev.dart
index 79ca515..175fc01 100644
--- a/sdk/lib/_collection_dev/collection_dev.dart
+++ b/sdk/lib/_collection_dev/collection_dev.dart
@@ -8,6 +8,7 @@
 
 import 'dart:core' hide Symbol;
 import 'dart:core' as core;
+import 'dart:math' show Random;
 
 part 'arrays.dart';
 part 'iterable.dart';
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 9e7b990..5001fe3 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -22,8 +22,13 @@
 //    sdk/lib/core/regexp.dart
 // TODO(floitsch): also used in dart:async until end of September for
 //    deprecation of runZonedExperimental.
+// TODO(floitsch): also used in dart:json and dart:utf until middle of October
+//    for deprecation of json and utf libraries.
 
-const deprecated = 0;
+// We use a random string constant to avoid it clashing with other constants.
+// This is, because we have a test that verifies that no metadata is included
+// in the output, when no mirrors need them.
+const deprecated = "qB2n4PYM";
 
 /**
  * An [Iterable] for classes that have efficient [length] and [elementAt].
@@ -953,6 +958,18 @@
     Sort.sort(list, compare);
   }
 
+  static void shuffleList(List list) {
+    Random random = new Random();
+    int length = list.length;
+    while (length > 1) {
+      int pos = random.nextInt(length);
+      length -= 1;
+      var tmp = list[length];
+      list[length] = list[pos];
+      list[pos] = tmp;
+    }
+  }
+
   static int indexOfList(List list, var element, int start) {
     return Arrays.indexOf(list, element, start, list.length);
   }
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/_collection_dev/list.dart
index f5db3bb..6acc5d2 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/_collection_dev/list.dart
@@ -140,6 +140,11 @@
         "Cannot modify an unmodifiable list");
   }
 
+  void shuffle() {
+    throw new UnsupportedError(
+        "Cannot modify an unmodifiable list");
+  }
+
   void clear() {
     throw new UnsupportedError(
         "Cannot clear an unmodifiable list");
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 6f673a3..303a467 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -731,7 +731,9 @@
     if (node == CURRENT_ELEMENT_SPANNABLE) {
       node = currentElement;
     }
-    if (node is Node) {
+    if (node is SourceSpan) {
+      return node;
+    } else if (node is Node) {
       return spanFromNode(node, uri);
     } else if (node is Token) {
       return spanFromTokens(node, node, uri);
@@ -1530,7 +1532,7 @@
   }
 }
 
-class SourceSpan {
+class SourceSpan implements Spannable {
   final Uri uri;
   final int begin;
   final int end;
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index f70517e..9fcd6c3 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -71,16 +71,6 @@
   DartType unalias(Compiler compiler);
 
   /**
-   * Finds the method, field or property named [name] declared or inherited
-   * on this type.
-   *
-   * If [isSetter] is [:true:] the member is interpreted as a setter access.
-   */
-  // TODO(johnniwinther): Implement this for [TypeVariableType], [FunctionType],
-  // and [TypedefType].
-  Member lookupMember(SourceString name, {bool isSetter: false}) => null;
-
-  /**
    * If this type is malformed or a generic type created with the wrong number
    * of type arguments then [userProvidedBadType] holds the bad type provided
    * by the user.
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index c09dfb3..d0e370e 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -117,6 +117,8 @@
 
   static const ElementKind AMBIGUOUS =
       const ElementKind('ambiguous', ElementCategory.NONE);
+  static const ElementKind WARN_ON_USE =
+      const ElementKind('warn_on_use', ElementCategory.NONE);
   static const ElementKind ERROR =
       const ElementKind('error', ElementCategory.NONE);
 
@@ -203,6 +205,7 @@
   bool isLibrary();
   bool isErroneous();
   bool isAmbiguous();
+  bool isWarnOnUse();
 
   bool isTopLevel();
   bool isAssignable();
@@ -261,6 +264,17 @@
   }
   static bool isErroneousElement(Element e) => e != null && e.isErroneous();
 
+  /// Unwraps [element] reporting any warnings attached to it, if any.
+  static Element unwrap(Element element,
+                        DiagnosticListener listener,
+                        Spannable spannable) {
+    if (element != null && element.isWarnOnUse()) {
+      WarnOnUseElement wrappedElement = element;
+      element = wrappedElement.unwrap(listener, spannable);
+    }
+    return element;
+  }
+
   static bool isClass(Element e) => e != null && e.kind == ElementKind.CLASS;
   static bool isTypedef(Element e) {
     return e != null && e.kind == ElementKind.TYPEDEF;
@@ -335,6 +349,7 @@
   static bool isNativeOrExtendsNative(ClassElement element) {
     if (element == null) return false;
     if (element.isNative()) return true;
+    assert(element.resolutionState == STATE_DONE);
     return isNativeOrExtendsNative(element.superclass);
   }
 
@@ -583,6 +598,17 @@
   Map get messageArguments;
 }
 
+/// An [Element] whose usage should cause a warning.
+abstract class WarnOnUseElement extends Element {
+  /// The element whose usage cause a warning.
+  Element get wrappedElement;
+
+  /// Reports the attached warning and returns the wrapped element.
+  /// [usageSpannable] is used to report messages on the reference of
+  /// [wrappedElement].
+  Element unwrap(DiagnosticListener listener, Spannable usageSpannable);
+}
+
 abstract class AmbiguousElement extends Element {
   DualKind get messageKind;
   Map get messageArguments;
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 394d4e4..e74bd0d 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -98,6 +98,9 @@
   /** See [AmbiguousElement] for documentation. */
   bool isAmbiguous() => false;
 
+  /** See [WarnOnUseElement] for documentation. */
+  bool isWarnOnUse() => false;
+
   /**
    * Is [:true:] if this element has a corresponding patch.
    *
@@ -350,6 +353,66 @@
   }
 }
 
+/// A message attached to a [WarnOnUseElementX].
+class WrappedMessage {
+  /// The message position. If [:null:] the position of the reference to the
+  /// [WarnOnUseElementX] is used.
+  final Spannable spannable;
+
+  /**
+   * The message to report on resolving a wrapped element.
+   */
+  final MessageKind messageKind;
+
+  /**
+   * The message arguments to report on resolving a wrapped element.
+   */
+  final Map messageArguments;
+
+  WrappedMessage(this.spannable, this.messageKind, this.messageArguments);
+}
+
+/**
+ * An [Element] whose reference should cause one or more warnings.
+ */
+class WarnOnUseElementX extends ElementX implements WarnOnUseElement {
+  /// Warning to report on resolving this element.
+  final WrappedMessage warning;
+
+  /// Info to report on resolving this element.
+  final WrappedMessage info;
+
+  /// The element whose usage cause a warning.
+  final Element wrappedElement;
+
+  WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info,
+                    Element enclosingElement, Element wrappedElement)
+      : this.wrappedElement = wrappedElement,
+        super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement);
+
+  bool isWarnOnUse() => true;
+
+  Element unwrap(DiagnosticListener listener, Spannable usageSpannable) {
+    var unwrapped = wrappedElement;
+    if (warning != null) {
+      Spannable spannable = warning.spannable;
+      if (spannable == null) spannable = usageSpannable;
+      listener.reportWarningCode(
+          spannable, warning.messageKind, warning.messageArguments);
+    }
+    if (info != null) {
+      Spannable spannable = info.spannable;
+      if (spannable == null) spannable = usageSpannable;
+      listener.reportInfo(
+          spannable, info.messageKind, info.messageArguments);
+    }
+    if (unwrapped.isWarnOnUse()) {
+      unwrapped = unwrapped.unwrap(listener, usageSpannable);
+    }
+    return unwrapped;
+  }
+}
+
 /**
  * An ambiguous element represents multiple elements accessible by the same name.
  *
@@ -404,7 +467,7 @@
         ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION;
     LibraryElementX importer = context.getLibrary();
     for (Element element in ambiguousElements) {
-      var arguments = {'element': element};
+      var arguments = {'name': element.name};
       listener.reportInfo(element, code, arguments);
       Link<Import> importers = importer.importers[element];
       listener.withCurrentElement(importer, () {
@@ -667,8 +730,7 @@
    * Adds [element] to the import scope of this library.
    *
    * If an element by the same name is already in the imported scope, an
-   * [ErroneousElement] will be put in the imported scope, allowing for the
-   * detection of ambiguous uses of imported names.
+   * [ErroneousElement] will be put in the imported scope, allowing for detection of ambiguous uses of imported names.
    */
   void addImport(Element element, Import import, DiagnosticListener listener) {
     importers[element] =
@@ -676,31 +738,42 @@
         .prepend(import);
     SourceString name = element.name;
     Element existing = importScope.putIfAbsent(name, () => element);
+
+    Element createWarnOnUseElement(Spannable spannable,
+                                   MessageKind messageKind,
+                                   Element hidingElement,
+                                   Element hiddenElement) {
+        Uri hiddenUri = hiddenElement.getLibrary().canonicalUri;
+        Uri hidingUri = hidingElement.getLibrary().canonicalUri;
+        return new WarnOnUseElementX(
+            new WrappedMessage(
+                null, // Report on reference to [hidingElement].
+                messageKind,
+                {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}),
+            new WrappedMessage(
+                listener.spanFromSpannable(spannable),
+                MessageKind.IMPORTED_HERE,
+                {'name': name}),
+            this, hidingElement);
+    }
+
     if (existing != element) {
-      // TODO(johnniwinther): Only emit these warnings if [element] is used.
       if (existing.getLibrary().isPlatformLibrary &&
           !element.getLibrary().isPlatformLibrary) {
         // [existing] is implicitly hidden.
-        importScope[name] = element;
-        listener.reportWarningCode(import, MessageKind.HIDDEN_IMPORT,
-            {'name': name,
-             'hiddenUri': existing.getLibrary().canonicalUri,
-             'hidingUri': element.getLibrary().canonicalUri});
+        importScope[name] = createWarnOnUseElement(
+            import, MessageKind.HIDDEN_IMPORT, element, existing);
       } else if (!existing.getLibrary().isPlatformLibrary &&
                  element.getLibrary().isPlatformLibrary) {
         // [element] is implicitly hidden.
         if (import == null) {
           // [element] is imported implicitly (probably through dart:core).
-          listener.reportWarningCode(importers[existing].head,
-              MessageKind.HIDDEN_IMPLICIT_IMPORT,
-              {'name': name,
-               'hiddenUri': element.getLibrary().canonicalUri,
-               'hidingUri': existing.getLibrary().canonicalUri});
+          importScope[name] = createWarnOnUseElement(
+              importers[existing].head, MessageKind.HIDDEN_IMPLICIT_IMPORT,
+              existing, element);
         } else {
-          listener.reportWarningCode(import, MessageKind.HIDDEN_IMPORT,
-              {'name': name,
-               'hiddenUri': element.getLibrary().canonicalUri,
-               'hidingUri': existing.getLibrary().canonicalUri});
+          importScope[name] = createWarnOnUseElement(
+              import, MessageKind.HIDDEN_IMPORT, existing, element);
         }
       } else {
         // TODO(johnniwinther): Provide access to the import tags from which
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 754e5aa..a60feea 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -477,9 +477,11 @@
   }
 
   bool isInterceptedMethod(Element element) {
-    return element.isInstanceMember()
-        && !element.isGenerativeConstructorBody()
-        && interceptedElements[element.name] != null;
+    if (!element.isInstanceMember()) return false;
+    if (element.isGenerativeConstructorBody()) {
+      return Elements.isNativeOrExtendsNative(element.getEnclosingClass());
+    }
+    return interceptedElements[element.name] != null;
   }
 
   bool fieldHasInterceptedGetter(Element element) {
@@ -952,6 +954,30 @@
     if (element.isTypedef()) {
       typedefTypeLiterals.add(element);
     }
+    if (element.isClass()) {
+      // TODO(sra): Can we register via a type parameter?
+      registerEscapingConstructorsOfClass(element, enqueuer);
+    }
+  }
+
+  void registerEscapingConstructorsOfClass(ClassElement classElement,
+                                           Enqueuer enqueuer) {
+    // Web component classes have constructors that are escaped to the host
+    // environment.
+    // TODO(13835): Defer registering generative constructors until the helper
+    // functions that fetch the constructors is seen.  These functions are
+    // called by document.register.
+    classElement.ensureResolved(compiler);
+    if (Elements.isNativeOrExtendsNative(classElement)) {
+      registerGenerativeConstructors(ClassElement enclosing, Element member) {
+        if (member.isGenerativeConstructor()) {
+          enqueuer.registerStaticUse(member);
+        }
+      }
+      classElement.forEachMember(registerGenerativeConstructors,
+          includeBackendMembers: false,
+          includeSuperAndInjectedMembers: false);
+    }
   }
 
   void registerStackTraceInCatch(TreeElements elements) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
index b7cf4f2..de6a0aa 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -8,26 +8,21 @@
 import 'dart:collection' show LinkedHashMap, Queue;
 
 import '../closure.dart';
-import '../../compiler.dart' as api;
 import '../elements/elements.dart';
-import '../elements/modelx.dart' show FunctionElementX;
-import '../js_emitter/js_emitter.dart' show Emitter, CodeEmitterTask, ClassBuilder;
+import '../js_emitter/js_emitter.dart'
+    show Emitter, CodeEmitterTask, ClassBuilder;
 
-// TODO(ahe): There seems to be a bug in the VM, so we have to hide "js".
-import '../dart2jslib.dart' hide Selector, TypedSelector, js;
+import '../dart2jslib.dart';
 import '../dart_types.dart';
 import '../js/js.dart' as jsAst;
-import '../js/js.dart' show js; // TODO(ahe): VM bug, see above.
+import '../js/js.dart' show js;
 import '../native_handler.dart' as native;
-import '../source_file.dart';
-import '../source_map_builder.dart';
-import '../ssa/ssa.dart' hide js; // TODO(ahe): VM bug, see above.
+import '../ssa/ssa.dart';
 import '../tree/tree.dart';
 import '../types/types.dart';
-import '../universe/universe.dart' hide js; // TODO(ahe): VM bug, see above.
+import '../universe/universe.dart';
 import '../util/characters.dart';
 import '../util/util.dart';
-import '../util/uri_extras.dart' show relativize;
 
 part 'backend.dart';
 part 'constant_emitter.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
index 1f83c5f..db7898d 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -187,7 +187,7 @@
     Set<ClassElement> neededByConstant =
         emitter.interceptorsReferencedFromConstants();
     Set<ClassElement> modifiedClasses =
-        emitter.classesModifiedByEmitRuntimeTypeSupport();
+        emitter.typeTestEmitter.classesModifiedByEmitRuntimeTypeSupport();
 
     for (ClassElement classElement in preOrder.reversed) {
       // Post-order traversal ensures we visit the subclasses before their
@@ -283,7 +283,7 @@
       if (!classElement.isNative()) continue;
       if (neededClasses.contains(classElement)) {
         // Define interceptor class for [classElement].
-        emitter.emitClassBuilderWithReflectionData(
+        emitter.classEmitter.emitClassBuilderWithReflectionData(
             backend.namer.getNameOfClass(classElement),
             classElement, builders[classElement],
             emitter.bufferForElement(classElement, mainBuffer));
@@ -341,14 +341,13 @@
     String superName = backend.namer.getNameOfClass(superclass);
 
     ClassBuilder builder = new ClassBuilder();
-    emitter.emitClassConstructor(classElement, builder, null);
-    emitter.emitSuper(superName, builder);
-    bool hasFields = emitter.emitFields(
+    emitter.classEmitter.emitClassConstructor(classElement, builder, null);
+    bool hasFields = emitter.classEmitter.emitFields(
         classElement, builder, superName, classIsNative: true);
     int propertyCount = builder.properties.length;
-    emitter.emitClassGettersSetters(classElement, builder);
-    emitter.emitInstanceMembers(classElement, builder);
-    emitter.emitIsTests(classElement, builder);
+    emitter.classEmitter.emitClassGettersSetters(classElement, builder);
+    emitter.classEmitter.emitInstanceMembers(classElement, builder);
+    emitter.typeTestEmitter.emitIsTests(classElement, builder);
 
     if (!hasFields &&
         builder.properties.length == propertyCount &&
@@ -513,7 +512,7 @@
       // If the native emitter has been asked to take care of the
       // noSuchMethod handlers, we do that now.
       if (handleNoSuchMethod) {
-        emitter.emitNoSuchMethodHandlers(addProperty);
+        emitter.nsmEmitter.emitNoSuchMethodHandlers(addProperty);
       }
     }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index fbb9da7..8f92771 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -262,8 +262,8 @@
         new Set<DartType>.from(universe.instantiatedTypes);
     for (DartType instantiatedType in universe.instantiatedTypes) {
       if (instantiatedType.kind == TypeKind.INTERFACE) {
-        Member member =
-            instantiatedType.lookupMember(Compiler.CALL_OPERATOR_NAME);
+        InterfaceType interface = instantiatedType;
+        Member member = interface.lookupMember(Compiler.CALL_OPERATOR_NAME);
         if (member != null) {
           instantiatedTypes.add(member.computeType(compiler));
         }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
new file mode 100644
index 0000000..edf808f
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
@@ -0,0 +1,593 @@
+// 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.js_emitter;
+
+class ClassEmitter extends CodeEmitterHelper {
+  /**
+   * Documentation wanted -- johnniwinther
+   *
+   * Invariant: [classElement] must be a declaration element.
+   */
+  void generateClass(ClassElement classElement, CodeBuffer buffer) {
+    final onlyForRti =
+        task.typeTestEmitter.rtiNeededClasses.contains(classElement);
+
+    assert(invariant(classElement, classElement.isDeclaration));
+    assert(invariant(classElement, !classElement.isNative() || onlyForRti));
+
+    task.needsDefineClass = true;
+    String className = namer.getNameOfClass(classElement);
+
+    ClassElement superclass = classElement.superclass;
+    String superName = "";
+    if (superclass != null) {
+      superName = namer.getNameOfClass(superclass);
+    }
+    String runtimeName =
+        namer.getPrimitiveInterceptorRuntimeName(classElement);
+
+    if (classElement.isMixinApplication) {
+      String mixinName = namer.getNameOfClass(computeMixinClass(classElement));
+      superName = '$superName+$mixinName';
+      task.needsMixinSupport = true;
+    }
+
+    ClassBuilder builder = new ClassBuilder();
+    emitClassConstructor(classElement, builder, runtimeName);
+    emitFields(classElement, builder, superName, onlyForRti: onlyForRti);
+    emitClassGettersSetters(classElement, builder);
+    if (!classElement.isMixinApplication) {
+      emitInstanceMembers(classElement, builder);
+    }
+    task.typeTestEmitter.emitIsTests(classElement, builder);
+
+    emitClassBuilderWithReflectionData(
+        className, classElement, builder, buffer);
+  }
+
+  void emitClassConstructor(ClassElement classElement,
+                            ClassBuilder builder,
+                            String runtimeName) {
+    List<String> fields = <String>[];
+    if (!classElement.isNative()) {
+      visitFields(classElement, false,
+                  (Element member,
+                   String name,
+                   String accessorName,
+                   bool needsGetter,
+                   bool needsSetter,
+                   bool needsCheckedSetter) {
+        fields.add(name);
+      });
+    }
+    String constructorName = namer.getNameOfClass(classElement);
+    task.precompiledFunction.add(new jsAst.FunctionDeclaration(
+        new jsAst.VariableDeclaration(constructorName),
+        js.fun(fields, fields.map(
+            (name) => js('this.$name = $name')).toList())));
+    if (runtimeName == null) {
+      runtimeName = constructorName;
+    }
+    task.precompiledFunction.addAll([
+        js('$constructorName.builtin\$cls = "$runtimeName"'),
+        js.if_('!"name" in $constructorName',
+              js('$constructorName.name = "$constructorName"')),
+        js('\$desc=\$collectedClasses.$constructorName'),
+        js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')),
+        js('$constructorName.prototype = \$desc'),
+    ]);
+
+    task.precompiledConstructorNames.add(js(constructorName));
+  }
+
+  /// Returns `true` if fields added.
+  bool emitFields(Element element,
+                  ClassBuilder builder,
+                  String superName,
+                  { bool classIsNative: false,
+                    bool emitStatics: false,
+                    bool onlyForRti: false }) {
+    assert(!emitStatics || !onlyForRti);
+    bool isClass = false;
+    bool isLibrary = false;
+    if (element.isClass()) {
+      isClass = true;
+    } else if (element.isLibrary()) {
+      isLibrary = false;
+      assert(invariant(element, emitStatics));
+    } else {
+      throw new SpannableAssertionFailure(
+          element, 'Must be a ClassElement or a LibraryElement');
+    }
+    StringBuffer buffer = new StringBuffer();
+    if (emitStatics) {
+      assert(invariant(element, superName == null, message: superName));
+    } else {
+      assert(invariant(element, superName != null));
+      String nativeName =
+          namer.getPrimitiveInterceptorRuntimeName(element);
+      if (nativeName != null) {
+        buffer.write('$nativeName/');
+      }
+      buffer.write('$superName;');
+    }
+    int bufferClassLength = buffer.length;
+
+    String separator = '';
+
+    var fieldMetadata = [];
+    bool hasMetadata = false;
+
+    if (!onlyForRti) {
+      visitFields(element, emitStatics,
+                  (VariableElement field,
+                   String name,
+                   String accessorName,
+                   bool needsGetter,
+                   bool needsSetter,
+                   bool needsCheckedSetter) {
+        // Ignore needsCheckedSetter - that is handled below.
+        bool needsAccessor = (needsGetter || needsSetter);
+        // We need to output the fields for non-native classes so we can auto-
+        // generate the constructor.  For native classes there are no
+        // constructors, so we don't need the fields unless we are generating
+        // accessors at runtime.
+        if (!classIsNative || needsAccessor) {
+          buffer.write(separator);
+          separator = ',';
+          var metadata = task.buildMetadataFunction(field);
+          if (metadata != null) {
+            hasMetadata = true;
+          } else {
+            metadata = new jsAst.LiteralNull();
+          }
+          fieldMetadata.add(metadata);
+          recordMangledField(field, accessorName, field.name.slowToString());
+          if (!needsAccessor) {
+            // Emit field for constructor generation.
+            assert(!classIsNative);
+            buffer.write(name);
+          } else {
+            // Emit (possibly renaming) field name so we can add accessors at
+            // runtime.
+            buffer.write(accessorName);
+            if (name != accessorName) {
+              buffer.write(':$name');
+              // Only the native classes can have renaming accessors.
+              assert(classIsNative);
+            }
+
+            int getterCode = 0;
+            if (needsGetter) {
+              if (field.isInstanceMember()) {
+                // 01:  function() { return this.field; }
+                // 10:  function(receiver) { return receiver.field; }
+                // 11:  function(receiver) { return this.field; }
+                bool isIntercepted = backend.fieldHasInterceptedGetter(field);
+                getterCode += isIntercepted ? 2 : 0;
+                getterCode += backend.isInterceptorClass(element) ? 0 : 1;
+                // TODO(sra): 'isInterceptorClass' might not be the correct test
+                // for methods forced to use the interceptor convention because
+                // the method's class was elsewhere mixed-in to an interceptor.
+                assert(!field.isInstanceMember() || getterCode != 0);
+                if (isIntercepted) {
+                  task.interceptorInvocationNames.add(namer.getterName(field));
+                }
+              } else {
+                getterCode = 1;
+              }
+            }
+            int setterCode = 0;
+            if (needsSetter) {
+              if (field.isInstanceMember()) {
+                // 01:  function(value) { this.field = value; }
+                // 10:  function(receiver, value) { receiver.field = value; }
+                // 11:  function(receiver, value) { this.field = value; }
+                bool isIntercepted = backend.fieldHasInterceptedSetter(field);
+                setterCode += isIntercepted ? 2 : 0;
+                setterCode += backend.isInterceptorClass(element) ? 0 : 1;
+                assert(!field.isInstanceMember() || setterCode != 0);
+                if (isIntercepted) {
+                  task.interceptorInvocationNames.add(namer.setterName(field));
+                }
+              } else {
+                setterCode = 1;
+              }
+            }
+            int code = getterCode + (setterCode << 2);
+            if (code == 0) {
+              compiler.reportInternalError(
+                  field, 'Internal error: code is 0 ($element/$field)');
+            } else {
+              buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]);
+            }
+          }
+          if (backend.isAccessibleByReflection(field)) {
+            buffer.write(new String.fromCharCode(REFLECTION_MARKER));
+          }
+        }
+      });
+    }
+
+    bool fieldsAdded = buffer.length > bufferClassLength;
+    String compactClassData = buffer.toString();
+    jsAst.Expression classDataNode = js.string(compactClassData);
+    if (hasMetadata) {
+      fieldMetadata.insert(0, classDataNode);
+      classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata);
+    }
+    builder.addProperty('', classDataNode);
+    return fieldsAdded;
+  }
+
+  void emitClassGettersSetters(ClassElement classElement,
+                               ClassBuilder builder) {
+
+    visitFields(classElement, false,
+                (VariableElement member,
+                 String name,
+                 String accessorName,
+                 bool needsGetter,
+                 bool needsSetter,
+                 bool needsCheckedSetter) {
+      compiler.withCurrentElement(member, () {
+        if (needsCheckedSetter) {
+          assert(!needsSetter);
+          generateCheckedSetter(member, name, accessorName, builder);
+        }
+        if (needsGetter) {
+          generateGetter(member, name, accessorName, builder);
+        }
+        if (needsSetter) {
+          generateSetter(member, name, accessorName, builder);
+        }
+      });
+    });
+  }
+
+  /**
+   * Documentation wanted -- johnniwinther
+   *
+   * Invariant: [classElement] must be a declaration element.
+   */
+  void emitInstanceMembers(ClassElement classElement,
+                           ClassBuilder builder) {
+    assert(invariant(classElement, classElement.isDeclaration));
+
+    void visitMember(ClassElement enclosing, Element member) {
+      assert(invariant(classElement, member.isDeclaration));
+      if (member.isInstanceMember()) {
+        task.containerBuilder.addMember(member, builder);
+      }
+    }
+
+    classElement.implementation.forEachMember(
+        visitMember,
+        includeBackendMembers: true);
+
+    if (identical(classElement, compiler.objectClass)
+        && compiler.enabledNoSuchMethod) {
+      // Emit the noSuchMethod handlers on the Object prototype now,
+      // so that the code in the dynamicFunction helper can find
+      // them. Note that this helper is invoked before analyzing the
+      // full JS script.
+      if (!task.nativeEmitter.handleNoSuchMethod) {
+        task.nsmEmitter.emitNoSuchMethodHandlers(builder.addProperty);
+      }
+    }
+  }
+
+  void emitClassBuilderWithReflectionData(String className,
+                                          ClassElement classElement,
+                                          ClassBuilder builder,
+                                          CodeBuffer buffer) {
+    var metadata = task.buildMetadataFunction(classElement);
+    if (metadata != null) {
+      builder.addProperty("@", metadata);
+    }
+
+    if (backend.isNeededForReflection(classElement)) {
+      Link typeVars = classElement.typeVariables;
+      List properties = [];
+      for (TypeVariableType typeVar in typeVars) {
+        properties.add(js.string(typeVar.name.slowToString()));
+        properties.add(js.toExpression(task.reifyType(typeVar.element.bound)));
+      }
+
+      ClassElement superclass = classElement.superclass;
+      bool hasSuper = superclass != null;
+      if ((!properties.isEmpty && !hasSuper) ||
+          (hasSuper && superclass.typeVariables != typeVars)) {
+        builder.addProperty('<>', new jsAst.ArrayInitializer.from(properties));
+      }
+    }
+    List<CodeBuffer> classBuffers = task.elementBuffers[classElement];
+    if (classBuffers == null) {
+      classBuffers = [];
+    } else {
+      task.elementBuffers.remove(classElement);
+    }
+    CodeBuffer statics = new CodeBuffer();
+    statics.write('{$n');
+    bool hasStatics = false;
+    ClassBuilder staticsBuilder = new ClassBuilder();
+    if (emitFields(classElement, staticsBuilder, null, emitStatics: true)) {
+      hasStatics = true;
+      statics.write('"":$_');
+      statics.write(
+          jsAst.prettyPrint(staticsBuilder.properties.single.value, compiler));
+      statics.write(',$n');
+    }
+    for (CodeBuffer classBuffer in classBuffers) {
+      // TODO(ahe): What about deferred?
+      if (classBuffer != null) {
+        hasStatics = true;
+        statics.addBuffer(classBuffer);
+      }
+    }
+    statics.write('}$n');
+    if (hasStatics) {
+      builder.addProperty('static', new jsAst.Blob(statics));
+    }
+
+    // TODO(ahe): This method (generateClass) should return a jsAst.Expression.
+    if (!buffer.isEmpty) {
+      buffer.write(',$n$n');
+    }
+    buffer.write('$className:$_');
+    buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler));
+    String reflectionName = task.getReflectionName(classElement, className);
+    if (reflectionName != null) {
+      List<int> interfaces = <int>[];
+      for (DartType interface in classElement.interfaces) {
+        interfaces.add(task.reifyType(interface));
+      }
+      buffer.write(',$n$n"+$reflectionName": $interfaces');
+    }
+  }
+
+  /**
+   * Calls [addField] for each of the fields of [element].
+   *
+   * [element] must be a [ClassElement] or a [LibraryElement].
+   *
+   * If [element] is a [ClassElement], the static fields of the class are
+   * visited if [visitStatics] is true and the instance fields are visited if
+   * [visitStatics] is false.
+   *
+   * If [element] is a [LibraryElement], [visitStatics] must be true.
+   *
+   * When visiting the instance fields of a class, the fields of its superclass
+   * are also visited if the class is instantiated.
+   *
+   * Invariant: [element] must be a declaration element.
+   */
+  void visitFields(Element element, bool visitStatics, AcceptField f) {
+    assert(invariant(element, element.isDeclaration));
+
+    bool isClass = false;
+    bool isLibrary = false;
+    if (element.isClass()) {
+      isClass = true;
+    } else if (element.isLibrary()) {
+      isLibrary = true;
+      assert(invariant(element, visitStatics));
+    } else {
+      throw new SpannableAssertionFailure(
+          element, 'Expected a ClassElement or a LibraryElement.');
+    }
+
+    // If the class is never instantiated we still need to set it up for
+    // inheritance purposes, but we can simplify its JavaScript constructor.
+    bool isInstantiated =
+        compiler.codegenWorld.instantiatedClasses.contains(element);
+
+    void visitField(Element holder, VariableElement field) {
+      assert(invariant(element, field.isDeclaration));
+      SourceString name = field.name;
+
+      // Keep track of whether or not we're dealing with a field mixin
+      // into a native class.
+      bool isMixinNativeField =
+          isClass && element.isNative() && holder.isMixinApplication;
+
+      // See if we can dynamically create getters and setters.
+      // We can only generate getters and setters for [element] since
+      // the fields of super classes could be overwritten with getters or
+      // setters.
+      bool needsGetter = false;
+      bool needsSetter = false;
+      // We need to name shadowed fields differently, so they don't clash with
+      // the non-shadowed field.
+      bool isShadowed = false;
+      if (isLibrary || isMixinNativeField || holder == element) {
+        needsGetter = fieldNeedsGetter(field);
+        needsSetter = fieldNeedsSetter(field);
+      } else {
+        ClassElement cls = element;
+        isShadowed = cls.isShadowedByField(field);
+      }
+
+      if ((isInstantiated && !holder.isNative())
+          || needsGetter
+          || needsSetter) {
+        String accessorName = isShadowed
+            ? namer.shadowedFieldName(field)
+            : namer.getNameOfField(field);
+        String fieldName = field.hasFixedBackendName()
+            ? field.fixedBackendName()
+            : (isMixinNativeField ? name.slowToString() : accessorName);
+        bool needsCheckedSetter = false;
+        if (compiler.enableTypeAssertions
+            && needsSetter
+            && canGenerateCheckedSetter(field)) {
+          needsCheckedSetter = true;
+          needsSetter = false;
+        }
+        // Getters and setters with suffixes will be generated dynamically.
+        f(field, fieldName, accessorName, needsGetter, needsSetter,
+          needsCheckedSetter);
+      }
+    }
+
+    if (isLibrary) {
+      LibraryElement library = element;
+      library.implementation.forEachLocalMember((Element member) {
+        if (member.isField()) visitField(library, member);
+      });
+    } else if (visitStatics) {
+      ClassElement cls = element;
+      cls.implementation.forEachStaticField(visitField);
+    } else {
+      ClassElement cls = element;
+      // TODO(kasperl): We should make sure to only emit one version of
+      // overridden fields. Right now, we rely on the ordering so the
+      // fields pulled in from mixins are replaced with the fields from
+      // the class definition.
+
+      // If a class is not instantiated then we add the field just so we can
+      // generate the field getter/setter dynamically. Since this is only
+      // allowed on fields that are in [element] we don't need to visit
+      // superclasses for non-instantiated classes.
+      cls.implementation.forEachInstanceField(
+          visitField, includeSuperAndInjectedMembers: isInstantiated);
+    }
+  }
+
+  void recordMangledField(Element member,
+                          String accessorName,
+                          String memberName) {
+    if (!backend.shouldRetainGetter(member)) return;
+    String previousName;
+    if (member.isInstanceMember()) {
+      previousName = task.mangledFieldNames.putIfAbsent(
+          '${namer.getterPrefix}$accessorName',
+          () => memberName);
+    } else {
+      previousName = task.mangledGlobalFieldNames.putIfAbsent(
+          accessorName,
+          () => memberName);
+    }
+    assert(invariant(member, previousName == memberName,
+                     message: '$previousName != ${memberName}'));
+  }
+
+  bool fieldNeedsGetter(VariableElement field) {
+    assert(field.isField());
+    if (fieldAccessNeverThrows(field)) return false;
+    return backend.shouldRetainGetter(field)
+        || compiler.codegenWorld.hasInvokedGetter(field, compiler);
+  }
+
+  bool fieldNeedsSetter(VariableElement field) {
+    assert(field.isField());
+    if (fieldAccessNeverThrows(field)) return false;
+    return (!field.modifiers.isFinalOrConst())
+        && (backend.shouldRetainSetter(field)
+            || compiler.codegenWorld.hasInvokedSetter(field, compiler));
+  }
+
+  // We never access a field in a closure (a captured variable) without knowing
+  // that it is there.  Therefore we don't need to use a getter (that will throw
+  // if the getter method is missing), but can always access the field directly.
+  static bool fieldAccessNeverThrows(VariableElement field) {
+    return field is ClosureFieldElement;
+  }
+
+  bool canGenerateCheckedSetter(VariableElement field) {
+    // We never generate accessors for top-level/static fields.
+    if (!field.isInstanceMember()) return false;
+    DartType type = field.computeType(compiler).unalias(compiler);
+    if (type.element.isTypeVariable() ||
+        (type is FunctionType && type.containsTypeVariables) ||
+        type.treatAsDynamic ||
+        type.element == compiler.objectClass) {
+      // TODO(ngeoffray): Support type checks on type parameters.
+      return false;
+    }
+    return true;
+  }
+
+  void generateCheckedSetter(Element member,
+                             String fieldName,
+                             String accessorName,
+                             ClassBuilder builder) {
+    assert(canGenerateCheckedSetter(member));
+    DartType type = member.computeType(compiler);
+    // TODO(ahe): Generate a dynamic type error here.
+    if (type.element.isErroneous()) return;
+    type = type.unalias(compiler);
+    // TODO(11273): Support complex subtype checks.
+    type = type.asRaw();
+    CheckedModeHelper helper =
+        backend.getCheckedModeHelper(type, typeCast: false);
+    FunctionElement helperElement = helper.getElement(compiler);
+    String helperName = namer.isolateAccess(helperElement);
+    List<jsAst.Expression> arguments = <jsAst.Expression>[js('v')];
+    if (helperElement.computeSignature(compiler).parameterCount != 1) {
+      arguments.add(js.string(namer.operatorIsType(type)));
+    }
+
+    String setterName = namer.setterNameFromAccessorName(accessorName);
+    String receiver = backend.isInterceptorClass(member.getEnclosingClass())
+        ? 'receiver' : 'this';
+    List<String> args = backend.isInterceptedMethod(member)
+        ? ['receiver', 'v']
+        : ['v'];
+    builder.addProperty(setterName,
+        js.fun(args,
+            js('$receiver.$fieldName = #', js(helperName)(arguments))));
+    generateReflectionDataForFieldGetterOrSetter(
+        member, setterName, builder, isGetter: false);
+  }
+
+  void generateGetter(Element member, String fieldName, String accessorName,
+                      ClassBuilder builder) {
+    String getterName = namer.getterNameFromAccessorName(accessorName);
+    ClassElement cls = member.getEnclosingClass();
+    String className = namer.getNameOfClass(cls);
+    String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this';
+    List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : [];
+    task.precompiledFunction.add(
+        js('$className.prototype.$getterName = #',
+           js.fun(args, js.return_(js('$receiver.$fieldName')))));
+    if (backend.isNeededForReflection(member)) {
+      task.precompiledFunction.add(
+          js('$className.prototype.$getterName.${namer.reflectableField} = 1'));
+    }
+  }
+
+  void generateSetter(Element member, String fieldName, String accessorName,
+                      ClassBuilder builder) {
+    String setterName = namer.setterNameFromAccessorName(accessorName);
+    ClassElement cls = member.getEnclosingClass();
+    String className = namer.getNameOfClass(cls);
+    String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this';
+    List<String> args =
+        backend.isInterceptedMethod(member) ? ['receiver', 'v'] : ['v'];
+    task.precompiledFunction.add(
+        js('$className.prototype.$setterName = #',
+           js.fun(args, js.return_(js('$receiver.$fieldName = v')))));
+    if (backend.isNeededForReflection(member)) {
+      task.precompiledFunction.add(
+          js('$className.prototype.$setterName.${namer.reflectableField} = 1'));
+    }
+  }
+
+  void generateReflectionDataForFieldGetterOrSetter(Element member,
+                                                    String name,
+                                                    ClassBuilder builder,
+                                                    {bool isGetter}) {
+    Selector selector = isGetter
+        ? new Selector.getter(member.name, member.getLibrary())
+        : new Selector.setter(member.name, member.getLibrary());
+    String reflectionName = task.getReflectionName(selector, name);
+    if (reflectionName != null) {
+      var reflectable =
+          js(backend.isAccessibleByReflection(member) ? '1' : '0');
+      builder.addProperty('+$reflectionName', reflectable);
+    }
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_helper.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_helper.dart
new file mode 100644
index 0000000..1adfce4
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_helper.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.js_emitter;
+
+class CodeEmitterHelper {
+  CodeEmitterTask task;
+
+  Namer get namer => task.namer;
+
+  JavaScriptBackend get backend => task.backend;
+
+  Compiler get compiler => task.compiler;
+
+  String get n => task.n;
+
+  String get _ => task._;
+
+  String get N => task.N;
+}
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 dae8663..cea45c9 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
@@ -12,6 +12,10 @@
  */
 class CodeEmitterTask extends CompilerTask {
   final ContainerBuilder containerBuilder = new ContainerBuilder();
+  final ClassEmitter classEmitter = new ClassEmitter();
+  final NsmEmitter nsmEmitter = new NsmEmitter();
+  final TypeTestEmitter typeTestEmitter = new TypeTestEmitter();
+
   bool needsDefineClass = false;
   bool needsMixinSupport = false;
   bool needsLazyInitializer = false;
@@ -26,11 +30,9 @@
   String isolateProperties;
   String classesCollector;
   final Set<ClassElement> neededClasses = new Set<ClassElement>();
-  final Set<ClassElement> rtiNeededClasses = new Set<ClassElement>();
   final List<ClassElement> regularClasses = <ClassElement>[];
   final List<ClassElement> deferredClasses = <ClassElement>[];
   final List<ClassElement> nativeClasses = <ClassElement>[];
-  final List<Selector> trivialNsmHandlers = <Selector>[];
   final Map<String, String> mangledFieldNames = <String, String>{};
   final Map<String, String> mangledGlobalFieldNames = <String, String>{};
   final Set<String> recordedMangledNames = new Set<String>();
@@ -54,26 +56,6 @@
   String get N => compiler.enableMinification ? "\n" : ";\n";
 
   /**
-   * Raw ClassElement symbols occuring in is-checks and type assertions.  If the
-   * program contains parameterized checks `x is Set<int>` and
-   * `x is Set<String>` then the ClassElement `Set` will occur once in
-   * [checkedClasses].
-   */
-  Set<ClassElement> checkedClasses;
-
-  /**
-   * The set of function types that checked, both explicity through tests of
-   * typedefs and implicitly through type annotations in checked mode.
-   */
-  Set<FunctionType> checkedFunctionTypes;
-
-  Map<ClassElement, Set<FunctionType>> checkedGenericFunctionTypes =
-      new Map<ClassElement, Set<FunctionType>>();
-
-  Set<FunctionType> checkedNonGenericFunctionTypes =
-      new Set<FunctionType>();
-
-  /**
    * List of expressions and statements that will be included in the
    * precompiled function.
    *
@@ -99,30 +81,8 @@
   final Map<Element, List<CodeBuffer>> elementBuffers =
       new Map<Element, List<CodeBuffer>>();
 
-  void registerDynamicFunctionTypeCheck(FunctionType functionType) {
-    ClassElement classElement = Types.getClassContext(functionType);
-    if (classElement != null) {
-      checkedGenericFunctionTypes.putIfAbsent(classElement,
-          () => new Set<FunctionType>()).add(functionType);
-    } else {
-      checkedNonGenericFunctionTypes.add(functionType);
-    }
-  }
-
   final bool generateSourceMap;
 
-  Iterable<ClassElement> cachedClassesUsingTypeVariableTests;
-
-  Iterable<ClassElement> get classesUsingTypeVariableTests {
-    if (cachedClassesUsingTypeVariableTests == null) {
-      cachedClassesUsingTypeVariableTests = compiler.codegenWorld.isChecks
-          .where((DartType t) => t is TypeVariableType)
-          .map((TypeVariableType v) => v.element.getEnclosingClass())
-          .toList();
-    }
-    return cachedClassesUsingTypeVariableTests;
-  }
-
   CodeEmitterTask(Compiler compiler, Namer namer, this.generateSourceMap)
       : mainBuffer = new CodeBuffer(),
         this.namer = namer,
@@ -130,38 +90,15 @@
         super(compiler) {
     nativeEmitter = new NativeEmitter(this);
     containerBuilder.task = this;
+    classEmitter.task = this;
+    nsmEmitter.task = this;
+    typeTestEmitter.task = this;
   }
 
   void addComment(String comment, CodeBuffer buffer) {
     buffer.write(jsAst.prettyPrint(js.comment(comment), compiler));
   }
 
-  void computeRequiredTypeChecks() {
-    assert(checkedClasses == null && checkedFunctionTypes == null);
-
-    backend.rti.addImplicitChecks(compiler.codegenWorld,
-                                  classesUsingTypeVariableTests);
-
-    checkedClasses = new Set<ClassElement>();
-    checkedFunctionTypes = new Set<FunctionType>();
-    compiler.codegenWorld.isChecks.forEach((DartType t) {
-      if (t is InterfaceType) {
-        checkedClasses.add(t.element);
-      } else if (t is FunctionType) {
-        checkedFunctionTypes.add(t);
-      }
-    });
-  }
-
-  ClassElement computeMixinClass(MixinApplicationElement mixinApplication) {
-    ClassElement mixin = mixinApplication.mixin;
-    while (mixin.isMixinApplication) {
-      mixinApplication = mixin;
-      mixin = mixinApplication.mixin;
-    }
-    return mixin;
-  }
-
   jsAst.Expression constantReference(Constant value) {
     return constantEmitter.reference(value);
   }
@@ -187,30 +124,6 @@
   String get lazyInitializerName
       => '${namer.isolateName}.\$lazy';
 
-  // Compact field specifications.  The format of the field specification is
-  // <accessorName>:<fieldName><suffix> where the suffix and accessor name
-  // prefix are optional.  The suffix directs the generation of getter and
-  // setter methods.  Each of the getter and setter has two bits to determine
-  // the calling convention.  Setter listed below, getter is similar.
-  //
-  //     00: no setter
-  //     01: function(value) { this.field = value; }
-  //     10: function(receiver, value) { receiver.field = value; }
-  //     11: function(receiver, value) { this.field = value; }
-  //
-  // The suffix encodes 4 bits using three ASCII ranges of non-identifier
-  // characters.
-  static const FIELD_CODE_CHARACTERS = r"<=>?@{|}~%&'()*";
-  static const NO_FIELD_CODE = 0;
-  static const FIRST_FIELD_CODE = 1;
-  static const RANGE1_FIRST = 0x3c;   //  <=>?@    encodes 1..5
-  static const RANGE1_LAST = 0x40;
-  static const RANGE2_FIRST = 0x7b;   //  {|}~     encodes 6..9
-  static const RANGE2_LAST = 0x7e;
-  static const RANGE3_FIRST = 0x25;   //  %&'()*+  encodes 10..16
-  static const RANGE3_LAST = 0x2b;
-  static const REFLECTION_MARKER = 0x2d;
-
   jsAst.FunctionDeclaration get generateAccessorFunction {
     const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
     const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1;
@@ -366,238 +279,6 @@
               ]))])())];
   }
 
-  static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4;
-
-  // If we need fewer than this many noSuchMethod handlers we can save space by
-  // just emitting them in JS, rather than emitting the JS needed to generate
-  // them at run time.
-  static const VERY_FEW_NO_SUCH_METHOD_HANDLERS = 10;
-
-  /**
-   * Adds (at runtime) the handlers to the Object class which catch calls to
-   * methods that the object does not have.  The handlers create an invocation
-   * mirror object.
-   *
-   * The current version only gives you the minified name when minifying (when
-   * not minifying this method is not called).
-   *
-   * In order to generate the noSuchMethod handlers we only need the minified
-   * name of the method.  We test the first character of the minified name to
-   * determine if it is a getter or a setter, and we use the arguments array at
-   * runtime to get the number of arguments and their values.  If the method
-   * involves named arguments etc. then we don't handle it here, but emit the
-   * handler method directly on the Object class.
-   *
-   * The minified names are mostly 1-4 character names, which we emit in sorted
-   * order (primary key is length, secondary ordering is lexicographic).  This
-   * gives an order like ... dD dI dX da ...
-   *
-   * Gzip is good with repeated text, but it can't diff-encode, so we do that
-   * for it.  We encode the minified names in a comma-separated string, but all
-   * the 1-4 character names are encoded before the first comma as a series of
-   * base 26 numbers.  The last digit of each number is lower case, the others
-   * are upper case, so 1 is "b" and 26 is "Ba".
-   *
-   * We think of the minified names as base 88 numbers using the ASCII
-   * characters from # to z.  The base 26 numbers each encode the delta from
-   * the previous minified name to the next.  So if there is a minified name
-   * called Df and the next is Dh, then they are 2971 and 2973 when thought of
-   * as base 88 numbers.  The difference is 2, which is "c" in lower-case-
-   * terminated base 26.
-   *
-   * The reason we don't encode long minified names with this method is that
-   * decoding the base 88 numbers would overflow JavaScript's puny integers.
-   *
-   * There are some selectors that have a special calling convention (because
-   * they are called with the receiver as the first argument).  They need a
-   * slightly different noSuchMethod handler, so we handle these first.
-   */
-  void addTrivialNsmHandlers(List<jsAst.Node> statements) {
-    if (trivialNsmHandlers.length == 0) return;
-    // Sort by calling convention, JS name length and by JS name.
-    trivialNsmHandlers.sort((a, b) {
-      bool aIsIntercepted = backend.isInterceptedName(a.name);
-      bool bIsIntercepted = backend.isInterceptedName(b.name);
-      if (aIsIntercepted != bIsIntercepted) return aIsIntercepted ? -1 : 1;
-      String aName = namer.invocationMirrorInternalName(a);
-      String bName = namer.invocationMirrorInternalName(b);
-      if (aName.length != bName.length) return aName.length - bName.length;
-      return aName.compareTo(bName);
-    });
-
-    // Find out how many selectors there are with the special calling
-    // convention.
-    int firstNormalSelector = trivialNsmHandlers.length;
-    for (int i = 0; i < trivialNsmHandlers.length; i++) {
-      if (!backend.isInterceptedName(trivialNsmHandlers[i].name)) {
-        firstNormalSelector = i;
-        break;
-      }
-    }
-
-    // Get the short names (JS names, perhaps minified).
-    Iterable<String> shorts = trivialNsmHandlers.map((selector) =>
-         namer.invocationMirrorInternalName(selector));
-    final diffShorts = <String>[];
-    var diffEncoding = new StringBuffer();
-
-    // Treat string as a number in base 88 with digits in ASCII order from # to
-    // z.  The short name sorting is based on length, and uses ASCII order for
-    // equal length strings so this means that names are ascending.  The hash
-    // character, #, is never given as input, but we need it because it's the
-    // implicit leading zero (otherwise we could not code names with leading
-    // dollar signs).
-    int fromBase88(String x) {
-      int answer = 0;
-      for (int i = 0; i < x.length; i++) {
-        int c = x.codeUnitAt(i);
-        // No support for Unicode minified identifiers in JS.
-        assert(c >= $$ && c <= $z);
-        answer *= 88;
-        answer += c - $HASH;
-      }
-      return answer;
-    }
-
-    // Big endian encoding, A = 0, B = 1...
-    // A lower case letter terminates the number.
-    String toBase26(int x) {
-      int c = x;
-      var encodingChars = <int>[];
-      encodingChars.add($a + (c % 26));
-      while (true) {
-        c ~/= 26;
-        if (c == 0) break;
-        encodingChars.add($A + (c % 26));
-      }
-      return new String.fromCharCodes(encodingChars.reversed.toList());
-    }
-
-    bool minify = compiler.enableMinification;
-    bool useDiffEncoding = minify && shorts.length > 30;
-
-    int previous = 0;
-    int nameCounter = 0;
-    for (String short in shorts) {
-      // Emit period that resets the diff base to zero when we switch to normal
-      // calling convention (this avoids the need to code negative diffs).
-      if (useDiffEncoding && nameCounter == firstNormalSelector) {
-        diffEncoding.write(".");
-        previous = 0;
-      }
-      if (short.length <= MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING &&
-          useDiffEncoding) {
-        int base63 = fromBase88(short);
-        int diff = base63 - previous;
-        previous = base63;
-        String base26Diff = toBase26(diff);
-        diffEncoding.write(base26Diff);
-      } else {
-        if (useDiffEncoding || diffEncoding.length != 0) {
-          diffEncoding.write(",");
-        }
-        diffEncoding.write(short);
-      }
-      nameCounter++;
-    }
-
-    // Startup code that loops over the method names and puts handlers on the
-    // Object class to catch noSuchMethod invocations.
-    ClassElement objectClass = compiler.objectClass;
-    String createInvocationMirror = namer.isolateAccess(
-        backend.getCreateInvocationMirror());
-    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
-        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);
-    var type = 0;
-    if (useDiffEncoding) {
-      statements.addAll([
-        js('var objectClassObject = '
-           '        collectedClasses["${namer.getNameOfClass(objectClass)}"],'
-           '    shortNames = "$diffEncoding".split(","),'
-           '    nameNumber = 0,'
-           '    diffEncodedString = shortNames[0],'
-           '    calculatedShortNames = [0, 1]'),  // 0, 1 are args for splice.
-        js.if_('objectClassObject instanceof Array',
-               js('objectClassObject = objectClassObject[1]')),
-        js.for_('var i = 0', 'i < diffEncodedString.length', 'i++', [
-          js('var codes = [],'
-             '    diff = 0,'
-             '    digit = diffEncodedString.charCodeAt(i)'),
-          js.if_('digit == ${$PERIOD}', [
-            js('nameNumber = 0'),
-            js('digit = diffEncodedString.charCodeAt(++i)')
-          ]),
-          js.while_('digit <= ${$Z}', [
-            js('diff *= 26'),
-            js('diff += (digit - ${$A})'),
-            js('digit = diffEncodedString.charCodeAt(++i)')
-          ]),
-          js('diff *= 26'),
-          js('diff += (digit - ${$a})'),
-          js('nameNumber += diff'),
-          js.for_('var remaining = nameNumber',
-                  'remaining > 0',
-                  'remaining = (remaining / 88) | 0', [
-            js('codes.unshift(${$HASH} + remaining % 88)')
-          ]),
-          js('calculatedShortNames.push('
-             '    String.fromCharCode.apply(String, codes))')
-        ]),
-        js('shortNames.splice.apply(shortNames, calculatedShortNames)')
-      ]);
-    } else {
-      // No useDiffEncoding version.
-      Iterable<String> longs = trivialNsmHandlers.map((selector) =>
-             selector.invocationMirrorMemberName);
-      String longNamesConstant = minify ? "" :
-          ',longNames = "${longs.join(",")}".split(",")';
-      statements.add(
-        js('var objectClassObject = '
-           '        collectedClasses["${namer.getNameOfClass(objectClass)}"],'
-           '    shortNames = "$diffEncoding".split(",")'
-           '    $longNamesConstant'));
-      statements.add(
-          js.if_('objectClassObject instanceof Array',
-                 js('objectClassObject = objectClassObject[1]')));
-    }
-
-    String sliceOffset = ', (j < $firstNormalSelector) ? 1 : 0';
-    if (firstNormalSelector == 0) sliceOffset = '';
-    if (firstNormalSelector == shorts.length) sliceOffset = ', 1';
-
-    String whatToPatch = nativeEmitter.handleNoSuchMethod ?
-                         "Object.prototype" :
-                         "objectClassObject";
-
-    var params = ['name', 'short', 'type'];
-    var sliceOffsetParam = '';
-    var slice = 'Array.prototype.slice.call';
-    if (!sliceOffset.isEmpty) {
-      sliceOffsetParam = ', sliceOffset';
-      params.add('sliceOffset');
-    }
-    statements.addAll([
-      js.for_('var j = 0', 'j < shortNames.length', 'j++', [
-        js('var type = 0'),
-        js('var short = shortNames[j]'),
-        js.if_('short[0] == "${namer.getterPrefix[0]}"', js('type = 1')),
-        js.if_('short[0] == "${namer.setterPrefix[0]}"', js('type = 2')),
-        // Generate call to:
-        // createInvocationMirror(String name, internalName, type, arguments,
-        //                        argumentNames)
-        js('$whatToPatch[short] = #(${minify ? "shortNames" : "longNames"}[j], '
-                                    'short, type$sliceOffset)',
-           js.fun(params, [js.return_(js.fun([],
-               [js.return_(js(
-                   'this.$noSuchMethodName('
-                       'this, '
-                       '$createInvocationMirror('
-                           'name, short, type, '
-                           '$slice(arguments$sliceOffsetParam), []))'))]))]))
-      ])
-    ]);
-  }
-
   jsAst.Fun get finishClassesFunction {
     // Class descriptions are collected in a JS object.
     // 'finishClasses' takes all collected descriptions and sets up
@@ -711,7 +392,7 @@
       buildFinishClass(),
     ];
 
-    addTrivialNsmHandlers(statements);
+    nsmEmitter.addTrivialNsmHandlers(statements);
 
     statements.add(
       js.forIn('cls', 'pendingClasses', js('finishClass(cls)'))
@@ -889,28 +570,6 @@
     buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N");
   }
 
-  bool fieldNeedsGetter(VariableElement field) {
-    assert(field.isField());
-    if (fieldAccessNeverThrows(field)) return false;
-    return backend.shouldRetainGetter(field)
-        || compiler.codegenWorld.hasInvokedGetter(field, compiler);
-  }
-
-  bool fieldNeedsSetter(VariableElement field) {
-    assert(field.isField());
-    if (fieldAccessNeverThrows(field)) return false;
-    return (!field.modifiers.isFinalOrConst())
-        && (backend.shouldRetainSetter(field)
-            || compiler.codegenWorld.hasInvokedSetter(field, compiler));
-  }
-
-  // We never access a field in a closure (a captured variable) without knowing
-  // that it is there.  Therefore we don't need to use a getter (that will throw
-  // if the getter method is missing), but can always access the field directly.
-  static bool fieldAccessNeverThrows(VariableElement field) {
-    return field is ClosureFieldElement;
-  }
-
   /// Returns the "reflection name" of an [Element] or [Selector].
   /// The reflection name of a getter 'foo' is 'foo'.
   /// The reflection name of a setter 'foo' is 'foo='.
@@ -1021,391 +680,6 @@
     return ':$names';
   }
 
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [classElement] must be a declaration element.
-   */
-  void emitInstanceMembers(ClassElement classElement,
-                           ClassBuilder builder) {
-    assert(invariant(classElement, classElement.isDeclaration));
-
-    void visitMember(ClassElement enclosing, Element member) {
-      assert(invariant(classElement, member.isDeclaration));
-      if (member.isInstanceMember()) {
-        containerBuilder.addMember(member, builder);
-      }
-    }
-
-    classElement.implementation.forEachMember(
-        visitMember,
-        includeBackendMembers: true);
-
-    if (identical(classElement, compiler.objectClass)
-        && compiler.enabledNoSuchMethod) {
-      // Emit the noSuchMethod handlers on the Object prototype now,
-      // so that the code in the dynamicFunction helper can find
-      // them. Note that this helper is invoked before analyzing the
-      // full JS script.
-      if (!nativeEmitter.handleNoSuchMethod) {
-        emitNoSuchMethodHandlers(builder.addProperty);
-      }
-    }
-  }
-
-  void emitIsTests(ClassElement classElement, ClassBuilder builder) {
-    assert(invariant(classElement, classElement.isDeclaration));
-
-    void generateIsTest(Element other) {
-      if (other == compiler.objectClass && other != classElement) {
-        // Avoid emitting [:$isObject:] on all classes but [Object].
-        return;
-      }
-      other = backend.getImplementationClass(other);
-      builder.addProperty(namer.operatorIs(other), js('true'));
-    }
-
-    void generateIsFunctionTypeTest(FunctionType type) {
-      String operator = namer.operatorIsType(type);
-      builder.addProperty(operator, new jsAst.LiteralBool(true));
-    }
-
-    void generateFunctionTypeSignature(Element method, FunctionType type) {
-      assert(method.isImplementation);
-      jsAst.Expression thisAccess = new jsAst.This();
-      Node node = method.parseNode(compiler);
-      ClosureClassMap closureData =
-          compiler.closureToClassMapper.closureMappingCache[node];
-      if (closureData != null) {
-        Element thisElement =
-            closureData.freeVariableMapping[closureData.thisElement];
-        if (thisElement != null) {
-          assert(thisElement.hasFixedBackendName());
-          String thisName = thisElement.fixedBackendName();
-          thisAccess = js('this')[js.string(thisName)];
-        }
-      }
-      RuntimeTypes rti = backend.rti;
-      jsAst.Expression encoding = rti.getSignatureEncoding(type, thisAccess);
-      String operatorSignature = namer.operatorSignature();
-      builder.addProperty(operatorSignature, encoding);
-    }
-
-    void generateSubstitution(ClassElement cls, {bool emitNull: false}) {
-      if (cls.typeVariables.isEmpty) return;
-      RuntimeTypes rti = backend.rti;
-      jsAst.Expression expression;
-      bool needsNativeCheck = nativeEmitter.requiresNativeIsCheck(cls);
-      expression = rti.getSupertypeSubstitution(
-          classElement, cls, alwaysGenerateFunction: true);
-      if (expression == null && (emitNull || needsNativeCheck)) {
-        expression = new jsAst.LiteralNull();
-      }
-      if (expression != null) {
-        builder.addProperty(namer.substitutionName(cls), expression);
-      }
-    }
-
-    generateIsTestsOn(classElement, generateIsTest,
-        generateIsFunctionTypeTest, generateFunctionTypeSignature,
-        generateSubstitution);
-  }
-
-  void emitRuntimeTypeSupport(CodeBuffer buffer) {
-    addComment('Runtime type support', buffer);
-    RuntimeTypes rti = backend.rti;
-    TypeChecks typeChecks = rti.requiredChecks;
-
-    // Add checks to the constructors of instantiated classes.
-    for (ClassElement cls in typeChecks) {
-      // TODO(9556).  The properties added to 'holder' should be generated
-      // directly as properties of the class object, not added later.
-      String holder = namer.isolateAccess(backend.getImplementationClass(cls));
-      for (TypeCheck check in typeChecks[cls]) {
-        ClassElement cls = check.cls;
-        buffer.write('$holder.${namer.operatorIs(cls)}$_=${_}true$N');
-        Substitution substitution = check.substitution;
-        if (substitution != null) {
-          CodeBuffer body =
-             jsAst.prettyPrint(substitution.getCode(rti, false), compiler);
-          buffer.write('$holder.${namer.substitutionName(cls)}$_=${_}');
-          buffer.write(body);
-          buffer.write('$N');
-        }
-      };
-    }
-
-    void addSignature(FunctionType type) {
-      jsAst.Expression encoding = rti.getTypeEncoding(type);
-      buffer.add('${namer.signatureName(type)}$_=${_}');
-      buffer.write(jsAst.prettyPrint(encoding, compiler));
-      buffer.add('$N');
-    }
-
-    checkedNonGenericFunctionTypes.forEach(addSignature);
-
-    checkedGenericFunctionTypes.forEach((_, Set<FunctionType> functionTypes) {
-      functionTypes.forEach(addSignature);
-    });
-  }
-
-  /**
-   * Returns the classes with constructors used as a 'holder' in
-   * [emitRuntimeTypeSupport].
-   * TODO(9556): Some cases will go away when the class objects are created as
-   * complete.  Not all classes will go away while constructors are referenced
-   * from type substitutions.
-   */
-  Set<ClassElement> classesModifiedByEmitRuntimeTypeSupport() {
-    TypeChecks typeChecks = backend.rti.requiredChecks;
-    Set<ClassElement> result = new Set<ClassElement>();
-    for (ClassElement cls in typeChecks) {
-      for (TypeCheck check in typeChecks[cls]) {
-        result.add(backend.getImplementationClass(cls));
-        break;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Calls [addField] for each of the fields of [element].
-   *
-   * [element] must be a [ClassElement] or a [LibraryElement].
-   *
-   * If [element] is a [ClassElement], the static fields of the class are
-   * visited if [visitStatics] is true and the instance fields are visited if
-   * [visitStatics] is false.
-   *
-   * If [element] is a [LibraryElement], [visitStatics] must be true.
-   *
-   * When visiting the instance fields of a class, the fields of its superclass
-   * are also visited if the class is instantiated.
-   *
-   * Invariant: [element] must be a declaration element.
-   */
-  void visitFields(Element element, bool visitStatics, AcceptField f) {
-    assert(invariant(element, element.isDeclaration));
-
-    bool isClass = false;
-    bool isLibrary = false;
-    if (element.isClass()) {
-      isClass = true;
-    } else if (element.isLibrary()) {
-      isLibrary = true;
-      assert(invariant(element, visitStatics));
-    } else {
-      throw new SpannableAssertionFailure(
-          element, 'Expected a ClassElement or a LibraryElement.');
-    }
-
-    // If the class is never instantiated we still need to set it up for
-    // inheritance purposes, but we can simplify its JavaScript constructor.
-    bool isInstantiated =
-        compiler.codegenWorld.instantiatedClasses.contains(element);
-
-    void visitField(Element holder, VariableElement field) {
-      assert(invariant(element, field.isDeclaration));
-      SourceString name = field.name;
-
-      // Keep track of whether or not we're dealing with a field mixin
-      // into a native class.
-      bool isMixinNativeField =
-          isClass && element.isNative() && holder.isMixinApplication;
-
-      // See if we can dynamically create getters and setters.
-      // We can only generate getters and setters for [element] since
-      // the fields of super classes could be overwritten with getters or
-      // setters.
-      bool needsGetter = false;
-      bool needsSetter = false;
-      // We need to name shadowed fields differently, so they don't clash with
-      // the non-shadowed field.
-      bool isShadowed = false;
-      if (isLibrary || isMixinNativeField || holder == element) {
-        needsGetter = fieldNeedsGetter(field);
-        needsSetter = fieldNeedsSetter(field);
-      } else {
-        ClassElement cls = element;
-        isShadowed = cls.isShadowedByField(field);
-      }
-
-      if ((isInstantiated && !holder.isNative())
-          || needsGetter
-          || needsSetter) {
-        String accessorName = isShadowed
-            ? namer.shadowedFieldName(field)
-            : namer.getNameOfField(field);
-        String fieldName = field.hasFixedBackendName()
-            ? field.fixedBackendName()
-            : (isMixinNativeField ? name.slowToString() : accessorName);
-        bool needsCheckedSetter = false;
-        if (compiler.enableTypeAssertions
-            && needsSetter
-            && canGenerateCheckedSetter(field)) {
-          needsCheckedSetter = true;
-          needsSetter = false;
-        }
-        // Getters and setters with suffixes will be generated dynamically.
-        f(field, fieldName, accessorName, needsGetter, needsSetter,
-          needsCheckedSetter);
-      }
-    }
-
-    if (isLibrary) {
-      LibraryElement library = element;
-      library.implementation.forEachLocalMember((Element member) {
-        if (member.isField()) visitField(library, member);
-      });
-    } else if (visitStatics) {
-      ClassElement cls = element;
-      cls.implementation.forEachStaticField(visitField);
-    } else {
-      ClassElement cls = element;
-      // TODO(kasperl): We should make sure to only emit one version of
-      // overridden fields. Right now, we rely on the ordering so the
-      // fields pulled in from mixins are replaced with the fields from
-      // the class definition.
-
-      // If a class is not instantiated then we add the field just so we can
-      // generate the field getter/setter dynamically. Since this is only
-      // allowed on fields that are in [element] we don't need to visit
-      // superclasses for non-instantiated classes.
-      cls.implementation.forEachInstanceField(
-          visitField, includeSuperAndInjectedMembers: isInstantiated);
-    }
-  }
-
-  void generateReflectionDataForFieldGetterOrSetter(Element member,
-                                                    String name,
-                                                    ClassBuilder builder,
-                                                    {bool isGetter}) {
-    Selector selector = isGetter
-        ? new Selector.getter(member.name, member.getLibrary())
-        : new Selector.setter(member.name, member.getLibrary());
-    String reflectionName = getReflectionName(selector, name);
-    if (reflectionName != null) {
-      var reflectable =
-          js(backend.isAccessibleByReflection(member) ? '1' : '0');
-      builder.addProperty('+$reflectionName', reflectable);
-    }
-  }
-
-  void generateGetter(Element member, String fieldName, String accessorName,
-                      ClassBuilder builder) {
-    String getterName = namer.getterNameFromAccessorName(accessorName);
-    ClassElement cls = member.getEnclosingClass();
-    String className = namer.getNameOfClass(cls);
-    String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this';
-    List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : [];
-    precompiledFunction.add(
-        js('$className.prototype.$getterName = #',
-           js.fun(args, js.return_(js('$receiver.$fieldName')))));
-    if (backend.isNeededForReflection(member)) {
-      precompiledFunction.add(
-          js('$className.prototype.$getterName.${namer.reflectableField} = 1'));
-    }
-  }
-
-  void generateSetter(Element member, String fieldName, String accessorName,
-                      ClassBuilder builder) {
-    String setterName = namer.setterNameFromAccessorName(accessorName);
-    ClassElement cls = member.getEnclosingClass();
-    String className = namer.getNameOfClass(cls);
-    String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this';
-    List<String> args =
-        backend.isInterceptedMethod(member) ? ['receiver', 'v'] : ['v'];
-    precompiledFunction.add(
-        js('$className.prototype.$setterName = #',
-           js.fun(args, js.return_(js('$receiver.$fieldName = v')))));
-    if (backend.isNeededForReflection(member)) {
-      precompiledFunction.add(
-          js('$className.prototype.$setterName.${namer.reflectableField} = 1'));
-    }
-  }
-
-  bool canGenerateCheckedSetter(VariableElement field) {
-    // We never generate accessors for top-level/static fields.
-    if (!field.isInstanceMember()) return false;
-    DartType type = field.computeType(compiler).unalias(compiler);
-    if (type.element.isTypeVariable() ||
-        (type is FunctionType && type.containsTypeVariables) ||
-        type.treatAsDynamic ||
-        type.element == compiler.objectClass) {
-      // TODO(ngeoffray): Support type checks on type parameters.
-      return false;
-    }
-    return true;
-  }
-
-  void generateCheckedSetter(Element member,
-                             String fieldName,
-                             String accessorName,
-                             ClassBuilder builder) {
-    assert(canGenerateCheckedSetter(member));
-    DartType type = member.computeType(compiler);
-    // TODO(ahe): Generate a dynamic type error here.
-    if (type.element.isErroneous()) return;
-    type = type.unalias(compiler);
-    // TODO(11273): Support complex subtype checks.
-    type = type.asRaw();
-    CheckedModeHelper helper =
-        backend.getCheckedModeHelper(type, typeCast: false);
-    FunctionElement helperElement = helper.getElement(compiler);
-    String helperName = namer.isolateAccess(helperElement);
-    List<jsAst.Expression> arguments = <jsAst.Expression>[js('v')];
-    if (helperElement.computeSignature(compiler).parameterCount != 1) {
-      arguments.add(js.string(namer.operatorIsType(type)));
-    }
-
-    String setterName = namer.setterNameFromAccessorName(accessorName);
-    String receiver = backend.isInterceptorClass(member.getEnclosingClass())
-        ? 'receiver' : 'this';
-    List<String> args = backend.isInterceptedMethod(member)
-        ? ['receiver', 'v']
-        : ['v'];
-    builder.addProperty(setterName,
-        js.fun(args,
-            js('$receiver.$fieldName = #', js(helperName)(arguments))));
-    generateReflectionDataForFieldGetterOrSetter(
-        member, setterName, builder, isGetter: false);
-  }
-
-  void emitClassConstructor(ClassElement classElement,
-                            ClassBuilder builder,
-                            String runtimeName) {
-    List<String> fields = <String>[];
-    if (!classElement.isNative()) {
-      visitFields(classElement, false,
-                  (Element member,
-                   String name,
-                   String accessorName,
-                   bool needsGetter,
-                   bool needsSetter,
-                   bool needsCheckedSetter) {
-        fields.add(name);
-      });
-    }
-    String constructorName = namer.getNameOfClass(classElement);
-    precompiledFunction.add(new jsAst.FunctionDeclaration(
-        new jsAst.VariableDeclaration(constructorName),
-        js.fun(fields, fields.map(
-            (name) => js('this.$name = $name')).toList())));
-    if (runtimeName == null) {
-      runtimeName = constructorName;
-    }
-    precompiledFunction.addAll([
-        js('$constructorName.builtin\$cls = "$runtimeName"'),
-        js.if_('!"name" in $constructorName',
-              js('$constructorName.name = "$constructorName"')),
-        js('\$desc=\$collectedClasses.$constructorName'),
-        js.if_('\$desc instanceof Array', js('\$desc = \$desc[1]')),
-        js('$constructorName.prototype = \$desc'),
-    ]);
-
-    precompiledConstructorNames.add(js(constructorName));
-  }
-
   jsAst.FunctionDeclaration buildPrecompiledFunction() {
     // TODO(ahe): Compute a hash code.
     String name = 'dart_precompiled';
@@ -1419,313 +693,10 @@
         js.fun([r'$collectedClasses'], precompiledFunction));
   }
 
-  void emitSuper(String superName, ClassBuilder builder) {
-    /* Do nothing. */
-  }
-
-  void emitRuntimeName(String runtimeName, ClassBuilder builder) {
-    /* Do nothing. */
-  }
-
-  void recordMangledField(Element member,
-                          String accessorName,
-                          String memberName) {
-    if (!backend.shouldRetainGetter(member)) return;
-    String previousName;
-    if (member.isInstanceMember()) {
-      previousName = mangledFieldNames.putIfAbsent(
-          '${namer.getterPrefix}$accessorName',
-          () => memberName);
-    } else {
-      previousName = mangledGlobalFieldNames.putIfAbsent(
-          accessorName,
-          () => memberName);
-    }
-    assert(invariant(member, previousName == memberName,
-                     message: '$previousName != ${memberName}'));
-  }
-
-  /// Returns `true` if fields added.
-  bool emitFields(Element element,
-                  ClassBuilder builder,
-                  String superName,
-                  { bool classIsNative: false,
-                    bool emitStatics: false,
-                    bool onlyForRti: false }) {
-    assert(!emitStatics || !onlyForRti);
-    bool isClass = false;
-    bool isLibrary = false;
-    if (element.isClass()) {
-      isClass = true;
-    } else if (element.isLibrary()) {
-      isLibrary = false;
-      assert(invariant(element, emitStatics));
-    } else {
-      throw new SpannableAssertionFailure(
-          element, 'Must be a ClassElement or a LibraryElement');
-    }
-    StringBuffer buffer = new StringBuffer();
-    if (emitStatics) {
-      assert(invariant(element, superName == null, message: superName));
-    } else {
-      assert(invariant(element, superName != null));
-      String nativeName =
-          namer.getPrimitiveInterceptorRuntimeName(element);
-      if (nativeName != null) {
-        buffer.write('$nativeName/');
-      }
-      buffer.write('$superName;');
-    }
-    int bufferClassLength = buffer.length;
-
-    String separator = '';
-
-    var fieldMetadata = [];
-    bool hasMetadata = false;
-
-    if (!onlyForRti) {
-      visitFields(element, emitStatics,
-                  (VariableElement field,
-                   String name,
-                   String accessorName,
-                   bool needsGetter,
-                   bool needsSetter,
-                   bool needsCheckedSetter) {
-        // Ignore needsCheckedSetter - that is handled below.
-        bool needsAccessor = (needsGetter || needsSetter);
-        // We need to output the fields for non-native classes so we can auto-
-        // generate the constructor.  For native classes there are no
-        // constructors, so we don't need the fields unless we are generating
-        // accessors at runtime.
-        if (!classIsNative || needsAccessor) {
-          buffer.write(separator);
-          separator = ',';
-          var metadata = buildMetadataFunction(field);
-          if (metadata != null) {
-            hasMetadata = true;
-          } else {
-            metadata = new jsAst.LiteralNull();
-          }
-          fieldMetadata.add(metadata);
-          recordMangledField(field, accessorName, field.name.slowToString());
-          if (!needsAccessor) {
-            // Emit field for constructor generation.
-            assert(!classIsNative);
-            buffer.write(name);
-          } else {
-            // Emit (possibly renaming) field name so we can add accessors at
-            // runtime.
-            buffer.write(accessorName);
-            if (name != accessorName) {
-              buffer.write(':$name');
-              // Only the native classes can have renaming accessors.
-              assert(classIsNative);
-            }
-
-            int getterCode = 0;
-            if (needsGetter) {
-              if (field.isInstanceMember()) {
-                // 01:  function() { return this.field; }
-                // 10:  function(receiver) { return receiver.field; }
-                // 11:  function(receiver) { return this.field; }
-                bool isIntercepted = backend.fieldHasInterceptedGetter(field);
-                getterCode += isIntercepted ? 2 : 0;
-                getterCode += backend.isInterceptorClass(element) ? 0 : 1;
-                // TODO(sra): 'isInterceptorClass' might not be the correct test
-                // for methods forced to use the interceptor convention because
-                // the method's class was elsewhere mixed-in to an interceptor.
-                assert(!field.isInstanceMember() || getterCode != 0);
-                if (isIntercepted) {
-                  interceptorInvocationNames.add(namer.getterName(field));
-                }
-              } else {
-                getterCode = 1;
-              }
-            }
-            int setterCode = 0;
-            if (needsSetter) {
-              if (field.isInstanceMember()) {
-                // 01:  function(value) { this.field = value; }
-                // 10:  function(receiver, value) { receiver.field = value; }
-                // 11:  function(receiver, value) { this.field = value; }
-                bool isIntercepted = backend.fieldHasInterceptedSetter(field);
-                setterCode += isIntercepted ? 2 : 0;
-                setterCode += backend.isInterceptorClass(element) ? 0 : 1;
-                assert(!field.isInstanceMember() || setterCode != 0);
-                if (isIntercepted) {
-                  interceptorInvocationNames.add(namer.setterName(field));
-                }
-              } else {
-                setterCode = 1;
-              }
-            }
-            int code = getterCode + (setterCode << 2);
-            if (code == 0) {
-              compiler.reportInternalError(
-                  field, 'Internal error: code is 0 ($element/$field)');
-            } else {
-              buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]);
-            }
-          }
-          if (backend.isAccessibleByReflection(field)) {
-            buffer.write(new String.fromCharCode(REFLECTION_MARKER));
-          }
-        }
-      });
-    }
-
-    bool fieldsAdded = buffer.length > bufferClassLength;
-    String compactClassData = buffer.toString();
-    jsAst.Expression classDataNode = js.string(compactClassData);
-    if (hasMetadata) {
-      fieldMetadata.insert(0, classDataNode);
-      classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata);
-    }
-    builder.addProperty('', classDataNode);
-    return fieldsAdded;
-  }
-
-  void emitClassGettersSetters(ClassElement classElement,
-                               ClassBuilder builder) {
-
-    visitFields(classElement, false,
-                (VariableElement member,
-                 String name,
-                 String accessorName,
-                 bool needsGetter,
-                 bool needsSetter,
-                 bool needsCheckedSetter) {
-      compiler.withCurrentElement(member, () {
-        if (needsCheckedSetter) {
-          assert(!needsSetter);
-          generateCheckedSetter(member, name, accessorName, builder);
-        }
-        if (needsGetter) {
-          generateGetter(member, name, accessorName, builder);
-        }
-        if (needsSetter) {
-          generateSetter(member, name, accessorName, builder);
-        }
-      });
-    });
-  }
-
-  /**
-   * Documentation wanted -- johnniwinther
-   *
-   * Invariant: [classElement] must be a declaration element.
-   */
   void generateClass(ClassElement classElement, CodeBuffer buffer) {
-    final onlyForRti = rtiNeededClasses.contains(classElement);
-
-    assert(invariant(classElement, classElement.isDeclaration));
-    assert(invariant(classElement, !classElement.isNative() || onlyForRti));
-
-    needsDefineClass = true;
-    String className = namer.getNameOfClass(classElement);
-
-    ClassElement superclass = classElement.superclass;
-    String superName = "";
-    if (superclass != null) {
-      superName = namer.getNameOfClass(superclass);
-    }
-    String runtimeName =
-        namer.getPrimitiveInterceptorRuntimeName(classElement);
-
-    if (classElement.isMixinApplication) {
-      String mixinName = namer.getNameOfClass(computeMixinClass(classElement));
-      superName = '$superName+$mixinName';
-      needsMixinSupport = true;
-    }
-
-    ClassBuilder builder = new ClassBuilder();
-    emitClassConstructor(classElement, builder, runtimeName);
-    emitSuper(superName, builder);
-    emitRuntimeName(runtimeName, builder);
-    emitFields(classElement, builder, superName, onlyForRti: onlyForRti);
-    emitClassGettersSetters(classElement, builder);
-    if (!classElement.isMixinApplication) {
-      emitInstanceMembers(classElement, builder);
-    }
-    emitIsTests(classElement, builder);
-
-    emitClassBuilderWithReflectionData(
-        className, classElement, builder, buffer);
+    classEmitter.generateClass(classElement, buffer);
   }
 
-  void emitClassBuilderWithReflectionData(String className,
-                                          ClassElement classElement,
-                                          ClassBuilder builder,
-                                          CodeBuffer buffer) {
-    var metadata = buildMetadataFunction(classElement);
-    if (metadata != null) {
-      builder.addProperty("@", metadata);
-    }
-
-    if (backend.isNeededForReflection(classElement)) {
-      Link typeVars = classElement.typeVariables;
-      List properties = [];
-      for (TypeVariableType typeVar in typeVars) {
-        properties.add(js.string(typeVar.name.slowToString()));
-        properties.add(js.toExpression(reifyType(typeVar.element.bound)));
-      }
-
-      ClassElement superclass = classElement.superclass;
-      bool hasSuper = superclass != null;
-      if ((!properties.isEmpty && !hasSuper) ||
-          (hasSuper && superclass.typeVariables != typeVars)) {
-        builder.addProperty('<>', new jsAst.ArrayInitializer.from(properties));
-      }
-    }
-    List<CodeBuffer> classBuffers = elementBuffers[classElement];
-    if (classBuffers == null) {
-      classBuffers = [];
-    } else {
-      elementBuffers.remove(classElement);
-    }
-    CodeBuffer statics = new CodeBuffer();
-    statics.write('{$n');
-    bool hasStatics = false;
-    ClassBuilder staticsBuilder = new ClassBuilder();
-    if (emitFields(classElement, staticsBuilder, null, emitStatics: true)) {
-      hasStatics = true;
-      statics.write('"":$_');
-      statics.write(
-          jsAst.prettyPrint(staticsBuilder.properties.single.value, compiler));
-      statics.write(',$n');
-    }
-    for (CodeBuffer classBuffer in classBuffers) {
-      // TODO(ahe): What about deferred?
-      if (classBuffer != null) {
-        hasStatics = true;
-        statics.addBuffer(classBuffer);
-      }
-    }
-    statics.write('}$n');
-    if (hasStatics) {
-      builder.addProperty('static', new jsAst.Blob(statics));
-    }
-
-    // TODO(ahe): This method (generateClass) should return a jsAst.Expression.
-    if (!buffer.isEmpty) {
-      buffer.write(',$n$n');
-    }
-    buffer.write('$className:$_');
-    buffer.write(jsAst.prettyPrint(builder.toObjectInitializer(), compiler));
-    String reflectionName = getReflectionName(classElement, className);
-    if (reflectionName != null) {
-      List<int> interfaces = <int>[];
-      for (DartType interface in classElement.interfaces) {
-        interfaces.add(reifyType(interface));
-      }
-      buffer.write(',$n$n"+$reflectionName": $interfaces');
-    }
-  }
-
-  /// If this is true then we can generate the noSuchMethod handlers at startup
-  /// time, instead of them being emitted as part of the Object class.
-  bool get generateTrivialNsmHandlers => true;
-
   int _selectorRank(Selector selector) {
     int arity = selector.argumentCount * 3;
     if (selector.isGetter()) return arity + 2;
@@ -1741,196 +712,6 @@
   }
 
   /**
-   * Returns a mapping containing all checked function types for which [type]
-   * can be a subtype. A function type is mapped to [:true:] if [type] is
-   * statically known to be a subtype of it and to [:false:] if [type] might
-   * be a subtype, provided with the right type arguments.
-   */
-  // TODO(johnniwinther): Change to return a mapping from function types to
-  // a set of variable points and use this to detect statically/dynamically
-  // known subtype relations.
-  Map<FunctionType, bool> getFunctionTypeChecksOn(DartType type) {
-    Map<FunctionType, bool> functionTypeMap =
-        new LinkedHashMap<FunctionType, bool>();
-    for (FunctionType functionType in checkedFunctionTypes) {
-      if (compiler.types.isSubtype(type, functionType)) {
-        functionTypeMap[functionType] = true;
-      } else if (compiler.types.isPotentialSubtype(type, functionType)) {
-        functionTypeMap[functionType] = false;
-      }
-    }
-    // TODO(johnniwinther): Ensure stable ordering of the keys.
-    return functionTypeMap;
-  }
-
-  /**
-   * Generate "is tests" for [cls]: itself, and the "is tests" for the
-   * classes it implements and type argument substitution functions for these
-   * tests.   We don't need to add the "is tests" of the super class because
-   * they will be inherited at runtime, but we may need to generate the
-   * substitutions, because they may have changed.
-   */
-  void generateIsTestsOn(ClassElement cls,
-                         void emitIsTest(Element element),
-                         FunctionTypeTestEmitter emitIsFunctionTypeTest,
-                         FunctionTypeSignatureEmitter emitFunctionTypeSignature,
-                         SubstitutionEmitter emitSubstitution) {
-    if (checkedClasses.contains(cls)) {
-      emitIsTest(cls);
-      emitSubstitution(cls);
-    }
-
-    RuntimeTypes rti = backend.rti;
-    ClassElement superclass = cls.superclass;
-
-    bool haveSameTypeVariables(ClassElement a, ClassElement b) {
-      if (a.isClosure()) return true;
-      if (b.isUnnamedMixinApplication) {
-        return false;
-      }
-      return a.typeVariables == b.typeVariables;
-    }
-
-    if (superclass != null && superclass != compiler.objectClass &&
-        !haveSameTypeVariables(cls, superclass)) {
-      // We cannot inherit the generated substitutions, because the type
-      // variable layout for this class is different.  Instead we generate
-      // substitutions for all checks and make emitSubstitution a NOP for the
-      // rest of this function.
-      Set<ClassElement> emitted = new Set<ClassElement>();
-      // TODO(karlklose): move the computation of these checks to
-      // RuntimeTypeInformation.
-      if (backend.classNeedsRti(cls)) {
-        emitSubstitution(superclass, emitNull: true);
-        emitted.add(superclass);
-      }
-      for (DartType supertype in cls.allSupertypes) {
-        ClassElement superclass = supertype.element;
-        if (classesUsingTypeVariableTests.contains(superclass)) {
-          emitSubstitution(superclass, emitNull: true);
-          emitted.add(superclass);
-        }
-        for (ClassElement check in checkedClasses) {
-          if (supertype.element == check && !emitted.contains(check)) {
-            // Generate substitution.  If no substitution is necessary, emit
-            // [:null:] to overwrite a (possibly) existing substitution from the
-            // super classes.
-            emitSubstitution(check, emitNull: true);
-            emitted.add(check);
-          }
-        }
-      }
-      void emitNothing(_, {emitNull}) {};
-      emitSubstitution = emitNothing;
-    }
-
-    Set<Element> generated = new Set<Element>();
-    // A class that defines a [:call:] method implicitly implements
-    // [Function] and needs checks for all typedefs that are used in is-checks.
-    if (checkedClasses.contains(compiler.functionClass) ||
-        !checkedFunctionTypes.isEmpty) {
-      Element call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
-      if (call == null) {
-        // If [cls] is a closure, it has a synthetic call operator method.
-        call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
-      }
-      if (call != null && call.isFunction()) {
-        generateInterfacesIsTests(compiler.functionClass,
-                                  emitIsTest,
-                                  emitSubstitution,
-                                  generated);
-        FunctionType callType = call.computeType(compiler);
-        Map<FunctionType, bool> functionTypeChecks =
-            getFunctionTypeChecksOn(callType);
-        generateFunctionTypeTests(call, callType, functionTypeChecks,
-            emitFunctionTypeSignature, emitIsFunctionTypeTest);
-     }
-    }
-
-    for (DartType interfaceType in cls.interfaces) {
-      generateInterfacesIsTests(interfaceType.element, emitIsTest,
-                                emitSubstitution, generated);
-    }
-  }
-
-  /**
-   * Generate "is tests" where [cls] is being implemented.
-   */
-  void generateInterfacesIsTests(ClassElement cls,
-                                 void emitIsTest(ClassElement element),
-                                 SubstitutionEmitter emitSubstitution,
-                                 Set<Element> alreadyGenerated) {
-    void tryEmitTest(ClassElement check) {
-      if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
-        alreadyGenerated.add(check);
-        emitIsTest(check);
-        emitSubstitution(check);
-      }
-    };
-
-    tryEmitTest(cls);
-
-    for (DartType interfaceType in cls.interfaces) {
-      Element element = interfaceType.element;
-      tryEmitTest(element);
-      generateInterfacesIsTests(element, emitIsTest, emitSubstitution,
-                                alreadyGenerated);
-    }
-
-    // We need to also emit "is checks" for the superclass and its supertypes.
-    ClassElement superclass = cls.superclass;
-    if (superclass != null) {
-      tryEmitTest(superclass);
-      generateInterfacesIsTests(superclass, emitIsTest, emitSubstitution,
-                                alreadyGenerated);
-    }
-  }
-
-  static const int MAX_FUNCTION_TYPE_PREDICATES = 10;
-
-  /**
-   * Generates function type checks on [method] with type [methodType] against
-   * the function type checks in [functionTypeChecks].
-   */
-  void generateFunctionTypeTests(
-      Element method,
-      FunctionType methodType,
-      Map<FunctionType, bool> functionTypeChecks,
-      FunctionTypeSignatureEmitter emitFunctionTypeSignature,
-      FunctionTypeTestEmitter emitIsFunctionTypeTest) {
-    bool hasDynamicFunctionTypeCheck = false;
-    int neededPredicates = 0;
-    functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
-      if (!knownSubtype) {
-        registerDynamicFunctionTypeCheck(functionType);
-        hasDynamicFunctionTypeCheck = true;
-      } else if (!backend.rti.isSimpleFunctionType(functionType)) {
-        // Simple function types are always checked using predicates and should
-        // not provoke generation of signatures.
-        neededPredicates++;
-      }
-    });
-    bool alwaysUseSignature = false;
-    if (hasDynamicFunctionTypeCheck ||
-        neededPredicates > MAX_FUNCTION_TYPE_PREDICATES) {
-      emitFunctionTypeSignature(method, methodType);
-      alwaysUseSignature = true;
-    }
-    functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
-      if (knownSubtype) {
-        if (backend.rti.isSimpleFunctionType(functionType)) {
-          // Simple function types are always checked using predicates.
-          emitIsFunctionTypeTest(functionType);
-        } else if (alwaysUseSignature) {
-          registerDynamicFunctionTypeCheck(functionType);
-        } else {
-          emitIsFunctionTypeTest(functionType);
-        }
-      }
-    });
-  }
-
-  /**
    * Return a function that returns true if its argument is a class
    * that needs to be emitted.
    */
@@ -2137,126 +918,6 @@
 ''');
   }
 
-  // Identify the noSuchMethod handlers that are so simple that we can
-  // generate them programatically.
-  bool isTrivialNsmHandler(
-      int type, List argNames, Selector selector, String internalName) {
-    if (!generateTrivialNsmHandlers) return false;
-    // Check for interceptor calling convention.
-    if (backend.isInterceptedName(selector.name)) {
-      // We can handle the calling convention used by intercepted names in the
-      // diff encoding, but we don't use that for non-minified code.
-      if (!compiler.enableMinification) return false;
-      String shortName = namer.invocationMirrorInternalName(selector);
-      if (shortName.length > MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING) {
-        return false;
-      }
-    }
-    // Check for named arguments.
-    if (argNames.length != 0) return false;
-    // Check for unexpected name (this doesn't really happen).
-    if (internalName.startsWith(namer.getterPrefix[0])) return type == 1;
-    if (internalName.startsWith(namer.setterPrefix[0])) return type == 2;
-    return type == 0;
-  }
-
-  void emitNoSuchMethodHandlers(DefineStubFunction defineStub) {
-    // Do not generate no such method handlers if there is no class.
-    if (compiler.codegenWorld.instantiatedClasses.isEmpty) return;
-
-    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
-        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);
-
-    // Keep track of the JavaScript names we've already added so we
-    // do not introduce duplicates (bad for code size).
-    Map<String, Selector> addedJsNames = new Map<String, Selector>();
-
-    void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) {
-      // Cache the object class and type.
-      ClassElement objectClass = compiler.objectClass;
-      DartType objectType = objectClass.computeType(compiler);
-
-      for (Selector selector in selectors) {
-        TypeMask mask = selector.mask;
-        if (mask == null) {
-          mask = new TypeMask.subclass(compiler.objectClass);
-        }
-
-        if (!mask.needsNoSuchMethodHandling(selector, compiler)) continue;
-        String jsName = namer.invocationMirrorInternalName(selector);
-        addedJsNames[jsName] = selector;
-        String reflectionName = getReflectionName(selector, jsName);
-        if (reflectionName != null) {
-          mangledFieldNames[jsName] = reflectionName;
-        }
-      }
-    }
-
-    compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers);
-    compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers);
-    compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers);
-
-    // Set flag used by generateMethod helper below.  If we have very few
-    // handlers we use defineStub for them all, rather than try to generate them
-    // at runtime.
-    bool haveVeryFewNoSuchMemberHandlers =
-        (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS);
-
-    jsAst.Expression generateMethod(String jsName, Selector selector) {
-      // Values match JSInvocationMirror in js-helper library.
-      int type = selector.invocationMirrorKind;
-      List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
-      CodeBuffer args = new CodeBuffer();
-      for (int i = 0; i < selector.argumentCount; i++) {
-        parameters.add(new jsAst.Parameter('\$$i'));
-      }
-
-      List<jsAst.Expression> argNames =
-          selector.getOrderedNamedArguments().map((SourceString name) =>
-              js.string(name.slowToString())).toList();
-
-      String methodName = selector.invocationMirrorMemberName;
-      String internalName = namer.invocationMirrorInternalName(selector);
-      String reflectionName = getReflectionName(selector, internalName);
-      if (!haveVeryFewNoSuchMemberHandlers &&
-          isTrivialNsmHandler(type, argNames, selector, internalName) &&
-          reflectionName == null) {
-        trivialNsmHandlers.add(selector);
-        return null;
-      }
-
-      assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD));
-      jsAst.Expression expression = js('this.$noSuchMethodName')(
-          [js('this'),
-           namer.elementAccess(backend.getCreateInvocationMirror())([
-               js.string(compiler.enableMinification ?
-                         internalName : methodName),
-               js.string(internalName),
-               type,
-               new jsAst.ArrayInitializer.from(
-                   parameters.map((param) => js(param.name)).toList()),
-               new jsAst.ArrayInitializer.from(argNames)])]);
-      parameters = backend.isInterceptedName(selector.name)
-          ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters))
-          : parameters;
-      return js.fun(parameters, js.return_(expression));
-    }
-
-    for (String jsName in addedJsNames.keys.toList()..sort()) {
-      Selector selector = addedJsNames[jsName];
-      jsAst.Expression method = generateMethod(jsName, selector);
-      if (method != null) {
-        defineStub(jsName, method);
-        String reflectionName = getReflectionName(selector, jsName);
-        if (reflectionName != null) {
-          bool accessible = compiler.world.allFunctions.filter(selector).any(
-              (Element e) => backend.isAccessibleByReflection(e));
-          defineStub('+$reflectionName', js(accessible ? '1' : '0'));
-        }
-      }
-    }
-  }
-
   String buildIsolateSetup(CodeBuffer buffer,
                            Element appMain,
                            Element isolateMain) {
@@ -2571,16 +1232,16 @@
     // these are thought to not have been instantiated, so we neeed to be able
     // to identify them later and make sure we only emit "empty shells" without
     // fields, etc.
-    computeRtiNeededClasses();
-    rtiNeededClasses.removeAll(neededClasses);
+    typeTestEmitter.computeRtiNeededClasses();
+    typeTestEmitter.rtiNeededClasses.removeAll(neededClasses);
     // rtiNeededClasses now contains only the "empty shells".
-    neededClasses.addAll(rtiNeededClasses);
+    neededClasses.addAll(typeTestEmitter.rtiNeededClasses);
 
     // 5. Finally, sort the classes.
     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
 
     for (ClassElement element in sortedClasses) {
-      if (rtiNeededClasses.contains(element)) {
+      if (typeTestEmitter.rtiNeededClasses.contains(element)) {
         regularClasses.add(element);
       } else if (Elements.isNativeOrExtendsNative(element)) {
         // For now, native classes and related classes cannot be deferred.
@@ -2597,55 +1258,6 @@
     }
   }
 
-  Set<ClassElement> computeRtiNeededClasses() {
-    void addClassWithSuperclasses(ClassElement cls) {
-      rtiNeededClasses.add(cls);
-      for (ClassElement superclass = cls.superclass;
-          superclass != null;
-          superclass = superclass.superclass) {
-        rtiNeededClasses.add(superclass);
-      }
-    }
-
-    void addClassesWithSuperclasses(Iterable<ClassElement> classes) {
-      for (ClassElement cls in classes) {
-        addClassWithSuperclasses(cls);
-      }
-    }
-
-    // 1.  Add classes that are referenced by type arguments or substitutions in
-    //     argument checks.
-    // TODO(karlklose): merge this case with 2 when unifying argument and
-    // object checks.
-    RuntimeTypes rti = backend.rti;
-    rti.getRequiredArgumentClasses(backend).forEach((ClassElement c) {
-      // Types that we represent with JS native types (like int and String) do
-      // not need a class definition as we use the interceptor classes instead.
-      if (!rti.isJsNative(c)) {
-        addClassWithSuperclasses(c);
-      }
-    });
-
-    // 2.  Add classes that are referenced by substitutions in object checks and
-    //     their superclasses.
-    TypeChecks requiredChecks =
-        rti.computeChecks(rtiNeededClasses, checkedClasses);
-    Set<ClassElement> classesUsedInSubstitutions =
-        rti.getClassesUsedInSubstitutions(backend, requiredChecks);
-    addClassesWithSuperclasses(classesUsedInSubstitutions);
-
-    // 3.  Add classes that contain checked generic function types. These are
-    //     needed to store the signature encoding.
-    for (FunctionType type in checkedFunctionTypes) {
-      ClassElement contextClass = Types.getClassContext(type);
-      if (contextClass != null) {
-        rtiNeededClasses.add(contextClass);
-      }
-    }
-
-    return rtiNeededClasses;
-  }
-
   // Returns a statement that takes care of performance critical
   // common case for a one-shot interceptor, or null if there is no
   // fast path.
@@ -2881,6 +1493,8 @@
   void emitMapTypeToInterceptor(CodeBuffer buffer) {
     // TODO(sra): Perhaps inject a constant instead?
     // TODO(sra): Filter by subclasses of native types.
+    // TODO(13835): Don't generate this unless we generated the functions that
+    // use the data structure.
     List<jsAst.Expression> elements = <jsAst.Expression>[];
     ConstantHandler handler = compiler.constantHandler;
     List<Constant> constants = handler.getConstantsForEmission();
@@ -2892,6 +1506,38 @@
           ClassElement classElement = element;
           elements.add(backend.emitter.constantReference(constant));
           elements.add(js(namer.isolateAccess(classElement)));
+
+          // Create JavaScript Object map for by-name lookup of generative
+          // constructors.  For example, the class A has three generative
+          // constructors
+          //
+          //     class A {
+          //       A() {}
+          //       A.foo() {}
+          //       A.bar() {}
+          //     }
+          //
+          // Which are described by the map
+          //
+          //     {"": A.A$, "foo": A.A$foo, "bar": A.A$bar}
+          //
+          // We expect most of the time the map will be a singleton.
+          var properties = [];
+          classElement.forEachMember(
+              (ClassElement enclosingClass, Element member) {
+                if (member.isGenerativeConstructor()) {
+                  properties.add(
+                      new jsAst.Property(
+                          js.string(member.name.slowToString()),
+                          new jsAst.VariableUse(
+                              backend.namer.isolateAccess(member))));
+                }
+              },
+              includeBackendMembers: false,
+              includeSuperAndInjectedMembers: false);
+
+          var map = new jsAst.ObjectInitializer(properties);
+          elements.add(map);
         }
       }
     }
@@ -3053,7 +1699,7 @@
     measure(() {
       // Compute the required type checks to know which classes need a
       // 'is$' method.
-      computeRequiredTypeChecks();
+      typeTestEmitter.computeRequiredTypeChecks();
 
       computeNeededClasses();
 
@@ -3153,7 +1799,8 @@
           if (element.isLibrary()) {
             LibraryElement library = element;
             ClassBuilder builder = new ClassBuilder();
-            if (emitFields(library, builder, null, emitStatics: true)) {
+            if (classEmitter.emitFields(
+                    library, builder, null, emitStatics: true)) {
               List<CodeBuffer> buffers = elementBuffers[library];
               var buffer = buffers[0];
               if (buffer == null) {
@@ -3273,7 +1920,7 @@
 
       containerBuilder.emitStaticFunctionGetters(mainBuffer);
 
-      emitRuntimeTypeSupport(mainBuffer);
+      typeTestEmitter.emitRuntimeTypeSupport(mainBuffer);
       emitGetInterceptorMethods(mainBuffer);
       // Constants in checked mode call into RTI code to set type information
       // which may need getInterceptor methods, so we have to make sure that
@@ -3503,3 +2150,6 @@
     return compiler.deferredLoadTask.areAnyElementsDeferred;
   }
 }
+
+// TODO(ahe): Move code for interceptors to own file.
+// TODO(ahe): Move code for reifying metadata/types to own file.
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
index 15ad85a..25a4fd3 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -8,23 +8,13 @@
 /// JavaScript representations of libraries, class-sides, and instance-sides.
 /// Initially, it is just a placeholder for code that is moved from
 /// [CodeEmitterTask].
-class ContainerBuilder {
+class ContainerBuilder extends CodeEmitterHelper {
   final Map<Element, Element> staticGetters = new Map<Element, Element>();
 
   /// A cache of synthesized closures for top-level, static or
   /// instance methods.
   final Map<String, Element> methodClosures = <String, Element>{};
 
-  CodeEmitterTask task;
-
-  Namer get namer => task.namer;
-
-  Compiler get compiler => task.compiler;
-
-  String get N => task.N;
-
-  JavaScriptBackend get backend => task.backend;
-
   /**
    * Generate stubs to handle invocation of methods with optional
    * arguments.
@@ -339,8 +329,9 @@
 
       FunctionType methodType = element.computeType(compiler);
       Map<FunctionType, bool> functionTypeChecks =
-          task.getFunctionTypeChecksOn(methodType);
-      task.generateFunctionTypeTests(element, methodType, functionTypeChecks,
+          task.typeTestEmitter.getFunctionTypeChecksOn(methodType);
+      task.typeTestEmitter.generateFunctionTypeTests(
+          element, methodType, functionTypeChecks,
           emitFunctionTypeSignature, emitIsFunctionTypeTest);
 
       closureClassElement =
@@ -473,9 +464,10 @@
 
     DartType memberType = member.computeType(compiler);
     Map<FunctionType, bool> functionTypeChecks =
-        task.getFunctionTypeChecksOn(memberType);
+        task.typeTestEmitter.getFunctionTypeChecksOn(memberType);
 
-    task.generateFunctionTypeTests(member, memberType, functionTypeChecks,
+    task.typeTestEmitter.generateFunctionTypeTests(
+        member, memberType, functionTypeChecks,
         emitFunctionTypeSignature, emitIsFunctionTypeTest);
 
     closureClassElement =
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
index 7a3e055..f21d3d8 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/declarations.dart
@@ -59,3 +59,27 @@
 //                        Instead, a closure that will invoke [main] is
 //                        passed to [dartMainRunner].
 """;
+
+// Compact field specifications.  The format of the field specification is
+// <accessorName>:<fieldName><suffix> where the suffix and accessor name
+// prefix are optional.  The suffix directs the generation of getter and
+// setter methods.  Each of the getter and setter has two bits to determine
+// the calling convention.  Setter listed below, getter is similar.
+//
+//     00: no setter
+//     01: function(value) { this.field = value; }
+//     10: function(receiver, value) { receiver.field = value; }
+//     11: function(receiver, value) { this.field = value; }
+//
+// The suffix encodes 4 bits using three ASCII ranges of non-identifier
+// characters.
+const FIELD_CODE_CHARACTERS = r"<=>?@{|}~%&'()*";
+const NO_FIELD_CODE = 0;
+const FIRST_FIELD_CODE = 1;
+const RANGE1_FIRST = 0x3c;   //  <=>?@    encodes 1..5
+const RANGE1_LAST = 0x40;
+const RANGE2_FIRST = 0x7b;   //  {|}~     encodes 6..9
+const RANGE2_LAST = 0x7e;
+const RANGE3_FIRST = 0x25;   //  %&'()*+  encodes 10..16
+const RANGE3_LAST = 0x2b;
+const REFLECTION_MARKER = 0x2d;
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/helpers.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/helpers.dart
new file mode 100644
index 0000000..017094b
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/helpers.dart
@@ -0,0 +1,14 @@
+// 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.js_emitter;
+
+ClassElement computeMixinClass(MixinApplicationElement mixinApplication) {
+  ClassElement mixin = mixinApplication.mixin;
+  while (mixin.isMixinApplication) {
+    mixinApplication = mixin;
+    mixin = mixinApplication.mixin;
+  }
+  return mixin;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
index dfd526b..8e9137c 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
@@ -56,8 +56,13 @@
     relativize;
 
 part 'class_builder.dart';
+part 'class_emitter.dart';
 part 'closure_invocation_element.dart';
+part 'code_emitter_helper.dart';
 part 'code_emitter_task.dart';
 part 'container_builder.dart';
 part 'declarations.dart';
+part 'helpers.dart';
+part 'nsm_emitter.dart';
 part 'reflection_data_parser.dart';
+part 'type_test_emitter.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/nsm_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/nsm_emitter.dart
new file mode 100644
index 0000000..8b565f5
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/nsm_emitter.dart
@@ -0,0 +1,365 @@
+// 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.js_emitter;
+
+class NsmEmitter extends CodeEmitterHelper {
+  final List<Selector> trivialNsmHandlers = <Selector>[];
+
+  /// If this is true then we can generate the noSuchMethod handlers at startup
+  /// time, instead of them being emitted as part of the Object class.
+  bool get generateTrivialNsmHandlers => true;
+
+  // If we need fewer than this many noSuchMethod handlers we can save space by
+  // just emitting them in JS, rather than emitting the JS needed to generate
+  // them at run time.
+  static const VERY_FEW_NO_SUCH_METHOD_HANDLERS = 10;
+
+  static const MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING = 4;
+
+  void emitNoSuchMethodHandlers(DefineStubFunction defineStub) {
+    // Do not generate no such method handlers if there is no class.
+    if (compiler.codegenWorld.instantiatedClasses.isEmpty) return;
+
+    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
+        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);
+
+    // Keep track of the JavaScript names we've already added so we
+    // do not introduce duplicates (bad for code size).
+    Map<String, Selector> addedJsNames = new Map<String, Selector>();
+
+    void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) {
+      // Cache the object class and type.
+      ClassElement objectClass = compiler.objectClass;
+      DartType objectType = objectClass.computeType(compiler);
+
+      for (Selector selector in selectors) {
+        TypeMask mask = selector.mask;
+        if (mask == null) {
+          mask = new TypeMask.subclass(compiler.objectClass);
+        }
+
+        if (!mask.needsNoSuchMethodHandling(selector, compiler)) continue;
+        String jsName = namer.invocationMirrorInternalName(selector);
+        addedJsNames[jsName] = selector;
+        String reflectionName = task.getReflectionName(selector, jsName);
+        if (reflectionName != null) {
+          task.mangledFieldNames[jsName] = reflectionName;
+        }
+      }
+    }
+
+    compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers);
+    compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers);
+    compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers);
+
+    // Set flag used by generateMethod helper below.  If we have very few
+    // handlers we use defineStub for them all, rather than try to generate them
+    // at runtime.
+    bool haveVeryFewNoSuchMemberHandlers =
+        (addedJsNames.length < VERY_FEW_NO_SUCH_METHOD_HANDLERS);
+
+    jsAst.Expression generateMethod(String jsName, Selector selector) {
+      // Values match JSInvocationMirror in js-helper library.
+      int type = selector.invocationMirrorKind;
+      List<jsAst.Parameter> parameters = <jsAst.Parameter>[];
+      CodeBuffer args = new CodeBuffer();
+      for (int i = 0; i < selector.argumentCount; i++) {
+        parameters.add(new jsAst.Parameter('\$$i'));
+      }
+
+      List<jsAst.Expression> argNames =
+          selector.getOrderedNamedArguments().map((SourceString name) =>
+              js.string(name.slowToString())).toList();
+
+      String methodName = selector.invocationMirrorMemberName;
+      String internalName = namer.invocationMirrorInternalName(selector);
+      String reflectionName = task.getReflectionName(selector, internalName);
+      if (!haveVeryFewNoSuchMemberHandlers &&
+          isTrivialNsmHandler(type, argNames, selector, internalName) &&
+          reflectionName == null) {
+        trivialNsmHandlers.add(selector);
+        return null;
+      }
+
+      assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD));
+      jsAst.Expression expression = js('this.$noSuchMethodName')(
+          [js('this'),
+           namer.elementAccess(backend.getCreateInvocationMirror())([
+               js.string(compiler.enableMinification ?
+                         internalName : methodName),
+               js.string(internalName),
+               type,
+               new jsAst.ArrayInitializer.from(
+                   parameters.map((param) => js(param.name)).toList()),
+               new jsAst.ArrayInitializer.from(argNames)])]);
+      parameters = backend.isInterceptedName(selector.name)
+          ? ([new jsAst.Parameter('\$receiver')]..addAll(parameters))
+          : parameters;
+      return js.fun(parameters, js.return_(expression));
+    }
+
+    for (String jsName in addedJsNames.keys.toList()..sort()) {
+      Selector selector = addedJsNames[jsName];
+      jsAst.Expression method = generateMethod(jsName, selector);
+      if (method != null) {
+        defineStub(jsName, method);
+        String reflectionName = task.getReflectionName(selector, jsName);
+        if (reflectionName != null) {
+          bool accessible = compiler.world.allFunctions.filter(selector).any(
+              (Element e) => backend.isAccessibleByReflection(e));
+          defineStub('+$reflectionName', js(accessible ? '1' : '0'));
+        }
+      }
+    }
+  }
+
+  // Identify the noSuchMethod handlers that are so simple that we can
+  // generate them programatically.
+  bool isTrivialNsmHandler(
+      int type, List argNames, Selector selector, String internalName) {
+    if (!generateTrivialNsmHandlers) return false;
+    // Check for interceptor calling convention.
+    if (backend.isInterceptedName(selector.name)) {
+      // We can handle the calling convention used by intercepted names in the
+      // diff encoding, but we don't use that for non-minified code.
+      if (!compiler.enableMinification) return false;
+      String shortName = namer.invocationMirrorInternalName(selector);
+      if (shortName.length > MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING) {
+        return false;
+      }
+    }
+    // Check for named arguments.
+    if (argNames.length != 0) return false;
+    // Check for unexpected name (this doesn't really happen).
+    if (internalName.startsWith(namer.getterPrefix[0])) return type == 1;
+    if (internalName.startsWith(namer.setterPrefix[0])) return type == 2;
+    return type == 0;
+  }
+
+  /**
+   * Adds (at runtime) the handlers to the Object class which catch calls to
+   * methods that the object does not have.  The handlers create an invocation
+   * mirror object.
+   *
+   * The current version only gives you the minified name when minifying (when
+   * not minifying this method is not called).
+   *
+   * In order to generate the noSuchMethod handlers we only need the minified
+   * name of the method.  We test the first character of the minified name to
+   * determine if it is a getter or a setter, and we use the arguments array at
+   * runtime to get the number of arguments and their values.  If the method
+   * involves named arguments etc. then we don't handle it here, but emit the
+   * handler method directly on the Object class.
+   *
+   * The minified names are mostly 1-4 character names, which we emit in sorted
+   * order (primary key is length, secondary ordering is lexicographic).  This
+   * gives an order like ... dD dI dX da ...
+   *
+   * Gzip is good with repeated text, but it can't diff-encode, so we do that
+   * for it.  We encode the minified names in a comma-separated string, but all
+   * the 1-4 character names are encoded before the first comma as a series of
+   * base 26 numbers.  The last digit of each number is lower case, the others
+   * are upper case, so 1 is "b" and 26 is "Ba".
+   *
+   * We think of the minified names as base 88 numbers using the ASCII
+   * characters from # to z.  The base 26 numbers each encode the delta from
+   * the previous minified name to the next.  So if there is a minified name
+   * called Df and the next is Dh, then they are 2971 and 2973 when thought of
+   * as base 88 numbers.  The difference is 2, which is "c" in lower-case-
+   * terminated base 26.
+   *
+   * The reason we don't encode long minified names with this method is that
+   * decoding the base 88 numbers would overflow JavaScript's puny integers.
+   *
+   * There are some selectors that have a special calling convention (because
+   * they are called with the receiver as the first argument).  They need a
+   * slightly different noSuchMethod handler, so we handle these first.
+   */
+  void addTrivialNsmHandlers(List<jsAst.Node> statements) {
+    if (trivialNsmHandlers.length == 0) return;
+    // Sort by calling convention, JS name length and by JS name.
+    trivialNsmHandlers.sort((a, b) {
+      bool aIsIntercepted = backend.isInterceptedName(a.name);
+      bool bIsIntercepted = backend.isInterceptedName(b.name);
+      if (aIsIntercepted != bIsIntercepted) return aIsIntercepted ? -1 : 1;
+      String aName = namer.invocationMirrorInternalName(a);
+      String bName = namer.invocationMirrorInternalName(b);
+      if (aName.length != bName.length) return aName.length - bName.length;
+      return aName.compareTo(bName);
+    });
+
+    // Find out how many selectors there are with the special calling
+    // convention.
+    int firstNormalSelector = trivialNsmHandlers.length;
+    for (int i = 0; i < trivialNsmHandlers.length; i++) {
+      if (!backend.isInterceptedName(trivialNsmHandlers[i].name)) {
+        firstNormalSelector = i;
+        break;
+      }
+    }
+
+    // Get the short names (JS names, perhaps minified).
+    Iterable<String> shorts = trivialNsmHandlers.map((selector) =>
+         namer.invocationMirrorInternalName(selector));
+    final diffShorts = <String>[];
+    var diffEncoding = new StringBuffer();
+
+    // Treat string as a number in base 88 with digits in ASCII order from # to
+    // z.  The short name sorting is based on length, and uses ASCII order for
+    // equal length strings so this means that names are ascending.  The hash
+    // character, #, is never given as input, but we need it because it's the
+    // implicit leading zero (otherwise we could not code names with leading
+    // dollar signs).
+    int fromBase88(String x) {
+      int answer = 0;
+      for (int i = 0; i < x.length; i++) {
+        int c = x.codeUnitAt(i);
+        // No support for Unicode minified identifiers in JS.
+        assert(c >= $$ && c <= $z);
+        answer *= 88;
+        answer += c - $HASH;
+      }
+      return answer;
+    }
+
+    // Big endian encoding, A = 0, B = 1...
+    // A lower case letter terminates the number.
+    String toBase26(int x) {
+      int c = x;
+      var encodingChars = <int>[];
+      encodingChars.add($a + (c % 26));
+      while (true) {
+        c ~/= 26;
+        if (c == 0) break;
+        encodingChars.add($A + (c % 26));
+      }
+      return new String.fromCharCodes(encodingChars.reversed.toList());
+    }
+
+    bool minify = compiler.enableMinification;
+    bool useDiffEncoding = minify && shorts.length > 30;
+
+    int previous = 0;
+    int nameCounter = 0;
+    for (String short in shorts) {
+      // Emit period that resets the diff base to zero when we switch to normal
+      // calling convention (this avoids the need to code negative diffs).
+      if (useDiffEncoding && nameCounter == firstNormalSelector) {
+        diffEncoding.write(".");
+        previous = 0;
+      }
+      if (short.length <= MAX_MINIFIED_LENGTH_FOR_DIFF_ENCODING &&
+          useDiffEncoding) {
+        int base63 = fromBase88(short);
+        int diff = base63 - previous;
+        previous = base63;
+        String base26Diff = toBase26(diff);
+        diffEncoding.write(base26Diff);
+      } else {
+        if (useDiffEncoding || diffEncoding.length != 0) {
+          diffEncoding.write(",");
+        }
+        diffEncoding.write(short);
+      }
+      nameCounter++;
+    }
+
+    // Startup code that loops over the method names and puts handlers on the
+    // Object class to catch noSuchMethod invocations.
+    ClassElement objectClass = compiler.objectClass;
+    String createInvocationMirror = namer.isolateAccess(
+        backend.getCreateInvocationMirror());
+    String noSuchMethodName = namer.publicInstanceMethodNameByArity(
+        Compiler.NO_SUCH_METHOD, Compiler.NO_SUCH_METHOD_ARG_COUNT);
+    var type = 0;
+    if (useDiffEncoding) {
+      statements.addAll([
+        js('var objectClassObject = '
+           '        collectedClasses["${namer.getNameOfClass(objectClass)}"],'
+           '    shortNames = "$diffEncoding".split(","),'
+           '    nameNumber = 0,'
+           '    diffEncodedString = shortNames[0],'
+           '    calculatedShortNames = [0, 1]'),  // 0, 1 are args for splice.
+        js.if_('objectClassObject instanceof Array',
+               js('objectClassObject = objectClassObject[1]')),
+        js.for_('var i = 0', 'i < diffEncodedString.length', 'i++', [
+          js('var codes = [],'
+             '    diff = 0,'
+             '    digit = diffEncodedString.charCodeAt(i)'),
+          js.if_('digit == ${$PERIOD}', [
+            js('nameNumber = 0'),
+            js('digit = diffEncodedString.charCodeAt(++i)')
+          ]),
+          js.while_('digit <= ${$Z}', [
+            js('diff *= 26'),
+            js('diff += (digit - ${$A})'),
+            js('digit = diffEncodedString.charCodeAt(++i)')
+          ]),
+          js('diff *= 26'),
+          js('diff += (digit - ${$a})'),
+          js('nameNumber += diff'),
+          js.for_('var remaining = nameNumber',
+                  'remaining > 0',
+                  'remaining = (remaining / 88) | 0', [
+            js('codes.unshift(${$HASH} + remaining % 88)')
+          ]),
+          js('calculatedShortNames.push('
+             '    String.fromCharCode.apply(String, codes))')
+        ]),
+        js('shortNames.splice.apply(shortNames, calculatedShortNames)')
+      ]);
+    } else {
+      // No useDiffEncoding version.
+      Iterable<String> longs = trivialNsmHandlers.map((selector) =>
+             selector.invocationMirrorMemberName);
+      String longNamesConstant = minify ? "" :
+          ',longNames = "${longs.join(",")}".split(",")';
+      statements.add(
+        js('var objectClassObject = '
+           '        collectedClasses["${namer.getNameOfClass(objectClass)}"],'
+           '    shortNames = "$diffEncoding".split(",")'
+           '    $longNamesConstant'));
+      statements.add(
+          js.if_('objectClassObject instanceof Array',
+                 js('objectClassObject = objectClassObject[1]')));
+    }
+
+    String sliceOffset = ', (j < $firstNormalSelector) ? 1 : 0';
+    if (firstNormalSelector == 0) sliceOffset = '';
+    if (firstNormalSelector == shorts.length) sliceOffset = ', 1';
+
+    String whatToPatch = task.nativeEmitter.handleNoSuchMethod ?
+                         "Object.prototype" :
+                         "objectClassObject";
+
+    var params = ['name', 'short', 'type'];
+    var sliceOffsetParam = '';
+    var slice = 'Array.prototype.slice.call';
+    if (!sliceOffset.isEmpty) {
+      sliceOffsetParam = ', sliceOffset';
+      params.add('sliceOffset');
+    }
+    statements.addAll([
+      js.for_('var j = 0', 'j < shortNames.length', 'j++', [
+        js('var type = 0'),
+        js('var short = shortNames[j]'),
+        js.if_('short[0] == "${namer.getterPrefix[0]}"', js('type = 1')),
+        js.if_('short[0] == "${namer.setterPrefix[0]}"', js('type = 2')),
+        // Generate call to:
+        // createInvocationMirror(String name, internalName, type, arguments,
+        //                        argumentNames)
+        js('$whatToPatch[short] = #(${minify ? "shortNames" : "longNames"}[j], '
+                                    'short, type$sliceOffset)',
+           js.fun(params, [js.return_(js.fun([],
+               [js.return_(js(
+                   'this.$noSuchMethodName('
+                       'this, '
+                       '$createInvocationMirror('
+                           'name, short, type, '
+                           '$slice(arguments$sliceOffsetParam), []))'))]))]))
+      ])
+    ]);
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart
new file mode 100644
index 0000000..90829b8
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/type_test_emitter.dart
@@ -0,0 +1,423 @@
+// 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.js_emitter;
+
+class TypeTestEmitter extends CodeEmitterHelper {
+  static const int MAX_FUNCTION_TYPE_PREDICATES = 10;
+
+  /**
+   * Raw ClassElement symbols occuring in is-checks and type assertions.  If the
+   * program contains parameterized checks `x is Set<int>` and
+   * `x is Set<String>` then the ClassElement `Set` will occur once in
+   * [checkedClasses].
+   */
+  Set<ClassElement> checkedClasses;
+
+  /**
+   * The set of function types that checked, both explicity through tests of
+   * typedefs and implicitly through type annotations in checked mode.
+   */
+  Set<FunctionType> checkedFunctionTypes;
+
+  Map<ClassElement, Set<FunctionType>> checkedGenericFunctionTypes =
+      new Map<ClassElement, Set<FunctionType>>();
+
+  Set<FunctionType> checkedNonGenericFunctionTypes =
+      new Set<FunctionType>();
+
+  final Set<ClassElement> rtiNeededClasses = new Set<ClassElement>();
+
+  Iterable<ClassElement> cachedClassesUsingTypeVariableTests;
+
+  Iterable<ClassElement> get classesUsingTypeVariableTests {
+    if (cachedClassesUsingTypeVariableTests == null) {
+      cachedClassesUsingTypeVariableTests = compiler.codegenWorld.isChecks
+          .where((DartType t) => t is TypeVariableType)
+          .map((TypeVariableType v) => v.element.getEnclosingClass())
+          .toList();
+    }
+    return cachedClassesUsingTypeVariableTests;
+  }
+
+  void emitIsTests(ClassElement classElement, ClassBuilder builder) {
+    assert(invariant(classElement, classElement.isDeclaration));
+
+    void generateIsTest(Element other) {
+      if (other == compiler.objectClass && other != classElement) {
+        // Avoid emitting [:$isObject:] on all classes but [Object].
+        return;
+      }
+      other = backend.getImplementationClass(other);
+      builder.addProperty(namer.operatorIs(other), js('true'));
+    }
+
+    void generateIsFunctionTypeTest(FunctionType type) {
+      String operator = namer.operatorIsType(type);
+      builder.addProperty(operator, new jsAst.LiteralBool(true));
+    }
+
+    void generateFunctionTypeSignature(Element method, FunctionType type) {
+      assert(method.isImplementation);
+      jsAst.Expression thisAccess = new jsAst.This();
+      Node node = method.parseNode(compiler);
+      ClosureClassMap closureData =
+          compiler.closureToClassMapper.closureMappingCache[node];
+      if (closureData != null) {
+        Element thisElement =
+            closureData.freeVariableMapping[closureData.thisElement];
+        if (thisElement != null) {
+          assert(thisElement.hasFixedBackendName());
+          String thisName = thisElement.fixedBackendName();
+          thisAccess = js('this')[js.string(thisName)];
+        }
+      }
+      RuntimeTypes rti = backend.rti;
+      jsAst.Expression encoding = rti.getSignatureEncoding(type, thisAccess);
+      String operatorSignature = namer.operatorSignature();
+      builder.addProperty(operatorSignature, encoding);
+    }
+
+    void generateSubstitution(ClassElement cls, {bool emitNull: false}) {
+      if (cls.typeVariables.isEmpty) return;
+      RuntimeTypes rti = backend.rti;
+      jsAst.Expression expression;
+      bool needsNativeCheck = task.nativeEmitter.requiresNativeIsCheck(cls);
+      expression = rti.getSupertypeSubstitution(
+          classElement, cls, alwaysGenerateFunction: true);
+      if (expression == null && (emitNull || needsNativeCheck)) {
+        expression = new jsAst.LiteralNull();
+      }
+      if (expression != null) {
+        builder.addProperty(namer.substitutionName(cls), expression);
+      }
+    }
+
+    generateIsTestsOn(classElement, generateIsTest,
+        generateIsFunctionTypeTest, generateFunctionTypeSignature,
+        generateSubstitution);
+  }
+
+  /**
+   * Generate "is tests" for [cls]: itself, and the "is tests" for the
+   * classes it implements and type argument substitution functions for these
+   * tests.   We don't need to add the "is tests" of the super class because
+   * they will be inherited at runtime, but we may need to generate the
+   * substitutions, because they may have changed.
+   */
+  void generateIsTestsOn(ClassElement cls,
+                         void emitIsTest(Element element),
+                         FunctionTypeTestEmitter emitIsFunctionTypeTest,
+                         FunctionTypeSignatureEmitter emitFunctionTypeSignature,
+                         SubstitutionEmitter emitSubstitution) {
+    if (checkedClasses.contains(cls)) {
+      emitIsTest(cls);
+      emitSubstitution(cls);
+    }
+
+    RuntimeTypes rti = backend.rti;
+    ClassElement superclass = cls.superclass;
+
+    bool haveSameTypeVariables(ClassElement a, ClassElement b) {
+      if (a.isClosure()) return true;
+      if (b.isUnnamedMixinApplication) {
+        return false;
+      }
+      return a.typeVariables == b.typeVariables;
+    }
+
+    if (superclass != null && superclass != compiler.objectClass &&
+        !haveSameTypeVariables(cls, superclass)) {
+      // We cannot inherit the generated substitutions, because the type
+      // variable layout for this class is different.  Instead we generate
+      // substitutions for all checks and make emitSubstitution a NOP for the
+      // rest of this function.
+      Set<ClassElement> emitted = new Set<ClassElement>();
+      // TODO(karlklose): move the computation of these checks to
+      // RuntimeTypeInformation.
+      if (backend.classNeedsRti(cls)) {
+        emitSubstitution(superclass, emitNull: true);
+        emitted.add(superclass);
+      }
+      for (DartType supertype in cls.allSupertypes) {
+        ClassElement superclass = supertype.element;
+        if (classesUsingTypeVariableTests.contains(superclass)) {
+          emitSubstitution(superclass, emitNull: true);
+          emitted.add(superclass);
+        }
+        for (ClassElement check in checkedClasses) {
+          if (supertype.element == check && !emitted.contains(check)) {
+            // Generate substitution.  If no substitution is necessary, emit
+            // [:null:] to overwrite a (possibly) existing substitution from the
+            // super classes.
+            emitSubstitution(check, emitNull: true);
+            emitted.add(check);
+          }
+        }
+      }
+      void emitNothing(_, {emitNull}) {};
+      emitSubstitution = emitNothing;
+    }
+
+    Set<Element> generated = new Set<Element>();
+    // A class that defines a [:call:] method implicitly implements
+    // [Function] and needs checks for all typedefs that are used in is-checks.
+    if (checkedClasses.contains(compiler.functionClass) ||
+        !checkedFunctionTypes.isEmpty) {
+      Element call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
+      if (call == null) {
+        // If [cls] is a closure, it has a synthetic call operator method.
+        call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
+      }
+      if (call != null && call.isFunction()) {
+        generateInterfacesIsTests(compiler.functionClass,
+                                  emitIsTest,
+                                  emitSubstitution,
+                                  generated);
+        FunctionType callType = call.computeType(compiler);
+        Map<FunctionType, bool> functionTypeChecks =
+            getFunctionTypeChecksOn(callType);
+        generateFunctionTypeTests(
+            call, callType, functionTypeChecks,
+            emitFunctionTypeSignature, emitIsFunctionTypeTest);
+     }
+    }
+
+    for (DartType interfaceType in cls.interfaces) {
+      generateInterfacesIsTests(interfaceType.element, emitIsTest,
+                                emitSubstitution, generated);
+    }
+  }
+
+  /**
+   * Generate "is tests" where [cls] is being implemented.
+   */
+  void generateInterfacesIsTests(ClassElement cls,
+                                 void emitIsTest(ClassElement element),
+                                 SubstitutionEmitter emitSubstitution,
+                                 Set<Element> alreadyGenerated) {
+    void tryEmitTest(ClassElement check) {
+      if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
+        alreadyGenerated.add(check);
+        emitIsTest(check);
+        emitSubstitution(check);
+      }
+    };
+
+    tryEmitTest(cls);
+
+    for (DartType interfaceType in cls.interfaces) {
+      Element element = interfaceType.element;
+      tryEmitTest(element);
+      generateInterfacesIsTests(element, emitIsTest, emitSubstitution,
+                                alreadyGenerated);
+    }
+
+    // We need to also emit "is checks" for the superclass and its supertypes.
+    ClassElement superclass = cls.superclass;
+    if (superclass != null) {
+      tryEmitTest(superclass);
+      generateInterfacesIsTests(superclass, emitIsTest, emitSubstitution,
+                                alreadyGenerated);
+    }
+  }
+
+  /**
+   * Returns a mapping containing all checked function types for which [type]
+   * can be a subtype. A function type is mapped to [:true:] if [type] is
+   * statically known to be a subtype of it and to [:false:] if [type] might
+   * be a subtype, provided with the right type arguments.
+   */
+  // TODO(johnniwinther): Change to return a mapping from function types to
+  // a set of variable points and use this to detect statically/dynamically
+  // known subtype relations.
+  Map<FunctionType, bool> getFunctionTypeChecksOn(DartType type) {
+    Map<FunctionType, bool> functionTypeMap =
+        new LinkedHashMap<FunctionType, bool>();
+    for (FunctionType functionType in checkedFunctionTypes) {
+      if (compiler.types.isSubtype(type, functionType)) {
+        functionTypeMap[functionType] = true;
+      } else if (compiler.types.isPotentialSubtype(type, functionType)) {
+        functionTypeMap[functionType] = false;
+      }
+    }
+    // TODO(johnniwinther): Ensure stable ordering of the keys.
+    return functionTypeMap;
+  }
+
+  /**
+   * Generates function type checks on [method] with type [methodType] against
+   * the function type checks in [functionTypeChecks].
+   */
+  void generateFunctionTypeTests(
+      Element method,
+      FunctionType methodType,
+      Map<FunctionType, bool> functionTypeChecks,
+      FunctionTypeSignatureEmitter emitFunctionTypeSignature,
+      FunctionTypeTestEmitter emitIsFunctionTypeTest) {
+    bool hasDynamicFunctionTypeCheck = false;
+    int neededPredicates = 0;
+    functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
+      if (!knownSubtype) {
+        registerDynamicFunctionTypeCheck(functionType);
+        hasDynamicFunctionTypeCheck = true;
+      } else if (!backend.rti.isSimpleFunctionType(functionType)) {
+        // Simple function types are always checked using predicates and should
+        // not provoke generation of signatures.
+        neededPredicates++;
+      }
+    });
+    bool alwaysUseSignature = false;
+    if (hasDynamicFunctionTypeCheck ||
+        neededPredicates > MAX_FUNCTION_TYPE_PREDICATES) {
+      emitFunctionTypeSignature(method, methodType);
+      alwaysUseSignature = true;
+    }
+    functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) {
+      if (knownSubtype) {
+        if (backend.rti.isSimpleFunctionType(functionType)) {
+          // Simple function types are always checked using predicates.
+          emitIsFunctionTypeTest(functionType);
+        } else if (alwaysUseSignature) {
+          registerDynamicFunctionTypeCheck(functionType);
+        } else {
+          emitIsFunctionTypeTest(functionType);
+        }
+      }
+    });
+  }
+
+  void registerDynamicFunctionTypeCheck(FunctionType functionType) {
+    ClassElement classElement = Types.getClassContext(functionType);
+    if (classElement != null) {
+      checkedGenericFunctionTypes.putIfAbsent(classElement,
+          () => new Set<FunctionType>()).add(functionType);
+    } else {
+      checkedNonGenericFunctionTypes.add(functionType);
+    }
+  }
+
+  void emitRuntimeTypeSupport(CodeBuffer buffer) {
+    task.addComment('Runtime type support', buffer);
+    RuntimeTypes rti = backend.rti;
+    TypeChecks typeChecks = rti.requiredChecks;
+
+    // Add checks to the constructors of instantiated classes.
+    for (ClassElement cls in typeChecks) {
+      // TODO(9556).  The properties added to 'holder' should be generated
+      // directly as properties of the class object, not added later.
+      String holder = namer.isolateAccess(backend.getImplementationClass(cls));
+      for (TypeCheck check in typeChecks[cls]) {
+        ClassElement cls = check.cls;
+        buffer.write('$holder.${namer.operatorIs(cls)}$_=${_}true$N');
+        Substitution substitution = check.substitution;
+        if (substitution != null) {
+          CodeBuffer body =
+             jsAst.prettyPrint(substitution.getCode(rti, false), compiler);
+          buffer.write('$holder.${namer.substitutionName(cls)}$_=${_}');
+          buffer.write(body);
+          buffer.write('$N');
+        }
+      };
+    }
+
+    void addSignature(FunctionType type) {
+      jsAst.Expression encoding = rti.getTypeEncoding(type);
+      buffer.add('${namer.signatureName(type)}$_=${_}');
+      buffer.write(jsAst.prettyPrint(encoding, compiler));
+      buffer.add('$N');
+    }
+
+    checkedNonGenericFunctionTypes.forEach(addSignature);
+
+    checkedGenericFunctionTypes.forEach((_, Set<FunctionType> functionTypes) {
+      functionTypes.forEach(addSignature);
+    });
+  }
+
+  /**
+   * Returns the classes with constructors used as a 'holder' in
+   * [emitRuntimeTypeSupport].
+   * TODO(9556): Some cases will go away when the class objects are created as
+   * complete.  Not all classes will go away while constructors are referenced
+   * from type substitutions.
+   */
+  Set<ClassElement> classesModifiedByEmitRuntimeTypeSupport() {
+    TypeChecks typeChecks = backend.rti.requiredChecks;
+    Set<ClassElement> result = new Set<ClassElement>();
+    for (ClassElement cls in typeChecks) {
+      for (TypeCheck check in typeChecks[cls]) {
+        result.add(backend.getImplementationClass(cls));
+        break;
+      }
+    }
+    return result;
+  }
+
+  Set<ClassElement> computeRtiNeededClasses() {
+    void addClassWithSuperclasses(ClassElement cls) {
+      rtiNeededClasses.add(cls);
+      for (ClassElement superclass = cls.superclass;
+          superclass != null;
+          superclass = superclass.superclass) {
+        rtiNeededClasses.add(superclass);
+      }
+    }
+
+    void addClassesWithSuperclasses(Iterable<ClassElement> classes) {
+      for (ClassElement cls in classes) {
+        addClassWithSuperclasses(cls);
+      }
+    }
+
+    // 1.  Add classes that are referenced by type arguments or substitutions in
+    //     argument checks.
+    // TODO(karlklose): merge this case with 2 when unifying argument and
+    // object checks.
+    RuntimeTypes rti = backend.rti;
+    rti.getRequiredArgumentClasses(backend).forEach((ClassElement c) {
+      // Types that we represent with JS native types (like int and String) do
+      // not need a class definition as we use the interceptor classes instead.
+      if (!rti.isJsNative(c)) {
+        addClassWithSuperclasses(c);
+      }
+    });
+
+    // 2.  Add classes that are referenced by substitutions in object checks and
+    //     their superclasses.
+    TypeChecks requiredChecks =
+        rti.computeChecks(rtiNeededClasses, checkedClasses);
+    Set<ClassElement> classesUsedInSubstitutions =
+        rti.getClassesUsedInSubstitutions(backend, requiredChecks);
+    addClassesWithSuperclasses(classesUsedInSubstitutions);
+
+    // 3.  Add classes that contain checked generic function types. These are
+    //     needed to store the signature encoding.
+    for (FunctionType type in checkedFunctionTypes) {
+      ClassElement contextClass = Types.getClassContext(type);
+      if (contextClass != null) {
+        rtiNeededClasses.add(contextClass);
+      }
+    }
+
+    return rtiNeededClasses;
+  }
+
+  void computeRequiredTypeChecks() {
+    assert(checkedClasses == null && checkedFunctionTypes == null);
+
+    backend.rti.addImplicitChecks(compiler.codegenWorld,
+                                  classesUsingTypeVariableTests);
+
+    checkedClasses = new Set<ClassElement>();
+    checkedFunctionTypes = new Set<FunctionType>();
+    compiler.codegenWorld.isChecks.forEach((DartType t) {
+      if (t is InterfaceType) {
+        checkedClasses.add(t.element);
+      } else if (t is FunctionType) {
+        checkedFunctionTypes.add(t);
+      }
+    });
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 1342ce8..85191f1 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -569,11 +569,13 @@
  * the library dependency graph.
  */
 class ExportLink {
+  final Export export;
   final CombinatorFilter combinatorFilter;
   final LibraryDependencyNode exportNode;
 
   ExportLink(Export export, LibraryDependencyNode this.exportNode)
-      : this.combinatorFilter = new CombinatorFilter.fromTag(export);
+      : this.export = export,
+        this.combinatorFilter = new CombinatorFilter.fromTag(export);
 
   /**
    * Exports [element] to the dependent library unless [element] is filtered by
@@ -582,7 +584,7 @@
    */
   bool exportElement(Element element) {
     if (combinatorFilter.exclude(element)) return false;
-    return exportNode.addElementToPendingExports(element);
+    return exportNode.addElementToPendingExports(element, export);
   }
 }
 
@@ -622,12 +624,17 @@
   Map<SourceString, Element> exportScope =
       new LinkedHashMap<SourceString, Element>();
 
+  /// Map from exported elements to the export directives that exported them.
+  Map<Element, Link<Export>> exporters = new Map<Element, Link<Export>>();
+
   /**
    * The set of exported elements that need to be propageted to dependent
    * libraries as part of the work-list computation performed in
-   * [LibraryDependencyHandler.computeExports].
+   * [LibraryDependencyHandler.computeExports]. Each export element is mapped
+   * to a list of exports directives that export it.
    */
-  Set<Element> pendingExportSet = new Set<Element>();
+  Map<Element, Link<Export>> pendingExportMap =
+      new Map<Element, Link<Export>>();
 
   LibraryDependencyNode(LibraryElement this.library);
 
@@ -656,15 +663,21 @@
    * the export scopes performed in [LibraryDependencyHandler.computeExports].
    */
   void registerInitialExports() {
-    pendingExportSet.addAll(library.getNonPrivateElementsInScope());
+    for (Element element in library.getNonPrivateElementsInScope()) {
+      pendingExportMap[element] = const Link<Export>();
+    }
   }
 
   void registerHandledExports(LibraryElement exportedLibraryElement,
+                              Export export,
                               CombinatorFilter filter) {
     assert(invariant(library, exportedLibraryElement.exportsHandled));
     for (Element exportedElement in exportedLibraryElement.exports) {
       if (!filter.exclude(exportedElement)) {
-        pendingExportSet.add(exportedElement);
+        Link<Export> exports =
+            pendingExportMap.putIfAbsent(exportedElement,
+                                         () => const Link<Export>());
+        pendingExportMap[exportedElement] = exports.prepend(export);
       }
     }
   }
@@ -688,9 +701,10 @@
   /**
    * Copies and clears pending export set for this node.
    */
-  List<Element> pullPendingExports() {
-    List<Element> pendingExports = new List.from(pendingExportSet);
-    pendingExportSet.clear();
+  Map<Element, Link<Export>> pullPendingExports() {
+    Map<Element, Link<Export>> pendingExports =
+        new Map<Element, Link<Export>>.from(pendingExportMap);
+    pendingExportMap.clear();
     return pendingExports;
   }
 
@@ -698,25 +712,64 @@
    * Adds [element] to the export scope for this node. If the [element] name
    * is a duplicate, an error element is inserted into the export scope.
    */
-  Element addElementToExportScope(Compiler compiler, Element element) {
+  Element addElementToExportScope(Compiler compiler, Element element,
+                                  Link<Export> exports) {
     SourceString name = element.name;
+
+    void reportDuplicateExport(Element duplicate,
+                               Link<Export> duplicateExports,
+                               {bool reportError: true}) {
+      assert(invariant(library, !duplicateExports.isEmpty,
+          message: "No export for $duplicate from ${duplicate.getLibrary()} "
+                   "in $library."));
+      compiler.withCurrentElement(library, () {
+        for (Export export in duplicateExports) {
+          if (reportError) {
+            compiler.reportError(export,
+                MessageKind.DUPLICATE_EXPORT, {'name': name});
+            reportError = false;
+          } else {
+            compiler.reportInfo(export,
+                MessageKind.DUPLICATE_EXPORT_CONT, {'name': name});
+          }
+        }
+      });
+    }
+
+    void reportDuplicateExportDecl(Element duplicate,
+                                   Link<Export> duplicateExports) {
+      assert(invariant(library, !duplicateExports.isEmpty,
+          message: "No export for $duplicate from ${duplicate.getLibrary()} "
+                   "in $library."));
+      compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL,
+          {'name': name, 'uriString': duplicateExports.head.uri});
+    }
+
     Element existingElement = exportScope[name];
-    if (existingElement != null) {
+    if (existingElement != null && existingElement != element) {
       if (existingElement.isErroneous()) {
-        compiler.reportError(element, MessageKind.DUPLICATE_EXPORT,
-                             {'name': name});
+        reportDuplicateExport(element, exports);
+        reportDuplicateExportDecl(element, exports);
         element = existingElement;
-      } else if (existingElement.getLibrary() != library) {
+      } else if (existingElement.getLibrary() == library) {
+        // Do nothing. [existingElement] hides [element].
+      } else if (element.getLibrary() == library) {
+        // [element] hides [existingElement].
+        exportScope[name] = element;
+        exporters[element] = exports;
+      } else {
         // Declared elements hide exported elements.
-        compiler.reportError(existingElement, MessageKind.DUPLICATE_EXPORT,
-                             {'name': name});
-        compiler.reportError(element, MessageKind.DUPLICATE_EXPORT,
-                             {'name': name});
+        Link<Export> existingExports = exporters[existingElement];
+        reportDuplicateExport(existingElement, existingExports);
+        reportDuplicateExport(element, exports, reportError: false);
+        reportDuplicateExportDecl(existingElement, existingExports);
+        reportDuplicateExportDecl(element, exports);
         element = exportScope[name] = new ErroneousElementX(
             MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
       }
     } else {
       exportScope[name] = element;
+      exporters[element] = exports;
     }
     return element;
   }
@@ -741,14 +794,16 @@
    * the pending export set was modified. The combinators of [export] are used
    * to filter the element.
    */
-  bool addElementToPendingExports(Element element) {
+  bool addElementToPendingExports(Element element, Export export) {
+    bool changed = false;
     if (!identical(exportScope[element.name], element)) {
-      if (!pendingExportSet.contains(element)) {
-        pendingExportSet.add(element);
-        return true;
-      }
+      Link<Export> exports = pendingExportMap.putIfAbsent(element, () {
+        changed = true;
+        return const Link<Export>();
+      });
+      pendingExportMap[element] = exports.prepend(export);
     }
-    return false;
+    return changed;
   }
 }
 
@@ -783,8 +838,8 @@
     bool changed = true;
     while (changed) {
       changed = false;
-      Map<LibraryDependencyNode, List<Element>> tasks =
-          new LinkedHashMap<LibraryDependencyNode, List<Element>>();
+      Map<LibraryDependencyNode, Map<Element, Link<Export>>> tasks =
+          new Map<LibraryDependencyNode, Map<Element, Link<Export>>>();
 
       // Locally defined elements take precedence over exported
       // elements.  So we must propagate local elements first.  We
@@ -792,12 +847,13 @@
       // propagating.  This enforces that we handle exports
       // breadth-first, with locally defined elements being level 0.
       nodeMap.forEach((_, LibraryDependencyNode node) {
-        List<Element> pendingExports = node.pullPendingExports();
+        Map<Element, Link<Export>> pendingExports = node.pullPendingExports();
         tasks[node] = pendingExports;
       });
-      tasks.forEach((LibraryDependencyNode node, List<Element> pendingExports) {
-        pendingExports.forEach((Element element) {
-          element = node.addElementToExportScope(compiler, element);
+      tasks.forEach((LibraryDependencyNode node,
+                     Map<Element, Link<Export>> pendingExports) {
+        pendingExports.forEach((Element element, Link<Export> exports) {
+          element = node.addElementToExportScope(compiler, element, exports);
           if (node.propagateElement(element)) {
             changed = true;
           }
@@ -833,7 +889,8 @@
       if (loadedLibrary.exportsHandled) {
         // Export scope already computed on [loadedLibrary].
         var combinatorFilter = new CombinatorFilter.fromTag(tag);
-        exportingNode.registerHandledExports(loadedLibrary, combinatorFilter);
+        exportingNode.registerHandledExports(
+            loadedLibrary, tag, combinatorFilter);
         return;
       }
       LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index e475aa7..f16461b 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -797,7 +797,7 @@
     }
     for (final typeString in specString.split('|')) {
       var type = _parseType(typeString, compiler,
-          (name) => resolver.resolveTypeFromString(name),
+          (name) => resolver.resolveTypeFromString(specLiteral, name),
           jsCall);
       behavior.typesInstantiated.add(type);
       behavior.typesReturned.add(type);
diff --git a/sdk/lib/_internal/compiler/implementation/patch_parser.dart b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
index 88da806..fcd0be2 100644
--- a/sdk/lib/_internal/compiler/implementation/patch_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
@@ -145,10 +145,6 @@
           // Patch elements are stored on the patched functions or classes.
           scanLibraryElements(patchLibrary.entryCompilationUnit, imports);
         });
-        // After scanning declarations, we handle the import tags in the patch.
-        // TODO(lrn): These imports end up in the original library and are in
-        // scope for the original methods too. This should be fixed.
-        compiler.importHelperLibrary(originLibrary);
         // TODO(rnystrom): Remove .toList() here if #11523 is fixed.
         return Future.forEach(imports.toLink().toList(), (tag) {
           return compiler.withCurrentElement(patchLibrary, () {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index af4208d..f09879a 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -469,12 +469,15 @@
     visitor.useElement(tree, element);
 
     SendSet send = tree.asSendSet();
+    Modifiers modifiers = element.modifiers;
     if (send != null) {
       // TODO(johnniwinther): Avoid analyzing initializers if
       // [Compiler.analyzeSignaturesOnly] is set.
       visitor.visit(send.arguments.head);
-    } else if (element.modifiers.isConst()) {
+    } else if (modifiers.isConst()) {
       compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER);
+    } else if (modifiers.isFinal() && !element.isInstanceMember()) {
+      compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER);
     }
 
     if (Elements.isStaticOrTopLevelField(element)) {
@@ -1531,10 +1534,10 @@
   TypeResolver(this.compiler);
 
   Element resolveTypeName(Scope scope,
-                          SourceString prefixName,
+                          Identifier prefixName,
                           Identifier typeName) {
     if (prefixName != null) {
-      Element e = scope.lookup(prefixName);
+      Element e = lookupInScope(compiler, prefixName, scope, prefixName.source);
       if (e != null) {
         if (identical(e.kind, ElementKind.PREFIX)) {
           // The receiver is a prefix. Lookup in the imported members.
@@ -1556,7 +1559,7 @@
       } else if (identical(stringValue, 'dynamic')) {
         return compiler.dynamicClass;
       } else {
-        return scope.lookup(typeName.source);
+        return lookupInScope(compiler, typeName, scope, typeName.source);
       }
     }
   }
@@ -1564,11 +1567,11 @@
   DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
                                  {bool malformedIsError: false}) {
     Identifier typeName;
-    SourceString prefixName;
+    Identifier prefixName;
     Send send = node.typeName.asSend();
     if (send != null) {
       // The type name is of the form [: prefix . identifier :].
-      prefixName = send.receiver.asIdentifier().source;
+      prefixName = send.receiver.asIdentifier();
       typeName = send.selector.asIdentifier();
     } else {
       typeName = node.typeName.asIdentifier();
@@ -1838,6 +1841,11 @@
   int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
       | ElementCategory.IMPLIES_TYPE;
 
+  /// When visiting the type declaration of the variable in a [ForIn] loop,
+  /// the initializer of the variable is implicit and we should not emit an
+  /// error when verifying that all final variables are initialized.
+  bool allowFinalWithoutInitializer = false;
+
   // TODO(ahe): Find a way to share this with runtime implementation.
   static final RegExp symbolValidationPattern =
       new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
@@ -1964,7 +1972,7 @@
       return null;
     } else {
       SourceString name = node.source;
-      Element element = scope.lookup(name);
+      Element element = lookupInScope(compiler, node, scope, name);
       if (Elements.isUnresolved(element) && name.slowToString() == 'dynamic') {
         element = compiler.dynamicClass;
       }
@@ -2519,8 +2527,9 @@
   }
 
   /// Callback for native enqueuer to parse a type.  Returns [:null:] on error.
-  DartType resolveTypeFromString(String typeName) {
-    Element element = scope.lookup(new SourceString(typeName));
+  DartType resolveTypeFromString(Node node, String typeName) {
+    Element element = lookupInScope(compiler, node,
+                                    scope, new SourceString(typeName));
     if (element == null) return null;
     if (element is! ClassElement) return null;
     ClassElement cls = element;
@@ -3080,7 +3089,11 @@
     visit(node.expression);
     Scope blockScope = new BlockScope(scope);
     Node declaration = node.declaredIdentifier;
+
+    bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer;
+    allowFinalWithoutInitializer = true;
     visitIn(declaration, blockScope);
+    allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer;
 
     Send send = declaration.asSend();
     VariableDefinitions variableDefinitions =
@@ -3990,7 +4003,7 @@
   }
 
   void visitIdentifier(Identifier node) {
-    Element element = context.lookup(node.source);
+    Element element = lookupInScope(compiler, node, context, node.source);
     if (element == null) {
       compiler.reportError(
           node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node});
@@ -4011,7 +4024,7 @@
       error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
       return;
     }
-    Element element = context.lookup(prefix.source);
+    Element element = lookupInScope(compiler, prefix, context, prefix.source);
     if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
       error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
       return;
@@ -4062,6 +4075,10 @@
     if (definitions.modifiers.isConst()) {
       compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER);
     }
+    if (definitions.modifiers.isFinal() &&
+        !resolver.allowFinalWithoutInitializer) {
+      compiler.reportError(node, MessageKind.FINAL_WITHOUT_INITIALIZER);
+    }
     return node.source;
   }
 
@@ -4476,7 +4493,7 @@
   Element visitIdentifier(Identifier node) {
     SourceString name = node.source;
     Element e = resolver.reportLookupErrorIfAny(
-        resolver.scope.lookup(name), node, name);
+        lookupInScope(compiler, node, resolver.scope, name), node, name);
     // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
     if (e == null) {
       return failOrReturnErroneousElement(resolver.enclosingElement, node, name,
@@ -4504,3 +4521,9 @@
                                       expression, expression);
   }
 }
+
+/// Looks up [name] in [scope] and unwraps the result.
+Element lookupInScope(Compiler compiler, Node node,
+                      Scope scope, SourceString name) {
+  return Elements.unwrap(scope.lookup(name), compiler, node);
+}
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index bda4b76..53a1f08 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -99,7 +99,7 @@
    */
   Token next;
 
-  Token(PrecedenceInfo this.info, int this.charOffset);
+  Token(this.info, this.charOffset);
 
   get value => info.value;
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 70713da..60bb2ad 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -275,6 +275,8 @@
     // classes, or the same as [:this:] for non-intercepted classes.
     ClassElement cls = element.getEnclosingClass();
     JavaScriptBackend backend = compiler.backend;
+    bool isNativeUpgradeFactory = element.isGenerativeConstructor()
+        && Elements.isNativeOrExtendsNative(cls);
     if (backend.isInterceptedMethod(element)) {
       bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
       SourceString name = isInterceptorClass
@@ -291,6 +293,14 @@
         directLocals[closureData.thisElement] = value;
       }
       value.instructionType = builder.getTypeOfThis();
+    } else if (isNativeUpgradeFactory) {
+      bool isInterceptorClass = backend.isInterceptorClass(cls.declaration);
+      Element parameter = new InterceptedElement(
+          cls.computeType(compiler), const SourceString('receiver'), element);
+      HParameterValue value = new HParameterValue(parameter);
+      builder.graph.explicitReceiverParameter = value;
+      builder.graph.entry.addAtEntry(value);
+      value.instructionType = builder.getTypeOfThis();
     }
   }
 
@@ -1267,6 +1277,13 @@
         }
       }
 
+      // Generative constructors of native classes should not be called directly
+      // and have an extra argument that causes problems with inlining.
+      if (element.isGenerativeConstructor()
+          && Elements.isNativeOrExtendsNative(element.getEnclosingClass())) {
+        return false;
+      }
+
       // A generative constructor body is not seen by global analysis,
       // so we should not query for its type.
       if (!element.isGenerativeConstructorBody()) {
@@ -1586,9 +1603,13 @@
             TreeElements definitions = compiler.analyzeElement(member);
             Node node = member.parseNode(compiler);
             SendSet assignment = node.asSendSet();
-            HInstruction value;
             if (assignment == null) {
-              value = graph.addConstantNull(compiler);
+              // Unassigned fields of native classes are not initialized to
+              // prevent overwriting pre-initialized native properties.
+              if (!Elements.isNativeOrExtendsNative(classElement)) {
+                HInstruction value = graph.addConstantNull(compiler);
+                fieldValues[member] = value;
+              }
             } else {
               Node right = assignment.arguments.head;
               TreeElements savedElements = elements;
@@ -1599,9 +1620,9 @@
                   member, node, elements);
               inlinedFrom(member, () => right.accept(this));
               elements = savedElements;
-              value = pop();
+              HInstruction value = pop();
+              fieldValues[member] = value;
             }
-            fieldValues[member] = value;
           });
         });
   }
@@ -1619,6 +1640,8 @@
     functionElement = functionElement.implementation;
     ClassElement classElement =
         functionElement.getEnclosingClass().implementation;
+    bool isNativeUpgradeFactory =
+        Elements.isNativeOrExtendsNative(classElement);
     FunctionExpression function = functionElement.parseNode(compiler);
     // Note that constructors (like any other static function) do not need
     // to deal with optional arguments. It is the callers job to provide all
@@ -1654,10 +1677,20 @@
 
     // Call the JavaScript constructor with the fields as argument.
     List<HInstruction> constructorArguments = <HInstruction>[];
+    List<Element> fields = <Element>[];
+
     classElement.forEachInstanceField(
         (ClassElement enclosingClass, Element member) {
-          constructorArguments.add(potentiallyCheckType(
-              fieldValues[member], member.computeType(compiler)));
+          HInstruction value = fieldValues[member];
+          if (value == null) {
+            // Uninitialized native fields are pre-initialized by the native
+            // implementation.
+            assert(isNativeUpgradeFactory);
+          } else {
+            fields.add(member);
+            constructorArguments.add(
+                potentiallyCheckType(value, member.computeType(compiler)));
+          }
         },
         includeSuperAndInjectedMembers: true);
 
@@ -1668,11 +1701,25 @@
     if (!currentInlinedInstantiations.isEmpty) {
       instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations);
     }
-    HForeignNew newObject = new HForeignNew(classElement,
-                                            ssaType,
-                                            constructorArguments,
-                                            instantiatedTypes);
-    add(newObject);
+
+    HInstruction newObject;
+    if (!isNativeUpgradeFactory) {
+      newObject = new HForeignNew(classElement,
+          ssaType,
+          constructorArguments,
+          instantiatedTypes);
+      add(newObject);
+    } else {
+      // Bulk assign to the initialized fields.
+      newObject = graph.explicitReceiverParameter;
+      // Null guard ensures an error if we are being called from an explicit
+      // 'new' of the constructor instead of via an upgrade. It is optimized out
+      // if there are field initializers.
+      add(new HFieldGet(null, newObject, isAssignable: false));
+      for (int i = 0; i < fields.length; i++) {
+        add(new HFieldSet(fields[i], newObject, constructorArguments[i]));
+      }
+    }
     removeInlinedInstantiation(type);
     // Create the runtime type information, if needed.
     if (backend.classNeedsRti(classElement)) {
@@ -1684,12 +1731,22 @@
     }
 
     // Generate calls to the constructor bodies.
+    HInstruction interceptor = null;
     for (int index = constructors.length - 1; index >= 0; index--) {
       FunctionElement constructor = constructors[index];
       assert(invariant(functionElement, constructor.isImplementation));
       ConstructorBodyElement body = getConstructorBody(constructor);
       if (body == null) continue;
+
       List bodyCallInputs = <HInstruction>[];
+      if (isNativeUpgradeFactory) {
+        if (interceptor == null) {
+          Constant constant = new InterceptorConstant(
+              classElement.computeType(compiler));
+          interceptor = graph.addConstant(constant, compiler);
+        }
+        bodyCallInputs.add(interceptor);
+      }
       bodyCallInputs.add(newObject);
       TreeElements elements =
           compiler.enqueuer.resolution.getCachedElements(constructor);
@@ -1697,7 +1754,6 @@
       ClosureClassMap parameterClosureData =
           compiler.closureToClassMapper.getMappingForNestedFunction(node);
 
-
       FunctionSignature functionSignature = body.computeSignature(compiler);
       // Provide the parameters to the generative constructor body.
       functionSignature.orderedForEachParameter((parameter) {
@@ -1724,7 +1780,8 @@
         bodyCallInputs.add(localsHandler.readLocal(scopeData.boxElement));
       }
 
-      if (tryInlineMethod(body, null, bodyCallInputs, function)) {
+      if (!isNativeUpgradeFactory && // TODO(13836): Fix inlining.
+          tryInlineMethod(body, null, bodyCallInputs, function)) {
         pop();
       } else {
         HInvokeConstructorBody invoke =
@@ -2715,11 +2772,11 @@
       }
       stack.add(value);
     } else if (Elements.isErroneousElement(element)) {
+      List<HInstruction> arguments =
+          send == null ? const <HInstruction>[] : <HInstruction>[value];
       // An erroneous element indicates an unresolved static setter.
-      generateThrowNoSuchMethod(
-          location,
-          getTargetName(element, 'set'),
-          argumentNodes: (send == null ? const Link<Node>() : send.arguments));
+      generateThrowNoSuchMethod(location, getTargetName(element, 'set'),
+                                argumentValues: arguments);
     } else {
       stack.add(value);
       // If the value does not already have a name, give it here.
@@ -3565,6 +3622,11 @@
     }
 
     var inputs = <HInstruction>[];
+    if (constructor.isGenerativeConstructor() &&
+        Elements.isNativeOrExtendsNative(constructor.getEnclosingClass())) {
+      // Native class generative constructors take a pre-constructed object.
+      inputs.add(graph.addConstantNull(compiler));
+    }
     // TODO(5347): Try to avoid the need for calling [implementation] before
     // calling [addStaticSendArgumentsToList].
     bool succeeded = addStaticSendArgumentsToList(selector, send.arguments,
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 7b0b1a1..d0e882fd2 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1796,7 +1796,8 @@
     List<js.Expression> arguments = visitArguments(node.inputs, start: 0);
     // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it
     // as if it was a string.
-    push(new js.New(new js.VariableUse(jsClassReference), arguments), node);
+    js.Expression constructor = new js.VariableUse(jsClassReference);
+    push(new js.New(constructor, arguments), node);
     registerForeignTypes(node);
     if (node.instantiatedTypes == null) {
       return;
@@ -1820,6 +1821,15 @@
       FunctionConstant function = constant;
       world.registerStaticUse(function.element);
     }
+    if (constant.isType()) {
+      // If the type is a web component, we need to ensure the constructors are
+      // available to 'upgrade' the native object.
+      TypeConstant type = constant;
+      Element element = type.representedType.element;
+      if (element != null && element.isClass()) {
+        backend.registerEscapingConstructorsOfClass(element, world);
+      }
+    }
     push(backend.emitter.constantReference(constant));
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index c3dc5a6..af8648d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1454,6 +1454,9 @@
 }
 
 class HInvokeConstructorBody extends HInvokeStatic {
+  // The 'inputs' are
+  //     [receiver, arg1, ..., argN] or
+  //     [interceptor, receiver, arg1, ... argN].
   HInvokeConstructorBody(element, inputs)
       : super(element, inputs, HType.UNKNOWN);
 
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 2b2a399..2cc56ef 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -396,7 +396,23 @@
     if (type.treatAsDynamic) {
       return const DynamicAccess();
     }
-    Member member = type.lookupMember(name,
+    DartType originalType = type;
+    while (identical(type.kind, TypeKind.TYPE_VARIABLE)) {
+      TypeVariableType variable = type;
+      type = variable.element.bound;
+      if (type == originalType) {
+        type = compiler.objectClass.rawType;
+      }
+    }
+    if (type.kind == TypeKind.FUNCTION || type.kind == TypeKind.TYPEDEF) {
+      // TODO(karlklose): handle calling `call` on the function type. Do we have
+      // to type-check the arguments against the function type.
+      type = compiler.functionClass.rawType;
+    }
+    assert(invariant(node, type.kind == TypeKind.INTERFACE,
+        message: "unexpected type kind ${type.kind}."));
+    InterfaceType interface = type;
+    Member member = interface.lookupMember(name,
         isSetter: identical(memberKind, MemberKind.SETTER));
     if (member != null) {
       checkPrivateAccess(node, member.element, name);
@@ -555,21 +571,6 @@
         return const DynamicAccess();
       }
       TypeKind receiverKind = receiverType.kind;
-      if (identical(receiverKind, TypeKind.TYPEDEF)) {
-        // TODO(johnniwinther): handle typedefs.
-        return const DynamicAccess();
-      }
-      if (identical(receiverKind, TypeKind.FUNCTION)) {
-        // TODO(johnniwinther): handle functions.
-        return const DynamicAccess();
-      }
-      if (identical(receiverKind, TypeKind.TYPE_VARIABLE)) {
-        // TODO(johnniwinther): handle type variables.
-        return const DynamicAccess();
-      }
-      assert(invariant(node.receiver,
-          identical(receiverKind, TypeKind.INTERFACE),
-          message: "interface type expected, got ${receiverKind}"));
       return lookupMember(node, receiverType, name, memberKind);
     } else {
       return computeResolvedAccess(node, name, element, memberKind);
@@ -715,8 +716,10 @@
                        identical(name, '[]'),
                        message: 'Unexpected operator $name'));
 
-      ElementAccess access = lookupMember(node, receiverType,
-                                          operatorName, MemberKind.OPERATOR);
+      // TODO(karlklose): handle `void` in expression context by calling
+      // [analyzeNonVoid] instead of [analyze].
+      ElementAccess access = receiverType.isVoid ? const DynamicAccess()
+          : lookupMember(node, receiverType, operatorName, MemberKind.OPERATOR);
       LinkBuilder<DartType> argumentTypesBuilder = new LinkBuilder<DartType>();
       DartType resultType =
           analyzeInvocation(node, access, argumentTypesBuilder);
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 3c3729e..554a3bc 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -214,7 +214,7 @@
 import 'dart:async'; // This imports a class Future.
 import 'future.dart';
 
-void main() {}""",
+void main() => new Future();""",
 
 'future.dart':
 """
@@ -228,7 +228,7 @@
 import 'future.dart';
 import 'dart:async'; // This imports a class Future.
 
-void main() {}""",
+void main() => new Future();""",
 
 'future.dart':
 """
@@ -242,7 +242,7 @@
 import 'export.dart';
 import 'dart:async'; // This imports a class Future.
 
-void main() {}""",
+void main() => new Future();""",
 
 'future.dart':
 """
@@ -269,7 +269,7 @@
 // This hides the implicit import of class Type from dart:core.
 import 'type.dart';
 
-void main() {}""",
+void main() => new Type();""",
 
 'type.dart':
 """
@@ -278,7 +278,22 @@
 class Type {}"""}]);
 
   static const MessageKind DUPLICATE_EXPORT = const MessageKind(
-      "Error: Duplicate export of '#{name}'.");
+      "Error: Duplicate export of '#{name}'.",
+      howToFix: "Trying adding 'hide #{name}' to one of the exports.",
+      examples: const [const {
+'main.dart': """
+export 'decl1.dart';
+export 'decl2.dart';
+
+main() {}""",
+'decl1.dart': "class Class {}",
+'decl2.dart': "class Class {}"}]);
+
+  static const MessageKind DUPLICATE_EXPORT_CONT = const MessageKind(
+      "Info: This is another export of '#{name}'.");
+
+  static const MessageKind DUPLICATE_EXPORT_DECL = const MessageKind(
+      "Info: The exported '#{name}' from export #{uriString} is defined here.");
 
   static const DualKind NOT_A_TYPE = const DualKind(
       error: const MessageKind("Error: '#{node}' is not a type."),
@@ -674,11 +689,11 @@
       examples: const ["""
 class C extends Object with String {}
 
-main() => new C();                       
+main() => new C();
 """, """
 typedef C = Object with String;
 
-main() => new C();                       
+main() => new C();
 """]);
 
   static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
@@ -894,6 +909,13 @@
   const c; // This constant variable must be initialized.
 }"""]);
 
+  static const MessageKind FINAL_WITHOUT_INITIALIZER = const MessageKind(
+      "Error: A final variable must be initialized.",
+      howToFix: "Try adding an initializer or "
+                "removing the 'final' modifier.",
+      examples: const [
+          "class C { static final field; } main() => C.field;"]);
+
   static const MessageKind MEMBER_USES_CLASS_NAME = const MessageKind(
       "Error: Member variable can't have the same name as the class it is "
       "declared in.",
@@ -965,13 +987,13 @@
 "operator.");
 
   static const MessageKind AMBIGUOUS_REEXPORT = const MessageKind(
-      "Info: '#{element}' is (re)exported by multiple libraries.");
+      "Info: '#{name}' is (re)exported by multiple libraries.");
 
   static const MessageKind AMBIGUOUS_LOCATION = const MessageKind(
-      "Info: '#{element}' is defined here.");
+      "Info: '#{name}' is defined here.");
 
   static const MessageKind IMPORTED_HERE = const MessageKind(
-      "Info: '#{element}' is imported here.");
+      "Info: '#{name}' is imported here.");
 
   static const MessageKind OVERRIDE_EQUALS_NOT_HASH_CODE = const MessageKind(
       "Hint: The class '#{class}' overrides 'operator==', "
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 1f94af6..c4fa58f 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -80,15 +80,7 @@
   if (outputDir.existsSync()) {
     outputDir.deleteSync(recursive: true);
   }
-
-  try {
-    // TODO(3914): Hack to avoid 'file already exists' exception thrown
-    // due to invalid result from dir.existsSync() (probably due to race
-    // conditions).
-    outputDir.createSync();
-  } on DirectoryException catch (e) {
-    // Ignore.
-  }
+  outputDir.createSync();
 }
 
 /**
@@ -359,7 +351,7 @@
     [new md.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
 
   Dartdoc() {
-    tmpPath = new Directory('').createTempSync().path;
+    tmpPath = Directory.systemTemp.createTempSync('dartdoc_').path;
     dartdocResolver = (String name) => resolveNameReference(name,
         currentLibrary: _currentLibrary, currentType: _currentType,
         currentMember: _currentMember);
diff --git a/sdk/lib/_internal/dartdoc/test/export_map_test.dart b/sdk/lib/_internal/dartdoc/test/export_map_test.dart
index ed5e392..4d43bd4 100644
--- a/sdk/lib/_internal/dartdoc/test/export_map_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/export_map_test.dart
@@ -389,7 +389,7 @@
 String libPath(String name) => pathos.normalize(pathos.join(tempDir, name));
 
 void createTempDir() {
-  tempDir = new Directory('').createTempSync().path;
+  tempDir = Directory.systemTemp.createTempSync('dartdoc_').path;
   new Directory(pathos.join(tempDir, 'packages')).createSync();
 }
 
diff --git a/sdk/lib/_internal/lib/interceptors.dart b/sdk/lib/_internal/lib/interceptors.dart
index 9dff6fb..78b591d 100644
--- a/sdk/lib/_internal/lib/interceptors.dart
+++ b/sdk/lib/_internal/lib/interceptors.dart
@@ -151,9 +151,10 @@
 
 
 /**
- * Data structure used to map a [Type] to the [Interceptor] for that type.  It
- * is JavaScript array of 2N entries of adjacent slots containing a [Type]
- * followed by an [Interceptor] class for the type.
+ * Data structure used to map a [Type] to the [Interceptor] and constructors for
+ * that type.  It is JavaScript array of 3N entries of adjacent slots containing
+ * a [Type], followed by an [Interceptor] class for the type, followed by a
+ * JavaScript object map for the constructors.
  *
  * The value of this variable is set by the compiler and contains only types
  * that are user extensions of native classes where the type occurs as a
@@ -162,18 +163,40 @@
 // TODO(sra): Mark this as initialized to a constant with unknown value.
 var mapTypeToInterceptor;
 
-findInterceptorConstructorForType(Type type) {
+int findIndexForWebComponentType(Type type) {
   JS_EFFECT((_){ mapTypeToInterceptor = _; });
   if (mapTypeToInterceptor == null) return null;
   List map = JS('JSFixedArray', '#', mapTypeToInterceptor);
-  for (int i = 0; i + 1 < map.length; i += 2) {
+  for (int i = 0; i + 1 < map.length; i += 3) {
     if (type == map[i]) {
-      return map[i + 1];
+      return i;
     }
   }
   return null;
 }
 
+findInterceptorConstructorForType(Type type) {
+  var index = findIndexForWebComponentType(type);
+  if (index == null) return null;
+  List map = JS('JSFixedArray', '#', mapTypeToInterceptor);
+  return mapTypeToInterceptor[index + 1];
+}
+
+/**
+ * Returns a JavaScript function that runs the constructor on its argument, or
+ * `null` if there is no such constructor.
+ *
+ * The returned function takes one argument, the web component object.
+ */
+findConstructorForWebComponentType(Type type, String name) {
+  var index = findIndexForWebComponentType(type);
+  if (index == null) return null;
+  List map = JS('JSFixedArray', '#', mapTypeToInterceptor);
+  var constructorMap = mapTypeToInterceptor[index + 2];
+  var constructorFn = JS('', '#[#]', constructorMap, name);
+  return constructorFn;
+}
+
 findInterceptorForType(Type type) {
   var constructor = findInterceptorConstructorForType(type);
   if (constructor == null) return null;
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index dd4444a..0acb7d4 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -9,9 +9,12 @@
   patch static _setCurrent(path) {
     throw new UnsupportedError("Directory_SetCurrent");
   }
-  patch static _createTemp(String template, bool system) {
+  patch static _createTemp(String path) {
     throw new UnsupportedError("Directory._createTemp");
   }
+  patch static String _systemTemp() {
+    throw new UnsupportedError("Directory._systemTemp");
+  }
   patch static int _exists(String path) {
     throw new UnsupportedError("Directory._exists");
   }
diff --git a/sdk/lib/_internal/lib/js_array.dart b/sdk/lib/_internal/lib/js_array.dart
index 5718c5d..b6ec0cb 100644
--- a/sdk/lib/_internal/lib/js_array.dart
+++ b/sdk/lib/_internal/lib/js_array.dart
@@ -243,6 +243,10 @@
     IterableMixinWorkaround.sortList(this, compare);
   }
 
+  void shuffle() {
+    IterableMixinWorkaround.shuffleList(this);
+  }
+
   int indexOf(Object element, [int start = 0]) {
     return IterableMixinWorkaround.indexOfList(this, element, start);
   }
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 2887c43..4d0fe51 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -781,18 +781,9 @@
   }
 
   int get hashCode {
-    // If the reflectee is a built-in type, use the base-level hashCode to
-    // preserve the illusion that, e.g. doubles, with the same value are
-    // identical. Otherwise, use the primitive identity hash to maintain
-    // correctness even if a user-defined hashCode returns different values for
-    // successive invocations.
-    var h = ((JS('bool', 'typeof # != "object"', reflectee)) ||
-             (reflectee == null))
-        ? reflectee.hashCode
-        : Primitives.objectHashCode(reflectee);
     // Avoid hash collisions with the reflectee. This constant is in Smi range
     // and happens to be the inner padding from RFC 2104.
-    return h ^ 0x36363636;
+    return identityHashCode(reflectee) ^ 0x36363636;
   }
 
   String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}';
diff --git a/sdk/lib/_internal/lib/math_patch.dart b/sdk/lib/_internal/lib/math_patch.dart
index 3bccb2c..7def542 100644
--- a/sdk/lib/_internal/lib/math_patch.dart
+++ b/sdk/lib/_internal/lib/math_patch.dart
@@ -4,6 +4,7 @@
 
 // Patch file for dart:math library.
 import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper' show checkNum;
 
 patch double sqrt(num x)
   => JS('double', r'Math.sqrt(#)', checkNum(x));
diff --git a/sdk/lib/_internal/lib/mirrors_patch.dart b/sdk/lib/_internal/lib/mirrors_patch.dart
index 4700984..ad05409 100644
--- a/sdk/lib/_internal/lib/mirrors_patch.dart
+++ b/sdk/lib/_internal/lib/mirrors_patch.dart
@@ -19,5 +19,8 @@
 patch InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
 
 patch ClassMirror reflectClass(Type key) {
+  if (key is! Type || key == dynamic) {
+  	throw new ArgumentError('$key does not denote a class');
+  }
   return js.reflectType(key).originalDeclaration;
 }
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart
index 803ec64..70b36b5 100644
--- a/sdk/lib/_internal/pub/lib/src/barback.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart
@@ -7,7 +7,10 @@
 import 'dart:async';
 
 import 'package:barback/barback.dart';
+import 'package:path/path.dart' as path;
 
+import 'barback/dart_forwarding_transformer.dart';
+import 'barback/dart2js_transformer.dart';
 import 'barback/load_all_transformers.dart';
 import 'barback/pub_package_provider.dart';
 import 'barback/server.dart';
@@ -54,6 +57,14 @@
 Future<BarbackServer> createServer(String host, int port, PackageGraph graph) {
   var provider = new PubPackageProvider(graph);
   var barback = new Barback(provider);
+
+  // TODO(rnystrom): Add dart2dart transformer here and some way to configure
+  // them.
+  var builtInTransformers = [
+    new Dart2JSTransformer(graph),
+    new DartForwardingTransformer()
+  ];
+
   return BarbackServer.bind(host, port, barback, graph.entrypoint.root.name)
       .then((server) {
     watchSources(graph, barback);
@@ -75,7 +86,7 @@
       })
     ];
 
-    loadAllTransformers(server, graph).then((_) {
+    loadAllTransformers(server, graph, builtInTransformers).then((_) {
       if (!completer.isCompleted) completer.complete(server);
     }).catchError((error) {
       if (!completer.isCompleted) completer.completeError(error);
@@ -141,3 +152,38 @@
 
   return new Uri(scheme: 'package', path: id.path.replaceFirst('lib/', ''));
 }
+
+/// Converts [uri] into an [AssetId] if it has a path containing "packages" or
+/// "assets".
+///
+/// If the URI doesn't contain one of those special directories, returns null.
+/// If it does contain a special directory, but lacks a following package name,
+/// throws a [FormatException].
+AssetId specialUrlToId(Uri url) {
+  var parts = path.url.split(url.path);
+
+  for (var pair in [["packages", "lib"], ["assets", "asset"]]) {
+    var partName = pair.first;
+    var dirName = pair.last;
+
+    // Find the package name and the relative path in the package.
+    var index = parts.indexOf(partName);
+    if (index == -1) continue;
+
+    // If we got here, the path *did* contain the special directory, which
+    // means we should not interpret it as a regular path. If it's missing the
+    // package name after the special directory, it's invalid.
+    if (index + 1 >= parts.length) {
+      throw new FormatException(
+          'Invalid package path "${path.url.joinAll(parts)}". '
+          'Expected package name after "$partName".');
+    }
+
+    var package = parts[index + 1];
+    var assetPath = path.url.join(dirName,
+        path.url.joinAll(parts.skip(index + 2)));
+    return new AssetId(package, assetPath);
+  }
+
+  return null;
+}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
new file mode 100644
index 0000000..9405f43
--- /dev/null
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -0,0 +1,226 @@
+// 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.dart2js_transformer;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analyzer_experimental/analyzer.dart';
+import 'package:barback/barback.dart';
+import 'package:path/path.dart' as path;
+
+import '../../../../compiler/compiler.dart' as compiler;
+import '../../../../compiler/implementation/dart2js.dart'
+    show AbortLeg;
+import '../../../../compiler/implementation/source_file.dart';
+import '../barback.dart';
+import '../dart.dart' as dart;
+import '../io.dart';
+import '../package.dart';
+import '../package_graph.dart';
+
+/// A [Transformer] that uses dart2js's library API to transform Dart
+/// entrypoints in "web" to JavaScript.
+class Dart2JSTransformer extends Transformer {
+  final PackageGraph _graph;
+
+  Dart2JSTransformer(this._graph);
+
+  /// Only ".dart" files within "web/" are processed.
+  Future<bool> isPrimary(Asset asset) {
+    return new Future.value(
+        asset.id.extension == ".dart" &&
+        asset.id.path.startsWith("web/"));
+  }
+
+  Future apply(Transform transform) {
+    var stopwatch = new Stopwatch();
+    stopwatch.start();
+
+    return transform.primaryInput.readAsString().then((code) {
+      try {
+        if (!dart.isEntrypoint(parseCompilationUnit(code))) return;
+      } on AnalyzerErrorGroup catch (e) {
+        transform.logger.error(e.message);
+        return;
+      }
+
+      var provider = new _BarbackInputProvider(_graph, transform);
+
+      // Create a "path" to the entrypoint script. The entrypoint may not
+      // actually be on disk, but this gives dart2js a root to resolve
+      // relative paths against.
+      var id = transform.primaryInput.id;
+      var entrypoint = path.join(_graph.packages[id.package].dir, id.path);
+      var packageRoot = path.join(_graph.entrypoint.root.dir, "packages");
+
+      // TODO(rnystrom): Should have more sophisticated error-handling here.
+      // Need to report compile errors to the user in an easily visible way.
+      // Need to make sure paths in errors are mapped to the original source
+      // path so they can understand them.
+      return dart.compile(entrypoint,
+          packageRoot: packageRoot,
+          inputProvider: provider.readStringFromUri,
+          diagnosticHandler: provider.handleDiagnostic).then((js) {
+        var id = transform.primaryInput.id.changeExtension(".dart.js");
+        transform.addOutput(new Asset.fromString(id, js));
+
+        stopwatch.stop();
+        transform.logger.info("Generated $id (${js.length} characters) in "
+            "${stopwatch.elapsed}");
+      });
+    });
+  }
+}
+
+/// Defines methods implementig [CompilerInputProvider] and [DiagnosticHandler]
+/// for dart2js to use to load files from Barback and report errors.
+///
+/// Note that most of the implementation of diagnostic handling here was
+/// copied from [FormattingDiagnosticHandler] in dart2js. The primary
+/// difference is that it uses barback's logging code and, more importantly, it
+/// handles missing source files more gracefully.
+class _BarbackInputProvider {
+  final PackageGraph _graph;
+  final Transform _transform;
+
+  /// The map of previously loaded files.
+  ///
+  /// Used to show where an error occurred in a source file.
+  final _sourceFiles = new Map<String, SourceFile>();
+
+  // TODO(rnystrom): Make these configurable.
+  /// Whether or not warnings should be logged.
+  var _showWarnings = true;
+
+  /// Whether or not hints should be logged.
+  var _showHints = true;
+
+  /// Whether or not verbose info messages should be logged.
+  var _verbose = false;
+
+  /// Whether an exception should be thrown on an error to stop compilation.
+  var _throwOnError = false;
+
+  /// This gets set after a fatal error is reported to quash any subsequent
+  /// errors.
+  var _isAborting = false;
+
+  compiler.Diagnostic _lastKind = null;
+
+  static final int _FATAL =
+      compiler.Diagnostic.CRASH.ordinal |
+      compiler.Diagnostic.ERROR.ordinal;
+  static final int _INFO =
+      compiler.Diagnostic.INFO.ordinal |
+      compiler.Diagnostic.VERBOSE_INFO.ordinal;
+
+  _BarbackInputProvider(this._graph, this._transform);
+
+  /// A [CompilerInputProvider] for dart2js.
+  Future<String> readStringFromUri(Uri resourceUri) {
+    // We only expect to get absolute "file:" URLs from dart2js.
+    assert(resourceUri.isAbsolute);
+    assert(resourceUri.scheme == "file");
+
+    var sourcePath = path.fromUri(resourceUri);
+    return _readResource(resourceUri).then((source) {
+      _sourceFiles[resourceUri.toString()] =
+          new SourceFile(path.relative(sourcePath), source);
+      return source;
+    });
+  }
+
+  /// A [DiagnosticHandler] for dart2js, loosely based on
+  /// [FormattingDiagnosticHandler].
+  void handleDiagnostic(Uri uri, int begin, int end,
+                        String message, compiler.Diagnostic kind) {
+    // TODO(ahe): Remove this when source map is handled differently.
+    if (kind.name == "source map") return;
+
+    if (_isAborting) return;
+    _isAborting = (kind == compiler.Diagnostic.CRASH);
+
+    var isInfo = (kind.ordinal & _INFO) != 0;
+    if (isInfo && uri == null && kind != compiler.Diagnostic.INFO) {
+      if (!_verbose && kind == compiler.Diagnostic.VERBOSE_INFO) return;
+      _transform.logger.info(message);
+      return;
+    }
+
+    // [_lastKind] records the previous non-INFO kind we saw.
+    // This is used to suppress info about a warning when warnings are
+    // suppressed, and similar for hints.
+    if (kind != compiler.Diagnostic.INFO) _lastKind = kind;
+
+    var logFn;
+    if (kind == compiler.Diagnostic.ERROR) {
+      logFn = _transform.logger.error;
+    } else if (kind == compiler.Diagnostic.WARNING) {
+      if (!_showWarnings) return;
+      logFn = _transform.logger.warning;
+    } else if (kind == compiler.Diagnostic.HINT) {
+      if (!_showHints) return;
+      logFn = _transform.logger.warning;
+    } else if (kind == compiler.Diagnostic.CRASH) {
+      logFn = _transform.logger.error;
+    } else if (kind == compiler.Diagnostic.INFO) {
+      if (_lastKind == compiler.Diagnostic.WARNING && !_showWarnings) return;
+      if (_lastKind == compiler.Diagnostic.HINT && !_showHints) return;
+      logFn = _transform.logger.info;
+    } else {
+      throw new Exception('Unknown kind: $kind (${kind.ordinal})');
+    }
+
+    var fatal = (kind.ordinal & _FATAL) != 0;
+    if (uri == null) {
+      assert(fatal);
+      logFn(message);
+    } else {
+      SourceFile file = _sourceFiles[uri.toString()];
+      if (file == null) {
+        // We got a message before loading the file, so just report the message
+        // itself.
+        logFn('$uri: $message');
+      } else {
+        logFn(file.getLocationMessage(message, begin, end, true, (i) => i));
+      }
+    }
+
+    if (fatal && _throwOnError) {
+      _isAborting = true;
+      throw new AbortLeg(message);
+    }
+  }
+
+  Future<String> _readResource(Uri url) {
+    // See if the path is within a package. If so, use Barback so we can use
+    // generated Dart assets.
+    var id = _sourceUrlToId(url);
+    if (id != null) return _transform.readInputAsString(id);
+
+    // If we get here, the path doesn't appear to be in a package, so we'll
+    // skip Barback and just hit the file system. This will occur at the very
+    // least for dart2js's implementations of the core libraries.
+    var sourcePath = path.fromUri(url);
+    return new File(sourcePath).readAsString();
+  }
+
+  AssetId _sourceUrlToId(Uri url) {
+    // See if it's a special path with "packages" or "assets" in it.
+    var id = specialUrlToId(url);
+    if (id != null) return id;
+
+    // See if it's a path within the root package.
+    var rootDir = _graph.entrypoint.root.dir;
+    var sourcePath = path.fromUri(url);
+    if (isBeneath(sourcePath, rootDir)) {
+      var relative = path.relative(sourcePath, from: rootDir);
+      return new AssetId(_graph.entrypoint.root.name, relative);
+    }
+
+    return null;
+  }
+}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart_forwarding_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart_forwarding_transformer.dart
new file mode 100644
index 0000000..8c25a38
--- /dev/null
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart_forwarding_transformer.dart
@@ -0,0 +1,26 @@
+// 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.dart_forwarding_transformer;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+
+import '../utils.dart';
+
+/// A single transformer that just forwards any ".dart" file as an output.
+///
+/// Since the [Dart2JSTransformer] consumes its inputs, this is used in
+/// parallel to make sure the original Dart file is still available for use by
+/// Dartium.
+class DartForwardingTransformer extends Transformer {
+  String get allowedExtensions => ".dart";
+
+  Future apply(Transform transform) {
+    return newFuture(() {
+      transform.addOutput(transform.primaryInput);
+    });
+  }
+}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
index 3efce84..a03ce3a 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
@@ -19,7 +19,11 @@
 ///
 /// This uses [server] to serve the Dart files from which transformers are
 /// loaded, then adds the transformers to `server.barback`.
-Future loadAllTransformers(BarbackServer server, PackageGraph graph) {
+///
+/// Any [builtInTransformers] that are provided will automatically be added to
+/// the end of every package's cascade.
+Future loadAllTransformers(BarbackServer server, PackageGraph graph,
+                           [Iterable<Transformer> builtInTransformers]) {
   // In order to determine in what order we should load transformers, we need to
   // know which transformers depend on which others. This is different than
   // normal package dependencies. Let's begin with some terminology:
@@ -109,7 +113,12 @@
     for (var package in graph.packages.values) {
       var phases = package.pubspec.transformers.map((phase) {
         return unionAll(phase.map((id) => loader.transformersFor(id)));
-      });
+      }).toList();
+
+      if (builtInTransformers != null && builtInTransformers.isNotEmpty) {
+        phases.add(builtInTransformers);
+      }
+
       server.barback.updateTransformers(package.name, phases);
     }
   });
diff --git a/sdk/lib/_internal/pub/lib/src/barback/server.dart b/sdk/lib/_internal/pub/lib/src/barback/server.dart
index 3b8c154..36faf4a 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/server.dart
@@ -11,6 +11,7 @@
 import 'package:path/path.dart' as path;
 import 'package:stack_trace/stack_trace.dart';
 
+import '../barback.dart';
 import '../log.dart' as log;
 import '../utils.dart';
 
@@ -74,9 +75,13 @@
       return;
     }
 
-    var id = _getIdFromUri(request.uri);
-    if (id == null) {
-      _notFound(request, "Path ${request.uri.path} is not valid.");
+    var id;
+    try {
+      id = _uriToId(_rootPackage, request.uri);
+    } on FormatException catch (ex) {
+      // If we got here, we had a path like "/packages" which is a special
+      // directory, but not a valid path since it lacks a following package name.
+      _notFound(request, ex.message);
       return;
     }
 
@@ -130,6 +135,22 @@
     });
   }
 
+  /// Converts a [url] served by pub serve into an [AssetId] that can be
+  /// requested from barback.
+  AssetId _uriToId(String rootPackage, Uri url) {
+    var id = specialUrlToId(url);
+    if (id != null) return id;
+
+    // Otherwise, it's a path in current package's web directory.
+    var parts = path.url.split(url.path);
+
+    // Strip the leading "/" from the URL.
+    parts = parts.skip(1);
+
+    var relativePath = path.url.join("web", path.url.joinAll(parts));
+    return new AssetId(rootPackage, relativePath);
+  }
+
   /// Responds to [request] with a 405 response and closes it.
   void _methodNotAllowed(HttpRequest request) {
     _logRequest(request, "405 Method Not Allowed");
@@ -150,53 +171,6 @@
     request.response.close();
   }
 
-  /// Converts a request [uri] into an [AssetId] that can be requested from
-  /// barback.
-  AssetId _getIdFromUri(Uri uri) {
-    var parts = path.url.split(uri.path);
-
-    // Strip the leading "/" from the URL.
-    parts.removeAt(0);
-
-    var isSpecial = false;
-
-    // Checks to see if [uri]'s path contains a special directory [name] that
-    // identifies an asset within some package. If so, maps the package name
-    // and path following that to be within [dir] inside that package.
-    AssetId _trySpecialUrl(String name, String dir) {
-      // Find the package name and the relative path in the package.
-      var index = parts.indexOf(name);
-      if (index == -1) return null;
-
-      // If we got here, the path *did* contain the special directory, which
-      // means we should not interpret it as a regular path, even if it's
-      // missing the package name after it, which makes it invalid here.
-      isSpecial = true;
-      if (index + 1 >= parts.length) return null;
-
-      var package = parts[index + 1];
-      var assetPath = path.url.join(dir,
-          path.url.joinAll(parts.skip(index + 2)));
-      return new AssetId(package, assetPath);
-    }
-
-    // See if it's "packages" URL.
-    var id = _trySpecialUrl("packages", "lib");
-    if (id != null) return id;
-
-    // See if it's an "assets" URL.
-    id = _trySpecialUrl("assets", "asset");
-    if (id != null) return id;
-
-    // If we got here, we had a path like "/packages" which is a special
-    // directory, but not a valid path since it lacks a following package name.
-    if (isSpecial) return null;
-
-    // Otherwise, it's a path in current package's web directory.
-    return new AssetId(_rootPackage,
-        path.url.join("web", path.url.joinAll(parts)));
-  }
-
   /// Log [message] at [log.Level.FINE] with metadata about [request].
   void _logRequest(HttpRequest request, String message) =>
     log.fine("BarbackServer ${request.method} ${request.uri}\n$message");
diff --git a/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart b/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
index 89f474c..bc1c7ec 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/watch_sources.dart
@@ -26,6 +26,11 @@
       // TODO(nweiz): close these watchers when [barback] is closed.
       var watcher = new DirectoryWatcher(subdirectory);
       watcher.events.listen((event) {
+        // Don't watch files symlinked into these directories.
+        // TODO(rnystrom): If pub gets rid of symlinks, remove this.
+        var parts = path.split(event.path);
+        if (parts.contains("packages") || parts.contains("assets")) return;
+
         var id = new AssetId(package.name,
             path.relative(event.path, from: package.dir));
         if (event.type == ChangeType.REMOVE) {
diff --git a/sdk/lib/_internal/pub/lib/src/dart.dart b/sdk/lib/_internal/pub/lib/src/dart.dart
index f6d8b11..4c746d1 100644
--- a/sdk/lib/_internal/pub/lib/src/dart.dart
+++ b/sdk/lib/_internal/pub/lib/src/dart.dart
@@ -26,31 +26,48 @@
 ///
 /// By default, the package root is assumed to be adjacent to [entrypoint], but
 /// if [packageRoot] is passed that will be used instead.
+///
+/// If [inputProvider] and [diagnosticHandler] are omitted, uses a default
+/// [compiler.CompilerInputProvider] that loads directly from the filesystem.
+/// If either is provided, both must be.
 Future<String> compile(String entrypoint, {String packageRoot,
-    bool toDart: false}) {
+    bool toDart: false, compiler.CompilerInputProvider inputProvider,
+    compiler.DiagnosticHandler diagnosticHandler}) {
   return new Future.sync(() {
-    var provider = new SourceFileProvider();
     var options = <String>['--categories=Client,Server', '--minify'];
     if (toDart) options.add('--output-type=dart');
     if (packageRoot == null) {
       packageRoot = path.join(path.dirname(entrypoint), 'packages');
     }
 
+    // Must either pass both of these or neither.
+    if ((inputProvider == null) != (diagnosticHandler == null)) {
+      throw new ArgumentError("If either inputProvider or diagnosticHandler "
+          "is passed, then both must be.");
+    }
+
+    if (inputProvider == null) {
+      var provider = new SourceFileProvider();
+      inputProvider = provider.readStringFromUri;
+      diagnosticHandler = new FormattingDiagnosticHandler(provider)
+          .diagnosticHandler;
+    }
+
     return compiler.compile(
         path.toUri(entrypoint),
         path.toUri(appendSlash(_libPath)),
         path.toUri(appendSlash(packageRoot)),
-        provider.readStringFromUri,
-        new FormattingDiagnosticHandler(provider).diagnosticHandler,
-        options);
+        inputProvider, diagnosticHandler, options);
   }).then((result) {
     if (result != null) return result;
     throw new ApplicationException('Failed to compile "$entrypoint".');
   });
 }
 
-/// Returns the path to the library directory. This corresponds to the "sdk"
-/// directory in the repo and to the root of the compiled SDK.
+/// Returns the path to the directory containing the Dart core libraries.
+///
+/// This corresponds to the "sdk" directory in the repo and to the root of the
+/// compiled SDK.
 String get _libPath {
   if (runningFromSdk) return sdk.rootDirectory;
   return path.join(repoRoot, 'sdk');
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index af8168e..d27fe13 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -228,23 +228,24 @@
   return dirPath;
 }
 
-/// Creates a temp directory whose name will be based on [dir] with a unique
-/// suffix appended to it. If [dir] is not provided, a temp directory will be
-/// created in a platform-dependent temporary location. Returns the path of the
-/// created directory.
+/// Creates a temp directory in [dir], whose name will be [prefix] with
+/// characters appended to it to make a unique name.
+/// Returns the path of the created directory.
 String createTempDir(String base, String prefix) {
   var tempDir = new Directory(base).createTempSync(prefix);
   log.io("Created temp directory ${tempDir.path}");
   return tempDir.path;
 }
 
+/// Creates a temp directory in the system temp directory, whose name will be
+/// 'pub_' with characters appended to it to make a unique name.
+/// Returns the path of the created directory.
 String createSystemTempDir() {
-  var tempDir = Directory.createSystemTempSync('pub_');
+  var tempDir = Directory.systemTemp.createTempSync('pub_');
   log.io("Created temp directory ${tempDir.path}");
   return tempDir.path;
 }
 
-
 /// Lists the contents of [dir]. If [recursive] is `true`, lists subdirectory
 /// contents (defaults to `false`). If [includeHidden] is `true`, includes files
 /// and directories beginning with `.` (defaults to `false`).
diff --git a/sdk/lib/_internal/pub/test/serve/serve_from_app_web_test.dart b/sdk/lib/_internal/pub/test/serve/serve_from_app_web_test.dart
index 529facb..6d46bac 100644
--- a/sdk/lib/_internal/pub/test/serve/serve_from_app_web_test.dart
+++ b/sdk/lib/_internal/pub/test/serve/serve_from_app_web_test.dart
@@ -15,19 +15,19 @@
       d.appPubspec(),
       d.dir("web", [
         d.file("index.html", "<body>"),
-        d.file("file.dart", "void main() => print('hello');"),
+        d.file("file.dart", "main() => print('hello');"),
         d.dir("sub", [
           d.file("file.html", "<body>in subdir</body>"),
-          d.file("lib.dart", "void foo() => 'foo';"),
+          d.file("lib.dart", "main() => 'foo';"),
         ])
       ])
     ]).create();
 
     startPubServe();
     requestShouldSucceed("index.html", "<body>");
-    requestShouldSucceed("file.dart", "void main() => print('hello');");
+    requestShouldSucceed("file.dart", "main() => print('hello');");
     requestShouldSucceed("sub/file.html", "<body>in subdir</body>");
-    requestShouldSucceed("sub/lib.dart", "void foo() => 'foo';");
+    requestShouldSucceed("sub/lib.dart", "main() => 'foo';");
     endPubServe();
   });
 }
diff --git a/sdk/lib/_internal/pub/test/serve/utils.dart b/sdk/lib/_internal/pub/test/serve/utils.dart
index 6c5f1ec..46d2a14 100644
--- a/sdk/lib/_internal/pub/test/serve/utils.dart
+++ b/sdk/lib/_internal/pub/test/serve/utils.dart
@@ -120,11 +120,13 @@
 }
 
 /// Schedules an HTTP request to the running pub server with [urlPath] and
-/// verifies that it responds with [expected].
-void requestShouldSucceed(String urlPath, String expected) {
+/// verifies that it responds with a body that matches [expectation].
+///
+/// [expectation] may either be a [Matcher] or a string to match an exact body.
+void requestShouldSucceed(String urlPath, expectation) {
   schedule(() {
     return http.get("http://127.0.0.1:$_port/$urlPath").then((response) {
-      expect(response.body, equals(expected));
+      expect(response.body, expectation);
     });
   }, "request $urlPath");
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/allows_import_in_dart_code_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/allows_import_in_dart_code_test.dart
new file mode 100644
index 0000000..441ef8b
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/allows_import_in_dart_code_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("handles imports in the Dart code", () {
+    d.dir("foo", [
+      d.libPubspec("foo", "0.0.1"),
+      d.dir("lib", [
+        d.file("foo.dart", """
+library foo;
+foo() => 'footext';
+""")
+      ])
+    ]).create();
+
+    d.dir(appPath, [
+      d.appPubspec({
+        "foo": {"path": "../foo"}
+      }),
+      d.dir("lib", [
+        d.file("lib.dart", """
+library lib;
+lib() => 'libtext';
+""")
+      ]),
+      d.dir("web", [
+        d.file("main.dart", """
+import 'package:foo/foo.dart';
+import 'package:myapp/lib.dart';
+void main() {
+  print(foo());
+  print(lib());
+}
+""")
+      ])
+    ]).create();
+
+    startPubServe(shouldInstallFirst: true);
+    requestShouldSucceed("main.dart.js", contains("footext"));
+    requestShouldSucceed("main.dart.js", contains("libtext"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_generated_dart_file_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_generated_dart_file_test.dart
new file mode 100644
index 0000000..399c2ce
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_generated_dart_file_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("compiles a generated Dart file to JS", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "version": "0.0.1",
+        "transformers": ["myapp/transformer"]
+      }),
+      d.dir("lib", [
+        d.file("transformer.dart", dartTransformer("munge"))
+      ]),
+      d.dir("web", [
+        d.file("main.dart", """
+const TOKEN = "before";
+void main() => print(TOKEN);
+""")
+      ])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    startPubServe();
+    requestShouldSucceed("main.dart.js", contains("(before, munge)"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_generated_file_from_dependency_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_generated_file_from_dependency_test.dart
new file mode 100644
index 0000000..45dc8a3
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_generated_file_from_dependency_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("compiles a Dart file that imports a generated file in another "
+              "package to JS", () {
+    d.dir("foo", [
+      d.pubspec({
+        "name": "foo",
+        "version": "0.0.1",
+        "transformers": ["foo/transformer"]
+      }),
+      d.dir("lib", [
+        d.file("foo.dart", """
+library foo;
+const TOKEN = "before";
+foo() => TOKEN;
+"""),
+        d.file("transformer.dart", dartTransformer("munge"))
+      ])
+    ]).create();
+
+    d.dir(appPath, [
+      d.appPubspec({
+        "foo": {
+          "path": "../foo"
+        }
+      }),
+      d.dir("web", [
+        d.file("main.dart", """
+import "package:foo/foo.dart";
+main() => print(foo());
+""")
+      ])
+    ]).create();
+
+    createLockFile("myapp", sandbox: ["foo"], pkg: ["barback"]);
+
+    startPubServe();
+    requestShouldSucceed("main.dart.js", contains("(before, munge)"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_imported_generated_file_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_imported_generated_file_test.dart
new file mode 100644
index 0000000..f5fb55d
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/compiles_imported_generated_file_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("compiles a Dart file that imports a generated file to JS", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "version": "0.0.1",
+        "transformers": ["myapp/transformer"]
+      }),
+      d.dir("lib", [
+        d.file("transformer.dart", dartTransformer("munge"))
+      ]),
+      d.dir("web", [
+        d.file("main.dart", """
+import "other.dart";
+void main() => print(TOKEN);
+"""),
+d.file("other.dart", """
+library other;
+const TOKEN = "before";
+""")
+      ])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    startPubServe();
+    requestShouldSucceed("main.dart.js", contains("(before, munge)"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/converts_entrypoint_in_web_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/converts_entrypoint_in_web_test.dart
new file mode 100644
index 0000000..538930a
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/converts_entrypoint_in_web_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("converts a Dart entrypoint in web to JS", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("web", [
+        d.file("main.dart", "void main() => print('hello');")
+      ])
+    ]).create();
+
+    startPubServe();
+    requestShouldSucceed("main.dart.js", contains("hello"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_entrypoint_in_dependency_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_entrypoint_in_dependency_test.dart
new file mode 100644
index 0000000..10aa1c2
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_entrypoint_in_dependency_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("ignores a Dart entrypoint in a dependency", () {
+    d.dir("foo", [
+      d.libPubspec("foo", "0.0.1"),
+      d.dir("lib", [
+        d.file("lib.dart", "main() => print('foo');")
+      ])
+    ]).create();
+
+    d.dir(appPath, [
+      d.appPubspec({
+        "foo": {"path": "../foo"}
+      })
+    ]).create();
+
+    startPubServe(shouldInstallFirst: true);
+    requestShould404("web/packages/foo/lib.dart.js");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_entrypoint_outside_web_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_entrypoint_outside_web_test.dart
new file mode 100644
index 0000000..baae7d4
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_entrypoint_outside_web_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("ignores a Dart entrypoint outside web", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("lib", [
+        d.file("main.dart", "void main() => print('hello');")
+      ])
+    ]).create();
+
+    startPubServe();
+    requestShould404("packages/myapp/main.dart.js");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_nonentrypoint_in_web_test.dart b/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_nonentrypoint_in_web_test.dart
new file mode 100644
index 0000000..f5922e6
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/dart2js/ignores_nonentrypoint_in_web_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  integration("ignores a non-entrypoint library in web", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("web", [
+        d.file("notmain.dart", "foo() => print('hello');")
+      ])
+    ]).create();
+
+    startPubServe();
+    waitForBuildSuccess();
+    requestShouldSucceed("notmain.dart", "foo() => print('hello');");
+    requestShould404("notmain.dart.js");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index ba07414..54085f7 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -8,6 +8,7 @@
 library dart.collection;
 
 import 'dart:_collection-dev';
+import 'dart:math' show Random;  // Used by ListMixin.shuffle.
 
 part 'collections.dart';
 part 'iterable.dart';
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 0e0c611..74cda1d 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -301,6 +301,18 @@
     Sort.sort(this, compare);
   }
 
+  void shuffle() {
+    Random random = new Random();
+    int length = this.length;
+    while (length > 1) {
+      int pos = random.nextInt(length);
+      length -= 1;
+      var tmp = this[length];
+      this[length] = this[pos];
+      this[pos] = tmp;
+    }
+  }
+
   Map<int, E> asMap() {
     return new ListMapView(this);
   }
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 02405b8..1cacd18 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -74,9 +74,6 @@
 /**
  * An entry in a doubly linked list. It contains a pointer to the next
  * entry, the previous entry, and the boxed element.
- *
- * WARNING: This class is temporary located in dart:core. It'll be removed
- * at some point in the near future.
  */
 class DoubleLinkedQueueEntry<E> {
   DoubleLinkedQueueEntry<E> _previous;
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index a0473cb..5d5132e 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -182,6 +182,11 @@
   void sort([int compare(E a, E b)]);
 
   /**
+   * Shuffles the elements of this list randomly.
+   */
+  void shuffle();
+
+  /**
    * Returns the first index of [element] in this list.
    *
    * Searches the list from index [start] to the end of the list.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 6c9cfd9..3641bda 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -57,6 +57,8 @@
     Interceptor, JSExtendableArray, findInterceptorConstructorForType,
     getNativeInterceptor;
 
+export 'dart:math' show Rectangle, Point;
+
 
 
 
@@ -1583,19 +1585,19 @@
    *     img.height = 100;
    *
    *     // Scale the image to 20x20.
-   *     ctx.drawImageToRect(img, new Rect(50, 50, 20, 20));
+   *     ctx.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
    *
    *     VideoElement video = document.query('video');
    *     video.width = 100;
    *     video.height = 100;
    *     // Take the middle 20x20 pixels from the video and stretch them.
-   *     ctx.drawImageToRect(video, new Rect(50, 50, 100, 100),
-   *         sourceRect: new Rect(40, 40, 20, 20));
+   *     ctx.drawImageToRect(video, new Rectangle(50, 50, 100, 100),
+   *         sourceRect: new Rectangle(40, 40, 20, 20));
    *
    *     // Draw the top 100x20 pixels from the otherCanvas.
    *     CanvasElement otherCanvas = document.query('canvas');
-   *     ctx.drawImageToRect(otherCanvas, new Rect(0, 0, 100, 20),
-   *         sourceRect: new Rect(0, 0, 100, 20));
+   *     ctx.drawImageToRect(otherCanvas, new Rectangle(0, 0, 100, 20),
+   *         sourceRect: new Rectangle(0, 0, 100, 20));
    *
    * See also:
    *
@@ -1605,8 +1607,8 @@
    * from the WHATWG.
    */
   @DomName('CanvasRenderingContext2D.drawImage')
-  void drawImageToRect(CanvasImageSource source, Rect destRect,
-      {Rect sourceRect}) {
+  void drawImageToRect(CanvasImageSource source, Rectangle destRect,
+      {Rectangle sourceRect}) {
     if (sourceRect == null) {
       drawImageScaled(source,
           destRect.left,
@@ -8166,6 +8168,10 @@
     throw new UnsupportedError('Cannot sort element lists');
   }
 
+  void shuffle() {
+    throw new UnsupportedError('Cannot shuffle element lists');
+  }
+
   void removeWhere(bool test(Element element)) {
     _filter(test, false);
   }
@@ -8611,6 +8617,10 @@
     throw new UnsupportedError('Cannot sort list');
   }
 
+  void shuffle() {
+    throw new UnsupportedError('Cannot shuffle list');
+  }
+
   Element get first => _nodeList.first;
 
   Element get last => _nodeList.last;
@@ -9232,12 +9242,14 @@
   /**
    * Gets the position of this element relative to the client area of the page.
    */
-  Rect get client => new Rect(clientLeft, clientTop, clientWidth, clientHeight);
+  Rectangle get client => new Rectangle(clientLeft, clientTop, clientWidth, 
+      clientHeight);
 
   /**
    * Gets the offset of this element relative to its offsetParent.
    */
-  Rect get offset => new Rect(offsetLeft, offsetTop, offsetWidth, offsetHeight);
+  Rectangle get offset => new Rectangle(offsetLeft, offsetTop, offsetWidth, 
+      offsetHeight);
 
   /**
    * Adds the specified text after the last child of this element.
@@ -10325,13 +10337,13 @@
 
   @DomName('Element.getBoundingClientRect')
   @DocsEditable()
-  Rect getBoundingClientRect() native;
+  Rectangle getBoundingClientRect() native;
 
   @DomName('Element.getClientRects')
   @DocsEditable()
   @Returns('_ClientRectList')
   @Creates('_ClientRectList')
-  List<Rect> getClientRects() native;
+  List<Rectangle> getClientRects() native;
 
   @DomName('Element.getDestinationInsertionPoints')
   @DocsEditable()
@@ -17181,7 +17193,8 @@
             'offsetX is only supported on elements');
       }
       Element target = this.target;
-      return (this.client - target.getBoundingClientRect().topLeft).toInt();
+      var point = (this.client - target.getBoundingClientRect().topLeft);
+      return new Point(point.x.toInt(), point.y.toInt());
     }
   }
 
@@ -17917,6 +17930,10 @@
     throw new UnsupportedError("Cannot sort Node list");
   }
 
+  void shuffle() {
+    throw new UnsupportedError("Cannot shuffle Node list");
+  }
+
   // FIXME: implement these.
   void setRange(int start, int end, Iterable<Node> iterable,
                 [int skipCount = 0]) {
@@ -20015,13 +20032,13 @@
 
   @DomName('Range.getBoundingClientRect')
   @DocsEditable()
-  Rect getBoundingClientRect() native;
+  Rectangle getBoundingClientRect() native;
 
   @DomName('Range.getClientRects')
   @DocsEditable()
   @Returns('_ClientRectList')
   @Creates('_ClientRectList')
-  List<Rect> getClientRects() native;
+  List<Rectangle> getClientRects() native;
 
   @DomName('Range.insertNode')
   @DocsEditable()
@@ -20825,7 +20842,7 @@
   @DomName('Screen.availLeft')
   @DomName('Screen.availTop')
   @DomName('Screen.availWidth')
-  Rect get available => new Rect(_availLeft, _availTop, _availWidth,
+  Rectangle get available => new Rectangle(_availLeft, _availTop, _availWidth,
       _availHeight);
 
   @JSName('availHeight')
@@ -26951,38 +26968,41 @@
 
 @DocsEditable()
 @DomName('ClientRect')
-class _ClientRect extends Interceptor implements Rect native "ClientRect" {
+class _ClientRect extends Interceptor implements Rectangle native "ClientRect" {
 
-  // NOTE! All code below should be common with Rect.
-  // TODO(blois): implement with mixins when available.
-
-  String toString() {
-    return '($left, $top, $width, $height)';
+  // NOTE! All code below should be common with RectangleBase.
+   String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
   }
 
   bool operator ==(other) {
-    if (other is !Rect) return false;
+    if (other is !Rectangle) return false;
     return left == other.left && top == other.top && width == other.width &&
         height == other.height;
   }
 
-  int get hashCode => JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
+  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
       width.hashCode, height.hashCode);
 
   /**
-   * Computes the intersection of this rectangle and the rectangle parameter.
-   * Returns null if there is no intersection.
+   * Computes the intersection of `this` and [other].
+   *
+   * The intersection of two axis-aligned rectangles, if any, is always another
+   * axis-aligned rectangle.
+   *
+   * Returns the intersection of this and `other`, or `null` if they don't
+   * intersect.
    */
-  Rect intersection(Rect rect) {
-    var x0 = max(left, rect.left);
-    var x1 = min(left + width, rect.left + rect.width);
+  Rectangle intersection(Rectangle other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
 
     if (x0 <= x1) {
-      var y0 = max(top, rect.top);
-      var y1 = min(top + height, rect.top + rect.height);
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
 
       if (y0 <= y1) {
-        return new Rect(x0, y0, x1 - x0, y1 - y0);
+        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
       }
     }
     return null;
@@ -26990,31 +27010,32 @@
 
 
   /**
-   * Returns whether a rectangle intersects this rectangle.
+   * Returns true if `this` intersects [other].
    */
-  bool intersects(Rect other) {
-    return (left <= other.left + other.width && other.left <= left + width &&
-        top <= other.top + other.height && other.top <= top + height);
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
   }
 
   /**
-   * Returns a new rectangle which completely contains this rectangle and the
-   * input rectangle.
+   * Returns a new rectangle which completely contains `this` and [other].
    */
-  Rect union(Rect rect) {
-    var right = max(this.left + this.width, rect.left + rect.width);
-    var bottom = max(this.top + this.height, rect.top + rect.height);
+  Rectangle boundingBox(Rectangle other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
 
-    var left = min(this.left, rect.left);
-    var top = min(this.top, rect.top);
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
 
-    return new Rect(left, top, right - left, bottom - top);
+    return new Rectangle(left, top, right - left, bottom - top);
   }
 
   /**
-   * Tests whether this rectangle entirely contains another rectangle.
+   * Tests whether `this` entirely contains [another].
    */
-  bool containsRect(Rect another) {
+  bool contains(Rectangle<num> another) {
     return left <= another.left &&
            left + width >= another.left + another.width &&
            top <= another.top &&
@@ -27022,32 +27043,23 @@
   }
 
   /**
-   * Tests whether this rectangle entirely contains a point.
+   * Tests whether [another] is inside or along the edges of `this`.
    */
-  bool containsPoint(Point another) {
+  bool containsPoint(Point<num> another) {
     return another.x >= left &&
            another.x <= left + width &&
            another.y >= top &&
            another.y <= top + height;
   }
 
-  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
-  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
-      height.floor());
-  Rect round() => new Rect(left.round(), top.round(), width.round(),
-      height.round());
-
-  /**
-   * Truncates coordinates to integers and returns the result as a new
-   * rectangle.
-   */
-  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
-      height.toInt());
-
   Point get topLeft => new Point(this.left, this.top);
+  Point get topRight => new Point(this.left + this.width, this.top);
   Point get bottomRight => new Point(this.left + this.width,
       this.top + this.height);
+  Point get bottomLeft => new Point(this.left,
+      this.top + this.height);
 
+  
   @DomName('ClientRect.bottom')
   @DocsEditable()
   final double bottom;
@@ -27072,6 +27084,43 @@
   @DocsEditable()
   final double width;
 }
+
+/**
+ * This is the [Jenkins hash function][1] but using masking to keep
+ * values in SMI range.
+ *
+ * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+ *
+ * Use:
+ * Hash each value with the hash of the previous value, then get the final
+ * hash by calling finish.
+ *
+ *     var hash = 0;
+ *     for (var value in values) {
+ *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
+ *     }
+ *     hash = JenkinsSmiHash.finish(hash);
+ */
+class _JenkinsSmiHash {
+  // TODO(11617): This class should be optimized and standardized elsewhere.
+
+  static int combine(int hash, int value) {
+    hash = 0x1fffffff & (hash + value);
+    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+    return hash ^ (hash >> 6);
+  }
+
+  static int finish(int hash) {
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) <<  3));
+    hash = hash ^ (hash >> 11);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  static int hash2(a, b) => finish(combine(combine(0, a), b));
+
+  static int hash4(a, b, c, d) =>
+      finish(combine(combine(combine(combine(0, a), b), c), d));
+}
 // 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.
@@ -27079,59 +27128,59 @@
 
 @DocsEditable()
 @DomName('ClientRectList')
-class _ClientRectList extends Interceptor with ListMixin<Rect>, ImmutableListMixin<Rect> implements JavaScriptIndexingBehavior, List<Rect> native "ClientRectList" {
+class _ClientRectList extends Interceptor with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle>, JavaScriptIndexingBehavior native "ClientRectList" {
 
   @DomName('ClientRectList.length')
   @DocsEditable()
   int get length => JS("int", "#.length", this);
 
-  Rect operator[](int index) {
+  Rectangle operator[](int index) {
     if (JS("bool", "# >>> 0 !== # || # >= #", index,
         index, index, length))
       throw new RangeError.range(index, 0, length);
-    return JS("Rect", "#[#]", this, index);
+    return JS("Rectangle", "#[#]", this, index);
   }
-  void operator[]=(int index, Rect value) {
+  void operator[]=(int index, Rectangle value) {
     throw new UnsupportedError("Cannot assign element of immutable List.");
   }
-  // -- start List<Rect> mixins.
-  // Rect is the element type.
+  // -- start List<Rectangle> mixins.
+  // Rectangle is the element type.
 
 
   void set length(int value) {
     throw new UnsupportedError("Cannot resize immutable List.");
   }
 
-  Rect get first {
+  Rectangle get first {
     if (this.length > 0) {
-      return JS('Rect', '#[0]', this);
+      return JS('Rectangle', '#[0]', this);
     }
     throw new StateError("No elements");
   }
 
-  Rect get last {
+  Rectangle get last {
     int len = this.length;
     if (len > 0) {
-      return JS('Rect', '#[#]', this, len - 1);
+      return JS('Rectangle', '#[#]', this, len - 1);
     }
     throw new StateError("No elements");
   }
 
-  Rect get single {
+  Rectangle get single {
     int len = this.length;
     if (len == 1) {
-      return JS('Rect', '#[0]', this);
+      return JS('Rectangle', '#[0]', this);
     }
     if (len == 0) throw new StateError("No elements");
     throw new StateError("More than one element");
   }
 
-  Rect elementAt(int index) => this[index];
-  // -- end List<Rect> mixins.
+  Rectangle elementAt(int index) => this[index];
+  // -- end List<Rectangle> mixins.
 
   @DomName('ClientRectList.item')
   @DocsEditable()
-  Rect item(int index) native;
+  Rectangle item(int index) native;
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -28767,18 +28816,19 @@
 /**
  * A class for representing CSS dimensions.
  *
- * In contrast to the more general purpose [Rect] class, this class's values are
- * mutable, so one can change the height of an element programmatically.
+ * In contrast to the more general purpose [Rectangle] class, this class's
+ * values are mutable, so one can change the height of an element
+ * programmatically.
  *
  * _Important_ _note_: use of these methods will perform CSS calculations that
  * can trigger a browser reflow. Therefore, use of these properties _during_ an
  * animation frame is discouraged. See also:
  * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
  */
-abstract class CssRect extends RectBase implements Rect {
+abstract class CssRect extends MutableRectangle<num> implements Rectangle<num> {
   Element _element;
 
-  CssRect(this._element);
+  CssRect(this._element) : super(0, 0, 0, 0);
 
   num get left;
 
@@ -29778,6 +29828,10 @@
     throw new UnsupportedError("Cannot sort immutable List.");
   }
 
+  void shuffle() {
+    throw new UnsupportedError("Cannot shuffle immutable List.");
+  }
+
   void insert(int index, E element) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
@@ -31279,7 +31333,7 @@
  * Scheduler which uses window.postMessage to schedule events.
  */
 class _PostMessageScheduler extends _MicrotaskScheduler {
-  const _MICROTASK_MESSAGE = "DART-MICROTASK";
+  final _MICROTASK_MESSAGE = "DART-MICROTASK";
 
   _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
       // Messages from other windows do not cause a security risk as
@@ -31839,77 +31893,6 @@
     return allowsElement(element);
   }
 }
-// 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.
-
-
-/**
- * A utility class for representing two-dimensional positions.
- */
-class Point {
-  final num x;
-  final num y;
-
-  const Point([num x = 0, num y = 0]): x = x, y = y;
-
-  String toString() => '($x, $y)';
-
-  bool operator ==(other) {
-    if (other is !Point) return false;
-    return x == other.x && y == other.y;
-  }
-
-  int get hashCode => JenkinsSmiHash.hash2(x.hashCode, y.hashCode);
-
-  Point operator +(Point other) {
-    return new Point(x + other.x, y + other.y);
-  }
-
-  Point operator -(Point other) {
-    return new Point(x - other.x, y - other.y);
-  }
-
-  Point operator *(num factor) {
-    return new Point(x * factor, y * factor);
-  }
-
-  /**
-   * Get the straight line (Euclidean) distance between the origin (0, 0) and
-   * this point.
-   */
-  num get magnitude => sqrt(x * x + y * y);
-
-  /**
-   * Returns the distance between two points.
-   */
-  double distanceTo(Point other) {
-    var dx = x - other.x;
-    var dy = y - other.y;
-    return sqrt(dx * dx + dy * dy);
-  }
-
-  /**
-   * Returns the squared distance between two points.
-   *
-   * Squared distances can be used for comparisons when the actual value is not
-   * required.
-   */
-  num squaredDistanceTo(Point other) {
-    var dx = x - other.x;
-    var dy = y - other.y;
-    return dx * dx + dy * dy;
-  }
-
-  Point ceil() => new Point(x.ceil(), y.ceil());
-  Point floor() => new Point(x.floor(), y.floor());
-  Point round() => new Point(x.round(), y.round());
-
-  /**
-   * Truncates x and y to integers and returns the result as a new point.
-   */
-  Point toInt() => new Point(x.toInt(), y.toInt());
-}
 // 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.
@@ -31935,163 +31918,6 @@
    */
   static const String COMPLETE = "complete";
 }
-// 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.
-
-
-/**
- * A base class for representing two-dimensional rectangles. This will hopefully
- * be moved merged with the dart:math Rect.
- */
-// TODO(efortuna): Merge with Math rect after finalizing with Florian.
-abstract class RectBase {
-  //  Not used, but keeps the VM from complaining about Rect having a const
-  // constructor and this one not.
-  const RectBase();
-
-  num get left;
-  num get top;
-  num get width;
-  num get height;
-
-  num get right => left + width;
-  num get bottom => top + height;
-
-  // NOTE! All code below should be common with Rect.
-
-  String toString() {
-    return '($left, $top, $width, $height)';
-  }
-
-  bool operator ==(other) {
-    if (other is !Rect) return false;
-    return left == other.left && top == other.top && width == other.width &&
-        height == other.height;
-  }
-
-  int get hashCode => JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
-      width.hashCode, height.hashCode);
-
-  /**
-   * Computes the intersection of this rectangle and the rectangle parameter.
-   * Returns null if there is no intersection.
-   */
-  Rect intersection(Rect rect) {
-    var x0 = max(left, rect.left);
-    var x1 = min(left + width, rect.left + rect.width);
-
-    if (x0 <= x1) {
-      var y0 = max(top, rect.top);
-      var y1 = min(top + height, rect.top + rect.height);
-
-      if (y0 <= y1) {
-        return new Rect(x0, y0, x1 - x0, y1 - y0);
-      }
-    }
-    return null;
-  }
-
-
-  /**
-   * Returns whether a rectangle intersects this rectangle.
-   */
-  bool intersects(Rect other) {
-    return (left <= other.left + other.width && other.left <= left + width &&
-        top <= other.top + other.height && other.top <= top + height);
-  }
-
-  /**
-   * Returns a new rectangle which completely contains this rectangle and the
-   * input rectangle.
-   */
-  Rect union(Rect rect) {
-    var right = max(this.left + this.width, rect.left + rect.width);
-    var bottom = max(this.top + this.height, rect.top + rect.height);
-
-    var left = min(this.left, rect.left);
-    var top = min(this.top, rect.top);
-
-    return new Rect(left, top, right - left, bottom - top);
-  }
-
-  /**
-   * Tests whether this rectangle entirely contains another rectangle.
-   */
-  bool containsRect(Rect another) {
-    return left <= another.left &&
-           left + width >= another.left + another.width &&
-           top <= another.top &&
-           top + height >= another.top + another.height;
-  }
-
-  /**
-   * Tests whether this rectangle entirely contains a point.
-   */
-  bool containsPoint(Point another) {
-    return another.x >= left &&
-           another.x <= left + width &&
-           another.y >= top &&
-           another.y <= top + height;
-  }
-
-  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
-  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
-      height.floor());
-  Rect round() => new Rect(left.round(), top.round(), width.round(),
-      height.round());
-
-  /**
-   * Truncates coordinates to integers and returns the result as a new
-   * rectangle.
-   */
-  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
-      height.toInt());
-
-  Point get topLeft => new Point(this.left, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
-      this.top + this.height);
-}
-
-
-
-/**
- * A class for representing two-dimensional rectangles.
- *
- * This class is distinctive from RectBase in that it enforces that its
- * properties are immutable.
- */
-class Rect extends RectBase {
-  final num left;
-  final num top;
-  final num width;
-  final num height;
-
-  const Rect(this.left, this.top, this.width, this.height): super();
-
-  factory Rect.fromPoints(Point a, Point b) {
-    var left;
-    var width;
-    if (a.x < b.x) {
-      left = a.x;
-      width = b.x - left;
-    } else {
-      left = b.x;
-      width = a.x - left;
-    }
-    var top;
-    var height;
-    if (a.y < b.y) {
-      top = a.y;
-      height = b.y - top;
-    } else {
-      top = b.y;
-      height = a.y - top;
-    }
-
-    return new Rect(left, top, width, height);
-  }
-}
 // 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.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index c9879ea..5c69f2c 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -51,6 +51,8 @@
 // native code for custom elements.
 // Not actually used, but imported since dart:html can generate these objects.
 
+export 'dart:math' show Rectangle, RectangleBase, Point;
+
 
 
 
@@ -1922,19 +1924,19 @@
    *     img.height = 100;
    *
    *     // Scale the image to 20x20.
-   *     ctx.drawImageToRect(img, new Rect(50, 50, 20, 20));
+   *     ctx.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
    *
    *     VideoElement video = document.query('video');
    *     video.width = 100;
    *     video.height = 100;
    *     // Take the middle 20x20 pixels from the video and stretch them.
-   *     ctx.drawImageToRect(video, new Rect(50, 50, 100, 100),
-   *         sourceRect: new Rect(40, 40, 20, 20));
+   *     ctx.drawImageToRect(video, new Rectangle(50, 50, 100, 100),
+   *         sourceRect: new Rectangle(40, 40, 20, 20));
    *
    *     // Draw the top 100x20 pixels from the otherCanvas.
    *     CanvasElement otherCanvas = document.query('canvas');
-   *     ctx.drawImageToRect(otherCanvas, new Rect(0, 0, 100, 20),
-   *         sourceRect: new Rect(0, 0, 100, 20));
+   *     ctx.drawImageToRect(otherCanvas, new Rectangle(0, 0, 100, 20),
+   *         sourceRect: new Rectangle(0, 0, 100, 20));
    *
    * See also:
    *
@@ -1944,8 +1946,8 @@
    * from the WHATWG.
    */
   @DomName('CanvasRenderingContext2D.drawImage')
-  void drawImageToRect(CanvasImageSource source, Rect destRect,
-      {Rect sourceRect}) {
+  void drawImageToRect(CanvasImageSource source, Rectangle destRect,
+      {Rectangle sourceRect}) {
     if (sourceRect == null) {
       _drawImage(source,
           destRect.left,
@@ -8722,6 +8724,10 @@
     throw new UnsupportedError('Cannot sort element lists');
   }
 
+  void shuffle() {
+    throw new UnsupportedError('Cannot shuffle element lists');
+  }
+
   void removeWhere(bool test(Element element)) {
     _filter(test, false);
   }
@@ -9167,6 +9173,10 @@
     throw new UnsupportedError('Cannot sort list');
   }
 
+  void shuffle() {
+    throw new UnsupportedError('Cannot shuffle list');
+  }
+
   Element get first => _nodeList.first;
 
   Element get last => _nodeList.last;
@@ -9788,12 +9798,14 @@
   /**
    * Gets the position of this element relative to the client area of the page.
    */
-  Rect get client => new Rect(clientLeft, clientTop, clientWidth, clientHeight);
+  Rectangle get client => new Rectangle(clientLeft, clientTop, clientWidth, 
+      clientHeight);
 
   /**
    * Gets the offset of this element relative to its offsetParent.
    */
-  Rect get offset => new Rect(offsetLeft, offsetTop, offsetWidth, offsetHeight);
+  Rectangle get offset => new Rectangle(offsetLeft, offsetTop, offsetWidth, 
+      offsetHeight);
 
   /**
    * Adds the specified text after the last child of this element.
@@ -10727,11 +10739,11 @@
 
   @DomName('Element.getBoundingClientRect')
   @DocsEditable()
-  Rect getBoundingClientRect() native "Element_getBoundingClientRect_Callback";
+  Rectangle getBoundingClientRect() native "Element_getBoundingClientRect_Callback";
 
   @DomName('Element.getClientRects')
   @DocsEditable()
-  List<Rect> getClientRects() native "Element_getClientRects_Callback";
+  List<Rectangle> getClientRects() native "Element_getClientRects_Callback";
 
   @DomName('Element.getDestinationInsertionPoints')
   @DocsEditable()
@@ -19227,6 +19239,10 @@
     throw new UnsupportedError("Cannot sort Node list");
   }
 
+  void shuffle() {
+    throw new UnsupportedError("Cannot shuffle Node list");
+  }
+
   // FIXME: implement these.
   void setRange(int start, int end, Iterable<Node> iterable,
                 [int skipCount = 0]) {
@@ -21555,11 +21571,11 @@
 
   @DomName('Range.getBoundingClientRect')
   @DocsEditable()
-  Rect getBoundingClientRect() native "Range_getBoundingClientRect_Callback";
+  Rectangle getBoundingClientRect() native "Range_getBoundingClientRect_Callback";
 
   @DomName('Range.getClientRects')
   @DocsEditable()
-  List<Rect> getClientRects() native "Range_getClientRects_Callback";
+  List<Rectangle> getClientRects() native "Range_getClientRects_Callback";
 
   @DomName('Range.insertNode')
   @DocsEditable()
@@ -22360,7 +22376,7 @@
   @DomName('Screen.availLeft')
   @DomName('Screen.availTop')
   @DomName('Screen.availWidth')
-  Rect get available => new Rect(_availLeft, _availTop, _availWidth,
+  Rectangle get available => new Rectangle(_availLeft, _availTop, _availWidth,
       _availHeight);
 
   @DomName('Screen.availHeight')
@@ -26535,13 +26551,13 @@
     if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_1(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_2(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaSource || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_3(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is _WebKitMediaSource || blob_OR_source_OR_stream == null)) {
+    if ((blob_OR_source_OR_stream is MediaStream || blob_OR_source_OR_stream == null)) {
       return _createObjectURL_4(blob_OR_source_OR_stream);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -28907,38 +28923,41 @@
 
 @DocsEditable()
 @DomName('ClientRect')
-class _ClientRect extends NativeFieldWrapperClass1 implements Rect {
+class _ClientRect extends NativeFieldWrapperClass1 implements Rectangle {
 
-  // NOTE! All code below should be common with Rect.
-  // TODO(blois): implement with mixins when available.
-
-  String toString() {
-    return '($left, $top, $width, $height)';
+  // NOTE! All code below should be common with RectangleBase.
+   String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
   }
 
   bool operator ==(other) {
-    if (other is !Rect) return false;
+    if (other is !Rectangle) return false;
     return left == other.left && top == other.top && width == other.width &&
         height == other.height;
   }
 
-  int get hashCode => JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
+  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
       width.hashCode, height.hashCode);
 
   /**
-   * Computes the intersection of this rectangle and the rectangle parameter.
-   * Returns null if there is no intersection.
+   * Computes the intersection of `this` and [other].
+   *
+   * The intersection of two axis-aligned rectangles, if any, is always another
+   * axis-aligned rectangle.
+   *
+   * Returns the intersection of this and `other`, or `null` if they don't
+   * intersect.
    */
-  Rect intersection(Rect rect) {
-    var x0 = max(left, rect.left);
-    var x1 = min(left + width, rect.left + rect.width);
+  Rectangle intersection(Rectangle other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
 
     if (x0 <= x1) {
-      var y0 = max(top, rect.top);
-      var y1 = min(top + height, rect.top + rect.height);
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
 
       if (y0 <= y1) {
-        return new Rect(x0, y0, x1 - x0, y1 - y0);
+        return new Rectangle(x0, y0, x1 - x0, y1 - y0);
       }
     }
     return null;
@@ -28946,31 +28965,32 @@
 
 
   /**
-   * Returns whether a rectangle intersects this rectangle.
+   * Returns true if `this` intersects [other].
    */
-  bool intersects(Rect other) {
-    return (left <= other.left + other.width && other.left <= left + width &&
-        top <= other.top + other.height && other.top <= top + height);
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
   }
 
   /**
-   * Returns a new rectangle which completely contains this rectangle and the
-   * input rectangle.
+   * Returns a new rectangle which completely contains `this` and [other].
    */
-  Rect union(Rect rect) {
-    var right = max(this.left + this.width, rect.left + rect.width);
-    var bottom = max(this.top + this.height, rect.top + rect.height);
+  Rectangle boundingBox(Rectangle other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
 
-    var left = min(this.left, rect.left);
-    var top = min(this.top, rect.top);
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
 
-    return new Rect(left, top, right - left, bottom - top);
+    return new Rectangle(left, top, right - left, bottom - top);
   }
 
   /**
-   * Tests whether this rectangle entirely contains another rectangle.
+   * Tests whether `this` entirely contains [another].
    */
-  bool containsRect(Rect another) {
+  bool contains(Rectangle<num> another) {
     return left <= another.left &&
            left + width >= another.left + another.width &&
            top <= another.top &&
@@ -28978,32 +28998,23 @@
   }
 
   /**
-   * Tests whether this rectangle entirely contains a point.
+   * Tests whether [another] is inside or along the edges of `this`.
    */
-  bool containsPoint(Point another) {
+  bool containsPoint(Point<num> another) {
     return another.x >= left &&
            another.x <= left + width &&
            another.y >= top &&
            another.y <= top + height;
   }
 
-  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
-  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
-      height.floor());
-  Rect round() => new Rect(left.round(), top.round(), width.round(),
-      height.round());
-
-  /**
-   * Truncates coordinates to integers and returns the result as a new
-   * rectangle.
-   */
-  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
-      height.toInt());
-
   Point get topLeft => new Point(this.left, this.top);
+  Point get topRight => new Point(this.left + this.width, this.top);
   Point get bottomRight => new Point(this.left + this.width,
       this.top + this.height);
+  Point get bottomLeft => new Point(this.left,
+      this.top + this.height);
 
+  
   @DomName('ClientRect.bottom')
   @DocsEditable()
   double get bottom native "ClientRect_bottom_Getter";
@@ -29028,6 +29039,43 @@
   @DocsEditable()
   double get width native "ClientRect_width_Getter";
 }
+
+/**
+ * This is the [Jenkins hash function][1] but using masking to keep
+ * values in SMI range.
+ *
+ * [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+ *
+ * Use:
+ * Hash each value with the hash of the previous value, then get the final
+ * hash by calling finish.
+ *
+ *     var hash = 0;
+ *     for (var value in values) {
+ *       hash = JenkinsSmiHash.combine(hash, value.hashCode);
+ *     }
+ *     hash = JenkinsSmiHash.finish(hash);
+ */
+class _JenkinsSmiHash {
+  // TODO(11617): This class should be optimized and standardized elsewhere.
+
+  static int combine(int hash, int value) {
+    hash = 0x1fffffff & (hash + value);
+    hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+    return hash ^ (hash >> 6);
+  }
+
+  static int finish(int hash) {
+    hash = 0x1fffffff & (hash + ((0x03ffffff & hash) <<  3));
+    hash = hash ^ (hash >> 11);
+    return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+  }
+
+  static int hash2(a, b) => finish(combine(combine(0, a), b));
+
+  static int hash4(a, b, c, d) =>
+      finish(combine(combine(combine(combine(0, a), b), c), d));
+}
 // 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.
@@ -29037,38 +29085,38 @@
 
 @DocsEditable()
 @DomName('ClientRectList')
-class _ClientRectList extends NativeFieldWrapperClass1 with ListMixin<Rect>, ImmutableListMixin<Rect> implements List<Rect> {
+class _ClientRectList extends NativeFieldWrapperClass1 with ListMixin<Rectangle>, ImmutableListMixin<Rectangle> implements List<Rectangle> {
 
   @DomName('ClientRectList.length')
   @DocsEditable()
   int get length native "ClientRectList_length_Getter";
 
-  Rect operator[](int index) {
+  Rectangle operator[](int index) {
     if (index < 0 || index >= length)
       throw new RangeError.range(index, 0, length);
     return _nativeIndexedGetter(index);
   }
-  Rect _nativeIndexedGetter(int index) native "ClientRectList_item_Callback";
+  Rectangle _nativeIndexedGetter(int index) native "ClientRectList_item_Callback";
 
-  void operator[]=(int index, Rect value) {
+  void operator[]=(int index, Rectangle value) {
     throw new UnsupportedError("Cannot assign element of immutable List.");
   }
-  // -- start List<Rect> mixins.
-  // Rect is the element type.
+  // -- start List<Rectangle> mixins.
+  // Rectangle is the element type.
 
 
   void set length(int value) {
     throw new UnsupportedError("Cannot resize immutable List.");
   }
 
-  Rect get first {
+  Rectangle get first {
     if (this.length > 0) {
       return _nativeIndexedGetter(0);
     }
     throw new StateError("No elements");
   }
 
-  Rect get last {
+  Rectangle get last {
     int len = this.length;
     if (len > 0) {
       return _nativeIndexedGetter(len - 1);
@@ -29076,7 +29124,7 @@
     throw new StateError("No elements");
   }
 
-  Rect get single {
+  Rectangle get single {
     int len = this.length;
     if (len == 1) {
       return _nativeIndexedGetter(0);
@@ -29085,12 +29133,12 @@
     throw new StateError("More than one element");
   }
 
-  Rect elementAt(int index) => this[index];
-  // -- end List<Rect> mixins.
+  Rectangle elementAt(int index) => this[index];
+  // -- end List<Rectangle> mixins.
 
   @DomName('ClientRectList.item')
   @DocsEditable()
-  Rect item(int index) native "ClientRectList_item_Callback";
+  Rectangle item(int index) native "ClientRectList_item_Callback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -30849,18 +30897,19 @@
 /**
  * A class for representing CSS dimensions.
  *
- * In contrast to the more general purpose [Rect] class, this class's values are
- * mutable, so one can change the height of an element programmatically.
+ * In contrast to the more general purpose [Rectangle] class, this class's
+ * values are mutable, so one can change the height of an element
+ * programmatically.
  *
  * _Important_ _note_: use of these methods will perform CSS calculations that
  * can trigger a browser reflow. Therefore, use of these properties _during_ an
  * animation frame is discouraged. See also:
  * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
  */
-abstract class CssRect extends RectBase implements Rect {
+abstract class CssRect extends MutableRectangle<num> implements Rectangle<num> {
   Element _element;
 
-  CssRect(this._element);
+  CssRect(this._element) : super(0, 0, 0, 0);
 
   num get left;
 
@@ -31860,6 +31909,10 @@
     throw new UnsupportedError("Cannot sort immutable List.");
   }
 
+  void shuffle() {
+    throw new UnsupportedError("Cannot shuffle immutable List.");
+  }
+
   void insert(int index, E element) {
     throw new UnsupportedError("Cannot add to immutable List.");
   }
@@ -33361,7 +33414,7 @@
  * Scheduler which uses window.postMessage to schedule events.
  */
 class _PostMessageScheduler extends _MicrotaskScheduler {
-  const _MICROTASK_MESSAGE = "DART-MICROTASK";
+  final _MICROTASK_MESSAGE = "DART-MICROTASK";
 
   _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
       // Messages from other windows do not cause a security risk as
@@ -33921,77 +33974,6 @@
     return allowsElement(element);
   }
 }
-// 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.
-
-
-/**
- * A utility class for representing two-dimensional positions.
- */
-class Point {
-  final num x;
-  final num y;
-
-  const Point([num x = 0, num y = 0]): x = x, y = y;
-
-  String toString() => '($x, $y)';
-
-  bool operator ==(other) {
-    if (other is !Point) return false;
-    return x == other.x && y == other.y;
-  }
-
-  int get hashCode => JenkinsSmiHash.hash2(x.hashCode, y.hashCode);
-
-  Point operator +(Point other) {
-    return new Point(x + other.x, y + other.y);
-  }
-
-  Point operator -(Point other) {
-    return new Point(x - other.x, y - other.y);
-  }
-
-  Point operator *(num factor) {
-    return new Point(x * factor, y * factor);
-  }
-
-  /**
-   * Get the straight line (Euclidean) distance between the origin (0, 0) and
-   * this point.
-   */
-  num get magnitude => sqrt(x * x + y * y);
-
-  /**
-   * Returns the distance between two points.
-   */
-  double distanceTo(Point other) {
-    var dx = x - other.x;
-    var dy = y - other.y;
-    return sqrt(dx * dx + dy * dy);
-  }
-
-  /**
-   * Returns the squared distance between two points.
-   *
-   * Squared distances can be used for comparisons when the actual value is not
-   * required.
-   */
-  num squaredDistanceTo(Point other) {
-    var dx = x - other.x;
-    var dy = y - other.y;
-    return dx * dx + dy * dy;
-  }
-
-  Point ceil() => new Point(x.ceil(), y.ceil());
-  Point floor() => new Point(x.floor(), y.floor());
-  Point round() => new Point(x.round(), y.round());
-
-  /**
-   * Truncates x and y to integers and returns the result as a new point.
-   */
-  Point toInt() => new Point(x.toInt(), y.toInt());
-}
 // 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.
@@ -34017,163 +33999,6 @@
    */
   static const String COMPLETE = "complete";
 }
-// 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.
-
-
-/**
- * A base class for representing two-dimensional rectangles. This will hopefully
- * be moved merged with the dart:math Rect.
- */
-// TODO(efortuna): Merge with Math rect after finalizing with Florian.
-abstract class RectBase {
-  //  Not used, but keeps the VM from complaining about Rect having a const
-  // constructor and this one not.
-  const RectBase();
-
-  num get left;
-  num get top;
-  num get width;
-  num get height;
-
-  num get right => left + width;
-  num get bottom => top + height;
-
-  // NOTE! All code below should be common with Rect.
-
-  String toString() {
-    return '($left, $top, $width, $height)';
-  }
-
-  bool operator ==(other) {
-    if (other is !Rect) return false;
-    return left == other.left && top == other.top && width == other.width &&
-        height == other.height;
-  }
-
-  int get hashCode => JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
-      width.hashCode, height.hashCode);
-
-  /**
-   * Computes the intersection of this rectangle and the rectangle parameter.
-   * Returns null if there is no intersection.
-   */
-  Rect intersection(Rect rect) {
-    var x0 = max(left, rect.left);
-    var x1 = min(left + width, rect.left + rect.width);
-
-    if (x0 <= x1) {
-      var y0 = max(top, rect.top);
-      var y1 = min(top + height, rect.top + rect.height);
-
-      if (y0 <= y1) {
-        return new Rect(x0, y0, x1 - x0, y1 - y0);
-      }
-    }
-    return null;
-  }
-
-
-  /**
-   * Returns whether a rectangle intersects this rectangle.
-   */
-  bool intersects(Rect other) {
-    return (left <= other.left + other.width && other.left <= left + width &&
-        top <= other.top + other.height && other.top <= top + height);
-  }
-
-  /**
-   * Returns a new rectangle which completely contains this rectangle and the
-   * input rectangle.
-   */
-  Rect union(Rect rect) {
-    var right = max(this.left + this.width, rect.left + rect.width);
-    var bottom = max(this.top + this.height, rect.top + rect.height);
-
-    var left = min(this.left, rect.left);
-    var top = min(this.top, rect.top);
-
-    return new Rect(left, top, right - left, bottom - top);
-  }
-
-  /**
-   * Tests whether this rectangle entirely contains another rectangle.
-   */
-  bool containsRect(Rect another) {
-    return left <= another.left &&
-           left + width >= another.left + another.width &&
-           top <= another.top &&
-           top + height >= another.top + another.height;
-  }
-
-  /**
-   * Tests whether this rectangle entirely contains a point.
-   */
-  bool containsPoint(Point another) {
-    return another.x >= left &&
-           another.x <= left + width &&
-           another.y >= top &&
-           another.y <= top + height;
-  }
-
-  Rect ceil() => new Rect(left.ceil(), top.ceil(), width.ceil(), height.ceil());
-  Rect floor() => new Rect(left.floor(), top.floor(), width.floor(),
-      height.floor());
-  Rect round() => new Rect(left.round(), top.round(), width.round(),
-      height.round());
-
-  /**
-   * Truncates coordinates to integers and returns the result as a new
-   * rectangle.
-   */
-  Rect toInt() => new Rect(left.toInt(), top.toInt(), width.toInt(),
-      height.toInt());
-
-  Point get topLeft => new Point(this.left, this.top);
-  Point get bottomRight => new Point(this.left + this.width,
-      this.top + this.height);
-}
-
-
-
-/**
- * A class for representing two-dimensional rectangles.
- *
- * This class is distinctive from RectBase in that it enforces that its
- * properties are immutable.
- */
-class Rect extends RectBase {
-  final num left;
-  final num top;
-  final num width;
-  final num height;
-
-  const Rect(this.left, this.top, this.width, this.height): super();
-
-  factory Rect.fromPoints(Point a, Point b) {
-    var left;
-    var width;
-    if (a.x < b.x) {
-      left = a.x;
-      width = b.x - left;
-    } else {
-      left = b.x;
-      width = a.x - left;
-    }
-    var top;
-    var height;
-    if (a.y < b.y) {
-      top = a.y;
-      height = b.y - top;
-    } else {
-      top = b.y;
-      height = a.y - top;
-    }
-
-    return new Rect(left, top, width, height);
-  }
-}
 // 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.
@@ -35022,7 +34847,6 @@
 
   static window() native "Utils_window";
   static forwardingPrint(String message) native "Utils_forwardingPrint";
-  static void spawnDomFunction(Function f, int replyTo) native "Utils_spawnDomFunction";
   static int _getNewIsolateId() native "Utils_getNewIsolateId";
 
   // The following methods were added for debugger integration to make working
@@ -35056,6 +34880,15 @@
   }
 
   static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables();
+
+  /**
+   * Header passed in from the Dartium Developer Tools when an expression is
+   * evaluated in the console as opposed to the watch window or another context
+   * that does not expect REPL support.
+   */
+  static const _CONSOLE_API_SUPPORT_HEADER =
+      'with ((this && this.console && this.console._commandLineAPI) || {}) {\n';
+
   /**
    * Takes an [expression] and a list of [local] variable and returns an
    * expression for a closure with a body matching the original expression
@@ -35066,11 +34899,22 @@
    * with the list of arguments passed to this method.
    *
    * For example:
-   * <code>wrapExpressionAsClosure("foo + bar", ["bar", 40, "foo", 2])</code>
+   * <code>
+   * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue}
+   * wrapExpressionAsClosure("${_CONSOLE_API_SUPPORT_HEADER}foo + bar + a",
+   *                         ["bar", 40, "foo", 2])
+   * </code>
    * will return:
-   * <code>["(final $var, final bar, final foo) => foo + bar", [40, 2]]</code>
+   * <code>
+   * ["""(final $consoleVariables, final bar, final foo, final a, final b) =>
+   * (foo + bar + a
+   * )""",
+   * [_consoleTempVariables, 40, 2, someValue, someOtherValue]]
+   * </code>
    */
   static List wrapExpressionAsClosure(String expression, List locals) {
+    // FIXME: dartbug.com/10434 find a less fragile way to determine whether
+    // we need to strip off console API support added by InjectedScript.
     var args = {};
     var sb = new StringBuffer("(");
     addArg(arg, value) {
@@ -35089,16 +34933,111 @@
       args[arg] = value;
     }
 
-    addArg("\$var", _consoleTempVariables);
+    if (expression.indexOf(_CONSOLE_API_SUPPORT_HEADER) == 0) {
+      expression = expression.substring(expression.indexOf('\n') + 1);
+      expression = expression.substring(0, expression.lastIndexOf('\n'));
 
-    for (int i = 0; i < locals.length; i+= 2) {
-      addArg(locals[i], locals[i+1]);
+      addArg("\$consoleVariables", _consoleTempVariables);
+
+      // FIXME: use a real Dart tokenizer. The following regular expressions
+      // only allow setting variables at the immediate start of the expression
+      // to limit the number of edge cases we have to handle.
+
+      // Match expressions that start with "var x"
+      final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)");
+      // Match expressions that start with "someExistingConsoleVar ="
+      final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)");
+      // Match trailing semicolons.
+      final _ENDING_SEMICOLONS = new RegExp("(;\\s*)*\$");
+      expression = expression.replaceAllMapped(_VARIABLE_DECLARATION,
+          (match) {
+            var variableName = match[2];
+            // Set the console variable if it isn't already set.
+            if (!_consoleTempVariables._data.containsKey(variableName)) {
+              _consoleTempVariables._data[variableName] = null;
+            }
+            return "${match[1]}\$consoleVariables.${variableName}";
+          });
+
+      expression = expression.replaceAllMapped(_SET_VARIABLE,
+          (match) {
+            var variableName = match[2];
+            // Only rewrite if the name matches an existing console variable.
+            if (_consoleTempVariables._data.containsKey(variableName)) {
+              return "${match[1]}\$consoleVariables.${variableName}${match[3]}";
+            } else {
+              return match[0];
+            }
+          });
+
+      // We only allow dart expressions not Dart statements. Silently remove
+      // trailing semicolons the user might have added by accident to reduce the
+      // number of spurious compile errors.
+      expression = expression.replaceFirst(_ENDING_SEMICOLONS, "");
     }
-    sb..write(')=>\n$expression');
+
+    if (locals != null) {
+      for (int i = 0; i < locals.length; i+= 2) {
+        addArg(locals[i], locals[i+1]);
+      }
+    }
+    // Inject all the already defined console variables.
+    _consoleTempVariables._data.forEach(addArg);
+    
+    // TODO(jacobr): remove the parentheses around the expresson once
+    // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses
+    // to ensure only valid Dart expressions are allowed. Otherwise the DartVM
+    // quietly ignores trailing Dart statements resulting in user confusion
+    // when part of an invalid expression they entered is ignored.
+    sb..write(') => (\n$expression\n)');
     return [sb.toString(), args.values.toList(growable: false)];
   }
 
   /**
+   * TODO(jacobr): this is a big hack to get around the fact that we are still
+   * passing some JS expression to the evaluate method even when in a Dart
+   * context.
+   */
+  static bool isJsExpression(String expression) =>
+    expression.startsWith("(function getCompletions");
+
+  /**
+   * Returns a list of completions to use if the receiver is o.
+   */
+  static List<String> getCompletions(o) {
+    MirrorSystem system = currentMirrorSystem(); 
+    var completions = new Set<String>();
+    addAll(Map<Symbol, dynamic> map, bool isStatic) {
+      map.forEach((symbol, mirror) {
+        if (mirror.isStatic == isStatic && !mirror.isPrivate) {
+          var name = MirrorSystem.getName(symbol);
+          if (mirror is MethodMirror && mirror.isSetter)
+            name = name.substring(0, name.length - 1);
+          completions.add(name);
+        }
+      });
+    }
+
+    addForClass(ClassMirror mirror, bool isStatic) {
+      if (mirror == null)
+        return;
+      addAll(mirror.members, isStatic);
+      if (mirror.superclass != null)
+        addForClass(mirror.superclass, isStatic);
+      for (var interface in mirror.superinterfaces) {
+        addForClass(interface, isStatic);
+      }
+    }
+    
+    if (o is Type) {
+      addForClass(reflectClass(o), true);
+    } else {
+      addForClass(reflect(o).type, false);
+    }
+    return completions.toList(growable: false);
+  }
+
+  /**
    * Convenience helper to get the keys of a [Map] as a [List].
    */
   static List getMapKeyList(Map map) => map.keys.toList();
@@ -35281,79 +35220,10 @@
   bool get isNotEmpty => Maps.isNotEmpty(this);
 }
 
-// TODO(vsm): Remove DOM isolate code.  This is only used to support
-// printing and timers in background isolates.  Background isolates
-// should just forward to the main DOM isolate instead of requiring a
-// special DOM isolate.
-
-_makeSendPortFuture(spawnRequest) {
-  final completer = new Completer<SendPort>.sync();
-  final port = new ReceivePort();
-  port.receive((result, _) {
-    completer.complete(result);
-    port.close();
-  });
-  // TODO: SendPort.hashCode is ugly way to access port id.
-  spawnRequest(port.toSendPort().hashCode);
-  return completer.future;
-}
-
-Future<SendPort> _spawnDomFunction(Function f) =>
-    _makeSendPortFuture((portId) { _Utils.spawnDomFunction(f, portId); });
-
-final Future<SendPort> __HELPER_ISOLATE_PORT =
-    _spawnDomFunction(_helperIsolateMain);
-
-// Tricky part.
-// Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
-// and to delay Timer.run is used. However, Timer.run will try to register
-// another Timer and here we got stuck: event cannot be posted as then
-// callback is not executed because it's delayed with timer.
-// Therefore once future is resolved, it's unsafe to call .then on it
-// in Timer code.
-SendPort __SEND_PORT;
-
-_sendToHelperIsolate(msg, SendPort replyTo) {
-  if (__SEND_PORT != null) {
-    __SEND_PORT.send(msg, replyTo);
-  } else {
-    __HELPER_ISOLATE_PORT.then((port) {
-      __SEND_PORT = port;
-      __SEND_PORT.send(msg, replyTo);
-    });
-  }
-}
-
-final _TIMER_REGISTRY = new Map<SendPort, Timer>();
-
-const _NEW_TIMER = 'NEW_TIMER';
-const _CANCEL_TIMER = 'CANCEL_TIMER';
-const _TIMER_PING = 'TIMER_PING';
-const _PRINT = 'PRINT';
-
-_helperIsolateMain() {
-  port.receive((msg, replyTo) {
-    final cmd = msg[0];
-    if (cmd == _NEW_TIMER) {
-      final duration = new Duration(milliseconds: msg[1]);
-      bool periodic = msg[2];
-      ping() { replyTo.send(_TIMER_PING); };
-      _TIMER_REGISTRY[replyTo] = periodic ?
-          new Timer.periodic(duration, (_) { ping(); }) :
-          new Timer(duration, ping);
-    } else if (cmd == _CANCEL_TIMER) {
-      _TIMER_REGISTRY.remove(replyTo).cancel();
-    } else if (cmd == _PRINT) {
-      final message = msg[1];
-      // TODO(antonm): we need somehow identify those isolates.
-      print('[From isolate] $message');
-    }
-  });
-}
-
 final _printClosure = window.console.log;
 final _pureIsolatePrintClosure = (s) {
-  _sendToHelperIsolate([_PRINT, s], null);
+  throw new UnimplementedError("Printing from a background isolate "
+                               "is not supported in the browser");
 };
 
 final _forwardingPrintClosure = _Utils.forwardingPrint;
@@ -35392,46 +35262,10 @@
   return new _Timer(milliSeconds, callback, repeating);
 };
 
-
-class _PureIsolateTimer implements Timer {
-  bool _isActive = true;
-  final ReceivePort _port = new ReceivePort();
-  SendPort _sendPort; // Effectively final.
-
-  static SendPort _SEND_PORT;
-
-  _PureIsolateTimer(int milliSeconds, callback, repeating) {
-    _sendPort = _port.toSendPort();
-    _port.receive((msg, replyTo) {
-      assert(msg == _TIMER_PING);
-      _isActive = repeating;
-      callback(this);
-      if (!repeating) _cancel();
-    });
-
-    _send([_NEW_TIMER, milliSeconds, repeating]);
-  }
-
-  void cancel() {
-    _cancel();
-    _send([_CANCEL_TIMER]);
-  }
-
-  void _cancel() {
-    _isActive = false;
-    _port.close();
-  }
-
-  _send(msg) {
-    _sendToHelperIsolate(msg, _sendPort);
-  }
-
-  bool get isActive => _isActive;
-}
-
 get _pureIsolateTimerFactoryClosure =>
     ((int milliSeconds, void callback(Timer time), bool repeating) =>
-        new _PureIsolateTimer(milliSeconds, callback, repeating));
+  throw new UnimplementedError("Timers on background isolates "
+                               "are not supported in the browser"));
 
 void _initializeCustomElement(Element e) {
   _Utils.initializeCustomElement(e);
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index 1944bd4..72d5dab 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -13,7 +13,6 @@
 part 'css_class_set.dart';
 part 'device.dart';
 part 'filtered_element_list.dart';
-part 'jenkins_smi_hash.dart';
 part 'lists.dart';
 
 // For annotating deprecated APIs.
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index c7b7ea1..3afd514 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -18,7 +18,6 @@
 part 'conversions.dart';
 part 'device.dart';
 part 'filtered_element_list.dart';
-part 'jenkins_smi_hash.dart';
 part 'lists.dart';
 
 // For annotating deprecated APIs.
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 6aa18f8..80391d4 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -68,59 +68,45 @@
   void createSync({bool recursive: false});
 
   /**
-   * Creates a temporary directory in this directory.  Additional random
-   * characters are appended to [template] to produce a unique directory
-   * name.
+   * Gets the system temp directory.
+   *
+   * Gets the directory provided by the operating system for creating
+   * temporary files and directories in.
+   * The location of the system temp directory is platform-dependent,
+   * and may be set by an environment variable.
+   */
+  static Directory get systemTemp => _Directory.systemTemp;
+
+  /**
+   * Creates a temporary directory in this directory. Additional random
+   * characters are appended to [prefix] to produce a unique directory
+   * name. If [prefix] is missing or null, the empty string is used
+   * for [prefix].
    *
    * Returns a [:Future<Directory>:] that completes with the newly
    * created temporary directory.
    *
    * Deprecated behavior, to be removed Oct 18, 2013: If the path is the
    * empty string, the directory is created in the default system temp
-   * directory.  This capability has been moved to the static function
-   * [createSystemTemp].
+   * directory. This capability has been moved to the static getter
+   * [systemTemp].
    */
   Future<Directory> createTemp([String template]);
 
   /**
    * Synchronously creates a temporary directory in this directory.
-   * Additional random characters are appended to [template] to produce
-   * a unique directory name.
+   * Additional random characters are appended to [prefix] to produce
+   * a unique directory name. If [prefix] is missing or null, the empty
+   * string is used for [prefix].
    *
    * Returns the newly created temporary directory.
    *
    * Deprecated behavior, to be removed Oct 18, 2013: If the path is the
    * empty string, the directory is created in the default system temp
-   * directory.  This capability has been moved to the static function
+   * directory. This capability has been moved to the static function
    * [createSystemTemp].
    */
- Directory createTempSync([String template]);
-
-  /**
-   * Creates a temporary directory in the system temp directory.
-   * The location of the system temp directory is platform-dependent,
-   * and may be set by an environment variable.
-   * Additional random characters are appended to [template] to produce
-   * a unique directory name.
-   *
-   * Returns a [:Future<Directory>:] that completes with the newly
-   * created temporary directory.
-   */
-  static Future<Directory> createSystemTemp([String template]) =>
-      _Directory.createSystemTemp(template);
-
-  /**
-   * Synchronously creates a temporary directory in the system temp directory.
-   * The location of the system temp directory is platform-dependent,
-   * and may be set by an environment variable.
-   * Additional random characters are appended to [template] to produce
-   * a unique directory name.
-   *
-   * Returns a [:Future<Directory>:] that completes with the newly
-   * created temporary directory.
-   */
-  static Directory createSystemTempSync([String template]) =>
-      _Directory.createSystemTempSync(template);
+  Directory createTempSync([String template]);
 
   Future<String> resolveSymbolicLinks();
 
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index ac048de..2883648 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -16,7 +16,8 @@
 
   external static _current();
   external static _setCurrent(path);
-  external static _createTemp(String template, bool system);
+  external static _createTemp(String path);
+  external static String _systemTemp();
   external static int _exists(String path);
   external static _create(String path);
   external static _deleteNative(String path, bool recursive);
@@ -149,17 +150,22 @@
     }
   }
 
-  // TODO(13720): Make template argument mandatory on Oct 18, 2013.
-  Future<Directory> createTemp([String template]) {
+  static Directory get systemTemp => new Directory(_systemTemp());
+
+  Future<Directory> createTemp([String prefix]) {
+    if (prefix == null) prefix = '';
     if (path == '') {
-      if (template == null) template = '';
-      return createSystemTemp(template);
+      return systemTemp.createTemp(prefix);
       // TODO(13720): On Oct 18, 2013, replace this with
       // an error.  createTemp cannot be called on a Directory with empty path.
     }
-    String fullTemplate = "$path${Platform.pathSeparator}";
-    if (template != null) fullTemplate = "$fullTemplate$template";
-    return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [fullTemplate])
+    String fullPrefix;
+    if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
+      fullPrefix = "$path$prefix";
+    } else {
+      fullPrefix = "$path${Platform.pathSeparator}$prefix";
+    }
+    return _IOService.dispatch(_DIRECTORY_CREATE_TEMP, [fullPrefix])
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionOrErrorFromResponse(
@@ -169,41 +175,23 @@
     });
   }
 
-  // TODO(13720): Make template argument mandatory on Oct 18, 2013.
-  Directory createTempSync([String template]) {
+  Directory createTempSync([String prefix]) {
+    if (prefix == null) prefix = '';
     if (path == '') {
-      if (template == null) template = '';
-      return createSystemTempSync(template);
+      return systemTemp.createTempSync(prefix);
       // TODO(13720): On Oct 18, 2013, replace this with
       // an error.  createTemp cannot be called on a Directory with empty path.
     }
-    String fullTemplate = "$path${Platform.pathSeparator}";
-    if (template != null) fullTemplate = "$fullTemplate$template";
-    var result = _createTemp(fullTemplate, false);
-    if (result is OSError) {
-      throw new DirectoryException("Creation of temporary directory failed",
-                                   fullTemplate,
-                                   result);
+    String fullPrefix;
+    if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
+      fullPrefix = "$path$prefix";
+    } else {
+      fullPrefix = "$path${Platform.pathSeparator}$prefix";
     }
-    return new Directory(result);
-  }
-
-  static Future<Directory> createSystemTemp(String template) {
-    return _IOService.dispatch(_DIRECTORY_CREATE_SYSTEM_TEMP,
-                               [template]).then((response) {
-      if (response is List && response[0] != _SUCCESS_RESPONSE) {
-        throw new _Directory(template)._exceptionOrErrorFromResponse(
-            response, "Creation of temporary directory failed");
-      }
-      return new Directory(response);
-    });
-  }
-
-  static Directory createSystemTempSync(String template) {
-    var result = _createTemp(template, true);
+    var result = _createTemp(fullPrefix);
     if (result is OSError) {
       throw new DirectoryException("Creation of temporary directory failed",
-                                   template,
+                                   fullPrefix,
                                    result);
     }
     return new Directory(result);
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index fcaf191..312bb1c 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1568,38 +1568,10 @@
   Future<HttpClientRequest> _openUrlFromRequest(String method,
                                                 Uri uri,
                                                 _HttpClientRequest previous) {
-    var u = uri;
     // If the new URI is relative (to either '/' or some sub-path),
     // construct a full URI from the previous one.
-    // See http://tools.ietf.org/html/rfc3986#section-4.2
-    replaceComponents({scheme, host, port, path}) {
-      uri = new Uri(
-          scheme: scheme != null ? scheme : uri.scheme,
-          host: host != null ? host : uri.host,
-          port: port != null ? port : uri.port,
-          path: path != null ? path : uri.path,
-          query: uri.query,
-          fragment: uri.fragment);
-    }
-
-    var scheme;
-    var host;
-    var port;
-    var path;
-    if (uri.host.isEmpty) {
-      host = previous.uri.host;
-      port = previous.uri.port;
-    }
-    if (uri.scheme.isEmpty) {
-      scheme = previous.uri.scheme;
-    }
-    if (!uri.path.startsWith('/')) {
-      var absolute = new _Path.raw(previous.uri.path).directoryPath;
-      absolute = absolute.join(new _Path.raw(u.path));
-      path = absolute.canonicalize().toString();
-    }
-    replaceComponents(scheme: scheme, host: host, port: port, path: path);
-    return openUrl(method, uri).then((_HttpClientRequest request) {
+    Uri resolved = previous.uri.resolveUri(uri);
+    return openUrl(method, resolved).then((_HttpClientRequest request) {
           // Only follow redirects if initial request did.
           request.followRedirects = previous.followRedirects;
           // Allow same number of redirects.
diff --git a/sdk/lib/io/io_service.dart b/sdk/lib/io/io_service.dart
index 037cdd1..bf4b42b 100644
--- a/sdk/lib/io/io_service.dart
+++ b/sdk/lib/io/io_service.dart
@@ -38,12 +38,11 @@
 const int _DIRECTORY_DELETE = 30;
 const int _DIRECTORY_EXISTS = 31;
 const int _DIRECTORY_CREATE_TEMP = 32;
-const int _DIRECTORY_CREATE_SYSTEM_TEMP = 33;
-const int _DIRECTORY_LIST_START = 34;
-const int _DIRECTORY_LIST_NEXT = 35;
-const int _DIRECTORY_LIST_STOP = 36;
-const int _DIRECTORY_RENAME = 37;
-const int _SSL_PROCESS_FILTER = 38;
+const int _DIRECTORY_LIST_START = 33;
+const int _DIRECTORY_LIST_NEXT = 34;
+const int _DIRECTORY_LIST_STOP = 35;
+const int _DIRECTORY_RENAME = 36;
+const int _SSL_PROCESS_FILTER = 37;
 
 class _IOService {
   external static Future dispatch(int request, List data);
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
index 8bd8ab2..114feea 100644
--- a/sdk/lib/json/json.dart
+++ b/sdk/lib/json/json.dart
@@ -6,14 +6,18 @@
  * Utilities for encoding and decoding JSON (JavaScript Object Notation) data.
  */
 
+@deprecated
 library dart.json;
 
 import "dart:convert";
+import "dart:_collection-dev" show deprecated;
 export "dart:convert" show JsonUnsupportedObjectError, JsonCyclicError;
 
 // JSON parsing and serialization.
 
 /**
+ * *DEPRECATED* Use `dart:convert JSON.decode` instead.
+ *
  * Parses [json] and build the corresponding parsed JSON value.
  *
  * Parsed JSON values are of the types [num], [String], [bool], [Null],
@@ -28,6 +32,7 @@
  *
  * Throws [FormatException] if the input is not valid JSON text.
  */
+@deprecated
 parse(String json, [reviver(var key, var value)]) {
   if (reviver != null) {
     var original = reviver;
@@ -37,6 +42,8 @@
 }
 
 /**
+ * *DEPRECATED* Use `dart:convert JSON.encode` instead.
+ *
  * Serializes [object] into a JSON string.
  *
  * Directly serializable values are [num], [String], [bool], and [Null], as well
@@ -63,11 +70,14 @@
  * the JSON text for it. I.e., if an object changes after it is first
  * serialized, the new values may or may not be reflected in the result.
  */
+@deprecated
 String stringify(Object object) {
   return _JsonStringifier.stringify(object);
 }
 
 /**
+ * *DEPRECATED* Use `package:json/json.dart` or `dart:convert` instead.
+ *
  * Serializes [object] into [output] stream.
  *
  * Performs the same operations as [stringify] but outputs the resulting
@@ -76,6 +86,7 @@
  * If serialization fails by throwing, some data might have been added to
  * [output], but it won't contain valid JSON text.
  */
+@deprecated
 void printOn(Object object, StringSink output) {
   return _JsonStringifier.printOn(object, output);
 }
@@ -84,6 +95,8 @@
 
 // Simple API for JSON parsing.
 
+/// *DEPRECATED* Use `package:json/json.dart` instead.
+@deprecated
 abstract class JsonListener {
   void handleString(String value) {}
   void handleNumber(num value) {}
@@ -101,11 +114,14 @@
 }
 
 /**
+ * *DEPRECATED* Use `package:json/json.dart` instead.
+ *
  * A [JsonListener] that builds data objects from the parser events.
  *
  * This is a simple stack-based object builder. It keeps the most recently
  * seen value in a variable, and uses it depending on the following event.
  */
+@deprecated
 class BuildJsonListener extends JsonListener {
   /**
    * Stack used to handle nested containers.
@@ -184,6 +200,8 @@
 
 typedef _Reviver(var key, var value);
 
+/// *DEPRECATED* Use `package:json/json.dart` instead.
+@deprecated
 class ReviverJsonListener extends BuildJsonListener {
   final _Reviver reviver;
   ReviverJsonListener(reviver(key, value)) : this.reviver = reviver;
@@ -204,6 +222,8 @@
   }
 }
 
+/// *DEPRECATED* Use `package:json/json.dart` instead.
+@deprecated
 class JsonParser {
   // A simple non-recursive state-based parser for JSON.
   //
diff --git a/sdk/lib/html/html_common/jenkins_smi_hash.dart b/sdk/lib/math/jenkins_smi_hash.dart
similarity index 90%
rename from sdk/lib/html/html_common/jenkins_smi_hash.dart
rename to sdk/lib/math/jenkins_smi_hash.dart
index 7938e50..8a0056e 100644
--- a/sdk/lib/html/html_common/jenkins_smi_hash.dart
+++ b/sdk/lib/math/jenkins_smi_hash.dart
@@ -1,8 +1,7 @@
 // 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 html_common;
+part of dart.math;
 
 /**
  * This is the [Jenkins hash function][1] but using masking to keep
@@ -20,8 +19,8 @@
  *     }
  *     hash = JenkinsSmiHash.finish(hash);
  */
-class JenkinsSmiHash {
-  // TODO: Bug 11617- This class should be optimized and standardized elsewhere.
+class _JenkinsSmiHash {
+  // TODO(11617): This class should be optimized and standardized elsewhere.
 
   static int combine(int hash, int value) {
     hash = 0x1fffffff & (hash + value);
diff --git a/sdk/lib/math/math.dart b/sdk/lib/math/math.dart
index 4cffa8f..95ed261 100644
--- a/sdk/lib/math/math.dart
+++ b/sdk/lib/math/math.dart
@@ -7,7 +7,10 @@
  */
 library dart.math;
 
+part "jenkins_smi_hash.dart";
+part "point.dart";
 part "random.dart";
+part "rectangle.dart";
 
 /**
  * Base of the natural logarithms.
diff --git a/sdk/lib/math/math_sources.gypi b/sdk/lib/math/math_sources.gypi
index ed2577e..c26d41c 100644
--- a/sdk/lib/math/math_sources.gypi
+++ b/sdk/lib/math/math_sources.gypi
@@ -6,6 +6,9 @@
   'sources': [
     'math.dart',
     # The above file needs to be first as it lists the parts below.
+    'jenkins_smi_hash.dart',
+    'point.dart',
     'random.dart',
+    'rectangle.dart',
   ],
 }
diff --git a/sdk/lib/math/point.dart b/sdk/lib/math/point.dart
new file mode 100644
index 0000000..37411b7
--- /dev/null
+++ b/sdk/lib/math/point.dart
@@ -0,0 +1,81 @@
+// 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 dart.math;
+
+/**
+ * A utility class for representing two-dimensional positions.
+ */
+class Point<T extends num> {
+  final T x;
+  final T y;
+
+  const Point([T x = 0, T y = 0]): this.x = x, this.y = y;
+
+  String toString() => 'Point($x, $y)';
+
+  bool operator ==(other) {
+    if (other is !Point) return false;
+    return x == other.x && y == other.y;
+  }
+
+  int get hashCode => _JenkinsSmiHash.hash2(x.hashCode, y.hashCode);
+
+  /**
+   * Add [other] to `this`, as if both points were vectors.
+   *
+   * Returns the resulting "vector" as a Point.
+   */
+  Point<T> operator +(Point<T> other) {
+    return new Point<T>(x + other.x, y + other.y);
+  }
+
+  /**
+   * Subtract [other] from `this`, as if both points were vectors.
+   *
+   * Returns the resulting "vector" as a Point.
+   */
+  Point<T> operator -(Point<T> other) {
+    return new Point<T>(x - other.x, y - other.y);
+  }
+
+  /**
+   * Scale this point by [factor] as if it were a vector.
+   *
+   * *Important* *Note*: This function accepts a `num` as its argument only so
+   * that you can scale Point<double> objects by an `int` factor. Because the
+   * star operator always returns the same type of Point that originally called
+   * it, passing in a double [factor] on a `Point<int>` _causes_ _a_
+   * _runtime_ _error_ in checked mode.
+   */
+  Point<T> operator *(num factor) {
+    return new Point<T>(x * factor, y * factor);
+  }
+
+  /**
+   * Get the straight line (Euclidean) distance between the origin (0, 0) and
+   * this point.
+   */
+  double get magnitude => sqrt(x * x + y * y);
+
+  /**
+   * Returns the distance between `this` and [other].
+   */
+  double distanceTo(Point<T> other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return sqrt(dx * dx + dy * dy);
+  }
+
+  /**
+   * Returns the squared distance between `this` and [other].
+   *
+   * Squared distances can be used for comparisons when the actual value is not
+   * required.
+   */
+  T squaredDistanceTo(Point<T> other) {
+    var dx = x - other.x;
+    var dy = y - other.y;
+    return dx * dx + dy * dy;
+  }
+}
diff --git a/sdk/lib/math/rectangle.dart b/sdk/lib/math/rectangle.dart
new file mode 100644
index 0000000..763a251
--- /dev/null
+++ b/sdk/lib/math/rectangle.dart
@@ -0,0 +1,157 @@
+// 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 dart.math;
+
+/**
+ * A base class for representing two-dimensional axis-aligned rectangles.
+ */
+abstract class _RectangleBase<T extends num> {
+  const _RectangleBase();
+
+  /** The x-coordinate of the left edge. */
+  T get left;
+  /** The y-coordinate of the top edge. */
+  T get top;
+  /** The `width` of the rectangle. */
+  T get width;
+  /** The `height` of the rectangle. */
+  T get height;
+
+  /** The x-coordinate of the right edge. */
+  T get right => left + width;
+  /** The y-coordinate of the bottom edge. */
+  T get bottom => top + height;
+
+  String toString() {
+    return 'Rectangle ($left, $top) $width x $height';
+  }
+
+  bool operator ==(other) {
+    if (other is !Rectangle) return false;
+    return left == other.left && top == other.top && width == other.width &&
+        height == other.height;
+  }
+
+  int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
+      width.hashCode, height.hashCode);
+
+  /**
+   * Computes the intersection of `this` and [other].
+   *
+   * The intersection of two axis-aligned rectangles, if any, is always another
+   * axis-aligned rectangle.
+   *
+   * Returns the intersection of this and `other`, or `null` if they don't
+   * intersect.
+   */
+  Rectangle<T> intersection(Rectangle<T> other) {
+    var x0 = max(left, other.left);
+    var x1 = min(left + width, other.left + other.width);
+
+    if (x0 <= x1) {
+      var y0 = max(top, other.top);
+      var y1 = min(top + height, other.top + other.height);
+
+      if (y0 <= y1) {
+        return new Rectangle<T>(x0, y0, x1 - x0, y1 - y0);
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns true if `this` intersects [other].
+   */
+  bool intersects(Rectangle<num> other) {
+    return (left <= other.left + other.width &&
+        other.left <= left + width &&
+        top <= other.top + other.height &&
+        other.top <= top + height);
+  }
+
+  /**
+   * Returns a new rectangle which completely contains `this` and [other].
+   */
+  Rectangle<T> boundingBox(Rectangle<T> other) {
+    var right = max(this.left + this.width, other.left + other.width);
+    var bottom = max(this.top + this.height, other.top + other.height);
+
+    var left = min(this.left, other.left);
+    var top = min(this.top, other.top);
+
+    return new Rectangle<T>(left, top, right - left, bottom - top);
+  }
+
+  /**
+   * Tests whether `this` entirely contains [another].
+   */
+  bool contains(Rectangle<num> another) {
+    return left <= another.left &&
+           left + width >= another.left + another.width &&
+           top <= another.top &&
+           top + height >= another.top + another.height;
+  }
+
+  /**
+   * Tests whether [another] is inside or along the edges of `this`.
+   */
+  bool containsPoint(Point<num> another) {
+    return another.x >= left &&
+           another.x <= left + width &&
+           another.y >= top &&
+           another.y <= top + height;
+  }
+
+  Point<T> get topLeft => new Point<T>(this.left, this.top);
+  Point<T> get topRight => new Point<T>(this.left + this.width, this.top);
+  Point<T> get bottomRight => new Point<T>(this.left + this.width,
+      this.top + this.height);
+  Point<T> get bottomLeft => new Point<T>(this.left,
+      this.top + this.height);
+}
+
+
+/**
+ * A class for representing two-dimensional rectangles whose properties are
+ * immutable.
+ */
+class Rectangle<T extends num> extends _RectangleBase<T> {
+  final T left;
+  final T top;
+  final T width;
+  final T height;
+
+  const Rectangle(this.left, this.top, this.width, this.height);
+
+  factory Rectangle.fromPoints(Point<T> a, Point<T> b) {
+    T left = min(a.x, b.x);
+    T width = max(a.x, b.x) - left;
+    T top = min(a.y, b.y);
+    T height = max(a.y, b.y) - top;
+    return new Rectangle<T>(left, top, width, height);
+  }
+}
+
+/**
+ * A class for representing two-dimensional axis-aligned rectangles with mutable
+ * properties.
+ */
+class MutableRectangle<T extends num>  extends _RectangleBase<T>
+    implements Rectangle<T> {
+  T left;
+  T top;
+  T width;
+  T height;
+
+  MutableRectangle(this.left, this.top, this.width, this.height);
+
+  factory MutableRectangle.fromPoints(Point<T> a, Point<T> b) {
+    T left = min(a.x, b.x);
+    T width = max(a.x, b.x) - left;
+    T top = min(a.y, b.y);
+    T height = max(a.y, b.y) - top;
+    return new MutableRectangle<T>(left, top, width, height);
+  }
+}
diff --git a/sdk/lib/utf/utf.dart b/sdk/lib/utf/utf.dart
index 43a2944..229b5aa 100644
--- a/sdk/lib/utf/utf.dart
+++ b/sdk/lib/utf/utf.dart
@@ -3,10 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /**
- * Support for encoding and decoding Unicode characters in UTF-8, UTF-16, and 
+ * Support for encoding and decoding Unicode characters in UTF-8, UTF-16, and
  * UTF-32.
  */
+@deprecated
 library dart.utf;
+import "dart:_collection-dev" show deprecated;
 import "dart:async";
 import "dart:collection";
 part "utf_stream.dart";
@@ -16,8 +18,11 @@
 
 // TODO(jmesserly): would be nice to have this on String (dartbug.com/6501).
 /**
+ * *DEPRECATED*: Use `dart:convert` or `package:utf/utf.dart` instead.
+ *
  * Provide a list of Unicode codepoints for a given string.
  */
+@deprecated
 List<int> stringToCodepoints(String str) {
   // Note: str.codeUnits gives us 16-bit code units on all Dart implementations.
   // So we need to convert.
@@ -29,6 +34,7 @@
  *
  * *Deprecated* Use [String.fromCharCodes] instead.
  */
+@deprecated
 String codepointsToString(List<int> codepoints) {
   return new String.fromCharCodes(codepoints);
 }
@@ -36,21 +42,36 @@
 /**
  * Invalid codepoints or encodings may be substituted with the value U+fffd.
  */
+@deprecated
 const int UNICODE_REPLACEMENT_CHARACTER_CODEPOINT = 0xfffd;
+@deprecated
 const int UNICODE_BOM = 0xfeff;
+@deprecated
 const int UNICODE_UTF_BOM_LO = 0xff;
+@deprecated
 const int UNICODE_UTF_BOM_HI = 0xfe;
 
+@deprecated
 const int UNICODE_BYTE_ZERO_MASK = 0xff;
+@deprecated
 const int UNICODE_BYTE_ONE_MASK = 0xff00;
+@deprecated
 const int UNICODE_VALID_RANGE_MAX = 0x10ffff;
+@deprecated
 const int UNICODE_PLANE_ONE_MAX = 0xffff;
+@deprecated
 const int UNICODE_UTF16_RESERVED_LO = 0xd800;
+@deprecated
 const int UNICODE_UTF16_RESERVED_HI = 0xdfff;
+@deprecated
 const int UNICODE_UTF16_OFFSET = 0x10000;
+@deprecated
 const int UNICODE_UTF16_SURROGATE_UNIT_0_BASE = 0xd800;
+@deprecated
 const int UNICODE_UTF16_SURROGATE_UNIT_1_BASE = 0xdc00;
+@deprecated
 const int UNICODE_UTF16_HI_MASK = 0xffc00;
+@deprecated
 const int UNICODE_UTF16_LO_MASK = 0x3ff;
 
 /**
@@ -123,11 +144,10 @@
 }
 
 /**
- * An Iterator<int> of codepoints built on an Iterator of UTF-16 code units.
- * The parameters can override the default Unicode replacement character. Set
- * the replacementCharacter to null to throw an ArgumentError
- * rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf16CodeUnitDecoder implements Iterator<int> {
   final _ListRangeIterator utf16CodeUnitIterator;
   final int replacementCodepoint;
diff --git a/sdk/lib/utf/utf16.dart b/sdk/lib/utf/utf16.dart
index 3518bbb..23be863 100644
--- a/sdk/lib/utf/utf16.dart
+++ b/sdk/lib/utf/utf16.dart
@@ -5,13 +5,10 @@
 part of dart.utf;
 
 /**
- * Decodes the UTF-16 bytes as an iterable. Thus, the consumer can only convert
- * as much of the input as needed. Determines the byte order from the BOM,
- * or uses big-endian as a default. This method always strips a leading BOM.
- * Set the [replacementCodepoint] to null to throw an ArgumentError
- * rather than replace the bad value. The default value for
- * [replacementCodepoint] is U+FFFD.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf16Decoder decodeUtf16AsIterable(List<int> bytes, [int offset = 0,
     int length, int replacementCodepoint =
     UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -21,13 +18,10 @@
 }
 
 /**
- * Decodes the UTF-16BE bytes as an iterable. Thus, the consumer can only
- * convert as much of the input as needed. This method strips a leading BOM by
- * default, but can be overridden by setting the optional parameter [stripBom]
- * to false. Set the [replacementCodepoint] to null to throw an
- * ArgumentError rather than replace the bad value. The default
- * value for the [replacementCodepoint] is U+FFFD.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf16Decoder decodeUtf16beAsIterable(List<int> bytes, [int offset = 0,
     int length, bool stripBom = true, int replacementCodepoint =
     UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -37,13 +31,10 @@
 }
 
 /**
- * Decodes the UTF-16LE bytes as an iterable. Thus, the consumer can only
- * convert as much of the input as needed. This method strips a leading BOM by
- * default, but can be overridden by setting the optional parameter [stripBom]
- * to false. Set the [replacementCodepoint] to null to throw an
- * ArgumentError rather than replace the bad value. The default
- * value for the [replacementCodepoint] is U+FFFD.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf16Decoder decodeUtf16leAsIterable(List<int> bytes, [int offset = 0,
     int length, bool stripBom = true, int replacementCodepoint =
     UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -53,11 +44,10 @@
 }
 
 /**
- * Produce a String from a sequence of UTF-16 encoded bytes. This method always
- * strips a leading BOM. Set the [replacementCodepoint] to null to throw  an
- * ArgumentError rather than replace the bad value. The default
- * value for the [replacementCodepoint] is U+FFFD.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf16(List<int> bytes, [int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
   Utf16BytesToCodeUnitsDecoder decoder = new Utf16BytesToCodeUnitsDecoder(bytes,
@@ -68,12 +58,10 @@
 }
 
 /**
- * Produce a String from a sequence of UTF-16BE encoded bytes. This method
- * strips a leading BOM by default, but can be overridden by setting the
- * optional parameter [stripBom] to false. Set the [replacementCodepoint] to
- * null to throw an ArgumentError rather than replace the bad value.
- * The default value for the [replacementCodepoint] is U+FFFD.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf16be(List<int> bytes, [int offset = 0, int length,
     bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -84,12 +72,10 @@
 }
 
 /**
- * Produce a String from a sequence of UTF-16LE encoded bytes. This method
- * strips a leading BOM by default, but can be overridden by setting the
- * optional parameter [stripBom] to false. Set the [replacementCodepoint] to
- * null to throw an ArgumentError rather than replace the bad value.
- * The default value for the [replacementCodepoint] is U+FFFD.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf16le(List<int> bytes, [int offset = 0, int length,
     bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -100,16 +86,18 @@
 }
 
 /**
- * Produce a list of UTF-16 encoded bytes. This method prefixes the resulting
- * bytes with a big-endian byte-order-marker.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf16(String str) =>
     encodeUtf16be(str, true);
 
 /**
- * Produce a list of UTF-16BE encoded bytes. By default, this method produces
- * UTF-16BE bytes with no BOM.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf16be(String str, [bool writeBOM = false]) {
   List<int> utf16CodeUnits = _stringToUtf16CodeUnits(str);
   List<int> encoding =
@@ -127,9 +115,10 @@
 }
 
 /**
- * Produce a list of UTF-16LE encoded bytes. By default, this method produces
- * UTF-16LE bytes with no BOM.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf16le(String str, [bool writeBOM = false]) {
   List<int> utf16CodeUnits = _stringToUtf16CodeUnits(str);
   List<int> encoding =
@@ -147,18 +136,20 @@
 }
 
 /**
- * Identifies whether a List of bytes starts (based on offset) with a
- * byte-order marker (BOM).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 bool hasUtf16Bom(List<int> utf32EncodedBytes, [int offset = 0, int length]) {
   return hasUtf16beBom(utf32EncodedBytes, offset, length) ||
       hasUtf16leBom(utf32EncodedBytes, offset, length);
 }
 
 /**
- * Identifies whether a List of bytes starts (based on offset) with a
- * big-endian byte-order marker (BOM).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 bool hasUtf16beBom(List<int> utf16EncodedBytes, [int offset = 0, int length]) {
   int end = length != null ? offset + length : utf16EncodedBytes.length;
   return (offset + 2) <= end &&
@@ -167,9 +158,10 @@
 }
 
 /**
- * Identifies whether a List of bytes starts (based on offset) with a
- * little-endian byte-order marker (BOM).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 bool hasUtf16leBom(List<int> utf16EncodedBytes, [int offset = 0, int length]) {
   int end = length != null ? offset + length : utf16EncodedBytes.length;
   return (offset + 2) <= end &&
@@ -184,12 +176,10 @@
 typedef _ListRangeIterator _CodeUnitsProvider();
 
 /**
- * Return type of [decodeUtf16AsIterable] and variants. The Iterable type
- * provides an iterator on demand and the iterator will only translate bytes
- * as requested by the user of the iterator. (Note: results are not cached.)
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
-// TODO(floitsch): Consider removing the extend and switch to implements since
-// that's cheaper to allocate.
+@deprecated
 class IterableUtf16Decoder extends IterableBase<int> {
   final _CodeUnitsProvider codeunitsProvider;
   final int replacementCodepoint;
@@ -202,10 +192,10 @@
 }
 
 /**
- * Convert UTF-16 encoded bytes to UTF-16 code units by grouping 1-2 bytes
- * to produce the code unit (0-(2^16)-1). Relies on BOM to determine
- * endian-ness, and defaults to BE.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 abstract class Utf16BytesToCodeUnitsDecoder implements _ListRangeIterator {
   final _ListRangeIterator utf16EncodedBytesIterator;
   final int replacementCodepoint;
@@ -287,9 +277,10 @@
 }
 
 /**
- * Convert UTF-16BE encoded bytes to utf16 code units by grouping 1-2 bytes
- * to produce the code unit (0-(2^16)-1).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf16beBytesToCodeUnitsDecoder extends Utf16BytesToCodeUnitsDecoder {
   Utf16beBytesToCodeUnitsDecoder(List<int> utf16EncodedBytes, [
       int offset = 0, int length, bool stripBom = true,
@@ -312,9 +303,10 @@
 }
 
 /**
- * Convert UTF-16LE encoded bytes to utf16 code units by grouping 1-2 bytes
- * to produce the code unit (0-(2^16)-1).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf16leBytesToCodeUnitsDecoder extends Utf16BytesToCodeUnitsDecoder {
   Utf16leBytesToCodeUnitsDecoder(List<int> utf16EncodedBytes, [
       int offset = 0, int length, bool stripBom = true,
diff --git a/sdk/lib/utf/utf32.dart b/sdk/lib/utf/utf32.dart
index acd465c..9f7293f 100644
--- a/sdk/lib/utf/utf32.dart
+++ b/sdk/lib/utf/utf32.dart
@@ -5,12 +5,10 @@
 part of dart.utf;
 
 /**
- * Decodes the UTF-32 bytes as an iterable. Thus, the consumer can only convert
- * as much of the input as needed. Determines the byte order from the BOM,
- * or uses big-endian as a default. This method always strips a leading BOM.
- * Set the replacementCharacter to null to throw an ArgumentError
- * rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf32Decoder decodeUtf32AsIterable(List<int> bytes, [
     int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -19,12 +17,10 @@
 }
 
 /**
- * Decodes the UTF-32BE bytes as an iterable. Thus, the consumer can only convert
- * as much of the input as needed. This method strips a leading BOM by default,
- * but can be overridden by setting the optional parameter [stripBom] to false.
- * Set the replacementCharacter to null to throw an ArgumentError
- * rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf32Decoder decodeUtf32beAsIterable(List<int> bytes, [
     int offset = 0, int length, bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -34,12 +30,10 @@
 }
 
 /**
- * Decodes the UTF-32LE bytes as an iterable. Thus, the consumer can only convert
- * as much of the input as needed. This method strips a leading BOM by default,
- * but can be overridden by setting the optional parameter [stripBom] to false.
- * Set the replacementCharacter to null to throw an ArgumentError
- * rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf32Decoder decodeUtf32leAsIterable(List<int> bytes, [
     int offset = 0, int length, bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -49,37 +43,32 @@
 }
 
 /**
- * Produce a String from a sequence of UTF-32 encoded bytes. The parameters
- * allow an offset into a list of bytes (as int), limiting the length of the
- * values be decoded and the ability of override the default Unicode
- * replacement character. Set the replacementCharacter to null to throw an
- * ArgumentError rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf32(List<int> bytes, [int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
   return new String.fromCharCodes((new Utf32BytesDecoder(bytes, offset, length,
       replacementCodepoint)).decodeRest());
 }
+
 /**
- * Produce a String from a sequence of UTF-32BE encoded bytes. The parameters
- * allow an offset into a list of bytes (as int), limiting the length of the
- * values be decoded and the ability of override the default Unicode
- * replacement character. Set the replacementCharacter to null to throw an
- * ArgumentError rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf32be(
     List<int> bytes, [int offset = 0, int length, bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) =>
-  new String.fromCharCodes((new Utf32beBytesDecoder(bytes, offset, length, 
+  new String.fromCharCodes((new Utf32beBytesDecoder(bytes, offset, length,
     stripBom, replacementCodepoint)).decodeRest());
 
 /**
- * Produce a String from a sequence of UTF-32LE encoded bytes. The parameters
- * allow an offset into a list of bytes (as int), limiting the length of the
- * values be decoded and the ability of override the default Unicode
- * replacement character. Set the replacementCharacter to null to throw an
- * ArgumentError rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf32le(
     List<int> bytes, [int offset = 0, int length, bool stripBom = true,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) =>
@@ -87,16 +76,18 @@
       stripBom, replacementCodepoint)).decodeRest());
 
 /**
- * Produce a list of UTF-32 encoded bytes. This method prefixes the resulting
- * bytes with a big-endian byte-order-marker.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf32(String str) =>
     encodeUtf32be(str, true);
 
 /**
- * Produce a list of UTF-32BE encoded bytes. By default, this method produces
- * UTF-32BE bytes with no BOM.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf32be(String str, [bool writeBOM = false]) {
   List<int> utf32CodeUnits = stringToCodepoints(str);
   List<int> encoding = new List<int>(4 * utf32CodeUnits.length +
@@ -118,9 +109,10 @@
 }
 
 /**
- * Produce a list of UTF-32LE encoded bytes. By default, this method produces
- * UTF-32BE bytes with no BOM.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf32le(String str, [bool writeBOM = false]) {
   List<int> utf32CodeUnits = stringToCodepoints(str);
   List<int> encoding = new List<int>(4 * utf32CodeUnits.length +
@@ -142,9 +134,10 @@
 }
 
 /**
- * Identifies whether a List of bytes starts (based on offset) with a
- * byte-order marker (BOM).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 bool hasUtf32Bom(
     List<int> utf32EncodedBytes, [int offset = 0, int length]) {
   return hasUtf32beBom(utf32EncodedBytes, offset, length) ||
@@ -152,9 +145,10 @@
 }
 
 /**
- * Identifies whether a List of bytes starts (based on offset) with a
- * big-endian byte-order marker (BOM).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 bool hasUtf32beBom(List<int> utf32EncodedBytes, [int offset = 0, int length]) {
   int end = length != null ? offset + length : utf32EncodedBytes.length;
   return (offset + 4) <= end &&
@@ -164,9 +158,10 @@
 }
 
 /**
- * Identifies whether a List of bytes starts (based on offset) with a
- * little-endian byte-order marker (BOM).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 bool hasUtf32leBom(List<int> utf32EncodedBytes, [int offset = 0, int length]) {
   int end = length != null ? offset + length : utf32EncodedBytes.length;
   return (offset + 4) <= end &&
@@ -178,12 +173,10 @@
 typedef Utf32BytesDecoder Utf32BytesDecoderProvider();
 
 /**
- * Return type of [decodeUtf32AsIterable] and variants. The Iterable type
- * provides an iterator on demand and the iterator will only translate bytes
- * as requested by the user of the iterator. (Note: results are not cached.)
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
-// TODO(floitsch): Consider removing the extend and switch to implements since
-// that's cheaper to allocate.
+@deprecated
 class IterableUtf32Decoder extends IterableBase<int> {
   final Utf32BytesDecoderProvider codeunitsProvider;
 
@@ -193,8 +186,10 @@
 }
 
 /**
- * Abstrace parent class converts encoded bytes to codepoints.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 abstract class Utf32BytesDecoder implements _ListRangeIterator {
   final _ListRangeIterator utf32EncodedBytesIterator;
   final int replacementCodepoint;
@@ -274,9 +269,10 @@
 }
 
 /**
- * Convert UTF-32BE encoded bytes to codepoints by grouping 4 bytes
- * to produce the unicode codepoint.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf32beBytesDecoder extends Utf32BytesDecoder {
   Utf32beBytesDecoder(List<int> utf32EncodedBytes, [int offset = 0,
       int length, bool stripBom = true,
@@ -303,9 +299,10 @@
 }
 
 /**
- * Convert UTF-32BE encoded bytes to codepoints by grouping 4 bytes
- * to produce the unicode codepoint.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf32leBytesDecoder extends Utf32BytesDecoder {
   Utf32leBytesDecoder(List<int> utf32EncodedBytes, [int offset = 0,
       int length, bool stripBom = true,
diff --git a/sdk/lib/utf/utf8.dart b/sdk/lib/utf/utf8.dart
index 7543865..5867b96 100644
--- a/sdk/lib/utf/utf8.dart
+++ b/sdk/lib/utf/utf8.dart
@@ -4,30 +4,100 @@
 
 part of dart.utf;
 
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_ONE_BYTE_MAX = 0x7f;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_TWO_BYTE_MAX = 0x7ff;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_THREE_BYTE_MAX = 0xffff;
 
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_LO_SIX_BIT_MASK = 0x3f;
 
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_TWO_BASE = 0xc0;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_THREE_BASE = 0xe0;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_FOUR_BASE = 0xf0;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_FIVE_BASE = 0xf8;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_SIX_BASE = 0xfc;
 
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_TWO_MASK = 0x1f;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_THREE_MASK = 0xf;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_OF_FOUR_MASK = 0x7;
 
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_FIRST_BYTE_BOUND_EXCL = 0xfe;
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 const int _UTF8_SUBSEQUENT_BYTE_BASE = 0x80;
 
 /**
- * Decodes the UTF-8 bytes as an iterable. Thus, the consumer can only convert
- * as much of the input as needed. Set the replacementCharacter to null to
- * throw an ArgumentError rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 IterableUtf8Decoder decodeUtf8AsIterable(List<int> bytes, [int offset = 0,
     int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -35,12 +105,10 @@
 }
 
 /**
- * Produce a String from a List of UTF-8 encoded bytes. The parameters
- * can set an offset into a list of bytes (as int), limit the length of the
- * values to be decoded, and override the default Unicode replacement character.
- * Set the replacementCharacter to null to throw an ArgumentError
- * rather than replace the bad value.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 String decodeUtf8(List<int> bytes, [int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
   return new String.fromCharCodes(
@@ -49,8 +117,10 @@
 }
 
 /**
- * Produce a sequence of UTF-8 encoded bytes from the provided string.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> encodeUtf8(String str) =>
   codepointsToUtf8(stringToCodepoints(str));
 
@@ -65,8 +135,10 @@
 }
 
 /**
- * Encode code points as UTF-8 code units.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 List<int> codepointsToUtf8(
     List<int> codepoints, [int offset = 0, int length]) {
   _ListRange source = new _ListRange(codepoints, offset, length);
@@ -115,8 +187,11 @@
   return encoded;
 }
 
-// Because UTF-8 specifies byte order, we do not have to follow the pattern
-// used by UTF-16 & UTF-32 regarding byte order.
+/**
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
+ */
+@deprecated
 List<int> utf8ToCodepoints(
     List<int> utf8EncodedBytes, [int offset = 0, int length,
     int replacementCodepoint = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT]) {
@@ -125,12 +200,10 @@
 }
 
 /**
- * Return type of [decodeUtf8AsIterable] and variants. The Iterable type
- * provides an iterator on demand and the iterator will only translate bytes
- * as requested by the user of the iterator. (Note: results are not cached.)
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
-// TODO(floitsch): Consider removing the extend and switch to implements since
-// that's cheaper to allocate.
+@deprecated
 class IterableUtf8Decoder extends IterableBase<int> {
   final List<int> bytes;
   final int offset;
@@ -145,13 +218,10 @@
 }
 
 /**
- * Provides an iterator of Unicode codepoints from UTF-8 encoded bytes. The
- * parameters can set an offset into a list of bytes (as int), limit the length
- * of the values to be decoded, and override the default Unicode replacement
- * character. Set the replacementCharacter to null to throw an
- * ArgumentError rather than replace the bad value. The return value
- * from this method can be used as an Iterable (e.g. in a for-loop).
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf8Decoder implements Iterator<int> {
   final _ListRangeIterator utf8EncodedBytesIterator;
   final int replacementCodepoint;
diff --git a/sdk/lib/utf/utf_stream.dart b/sdk/lib/utf/utf_stream.dart
index 8440313..590790a 100644
--- a/sdk/lib/utf/utf_stream.dart
+++ b/sdk/lib/utf/utf_stream.dart
@@ -93,8 +93,10 @@
 }
 
 /**
- * StringTransformer that decodes a stream of UTF-8 encoded bytes.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf8DecoderTransformer extends _StringDecoder {
   Utf8DecoderTransformer(
       [int replacementChar = UNICODE_REPLACEMENT_CHARACTER_CODEPOINT])
@@ -160,8 +162,10 @@
 }
 
 /**
- * StringTransformer that UTF-8 encodes a stream of strings.
+ * *DEPRECATED*: Use `package:utf/utf.dart` or, when applicable, `dart:convert`
+ * instead.
  */
+@deprecated
 class Utf8EncoderTransformer extends _StringEncoder {
   List<int> _processString(String string) {
     var bytes = [];
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index 2859980..20082fc 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -16,17 +16,20 @@
 Language/15_Types/4_Interface_Types_A11_t01: Skip
 Language/15_Types/4_Interface_Types_A11_t02: Skip
 
-# co19 issue #380, Strings class has been removed
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
+# TBF: "class B1 = A with M1;", typedef cannot be used for mixins
+Language/09_Mixins/1_Mixin_Application_A01_t01: Fail
 
-# co19 issue #400, collection library reorg
-LibTest/core/String/concat_A01_t01: fail, OK
-LibTest/core/String/concat_A02_t01: fail, OK
-LibTest/core/Set/isSubsetOf_A01_t01: fail, OK
-LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
+# TBF: It is a compile-time error if the key of an entry in a constant map literal is an instance of a class that implements the operator == unless the key is a string or integer.
+Language/12_Expressions/07_Maps_A13_t01: Fail
 
-# co19 issue #425, Only static fields can be declared as 'const'
-Language/07_Classes/07_Classes_A02_t11: fail, OK
+# TBF: malformed or malbounded type in "conts" is static warning
+Language/12_Expressions/12_Instance_Creation_A01_t08: Fail
+
+# TBF: typedef self reference
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail
+Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail
+
+
 
 # co19 issue #442, undefined name "Expect"
 Language/15_Types/4_Interface_Types_A08_t03: fail, OK
@@ -80,47 +83,63 @@
 # co19 issue #609, return type of "factory M" is M, so we need static warning for "return;".
 Language/13_Statements/11_Return_A07_t01: fail, OK
 
-Language/09_Mixins/1_Mixin_Application_A01_t01: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/01_Constants_A22_t01: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/07_Maps_A13_t01: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/12_Instance_Creation_A01_t08: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/13_Property_Extraction_A02_t02: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/13_Property_Extraction_A04_t02: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/13_Property_Extraction_A04_t03: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t04: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t04: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/16_Getter_Lookup_A02_t05: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/16_Getter_Lookup_A02_t06: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/17_Getter_Invocation_A07_t01: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/17_Getter_Invocation_A07_t02: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/18_Assignment_A01_t07: Fail # co19-roll r607: Please triage this failure
-Language/12_Expressions/18_Assignment_A04_t09: Fail # co19-roll r607: Please triage this failure
-Language/13_Statements/02_Expression_Statements_A01_t13: Fail # co19-roll r607: Please triage this failure
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t08: Fail # co19-roll r607: Please triage this failure
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t09: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/LinkedList_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/first_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/reduce_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isAccessor_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isAccessor_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isGetter_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isGetter_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isMethod_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isMethod_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isSetter_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/isSetter_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/memberName_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/RuneIterator/currentAsString_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/RuneIterator/current_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Runes/isEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Runes/isNotEmpty_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Runes/lastWhere_A02_t01: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Runes/length_A01_t02: Fail # co19-roll r607: Please triage this failure
-LibTest/core/Symbol/Symbol_A01_t04: Fail # co19-roll r607: Please triage this failure
+# co19 issue #613: @static-warning missing, only runtime behavior is tested
+Language/12_Expressions/13_Property_Extraction_A02_t02: Fail, OK
+Language/12_Expressions/13_Property_Extraction_A04_t02: Fail, OK
+Language/12_Expressions/13_Property_Extraction_A04_t03: Fail, OK
+Language/12_Expressions/17_Getter_Invocation_A07_t01: Fail, OK
+Language/12_Expressions/17_Getter_Invocation_A07_t02: Fail, OK
+Language/12_Expressions/18_Assignment_A01_t07: Fail, OK
+Language/12_Expressions/18_Assignment_A04_t09: Fail, OK
+LibTest/core/Invocation/isAccessor_A01_t01: Fail, OK
+LibTest/core/Invocation/isAccessor_A01_t02: Fail, OK
+LibTest/core/Invocation/isGetter_A01_t01: Fail, OK
+LibTest/core/Invocation/isGetter_A01_t02: Fail, OK
+LibTest/core/Invocation/isMethod_A01_t01: Fail, OK
+LibTest/core/Invocation/isMethod_A01_t02: Fail, OK
+LibTest/core/Invocation/isSetter_A01_t01: Fail, OK
+LibTest/core/Invocation/isSetter_A01_t02: Fail, OK
+LibTest/core/Invocation/memberName_A01_t01: Fail, OK
+LibTest/core/Invocation/namedArguments_A01_t01: Fail, OK
+LibTest/core/Invocation/positionalArguments_A01_t01: Fail, OK
+LibTest/core/Symbol/Symbol_A01_t04: Fail, OK
+
+# co19 issue #614: abstract class
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail, OK
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t04: Fail, OK
+Language/12_Expressions/16_Getter_Lookup_A02_t05: Fail, OK
+Language/12_Expressions/16_Getter_Lookup_A02_t06: Fail, OK
+
+# co19 issue #615: Expect import missing
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A03_t03: Fail, OK
+LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
+
+# co19 issue #616: X required argument(s) expected, but Y found
+Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A04_t04: Fail, OK
+Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A02_t05: Fail, OK
+
+# co19 issue #617: "hasNext" is not a function; "Expec"
+LibTest/collection/HasNextIterator/HasNextIterator_A01_t01: Fail, OK
+
+# co19 issue #618: Just a mess - mix of Map and Set
+LibTest/collection/LinkedHashSet/LinkedHashSet.from_A01_t01: Fail, OK
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: Fail, OK
+LibTest/collection/LinkedList/first_A01_t02: Fail, OK
+
+# co19 issue #619: 1 required argument(s) expected, but 0 found
+LibTest/collection/LinkedList/reduce_A01_t01: Fail, OK
+
+# co19 issue #620: The name 'NoSuchMethoError' is not a type and cannot be used in an on-catch clause
+LibTest/core/RuneIterator/currentAsString_A01_t02: Fail, OK
+LibTest/core/RuneIterator/current_A01_t02: Fail, OK
+LibTest/core/Runes/length_A01_t02: Fail, OK
+
+# co19 issue #621: Undefined name 'runes'
+LibTest/core/Runes/isEmpty_A01_t02: Fail, OK
+LibTest/core/Runes/isNotEmpty_A01_t02: Fail, OK
+
+# co19 issue #622: Undefined class 'Int16List.fromList'
+LibTest/core/Runes/lastWhere_A02_t01: Fail, OK
+
+# co19 issue #623: main() { {}; } is block and empty statement, not a map
+Language/13_Statements/02_Expression_Statements_A01_t13: Fail, OK
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 5dcead1..8e0d9e1 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -23,7 +23,6 @@
 Language/09_Mixins/1_Mixin_Application_A01_t01: CompileTimeError # co19-roll r607: Please triage this failure
 LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: CompileTimeError # co19-roll r607: Please triage this failure
 LibTest/collection/LinkedList/first_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
-Language/12_Expressions/18_Assignment_A01_t07: RuntimeError # co19-roll r607: Please triage this failure
 Language/12_Expressions/18_Assignment_A04_t09: RuntimeError # co19-roll r607: Please triage this failure
 Language/13_Statements/04_Local_Function_Declaration_A04_t01: MissingCompileTimeError # co19-roll r607: Please triage this failure
 Language/13_Statements/02_Expression_Statements_A01_t13: MissingCompileTimeError # co19-roll r607: Please triage this failure
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 5da24a9..df86f4c 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -36,6 +36,7 @@
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: Fail # Issue 13652
 Language/07_Classes/6_Constructors_A02_t01: Fail # http://dartbug.com/5519
 Language/12_Expressions/01_Constants_A03_t01: Fail # Issue 13652
+Language/12_Expressions/18_Assignment_A01_t07: RuntimeError # Issue 13494
 Language/13_Statements/09_Switch_A02_t04: Fail # co19 issue 605
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: Fail # co19 issue 606
 
@@ -67,6 +68,12 @@
 LibTest/math/sin_A01_t01: Fail # Inherited from VM.
 LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
 LibTest/typed_data/Float32x4/clamp_A01_t01: RuntimeError # co19 Issue 600
+Language/05_Variables/05_Variables_A06_t01: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t02: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t03: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t04: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t05: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t06: CompileTimeError, OK # dartbug.com/12543
 
 
 [ $compiler == dart2dart && $system == windows ]
@@ -188,4 +195,4 @@
 LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
 LibTest/json/stringify_A03_t02: fail # co19-roll r587: Please triage this failure
 LibTest/json/printOn_A02_t01: fail # co19-roll r587: Please triage this failure
-LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
\ No newline at end of file
+LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 0021c0c..7af904e 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -161,6 +161,13 @@
 # can understand so he can file a bug later.
 #
 [ $compiler == dart2js ]
+Language/05_Variables/05_Variables_A06_t01: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t02: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t03: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t04: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t05: CompileTimeError, OK # dartbug.com/12543
+Language/05_Variables/05_Variables_A06_t06: CompileTimeError, OK # dartbug.com/12543
+
 Language/03_Overview/2_Privacy_A01_t09: RuntimeError, OK # co19 issue 198
 Language/03_Overview/2_Privacy_A01_t11: Pass, OK # co19 issue 316
 Language/06_Functions/4_External_Functions_A01_t01: CompileTimeError, OK # http://dartbug.com/5021
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 471d509..7affca6 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -2,6 +2,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+[ $compiler == none && $runtime == drt ]
+*: Skip # running co19 tests on content_shell would make our dartium cycle-times very long
+
 [ $compiler == none && $runtime == dartium ]
 Language/03_Overview/2_Privacy_A01_t06: Fail # Issue 13719: Please triage this failure.
 Language/05_Variables/05_Variables_A05_t01: Fail # Issue 13719: Please triage this failure.
@@ -24,6 +27,8 @@
 Language/12_Expressions/01_Constants_A16_t02: Fail # Issue 13719: Please triage this failure.
 Language/12_Expressions/01_Constants_A16_t04: Fail # Issue 13719: Please triage this failure.
 Language/12_Expressions/01_Constants_A16_t05: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/05_Strings_A02_t46: Fail # Issue 13719: Please triage this failure.
+Language/12_Expressions/05_Strings_A02_t48: Fail # Issue 13719: Please triage this failure.
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: Fail # Issue 13719: Please triage this failure.
 Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: Fail # Issue 13719: Please triage this failure.
 Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: Fail # Issue 13719: Please triage this failure.
@@ -77,6 +82,7 @@
 LibTest/core/double/floor_A01_t04: Fail # Issue 13719: Please triage this failure.
 LibTest/core/double/round_A01_t02: Fail # Issue 13719: Please triage this failure.
 LibTest/core/double/round_A01_t04: Fail # Issue 13719: Please triage this failure.
+LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Issue 13719: Please triage this failure.
 LibTest/core/int/toRadixString_A01_t01: Fail # Issue 13719: Please triage this failure.
 LibTest/core/Invocation/namedArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
 LibTest/core/Invocation/positionalArguments_A01_t01: Fail # co19-roll r607: Please triage this failure
@@ -111,7 +117,11 @@
 LibTest/isolate/IsolateSink/addError_A01_t02: Fail # Issue 13719: Please triage this failure.
 LibTest/isolate/IsolateStream/any_A02_t01: Fail # Issue 13719: Please triage this failure.
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 13719: Please triage this failure.
+LibTest/isolate/ReceivePort/toSendPort_A01_t02: Pass, Fail # Issue 13719: Please triage this failure.
 LibTest/isolate/SendPort/send_A01_t01: Fail # Issue 13719: Please triage this failure.
+LibTest/math/acos_A01_t01: Pass, Fail # Issue 13719: Please triage this failure.
+LibTest/math/asin_A01_t01: Pass, Fail # Issue 13719: Please triage this failure.
+LibTest/math/atan_A01_t01: Pass, Fail # Issue 13719: Please triage this failure.
 LibTest/typed_data/ByteData/elementSizeInBytes_A01_t01: Fail # Issue 13719: Please triage this failure.
 LibTest/typed_data/Float32x4/clamp_A01_t01: Fail # Issue 13719: Please triage this failure.
-LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # Issue 13719: Please triage this failure.
\ No newline at end of file
+LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 6796d88..0e1840f 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -74,6 +74,7 @@
 Language/12_Expressions/12_Instance_Creation/1_New_A09_t09: fail # Dart issue 1372
 Language/12_Expressions/12_Instance_Creation/2_Const_A10_t01: fail # co19 issue 525
 Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # Dart issue 12549
+Language/12_Expressions/18_Assignment_A01_t07: RuntimeError # Issue 13494
 Language/12_Expressions/30_Identifier_Reference_A08_t02: fail # Dart issue 12593
 Language/12_Expressions/32_Type_Test_A04_t02: fail # co19 issue 503
 Language/12_Expressions/32_Type_Test_A04_t03: fail # co19 issue 534
@@ -150,8 +151,3 @@
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
 
-[ $compiler == none && $runtime == vm && $mode == debug && $checked ]
-LibTest/collection/LinkedList/add_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/iterator_current_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/single_A01_t01: Pass, Crash # co19-roll r607: Please triage this failure
-
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 5469890..c57dfb3 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -179,8 +179,8 @@
 }
 
 testVariableDefinitions() {
-  testDart2Dart('main(){var x,y;final String s;}');
-  testDart2Dart('main(){final int x,y;final String s;}');
+  testDart2Dart('main(){var x,y;final String s=null;}');
+  testDart2Dart('main(){final int x=0,y=0;final String s=null;}');
   testDart2Dart('foo(f,g){}main(){foo(1,2);}');
   testDart2Dart('foo(f(arg)){}main(){foo(main);}');
   // A couple of static/finals inside a class.
@@ -205,7 +205,7 @@
 }
 
 testAbstractClass() {
-  testDart2Dart('main(){A.foo;}abstract class A{final static num foo;}');
+  testDart2Dart('main(){A.foo;}abstract class A{final static num foo=0;}');
 }
 
 testConflictSendsRename() {
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 0ebba79..2347825 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -33,12 +33,12 @@
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     diagnostics.sort();
     var expected = [
-        "memory:exporter.dart:43:47:Info: 'function(hest)' is defined here."
+        "memory:exporter.dart:43:47:Info: 'hest' is defined here."
         ":info",
-        "memory:library.dart:41:45:Info: 'function(hest)' is defined here."
+        "memory:library.dart:41:45:Info: 'hest' is defined here."
         ":info",
-        "memory:main.dart:0:22:Info: 'function(hest)' is imported here.:info",
-        "memory:main.dart:23:46:Info: 'function(hest)' is imported here.:info",
+        "memory:main.dart:0:22:Info: 'hest' is imported here.:info",
+        "memory:main.dart:23:46:Info: 'hest' is imported here.:info",
         "memory:main.dart:86:90:Error: Duplicate import of 'hest'.:error"
     ];
     Expect.listEquals(expected, diagnostics);
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 95c0e0d..ca31c6a 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -52,6 +52,11 @@
                 testOperatorsAssignability,
                 testFieldInitializers,
                 testTypeVariableExpressions,
+                testTypeVariableLookup1,
+                testTypeVariableLookup2,
+                testTypeVariableLookup3,
+                testFunctionTypeLookup,
+                testTypedefLookup,
                 testTypeLiteral,
                 testInitializers];
   for (Function test in tests) {
@@ -1074,6 +1079,121 @@
   analyzeIn(method, "{ T + 1; }", MessageKind.OPERATOR_NOT_FOUND);
 }
 
+void testTypeVariableLookup1() {
+  String script = """
+class Foo {
+  int field;
+  void method(int argument) {}
+  int operator +(Foo foo) {}
+  int get getter => 21;
+}
+
+class Test<S extends Foo, T> {
+  S s;
+  T t;
+  test() {}
+}
+""";
+
+  LibraryElement library = mockLibrary(compiler, script);
+  compiler.parseScript(script, library);
+  ClassElement classTest = library.find(const SourceString("Test"));
+  classTest.ensureResolved(compiler);
+  FunctionElement methodTest =
+    classTest.lookupLocalMember(const SourceString("test"));
+
+  test(String expression, [message]) {
+    analyzeIn(methodTest, "{ $expression; }", message);
+  }
+
+  test('s.field');
+  test('s.method(1)');
+  test('s + s');
+  test('s.getter');
+
+  test('t.toString');
+  test('t.field', MEMBER_NOT_FOUND);
+  test('t.method(1)', MessageKind.METHOD_NOT_FOUND);
+  test('t + t', MessageKind.OPERATOR_NOT_FOUND);
+  test('t.getter', MEMBER_NOT_FOUND);
+
+  test('s.field = "hest"', NOT_ASSIGNABLE);
+  test('s.method("hest")', NOT_ASSIGNABLE);
+  test('s + "hest"', NOT_ASSIGNABLE);
+  test('String v = s.getter', NOT_ASSIGNABLE);
+}
+
+void testTypeVariableLookup2() {
+  String script = """
+class Foo {
+  int field;
+  void method(int argument) {}
+  int operator +(Foo foo) {}
+  int get getter => 21;
+}
+
+class Test<S extends T, T extends Foo> {
+  S s;
+  test() {}
+}""";
+
+  LibraryElement library = mockLibrary(compiler, script);
+  compiler.parseScript(script, library);
+  ClassElement classTest = library.find(const SourceString("Test"));
+  classTest.ensureResolved(compiler);
+  FunctionElement methodTest =
+    classTest.lookupLocalMember(const SourceString("test"));
+
+  test(String expression, [message]) {
+    analyzeIn(methodTest, "{ $expression; }", message);
+  }
+
+  test('s.field');
+  test('s.method(1)');
+  test('s + s');
+  test('s.getter');
+}
+
+void testTypeVariableLookup3() {
+  String script = """
+class Test<S extends T, T extends S> {
+  S s;
+  test() {}
+}""";
+
+  LibraryElement library = mockLibrary(compiler, script);
+  compiler.parseScript(script, library);
+  ClassElement classTest = library.find(const SourceString("Test"));
+  classTest.ensureResolved(compiler);
+  FunctionElement methodTest =
+    classTest.lookupLocalMember(const SourceString("test"));
+
+  test(String expression, [message]) {
+    analyzeIn(methodTest, "{ $expression; }", message);
+  }
+
+  test('s.toString');
+  test('s.field', MEMBER_NOT_FOUND);
+  test('s.method(1)', MessageKind.METHOD_NOT_FOUND);
+  test('s + s', MessageKind.OPERATOR_NOT_FOUND);
+  test('s.getter', MEMBER_NOT_FOUND);
+}
+
+void testFunctionTypeLookup() {
+  analyze('(int f(int)) => f.toString;');
+  analyze('(int f(int)) => f.toString();');
+  analyze('(int f(int)) => f.foo;', MEMBER_NOT_FOUND);
+  analyze('(int f(int)) => f.foo();', MessageKind.METHOD_NOT_FOUND);
+}
+
+void testTypedefLookup() {
+  compiler.parseScript("typedef int F(int);");
+  analyze('(F f) => f.toString;');
+  analyze('(F f) => f.toString();');
+  analyze('(F f) => f.foo;', MEMBER_NOT_FOUND);
+  analyze('(F f) => f.foo();', MessageKind.METHOD_NOT_FOUND);
+}
+
 void testTypeLiteral() {
   final String source = r"""class Class {
                               static var field = null;
diff --git a/tests/compiler/dart2js_native/oddly_named_fields_test.dart b/tests/compiler/dart2js_native/oddly_named_fields_test.dart
index 6ade208..b2dae29 100644
--- a/tests/compiler/dart2js_native/oddly_named_fields_test.dart
+++ b/tests/compiler/dart2js_native/oddly_named_fields_test.dart
@@ -1369,7 +1369,7 @@
   if (object.yieldValue) throw 'incorrect value in "yieldValue"';
 }
 
-makeNativeClassWithOddNames() native;
+NativeClassWithOddNames makeNativeClassWithOddNames() native;
 
 setup() native """
 function NativeClassWithOddNames() {}
@@ -1378,7 +1378,7 @@
 
 main() {
   setup();
-  var object = new NativeClassWithOddNames();
+  var object = makeNativeClassWithOddNames();
   object.testMyFields();
   testObjectStronglyTyped(object);
   testObjectWeaklyTyped([object]);
diff --git a/tests/compiler/dart2js_native/subclassing_constructor_1_test.dart b/tests/compiler/dart2js_native/subclassing_constructor_1_test.dart
new file mode 100644
index 0000000..333a9f2
--- /dev/null
+++ b/tests/compiler/dart2js_native/subclassing_constructor_1_test.dart
@@ -0,0 +1,176 @@
+// 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 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper' show Creates, setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show
+    findInterceptorForType, findConstructorForWebComponentType;
+
+// Test that subclasses of native classes can be initialized by calling the
+// 'upgrade' constructor.
+
+var trace = [];
+
+var log;
+
+class A native "A" {
+  final a1 = log(101);  // Only initialized IF named constructor called.
+  final a2;             // Initialized by native constructor.
+  final a3;             // Initialized only by A.two.
+  var a4 = log(104);
+
+  A.one();
+
+  A.two() : a3 = log(103) {
+    log('body(A.two)');
+    log(a4 += increment);
+  }
+
+  A.three(x, this.a4) {
+    log('body(A.three)');
+    log(a4 = '($a4, $x)');
+  }
+
+  get increment => 10;
+}
+
+class B extends A {
+  final b1;
+  final b2 = log(202);
+  var b3;
+
+  B.one() : super.one();
+
+  B.two() : b1 = log(201), super.two(), b3 = log(203) {
+    log('body(B.two)');
+  }
+
+  B.three([x]) : super.three(205, x);
+
+  get increment => 20;
+}
+
+
+makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() native r"""
+function B() { this.a2 = 102; }
+
+makeB = function(){return new B;};
+
+getBPrototype = function(){return B.prototype;};
+""";
+
+
+test_one() {
+  trace = [];
+  var constructor = findConstructorForWebComponentType(B, 'one');
+  Expect.isNotNull(constructor);
+  Expect.isNull(findConstructorForWebComponentType(B, 'Missing'));
+
+  var b = makeB();
+  Expect.isTrue(b is B);
+  // Call constructor to initialize native object.
+  var b2 = JS('', '#(#)', constructor, b);
+  Expect.identical(b, b2);
+  Expect.isTrue(b is B);
+
+  Expect.equals(101, b.a1);
+  Expect.equals(102, b.a2);
+  Expect.equals(null, b.a3);
+  Expect.equals(104, b.a4);
+  Expect.equals(null, b.b1);
+  Expect.equals(202, b.b2);
+  Expect.equals(null, b.b3);
+
+  Expect.equals('[202, 101, 104]', '$trace');
+}
+
+test_two() {
+  trace = [];
+  var constructor = findConstructorForWebComponentType(B, 'two');
+  Expect.isNotNull(constructor);
+
+  var b = makeB();
+  Expect.isTrue(b is B);
+  // Call constructor to initialize native object.
+  JS('', '#(#)', constructor, b);
+  Expect.isTrue(b is B);
+
+  Expect.equals(101, b.a1);
+  Expect.equals(102, b.a2);
+  Expect.equals(103, b.a3);
+  Expect.equals(124, b.a4);
+  Expect.equals(201, b.b1);
+  Expect.equals(202, b.b2);
+  Expect.equals(203, b.b3);
+
+  Expect.equals(
+      '[202, 201, 101, 104, 103, 203, body(A.two), 124, body(B.two)]',
+      '$trace');
+}
+
+test_three() {
+  trace = [];
+  var constructor = findConstructorForWebComponentType(B, 'three');
+  Expect.isNotNull(constructor);
+
+  var b = makeB();
+  Expect.isTrue(b is B);
+  // Call constructor to initialize native object.
+  //
+  // Since the constructor takes some optional arguments that are not passed, it
+  // is as though the web components runtime explicitly passed `null` for all
+  // parameters.
+  //
+  // TODO(sra): The constructor returned by findConstructorForWebComponentType
+  // should be a function that fills in the default values.
+  JS('', '#(#)', constructor, b);
+  Expect.isTrue(b is B);
+
+  Expect.equals(101, b.a1);
+  Expect.equals(102, b.a2);
+  Expect.equals(null, b.a3);
+  Expect.equals('(null, 205)', b.a4);
+  Expect.equals(null, b.b1);
+  Expect.equals(202, b.b2);
+  Expect.equals(null, b.b3);
+  print(trace);
+  Expect.equals('[202, 101, 104, body(A.three), (null, 205)]', '$trace');
+}
+
+test_new() {
+  trace = [];
+  checkThrows(action, description) {
+    Expect.throws(action, (e) => true, "'$description must fail'");
+  }
+
+  checkThrows(() => new B.one(), 'new B.one()');
+  checkThrows(() => new B.two(), 'new B.two()');
+  checkThrows(() => new B.three(), 'new B.three()');
+  checkThrows(() => new B.three(1), 'new B.three(1)');
+  checkThrows(() => new B.three([]), 'new B.three([])');
+}
+
+var inscrutable;
+
+main() {
+  setup();
+  inscrutable = (x) => x;
+  log = (message) {
+    trace.add('$message');
+    return message;
+  };
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  test_one();
+  test_two();
+  test_three();
+  test_new();
+}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 7902d5a..61892e6 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -48,6 +48,7 @@
 date_time7_test: Fail # BUG(3304): Maybe this doesn't time out?
 string_base_vm_test: Fail # BUG(3304): Maybe this doesn't time out?
 list_test: Fail # IE doesn't support typed data.
+shuffle_test: Fail # IE doesn't support typed data.
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 list_as_map_test: Pass, Slow # TODO(kasperl): Please triage.
diff --git a/tests/corelib/hashcode_boxed_test.dart b/tests/corelib/hashcode_boxed_test.dart
new file mode 100644
index 0000000..6b1d44c
--- /dev/null
+++ b/tests/corelib/hashcode_boxed_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+double fib(double n) {
+  return n <= 1.0 ? 1.0 : fib(n-1) + fib(n-2);
+}
+
+main() {
+  // Compute the same value in a way that won't be optimized away so the results
+  // are different objects in memory.
+  var a = fib(5.0) + 1.0;
+  var b = fib(4.0) + 4.0;
+
+  Expect.isTrue(identical(a, b));
+  Expect.equals(identityHashCode(a), identityHashCode(b));
+  Expect.equals(a, b);
+  Expect.equals(a.hashCode, b.hashCode);
+}
diff --git a/tests/corelib/shuffle_test.dart b/tests/corelib/shuffle_test.dart
new file mode 100644
index 0000000..786dc91
--- /dev/null
+++ b/tests/corelib/shuffle_test.dart
@@ -0,0 +1,92 @@
+// 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.
+
+// Dart test for List.shuffle.
+library shuffle_test;
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
+main() {
+  List mkList(int n) => new List.generate(n, (x) => x);
+
+  for (int size in [0, 1, 2, 3, 7, 15, 99, 1023]) {
+    List numbers = new List.generate(size, (x) => x);
+    testShuffle(numbers.toList(growable: true));
+    testShuffle(numbers.toList(growable: false));
+    testShuffle(new Uint32List(size)..setAll(0, numbers));
+    testShuffle(new Int32List(size)..setAll(0, numbers));
+    testShuffle(new Uint16List(size)..setAll(0, numbers));
+    testShuffle(new Int16List(size)..setAll(0, numbers));
+    // Some numbers will be truncated in the following two.
+    testShuffle(new Uint8List(size)..setAll(0, numbers));
+    testShuffle(new Int8List(size)..setAll(0, numbers));
+    testShuffle(numbers.map((x) => "$x").toList());
+  }
+
+  // Check that it actually can keep the same list (regression test).
+  List l = [1, 2];
+  success: {
+    for (int i = 0; i < 266; i++) {
+      int first = l.first;
+      l.shuffle();
+      if (l.first == first) break success;  // List didn't change.
+    }
+    // Chance of changing 266 times in a row should be < 1:1e80.
+    Expect.fail("List changes every time.");
+  }
+}
+
+void testShuffle(list) {
+  List copy = list.toList();
+  list.shuffle();
+  if (list.length < 2) {
+    Expect.listEquals(copy, list);
+    return;
+  }
+  // Test that the list after shuffling has the same elements as before,
+  // without considering order.
+  Map seen = {};
+  for (var e in list) {
+    seen[e] = seen.putIfAbsent(e, () => 0) + 1;
+  }
+  for (var e in copy) {
+    int remaining = seen[e];
+    remaining -= 1;  // Throws if e was not in map at all.
+    if (remaining == 0) {
+      seen.remove(e);
+    } else {
+      seen[e] = remaining;
+    }
+  }
+  Expect.isTrue(seen.isEmpty);
+  // Test that shuffle actually does make a change. Repeat until the probability
+  // of a proper shuffling hitting the same list again is less than 10^80
+  // (arbitrary bignum - approx. number of elemental particles in the universe).
+  //
+  // The probablility of shuffling a list of length n into the same list is
+  // 1/n!. If one shuffle didn't change the list, repeat shuffling until
+  // probability of randomly hitting the same list every time is less than
+  // 1/1e80.
+
+  bool listsDifferent() {
+    for (int i = 0; i < list.length; i++) {
+      if (list[i] != copy[i]) return true;
+    }
+    return false;
+  }
+  if (list.length < 59) {  // 59! > 1e80.
+    double limit = 1e80;
+    double fact = 1.0;
+    for (int i = 2; i < list.length; i++) fact *= i;
+    double combos = fact;
+
+    while (!listsDifferent() && combos < limit) {
+      list.shuffle();
+      combos *= fact;
+    }
+  }
+  if (!listsDifferent()) {
+    Expect.fail("Didn't shuffle at all, p < 1:1e80: $list");
+  }
+}
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart
index b10756f..da9338b 100644
--- a/tests/html/canvasrenderingcontext2d_test.dart
+++ b/tests/html/canvasrenderingcontext2d_test.dart
@@ -363,7 +363,7 @@
       var img = new ImageElement();
 
       img.onLoad.listen(expectAsync1((_) {
-        context.drawImageToRect(img, new Rect(50, 50, 20, 20));
+        context.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
 
         expectPixelFilled(50, 50);
         expectPixelFilled(55, 55);
@@ -393,8 +393,8 @@
         // This will take a 6x6 square from the first canvas from position 2,2
         // and then scale it to a 20x20 square and place it to the second
         // canvas at 50,50.
-        context.drawImageToRect(img, new Rect(50, 50, 20, 20),
-          sourceRect: new Rect(2, 2, 6, 6));
+        context.drawImageToRect(img, new Rectangle(50, 50, 20, 20),
+          sourceRect: new Rectangle(2, 2, 6, 6));
 
         checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
         checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
@@ -511,7 +511,7 @@
 
     test('with 5 params', () {
       video.onCanPlay.listen(expectAsync1((_) {
-        context.drawImageToRect(video, new Rect(50, 50, 20, 20));
+        context.drawImageToRect(video, new Rectangle(50, 50, 20, 20));
 
         expectPixelFilled(50, 50);
         expectPixelFilled(55, 55);
@@ -541,8 +541,8 @@
 
     test('with 9 params', () {
       video.onCanPlay.listen(expectAsync1((_) {
-        context.drawImageToRect(video, new Rect(50, 50, 20, 20),
-          sourceRect: new Rect(2, 2, 6, 6));
+        context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
+          sourceRect: new Rectangle(2, 2, 6, 6));
 
         expectPixelFilled(50, 50);
         expectPixelFilled(55, 55);
@@ -579,8 +579,8 @@
       video = new VideoElement();
       canvas = new CanvasElement();
       video.onCanPlay.listen(expectAsync1((_) {
-        context.drawImageToRect(video, new Rect(50, 50, 20, 20),
-          sourceRect: new Rect(2, 2, 6, 6));
+        context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
+          sourceRect: new Rectangle(2, 2, 6, 6));
 
         expectPixelFilled(50, 50);
         expectPixelFilled(55, 55);
@@ -626,7 +626,7 @@
     });
     test('with 5 params', () {
       // Draw an image to the canvas from a canvas element.
-      context.drawImageToRect(otherCanvas, new Rect(50, 50, 20, 20));
+      context.drawImageToRect(otherCanvas, new Rectangle(50, 50, 20, 20));
 
       expectPixelFilled(50, 50);
       expectPixelFilled(55, 55);
@@ -641,8 +641,8 @@
       // Draw an image to the canvas from a canvas element.
       otherContext.fillStyle = "blue";
       otherContext.fillRect(5, 5, 5, 5);
-      context.drawImageToRect(otherCanvas, new Rect(50, 50, 20, 20),
-          sourceRect: new Rect(2, 2, 6, 6));
+      context.drawImageToRect(otherCanvas, new Rectangle(50, 50, 20, 20),
+          sourceRect: new Rectangle(2, 2, 6, 6));
 
       checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
       checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
diff --git a/tests/html/client_rect_test.dart b/tests/html/client_rect_test.dart
index 76751da..9bc233f 100644
--- a/tests/html/client_rect_test.dart
+++ b/tests/html/client_rect_test.dart
@@ -6,7 +6,7 @@
 main() {
 
   var isRectList =
-      predicate((x) => x is List<Rect>, 'is a List<Rect>');
+      predicate((x) => x is List<Rectangle>, 'is a List<Rectangle>');
 
   insertTestDiv() {
     var element = new Element.tag('div');
diff --git a/tests/html/custom/attribute_changed_callback_test.dart b/tests/html/custom/attribute_changed_callback_test.dart
index 3a9271a..1bcc453 100644
--- a/tests/html/custom/attribute_changed_callback_test.dart
+++ b/tests/html/custom/attribute_changed_callback_test.dart
@@ -92,6 +92,8 @@
 
   group('unsupported_on_polyfill', () {
     test('add, change ID', () {
+      B.invocations = [];
+
       var b = new B();
       b.id = 'x';
       expect(B.invocations, ['created', 'id: null => x']);
diff --git a/tests/html/custom/entered_left_view_test.dart b/tests/html/custom/entered_left_view_test.dart
index a523854..19899ff 100644
--- a/tests/html/custom/entered_left_view_test.dart
+++ b/tests/html/custom/entered_left_view_test.dart
@@ -127,14 +127,13 @@
           'document without a view');
     });
 
-    /*
     test('Attribute changed in document without a view', () {
       a.setAttribute('data-foo', 'bar');
       expect(invocations, ['attribute changed'],
           reason: 'changing an attribute should invoke the callback, even in a '
           'document without a view');
     });
-    */
+
     test('Entered document with a view', () {
       document.body.append(a);
       customElementsTakeRecords();
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 42015fd..58b0fe0 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -10,7 +10,7 @@
 import 'dart:svg' as svg;
 import 'utils.dart';
 
-expectLargeRect(Rect rect) {
+expectLargeRect(Rectangle rect) {
   expect(rect.top, 0);
   expect(rect.left, 0);
   expect(rect.width, greaterThan(100));
diff --git a/tests/html/html.status b/tests/html/html.status
index 5db1caa..cfc5b61 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -28,7 +28,6 @@
 # postMessage in dartium always transfers the typed array buffer, never a view
 postmessage_structured_test/typed_arrays: Fail
 xhr_test: Pass, Fail # Issue 12648
-custom/attribute_changed_callback_test: Fail # 12643
 xhr_test/json: Fail # Issue 13069
 uri_test: Fail Issue 13581
 async_test: Fail # Background timers not implemented.
@@ -404,3 +403,25 @@
 
 [ $compiler == dart2js && $runtime == drt ]
 wheelevent_test: Fail # http://dartbug.com/12958
+
+[ $compiler == none && $runtime == dartium ]
+async_test: Timeout # Issue 13719: Please triage this failure.
+custom/attribute_changed_callback_test/fully_supported: Fail # Issue 13719: Please triage this failure.
+custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Issue 13719: Please triage this failure.
+custom/constructor_calls_created_synchronously_test: Fail # Issue 13719: Please triage this failure.
+custom/created_callback_test: Fail # Issue 13719: Please triage this failure.
+custom/document_register_basic_test: Fail # Issue 13719: Please triage this failure.
+custom/document_register_type_extensions_test/construction: Fail # Issue 13719: Please triage this failure.
+custom/document_register_type_extensions_test/namespaces: Fail # Issue 13719: Please triage this failure.
+custom/document_register_type_extensions_test/parsing: Fail # Issue 13719: Please triage this failure.
+custom_elements_test/innerHtml: Fail # Issue 13719: Please triage this failure.
+custom_elements_test/lifecycle: Fail # Issue 13719: Please triage this failure.
+custom_elements_test/mixins: Fail # Issue 13719: Please triage this failure.
+custom_elements_test/register: Fail # Issue 13719: Please triage this failure.
+custom/entered_left_view_test/disconnected_subtree: Fail # Issue 13719: Please triage this failure.
+custom/entered_left_view_test/shadow_dom: Fail # Issue 13719: Please triage this failure.
+custom/entered_left_view_test/standard_events: Fail # Issue 13719: Please triage this failure.
+custom/entered_left_view_test/viewless_document: Fail # Issue 13719: Please triage this failure.
+dromaeo_smoke_test: Fail # Issue 13719: Please triage this failure.
+element_offset_test/offset: Fail # Issue 13719: Please triage this failure.
+touchevent_test/supported: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/html/rect_test.dart b/tests/html/rect_test.dart
deleted file mode 100644
index 8b52f61..0000000
--- a/tests/html/rect_test.dart
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library rect_test;
-
-import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-
-main() {
-  useHtmlConfiguration();
-
-  Rect createRect(List<num> a) {
-    return a != null ? new Rect(a[0], a[1], a[2] - a[0], a[3] - a[1]) : null;
-  }
-
-  test('construction', () {
-    var r0 = new Rect(10, 20, 30, 40);
-    expect(r0.toString(), '(10, 20, 30, 40)');
-    expect(r0.right, 40);
-    expect(r0.bottom, 60);
-
-    var r1 = new Rect.fromPoints(r0.topLeft, r0.bottomRight);
-    expect(r1, r0);
-
-    var r2 = new Rect.fromPoints(r0.bottomRight, r0.topLeft);
-    expect(r2, r0);
-  });
-
-  test('intersection', () {
-    var tests = [
-        [[10, 10, 20, 20], [15, 15, 25, 25], [15, 15, 20, 20]],
-        [[10, 10, 20, 20], [20, 0, 30, 10], [20, 10, 20, 10]],
-        [[0, 0, 1, 1], [10, 11, 12, 13], null],
-        [[11, 12, 98, 99], [22, 23, 34, 35], [22, 23, 34, 35]]];
-
-    for (var test in tests) {
-      var r0 = createRect(test[0]);
-      var r1 = createRect(test[1]);
-      var expected = createRect(test[2]);
-
-      expect(r0.intersection(r1), expected);
-      expect(r1.intersection(r0), expected);
-    }
-  });
-
-  test('intersects', () {
-    var r0 = new Rect(10, 10, 20, 20);
-    var r1 = new Rect(15, 15, 25, 25);
-    var r2 = new Rect(0, 0, 1, 1);
-
-    expect(r0.intersects(r1), isTrue);
-    expect(r1.intersects(r0), isTrue);
-
-    expect(r0.intersects(r2), isFalse);
-    expect(r2.intersects(r0), isFalse);
-  });
-
-  test('union', () {
-    var tests = [
-        [[10, 10, 20, 20], [15, 15, 25, 25], [10, 10, 25, 25]],
-        [[10, 10, 20, 20], [20, 0, 30, 10], [10, 0, 30, 20]],
-        [[0, 0, 1, 1], [10, 11, 12, 13], [0, 0, 12, 13]],
-        [[11, 12, 98, 99], [22, 23, 34, 35], [11, 12, 98, 99]]];
-
-    for (var test in tests) {
-      var r0 = createRect(test[0]);
-      var r1 = createRect(test[1]);
-      var expected = createRect(test[2]);
-
-      expect(r0.union(r1), expected);
-      expect(r1.union(r0), expected);
-    }
-  });
-
-  test('containsRect', () {
-    var r = new Rect(-10, 0, 20, 10);
-    expect(r.containsRect(r), isTrue);
-
-    expect(r.containsRect(
-        new Rect(double.NAN, double.NAN, double.NAN, double.NAN)), isFalse);
-
-    var r2 = new Rect(0, 2, 5, 5);
-    expect(r.containsRect(r2), isTrue);
-    expect(r2.containsRect(r), isFalse);
-
-    r2 = new Rect(-11, 2, 5, 5);
-    expect(r.containsRect(r2), isFalse);
-    r2 = new Rect(0, 2, 15, 5);
-    expect(r.containsRect(r2), isFalse);
-    r2 = new Rect(0, 2, 5, 10);
-    expect(r.containsRect(r2), isFalse);
-    r2 = new Rect(0, 0, 5, 10);
-    expect(r.containsRect(r2), isTrue);
-  });
-
-  test('containsPoint', () {
-    var r = new Rect(20, 40, 60, 80);
-
-    // Test middle.
-    expect(r.containsPoint(new Point(50, 80)), isTrue);
-
-    // Test edges.
-    expect(r.containsPoint(new Point(20, 40)), isTrue);
-    expect(r.containsPoint(new Point(50, 40)), isTrue);
-    expect(r.containsPoint(new Point(80, 40)), isTrue);
-    expect(r.containsPoint(new Point(80, 80)), isTrue);
-    expect(r.containsPoint(new Point(80, 120)), isTrue);
-    expect(r.containsPoint(new Point(50, 120)), isTrue);
-    expect(r.containsPoint(new Point(20, 120)), isTrue);
-    expect(r.containsPoint(new Point(20, 80)), isTrue);
-
-    // Test outside.
-    expect(r.containsPoint(new Point(0, 0)), isFalse);
-    expect(r.containsPoint(new Point(50, 0)), isFalse);
-    expect(r.containsPoint(new Point(100, 0)), isFalse);
-    expect(r.containsPoint(new Point(100, 80)), isFalse);
-    expect(r.containsPoint(new Point(100, 160)), isFalse);
-    expect(r.containsPoint(new Point(50, 160)), isFalse);
-    expect(r.containsPoint(new Point(0, 160)), isFalse);
-    expect(r.containsPoint(new Point(0, 80)), isFalse);
-  });
-
-  test('ceil', () {
-    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
-    expect(rect.ceil(), new Rect(12.0, 27.0, 18.0, 10.0));
-  });
-
-  test('floor', () {
-    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
-    expect(rect.floor(), new Rect(11.0, 26.0, 17.0, 9.0));
-  });
-
-  test('round', () {
-    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
-    expect(rect.round(), new Rect(11.0, 27.0, 18.0, 9.0));
-  });
-
-  test('toInt', () {
-    var rect = new Rect(11.4, 26.6, 17.8, 9.2);
-    var b = rect.toInt();
-    expect(b, new Rect(11, 26, 17, 9));
-
-    expect(b.left is int, isTrue);
-    expect(b.top is int, isTrue);
-    expect(b.width is int, isTrue);
-    expect(b.height is int, isTrue);
-  });
-
-  test('hashCode', () {
-    var a = new Rect(0, 1, 2, 3);
-    var b = new Rect(0, 1, 2, 3);
-    expect(a.hashCode, b.hashCode);
-
-    var c = new Rect(1, 0, 2, 3);
-    expect(a.hashCode == c.hashCode, isFalse);
-  });
-}
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index 1dad882..7ab3d5138 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -426,7 +426,7 @@
   });
 
   group('getBoundingClientRect', () {
-    test('is a Rect', () {
+    test('is a Rectangle', () {
       var element = new svg.RectElement();
       element.attributes['width'] = '100';
       element.attributes['height'] = '100';
@@ -436,7 +436,7 @@
       document.body.append(root);
 
       var rect = element.getBoundingClientRect();
-      expect(rect is Rect, isTrue);
+      expect(rect is Rectangle, isTrue);
       expect(rect.width, closeTo(100, 1));
       expect(rect.height, closeTo(100, 1));
     });
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index a74948a..50b8d2a 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -103,4 +103,8 @@
 spawn_uri_multi_test/none: RuntimeError # http://dartbug.com/13544
 
 [ $compiler == none && $runtime == dartium ]
+cross_isolate_message_stream_test: Fail # Issue 13719: Please triage this failure.
 global_error_handler2_test: Fail # Issue 13719: Please triage this failure.
+global_error_handler_stream2_test: Fail # Issue 13719: Please triage this failure.
+nested_spawn_stream2_test: Fail # Issue 13719: Please triage this failure.
+
diff --git a/tests/language/compile_time_constant_test.dart b/tests/language/compile_time_constant_test.dart
index 53e9198..ae3333d 100644
--- a/tests/language/compile_time_constant_test.dart
+++ b/tests/language/compile_time_constant_test.dart
@@ -4,7 +4,7 @@
 
 class Bad {
   int foo;
-  const int bar =
+  final int bar =
       foo /// 01: compile-time error
       -1;
   static const int toto =
diff --git a/tests/language/const_escape_frog_test.dart b/tests/language/const_escape_frog_test.dart
index ea39cc3..1cb6cd2 100644
--- a/tests/language/const_escape_frog_test.dart
+++ b/tests/language/const_escape_frog_test.dart
@@ -7,7 +7,7 @@
 import "package:expect/expect.dart";
 
 class Foo {
-  const Bar<Foo> bar = const Bar/* comment here use to trigger bug 323 */();
+  final Bar<Foo> bar = const Bar/* comment here use to trigger bug 323 */();
 }
 
 class Bar<T extends Foo> {
diff --git a/tests/language/duplicate_export_liba.dart b/tests/language/duplicate_export_liba.dart
new file mode 100644
index 0000000..7b68d42
--- /dev/null
+++ b/tests/language/duplicate_export_liba.dart
@@ -0,0 +1,7 @@
+// 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 export_liba;
+
+export 'duplicate_import_liba.dart';
diff --git a/tests/language/duplicate_export_test.dart b/tests/language/duplicate_export_test.dart
new file mode 100644
index 0000000..239de6a
--- /dev/null
+++ b/tests/language/duplicate_export_test.dart
@@ -0,0 +1,14 @@
+// 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 it is not a compile-time error to reexport the same elements
+// through different paths.
+
+library duplicate_export_test;
+
+export 'duplicate_import_liba.dart';
+export 'duplicate_export_liba.dart'; // reexports 'duplicate_import_liba.dart'.
+
+void main() {
+}
\ No newline at end of file
diff --git a/tests/language/issue13474_test.dart b/tests/language/issue13474_test.dart
new file mode 100644
index 0000000..f35f5b6
--- /dev/null
+++ b/tests/language/issue13474_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.
+// VMOptions=--enable_type_checks
+
+import "package:expect/expect.dart";
+
+main() {
+  var a;
+  Expect.throws(() { true && (a = 5); }, (error) => error is TypeError);
+  Expect.throws(() { (a = 5) && true; }, (error) => error is TypeError);
+  Expect.throws(() { false || (a = 5); }, (error) => error is TypeError);
+  Expect.throws(() { (a = 5) || false; }, (error) => error is TypeError);
+  Expect.throws(() { (a = 5) || true; }, (error) => error is TypeError);
+
+  // No exceptions thrown.
+  false && (a = 5);
+  true || (a = 5);
+}
+
diff --git a/tests/language/language.status b/tests/language/language.status
index bd6e7e2..bc2c98c 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -55,6 +55,7 @@
 compile_time_constant_checked3_test/06: Fail, OK
 
 [ $runtime == vm || ($runtime == drt && $compiler == none) ]
+regress_13494_test: Fail # Issue 13494
 first_class_types_literals_test: Fail # issue 11761
 call_test: Fail # Issue 12602
 dynamic_prefix_core_test: Fail # Issue 12478
@@ -86,3 +87,7 @@
 positional_parameters_type_test/02: Fail # Issue 13719: Please triage this failure.
 type_checks_in_factory_method_test: Fail # Issue 13719: Please triage this failure.
 vm/type_vm_test: Fail # Issue 13719: Please triage this failure.
+
+
+[ $compiler == none && $runtime == dartium ]
+regress_13494_test: Fail # Issue 13719: Please triage this failure.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 536168e..34ee194 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -64,10 +64,6 @@
 final_syntax_test/02: Fail # Issue 11124
 final_syntax_test/03: Fail # Issue 11124
 
-# Test issue 11123, Only static fields can be declared as 'const'
-const_escape_frog_test: fail
-compile_time_constant_test/none: fail
-
 # Test issue 11545, using not existing constructor name in annotation
 metadata_test: fail
 
@@ -189,6 +185,9 @@
 static_field_test/03: fail # Issue 12541
 static_field_test/04: fail # Issue 12541
 
+# test issue 13787; duplicate exports of the same declaration is not handled
+duplicate_export_test: fail # Issue 13787
+
 [ $compiler == dartanalyzer && $checked ]
 factory1_test/00: fail
 factory1_test/01: fail
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 17a459a..1bb5a27 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -75,10 +75,6 @@
 final_syntax_test/02: Fail # Issue 11124
 final_syntax_test/03: Fail # Issue 11124
 
-# Test issue 11123, Only static fields can be declared as 'const'
-const_escape_frog_test: fail
-compile_time_constant_test/none: fail
-
 # Test issue 11545, using not existing constructor name in annotation
 metadata_test: fail
 
@@ -200,6 +196,9 @@
 static_field_test/03: fail # Issue 12541
 static_field_test/04: fail # Issue 12541
 
+# test issue 13787; duplicate exports of the same declaration is not handled
+duplicate_export_test: fail # Issue 13787
+
 [ $compiler == dart2analyzer && $checked ]
 factory1_test/00: fail
 factory1_test/01: fail
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 87857b1..1c1f692 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -66,6 +66,7 @@
 named_parameters_type_test/03: MissingRuntimeError, OK
 positional_parameters_type_test/01: MissingRuntimeError, OK
 positional_parameters_type_test/02: MissingRuntimeError, OK
+issue13474_test: RuntimeError, OK
 
 [ $compiler == dart2js && $minified ]
 f_bounded_quantification4_test: Fail # Issue 12605.
@@ -156,11 +157,6 @@
 bit_operations_test: RuntimeError, OK # Issue 1533
 expect_test: RuntimeError, OK # Issue 13080
 
-final_syntax_test/01: MissingCompileTimeError # Issue 13020
-final_syntax_test/02: MissingCompileTimeError # Issue 13020
-final_syntax_test/03: MissingCompileTimeError # Issue 13020
-final_syntax_test/04: MissingCompileTimeError # Issue 13020
-
 null_test/none: RuntimeError  # Issue 12482
 
 
@@ -244,10 +240,6 @@
 
 constructor9_test/01: Fail # Issue 12935
 constructor_named_arguments_test/01: Fail # Issue 5519
-final_syntax_test/01: Fail # Issue 13020
-final_syntax_test/02: Fail # Issue 13020
-final_syntax_test/03: Fail # Issue 13020
-final_syntax_test/04: Fail # Issue 13020
 named_parameters_aggregated_test/03: Fail # Issue 12813
 not_enough_positional_arguments_test/01: Fail # Issue 12839
 not_enough_positional_arguments_test/02: Fail # Issue 12839
diff --git a/tests/language/regress_13494_test.dart b/tests/language/regress_13494_test.dart
new file mode 100644
index 0000000..aaf975a
--- /dev/null
+++ b/tests/language/regress_13494_test.dart
@@ -0,0 +1,25 @@
+// 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. Test that the argument to an unresolved static
+// getter is only evaluated once.
+
+import "package:expect/expect.dart";
+
+int i = 0;
+
+p(x) => i++;
+
+class A {}
+
+main() {
+  bool caught = false;
+  try {
+    A.unknown = p(2);
+  } catch (_) {
+    caught = true;
+  }
+  Expect.isTrue(caught);
+  Expect.equals(1, i);
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 61ba7ee..763dde2 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -7,11 +7,16 @@
 math/low_test: RuntimeError
 math/random_test: RuntimeError
 mirrors/closure_mirror_find_in_context_test: Fail # Issue 6490
+mirrors/constructor_kinds_test: RuntimeError # Issue 13799
 mirrors/equality_test/02: RuntimeError # Issue 12333
 mirrors/fake_function_test: RuntimeError # Issue 11612
 mirrors/function_type_mirror_test: RuntimeError # Issue 12166
-mirrors/generics_test/01: RuntimeError # Issue 12333
+mirrors/generics_test/01: RuntimeError # Issue 12087
+mirrors/generic_function_typedef_test: RuntimeError # Issue 12333
+mirrors/generic_mixin_applications_test: RuntimeError # Issue 12333
+mirrors/generics_substitution_test: RuntimeError # Issue 12087
 mirrors/hierarchy_invariants_test: RuntimeError # Issue 11863
+mirrors/initializing_formals_test: CompileTimeError # Issue 12164
 mirrors/invoke_test: RuntimeError # Issue 11954
 mirrors/invoke_closurization_test: RuntimeError # Issue 13002
 mirrors/invoke_named_test/none: RuntimeError # Issue 12863
@@ -29,6 +34,7 @@
 mirrors/parameter_test/none: RuntimeError # Issue 6490
 mirrors/parameter_metadata_test: CompileTimeError # Issue 10905
 mirrors/reflected_type_test: RuntimeError # Issue 12607
+mirrors/type_argument_is_type_variable_test: RuntimeError # Issue 12333
 mirrors/typedef_metadata_test: RuntimeError # Issue 12785
 mirrors/typevariable_mirror_metadata_test: CompileTimeError # Issue 10905
 mirrors/unnamed_library_test: RuntimeError # Issue 10580
@@ -120,6 +126,7 @@
 convert/streamed_conversion_json_utf8_decode_test: Pass, Timeout # Issue 12029
 async/deferred/deferred_api_test: Pass, Timeout # http://dartbug.com/12635
 convert/streamed_conversion_utf8_decode_test: Pass, Timeout # http://dartbug.com/12768
+convert/utf85_test: Skip # Issue 12029.
 
 [ $compiler == dart2js ]
 typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
@@ -144,6 +151,13 @@
 mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
 mirrors/closures_test/01: Fail, OK # Incorrect dart2js behavior.
 
+mirrors/constructor_kinds_test: RuntimeError # Issue 13798
+mirrors/generics_substitution_test: RuntimeError # Issue 13808
+mirrors/initializing_formals_test/01: RuntimeError # Issue 11281
+mirrors/generic_function_typedef_test: RuntimeError # Issue 12282
+mirrors/generic_mixin_applications_test: RuntimeError # Issue 12282
+mirrors/type_argument_is_type_variable_test: RuntimeError # Issue 12282
+
 [ $compiler == none && $runtime == drt ]
 async/timer_isolate_test: Skip # See Issue 4997
 async/timer_not_available_test: Skip # only meant to test when there is no way to
@@ -162,6 +176,7 @@
 
 [ $arch == simarm ]
 convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12644.
+convert/utf85_test: Pass, Slow # Issue 12644.
 
 [ $compiler == none && $runtime == drt ]
 async/run_zoned6_test/01: fail # Issue 12756.
@@ -174,11 +189,6 @@
 mirrors/generics_test/none: Fail # Issue 13432
 mirrors/invoke_named_test/none: Fail # http://dartbug.com/13612
 
-mirrors/parameter_metadata_test: Fail # Issue 13510
-mirrors/method_mirror_returntype_test: Fail # Issue 13510
-mirrors/function_type_mirror_test: Fail # Issue 13510
-mirrors/typevariable_mirror_metadata_test: Fail # Issue 13510
-
 [ $compiler == dart2analyzer ]
 mirrors/typedef_test/none: Fail # Issue 13093
 mirrors/generics_test/none: Fail # Issue 13432
@@ -200,3 +210,7 @@
 mirrors/local_isolate_test: Fail # Issue 13719: Please triage this failure.
 mirrors/mixin_test/01: Fail # Issue 13719: Please triage this failure.
 mirrors/typedef_test/01: Fail # Issue 13719: Please triage this failure.
+
+[ $compiler == none && $runtime == dartium ]
+async/timer_isolate_test: Fail # Issue 13719: Please triage this failure.
+async/run_async5_test: Pass, Timeout  # Issue 13719: Please triage this failure.
diff --git a/tests/html/point_test.dart b/tests/lib/math/point_test.dart
similarity index 61%
rename from tests/html/point_test.dart
rename to tests/lib/math/point_test.dart
index ef1fe5a..f15c635 100644
--- a/tests/html/point_test.dart
+++ b/tests/lib/math/point_test.dart
@@ -4,46 +4,43 @@
 
 library point_test;
 
-import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:math';
+import 'package:unittest/unittest.dart';
 
 main() {
-  useHtmlConfiguration();
-
   test('constructor', () {
     var point = new Point();
     expect(point.x, 0);
     expect(point.y, 0);
-    expect('$point', '(0, 0)');
+    expect('$point', 'Point(0, 0)');
   });
 
   test('constructor X', () {
-    var point = new Point(10);
+    var point = new Point<int>(10);
     expect(point.x, 10);
     expect(point.y, 0);
-    expect('$point', '(10, 0)');
+    expect('$point', 'Point(10, 0)');
   });
 
   test('constructor X Y', () {
-    var point = new Point(10, 20);
+    var point = new Point<int>(10, 20);
     expect(point.x, 10);
     expect(point.y, 20);
-    expect('$point', '(10, 20)');
+    expect('$point', 'Point(10, 20)');
   });
 
   test('constructor X Y double', () {
-    var point = new Point(10.5, 20.897);
+    var point = new Point<double>(10.5, 20.897);
     expect(point.x, 10.5);
     expect(point.y, 20.897);
-    expect('$point', '(10.5, 20.897)');
+    expect('$point', 'Point(10.5, 20.897)');
   });
 
   test('constructor X Y NaN', () {
     var point = new Point(double.NAN, 1000);
     expect(point.x.isNaN, isTrue);
     expect(point.y, 1000);
-    expect('$point', '(NaN, 1000)');
+    expect('$point', 'Point(NaN, 1000)');
   });
 
   test('squaredDistanceTo', () {
@@ -72,38 +69,6 @@
     expect(a + b, new Point(7, 60));
   });
 
-  test('ceil', () {
-    var a = new Point(5.1, 10.8);
-    expect(a.ceil(), new Point(6.0, 11.0));
-
-    var b = new Point(5, 10);
-    expect(b.ceil(), new Point(5, 10));
-  });
-
-  test('floor', () {
-    var a = new Point(5.1, 10.8);
-    expect(a.floor(), new Point(5.0, 10.0));
-
-    var b = new Point(5, 10);
-    expect(b.floor(), new Point(5, 10));
-  });
-
-  test('round', () {
-    var a = new Point(5.1, 10.8);
-    expect(a.round(), new Point(5.0, 11.0));
-
-    var b = new Point(5, 10);
-    expect(b.round(), new Point(5, 10));
-  });
-
-  test('toInt', () {
-    var a = new Point(5.1, 10.8);
-    var b = a.toInt();
-    expect(b, new Point(5, 10));
-    expect(b.x is int, isTrue);
-    expect(b.y is int, isTrue);
-  });
-
   test('hashCode', () {
     var a = new Point(0, 1);
     var b = new Point(0, 1);
diff --git a/tests/lib/math/rectangle_test.dart b/tests/lib/math/rectangle_test.dart
new file mode 100644
index 0000000..2b214d2
--- /dev/null
+++ b/tests/lib/math/rectangle_test.dart
@@ -0,0 +1,131 @@
+// 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 rect_test;
+
+import 'dart:math';
+import 'package:unittest/unittest.dart';
+
+main() {
+  Rectangle createRectangle(List<num> a) {
+    return a != null ? new Rectangle(a[0], a[1], a[2] - a[0], a[3] - a[1])
+        : null;
+  }
+
+  test('construction', () {
+    var r0 = new Rectangle(10, 20, 30, 40);
+    expect(r0.toString(), 'Rectangle (10, 20) 30 x 40');
+    expect(r0.right, 40);
+    expect(r0.bottom, 60);
+
+    var r1 = new Rectangle.fromPoints(r0.topLeft, r0.bottomRight);
+    expect(r1, r0);
+
+    var r2 = new Rectangle.fromPoints(r0.bottomRight, r0.topLeft);
+    expect(r2, r0);
+  });
+
+  test('intersection', () {
+    var tests = [
+        [[10, 10, 20, 20], [15, 15, 25, 25], [15, 15, 20, 20]],
+        [[10, 10, 20, 20], [20, 0, 30, 10], [20, 10, 20, 10]],
+        [[0, 0, 1, 1], [10, 11, 12, 13], null],
+        [[11, 12, 98, 99], [22, 23, 34, 35], [22, 23, 34, 35]]];
+
+    for (var test in tests) {
+      var r0 = createRectangle(test[0]);
+      var r1 = createRectangle(test[1]);
+      var expected = createRectangle(test[2]);
+
+      expect(r0.intersection(r1), expected);
+      expect(r1.intersection(r0), expected);
+    }
+  });
+
+  test('intersects', () {
+    var r0 = new Rectangle(10, 10, 20, 20);
+    var r1 = new Rectangle(15, 15, 25, 25);
+    var r2 = new Rectangle(0, 0, 1, 1);
+
+    expect(r0.intersects(r1), isTrue);
+    expect(r1.intersects(r0), isTrue);
+
+    expect(r0.intersects(r2), isFalse);
+    expect(r2.intersects(r0), isFalse);
+  });
+
+  test('boundingBox', () {
+    var tests = [
+        [[10, 10, 20, 20], [15, 15, 25, 25], [10, 10, 25, 25]],
+        [[10, 10, 20, 20], [20, 0, 30, 10], [10, 0, 30, 20]],
+        [[0, 0, 1, 1], [10, 11, 12, 13], [0, 0, 12, 13]],
+        [[11, 12, 98, 99], [22, 23, 34, 35], [11, 12, 98, 99]]];
+
+    for (var test in tests) {
+      var r0 = createRectangle(test[0]);
+      var r1 = createRectangle(test[1]);
+      var expected = createRectangle(test[2]);
+
+      expect(r0.boundingBox(r1), expected);
+      expect(r1.boundingBox(r0), expected);
+    }
+  });
+
+  test('containsRectangle', () {
+    var r = new Rectangle(-10, 0, 20, 10);
+    expect(r.contains(r), isTrue);
+
+    expect(r.contains(
+        new Rectangle(double.NAN, double.NAN, double.NAN, double.NAN)), isFalse);
+
+    var r2 = new Rectangle(0, 2, 5, 5);
+    expect(r.contains(r2), isTrue);
+    expect(r2.contains(r), isFalse);
+
+    r2 = new Rectangle(-11, 2, 5, 5);
+    expect(r.contains(r2), isFalse);
+    r2 = new Rectangle(0, 2, 15, 5);
+    expect(r.contains(r2), isFalse);
+    r2 = new Rectangle(0, 2, 5, 10);
+    expect(r.contains(r2), isFalse);
+    r2 = new Rectangle(0, 0, 5, 10);
+    expect(r.contains(r2), isTrue);
+  });
+
+  test('containsPoint', () {
+    var r = new Rectangle(20, 40, 60, 80);
+
+    // Test middle.
+    expect(r.containsPoint(new Point(50, 80)), isTrue);
+
+    // Test edges.
+    expect(r.containsPoint(new Point(20, 40)), isTrue);
+    expect(r.containsPoint(new Point(50, 40)), isTrue);
+    expect(r.containsPoint(new Point(80, 40)), isTrue);
+    expect(r.containsPoint(new Point(80, 80)), isTrue);
+    expect(r.containsPoint(new Point(80, 120)), isTrue);
+    expect(r.containsPoint(new Point(50, 120)), isTrue);
+    expect(r.containsPoint(new Point(20, 120)), isTrue);
+    expect(r.containsPoint(new Point(20, 80)), isTrue);
+
+    // Test outside.
+    expect(r.containsPoint(new Point(0, 0)), isFalse);
+    expect(r.containsPoint(new Point(50, 0)), isFalse);
+    expect(r.containsPoint(new Point(100, 0)), isFalse);
+    expect(r.containsPoint(new Point(100, 80)), isFalse);
+    expect(r.containsPoint(new Point(100, 160)), isFalse);
+    expect(r.containsPoint(new Point(50, 160)), isFalse);
+    expect(r.containsPoint(new Point(0, 160)), isFalse);
+    expect(r.containsPoint(new Point(0, 80)), isFalse);
+  });
+
+  test('hashCode', () {
+    var a = new Rectangle(0, 1, 2, 3);
+    var b = new Rectangle(0, 1, 2, 3);
+    expect(a.hashCode, b.hashCode);
+
+    var c = new Rectangle(1, 0, 2, 3);
+    expect(a.hashCode == c.hashCode, isFalse);
+  });
+}
diff --git a/tests/lib/mirrors/constructor_kinds_test.dart b/tests/lib/mirrors/constructor_kinds_test.dart
new file mode 100644
index 0000000..f3339ca
--- /dev/null
+++ b/tests/lib/mirrors/constructor_kinds_test.dart
@@ -0,0 +1,104 @@
+// 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 test.constructor_kinds_test;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class ClassWithDefaultConstructor {}
+
+class Class {
+  Class.generative();
+  Class.redirectingGenerative() : this.generative();
+  factory Class.faktory () => new Class.generative();
+  factory Class.redirectingFactory() = Class.faktory;
+
+  const Class.constGenerative();
+  const Class.constRedirectingGenerative() : this.constGenerative();
+  // Not legal.
+  // const factory Class.constFaktory () => const Class.constGenerative();
+  const factory Class.constRedirectingFactory() = Class.constGenerative;
+}
+
+main() {
+  ClassMirror cm;
+  MethodMirror mm;
+
+  new Class.generative();  
+  new Class.redirectingGenerative();
+  new Class.faktory();
+  new Class.redirectingFactory();
+  const Class.constGenerative();
+  const Class.constRedirectingGenerative();
+  const Class.constRedirectingFactory();
+
+  cm = reflectClass(ClassWithDefaultConstructor);
+  mm = cm.constructors.values.single;
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+
+  cm = reflectClass(Class);
+
+  mm = cm.constructors[#generative];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.constructors[#redirectingGenerative];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.constructors[#faktory];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isFalse(mm.isGenerativeConstructor);
+  Expect.isTrue(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.constructors[#redirectingFactory];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isFalse(mm.isGenerativeConstructor);
+  Expect.isTrue(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isFalse(mm.isConstConstructor);
+
+  mm = cm.constructors[#constGenerative];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isFalse(mm.isRedirectingConstructor);
+  Expect.isTrue(mm.isConstConstructor);
+
+  mm = cm.constructors[#constRedirectingGenerative];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isTrue(mm.isGenerativeConstructor);
+  Expect.isFalse(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isTrue(mm.isConstConstructor);
+
+  // Not legal.
+  // mm = cm.constructors[#constFaktory];
+  // Expect.isTrue(mm.isConstructor);
+  // Expect.isFalse(mm.isGenerativeConstructor);
+  // Expect.isTrue(mm.isFactoryConstructor);
+  // Expect.isFalse(mm.isRedirectingConstructor);
+  // Expect.isTrue(mm.isConstConstructor);
+
+  mm = cm.constructors[#constRedirectingFactory];
+  Expect.isTrue(mm.isConstructor);
+  Expect.isFalse(mm.isGenerativeConstructor);
+  Expect.isTrue(mm.isFactoryConstructor);
+  Expect.isTrue(mm.isRedirectingConstructor);
+  Expect.isTrue(mm.isConstConstructor);
+}
diff --git a/tests/lib/mirrors/constructors_test.dart b/tests/lib/mirrors/constructors_test.dart
index b42472f..b55e440a 100644
--- a/tests/lib/mirrors/constructors_test.dart
+++ b/tests/lib/mirrors/constructors_test.dart
@@ -27,7 +27,6 @@
 }
 
 main() {
-  MirrorSystem mirrors = currentMirrorSystem();
   ClassMirror fooMirror = reflectClass(Foo);
   Map<Symbol, MethodMirror> fooConstructors = fooMirror.constructors;
   ClassMirror barMirror = reflectClass(Bar);
diff --git a/tests/lib/mirrors/delegate_test.dart b/tests/lib/mirrors/delegate_test.dart
new file mode 100644
index 0000000..1f7edc6
--- /dev/null
+++ b/tests/lib/mirrors/delegate_test.dart
@@ -0,0 +1,52 @@
+// 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 test.invoke_named_test;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+import 'invoke_test.dart';
+
+class C {
+  method(a, b, c) => "$a-$b-$c";
+  methodWithNamed(a, {b:'B', c}) => "$a-$b-$c";
+  methodWithOpt(a, [b, c='C']) => "$a-$b-$c";
+  get getter => 'g';
+  set setter(x) {
+    field = x*2;
+    return 'unobservable value';
+  }
+  var field;
+}
+
+class Proxy {
+  var targetMirror;
+  Proxy(target) : this.targetMirror = reflect(target);
+  noSuchMethod(invocation) => targetMirror.delegate(invocation);
+}
+
+main() {
+  var c = new C();
+  var proxy = new Proxy(c);
+  var result;
+
+  Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z'));
+
+  Expect.equals('X-B-null', proxy.methodWithNamed('X'));
+  Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z'));
+
+  Expect.equals('X-null-C', proxy.methodWithOpt('X'));
+  Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y'));
+  Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z'));
+
+  Expect.equals('g', proxy.getter);
+
+  Expect.equals(5, proxy.setter = 5);
+  Expect.equals(10, proxy.field);
+
+  Expect.equals(5, proxy.field = 5);
+  Expect.equals(5, proxy.field);
+}
diff --git a/tests/lib/mirrors/generic_function_typedef_test.dart b/tests/lib/mirrors/generic_function_typedef_test.dart
new file mode 100644
index 0000000..051f25d
--- /dev/null
+++ b/tests/lib/mirrors/generic_function_typedef_test.dart
@@ -0,0 +1,113 @@
+// 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 test.generic_function_typedef;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_test.dart';
+
+typedef bool NonGenericPredicate(num);
+typedef bool GenericPredicate<T>(T);
+typedef S GenericTransform<S>(S);
+
+class C<R> {
+  GenericPredicate<num> predicateOfNum;
+  GenericTransform<String> transformOfString;
+  GenericTransform<R> transformOfR;
+}
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  TypedefMirror predicateOfNum = reflectClass(C).variables[#predicateOfNum].type;
+  TypedefMirror transformOfString = reflectClass(C).variables[#transformOfString].type;
+  TypedefMirror transformOfR = reflectClass(C).variables[#transformOfR].type;
+  TypedefMirror transformOfDouble = reflect(new C<double>()).type.variables[#transformOfR].type;
+
+  TypeVariableMirror rFromC = reflectClass(C).typeVariables[0];
+
+  // Typedefs.
+  typeParameters(reflectClass(NonGenericPredicate), []);
+  typeParameters(reflectClass(GenericPredicate), [#T]);
+  typeParameters(reflectClass(GenericTransform), [#S]);
+  typeParameters(predicateOfNum, [#T]);
+  typeParameters(transformOfString, [#S]);
+  typeParameters(transformOfR, [#R]);
+  typeParameters(transformOfDouble, [#R]);
+
+  typeArguments(reflectClass(NonGenericPredicate), []);
+  typeArguments(reflectClass(GenericPredicate), []);
+  typeArguments(reflectClass(GenericTransform), []);
+  typeArguments(predicateOfNum, [reflectClass(num)]);
+  typeArguments(transformOfString, [reflectClass(String)]);
+  typeArguments(transformOfR, [rFromC]);
+  typeArguments(transformOfDouble, [reflect(double)]);
+
+  Expect.isTrue(reflectClass(NonGenericPredicate).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(GenericPredicate).isOriginalDeclaration);
+  Expect.isTrue(reflectClass(GenericTransform).isOriginalDeclaration);  
+  Expect.isFalse(predicateOfNum.isOriginalDeclaration);  
+  Expect.isFalse(transformOfString.isOriginalDeclaration);  
+  Expect.isFalse(transformOfR.isOriginalDeclaration);  
+  Expect.isFalse(transformOfDouble.isOriginalDeclaration);  
+
+  // Function types.
+  typeParameters(reflectClass(NonGenericPredicate).referent, []);
+  typeParameters(reflectClass(GenericPredicate).referent, []);
+  typeParameters(reflectClass(GenericTransform).referent, []);
+  typeParameters(predicateOfNum.referent, []);
+  typeParameters(transformOfString.referent, []);
+  typeParameters(transformOfR.referent, []);
+  typeParameters(transformOfDouble.referent, []);
+
+  typeArguments(reflectClass(NonGenericPredicate).referent, []);
+  typeArguments(reflectClass(GenericPredicate).referent, []);
+  typeArguments(reflectClass(GenericTransform).referent, []);
+  typeArguments(predicateOfNum.referent, []);
+  typeArguments(transformOfString.referent, []);
+  typeArguments(transformOfR.referent, []);
+  typeArguments(transformOfDouble.referent, []);
+
+  // Function types are always non-generic. Only the typedef is generic.
+  Expect.isTrue(reflectClass(NonGenericPredicate).referent.isOriginalDeclaration);
+  Expect.isTrue(reflectClass(GenericPredicate).referent.isOriginalDeclaration);
+  Expect.isTrue(reflectClass(GenericTransform).referent.isOriginalDeclaration);  
+  Expect.isTrue(predicateOfNum.referent.isOriginalDeclaration);  
+  Expect.isTrue(transformOfString.referent.isOriginalDeclaration); 
+  Expect.isTrue(transformOfR.referent.isOriginalDeclaration); // Er, but here we don't have concrete types...
+  Expect.isTrue(transformOfDouble.referent.isOriginalDeclaration); 
+
+  Expect.equals(reflectClass(num),
+                reflectClass(NonGenericPredicate).referent.parameters[0].type);
+  Expect.equals(dynamicMirror,
+                reflectClass(GenericPredicate).referent.parameters[0].type);
+  Expect.equals(dynamicMirror,
+                reflectClass(GenericTransform).referent.parameters[0].type);
+  Expect.equals(reflectClass(num),
+                predicateOfNum.referent.parameters[0].type);
+  Expect.equals(reflectClass(String),
+                transformOfString.referent.parameters[0].type);
+  Expect.equals(rFromC,
+                transformOfR.referent.parameters[0].type);
+  Expect.equals(reflectClass(double),
+                transformOfDouble.referent.parameters[0].type);
+
+  Expect.equals(reflectClass(bool),
+                reflectClass(NonGenericPredicate).referent.returnType);
+  Expect.equals(reflectClass(bool),
+                reflectClass(GenericPredicate).referent.returnType);
+  Expect.equals(dynamicMirror,
+                reflectClass(GenericTransform).referent.returnType);
+  Expect.equals(reflectClass(bool),
+                predicateOfNum.referent.returnType);
+  Expect.equals(reflectClass(String),
+                transformOfString.referent.returnType);
+  Expect.equals(rFromC,
+                transformOfR.referent.returnType);
+  Expect.equals(reflectClass(double),
+                transformOfDouble.referent.returnType);
+}
diff --git a/tests/lib/mirrors/generic_mixin_applications_test.dart b/tests/lib/mirrors/generic_mixin_applications_test.dart
new file mode 100644
index 0000000..47e6234
--- /dev/null
+++ b/tests/lib/mirrors/generic_mixin_applications_test.dart
@@ -0,0 +1,96 @@
+// 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 test.generic_mixin_applications;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_test.dart';
+
+class Super<S> {}
+class Mixin<M> {}
+class Nixim<N> {}
+
+typedef NonGenericMixinApplication1 = Super with Mixin;
+typedef NonGenericMixinApplication2 = Super<num> with Mixin<String>;
+
+typedef GenericMixinApplication1<MA> = Super<MA> with Mixin<MA>;
+typedef GenericMixinApplication2<MA> = Super<num> with Mixin<String>;
+
+class NonGenericClass1 extends Super with Mixin {}
+class NonGenericClass2 extends Super<num> with Mixin<String> {}
+
+class GenericClass1<C> extends Super<C> with Mixin<C> {}
+class GenericClass2<C> extends Super<num> with Mixin<String> {}
+
+class GenericMultipleMixins<A, B, C> extends Super<A> with Mixin<B>, Nixim<C> {}
+
+main() {
+  TypeMirror dynamicMirror = currentMirrorSystem().dynamicType;
+
+  // Declarations.
+  typeParameters(reflectClass(NonGenericMixinApplication1), []);
+  typeParameters(reflectClass(NonGenericMixinApplication2), []);
+  typeParameters(reflectClass(GenericMixinApplication1), [#MA]);
+  typeParameters(reflectClass(GenericMixinApplication2), [#MA]);
+  typeParameters(reflectClass(NonGenericClass1), []);
+  typeParameters(reflectClass(NonGenericClass2), []);
+  typeParameters(reflectClass(GenericClass1), [#C]);
+  typeParameters(reflectClass(GenericClass2), [#C]);
+  typeParameters(reflectClass(GenericMultipleMixins), [#A, #B, #C]);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeParameters(reflectClass(NonGenericClass1).superclass, []);
+  typeParameters(reflectClass(NonGenericClass2).superclass, []);
+  typeParameters(reflectClass(GenericClass1).superclass, []);
+  typeParameters(reflectClass(GenericClass2).superclass, []);
+  
+  typeArguments(reflectClass(NonGenericMixinApplication1), []);
+  typeArguments(reflectClass(NonGenericMixinApplication2), []);
+  typeArguments(reflectClass(GenericMixinApplication1), []);
+  typeArguments(reflectClass(GenericMixinApplication2), []);
+  typeArguments(reflectClass(NonGenericClass1), []);
+  typeArguments(reflectClass(NonGenericClass2), []);
+  typeArguments(reflectClass(GenericClass1), []);
+  typeArguments(reflectClass(GenericClass2), []);
+  typeArguments(reflectClass(GenericMultipleMixins), []);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeArguments(reflectClass(NonGenericClass1).superclass.originalDeclaration, []);
+  typeArguments(reflectClass(NonGenericClass2).superclass.originalDeclaration, []);
+  typeArguments(reflectClass(GenericClass1).superclass.originalDeclaration, []);
+  typeArguments(reflectClass(GenericClass2).superclass.originalDeclaration, []);
+
+
+  // Instantiations.
+  typeParameters(reflect(new NonGenericMixinApplication1()).type, []);
+  typeParameters(reflect(new NonGenericMixinApplication2()).type, []);
+  typeParameters(reflect(new GenericMixinApplication1<bool>()).type, [#MA]);
+  typeParameters(reflect(new GenericMixinApplication2<bool>()).type, [#MA]);
+  typeParameters(reflect(new NonGenericClass1()).type, []);
+  typeParameters(reflect(new NonGenericClass2()).type, []);
+  typeParameters(reflect(new GenericClass1<bool>()).type, [#C]);
+  typeParameters(reflect(new GenericClass2<bool>()).type, [#C]);
+  typeParameters(reflect(new GenericMultipleMixins<bool, String, int>()).type, [#A, #B, #C]);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeParameters(reflect(new NonGenericClass1()).type.superclass, []);
+  typeParameters(reflect(new NonGenericClass2()).type.superclass, []);
+  typeParameters(reflect(new GenericClass1<bool>()).type.superclass, []);
+  typeParameters(reflect(new GenericClass2<bool>()).type.superclass, []);
+ 
+  typeArguments(reflect(new NonGenericMixinApplication1()).type, []);
+  typeArguments(reflect(new NonGenericMixinApplication2()).type, []);
+  typeArguments(reflect(new GenericMixinApplication1<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new GenericMixinApplication2<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new NonGenericClass1()).type, []);
+  typeArguments(reflect(new NonGenericClass2()).type, []);
+  typeArguments(reflect(new GenericClass1<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new GenericClass2<bool>()).type, [reflectClass(bool)]);
+  typeArguments(reflect(new GenericMultipleMixins<bool, String, int>()).type, [reflectClass(bool), reflectClass(String), reflectClass(int)]);
+  // Anonymous mixin applications have no type parameters or type arguments.
+  typeArguments(reflect(new NonGenericClass1()).type.superclass, []);
+  typeArguments(reflect(new NonGenericClass2()).type.superclass, []);
+  typeArguments(reflect(new GenericClass1<bool>()).type.superclass, []);
+  typeArguments(reflect(new GenericClass2<bool>()).type.superclass, []);
+}
diff --git a/tests/lib/mirrors/generics_substitution_test.dart b/tests/lib/mirrors/generics_substitution_test.dart
new file mode 100644
index 0000000..2293e7d
--- /dev/null
+++ b/tests/lib/mirrors/generics_substitution_test.dart
@@ -0,0 +1,52 @@
+// 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 test.generics_substitution;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class SuperGeneric<R, S> {
+  R r;
+  s(S s) {}
+}
+
+class Generic<T> extends SuperGeneric<T, int> {
+  T t() {}
+}
+
+main() {
+  ClassMirror genericDecl = reflectClass(Generic);
+  ClassMirror genericOfString = reflect(new Generic<String>()).type;
+  ClassMirror superGenericDecl = reflectClass(SuperGeneric);
+  ClassMirror superOfTAndInt = genericDecl.superclass;
+  ClassMirror superOfStringAndInt = genericOfString.superclass;
+
+  Expect.isTrue(genericDecl.isOriginalDeclaration);
+  Expect.isFalse(genericOfString.isOriginalDeclaration);
+  Expect.isTrue(superGenericDecl.isOriginalDeclaration);
+  Expect.isFalse(superOfTAndInt.isOriginalDeclaration);
+  Expect.isFalse(superOfStringAndInt.isOriginalDeclaration);
+
+  Symbol r(ClassMirror cm) => cm.variables[#r].type.simpleName;
+  Symbol s(ClassMirror cm) => cm.methods[#s].parameters[0].type.simpleName;
+  Symbol t(ClassMirror cm) => cm.methods[#t].returnType.simpleName;
+  
+  Expect.equals(#T, r(genericDecl.superclass));
+  Expect.equals(#int, s(genericDecl.superclass));
+  Expect.equals(#T, t(genericDecl));
+
+  Expect.equals(#String, r(genericOfString.superclass));
+  Expect.equals(#int, s(genericOfString.superclass));
+  Expect.equals(#String, t(genericOfString));
+
+  Expect.equals(#R, r(superGenericDecl));
+  Expect.equals(#S, s(superGenericDecl));
+
+  Expect.equals(#T, r(superOfTAndInt));
+  Expect.equals(#int, s(superOfTAndInt));
+
+  Expect.equals(#String, r(superOfStringAndInt));
+  Expect.equals(#int, t(superOfStringAndInt));
+}
diff --git a/tests/lib/mirrors/generics_test.dart b/tests/lib/mirrors/generics_test.dart
index 7f6386a..8eb63ee 100644
--- a/tests/lib/mirrors/generics_test.dart
+++ b/tests/lib/mirrors/generics_test.dart
@@ -22,7 +22,7 @@
 class I extends G {}
 
 typeParameters(mirror, parameterNames) {
-  Expect.listEquals(parameterNames.map((n) => new Symbol(n)).toList(),
+  Expect.listEquals(parameterNames,
                     mirror.typeVariables.map((v) => v.simpleName).toList());
 }
 
@@ -32,15 +32,15 @@
 
 main() {
   // Declarations.
-  typeParameters(reflectClass(A), ['T']);
+  typeParameters(reflectClass(A), [#T]);
   typeParameters(reflectClass(G), []);
   typeParameters(reflectClass(B), []);
   typeParameters(reflectClass(C), []);
   typeParameters(reflectClass(D), []);
-  typeParameters(reflectClass(E), ['S']);
-  typeParameters(reflectClass(F), ['R']);
+  typeParameters(reflectClass(E), [#S]);
+  typeParameters(reflectClass(F), [#R]);
   typeParameters(reflectClass(G), []);
-  typeParameters(reflectClass(H), ['A', 'B', 'C']);
+  typeParameters(reflectClass(H), [#A, #B, #C]);
   typeParameters(reflectClass(I), []);
 
   typeArguments(reflectClass(A), []);
@@ -74,14 +74,14 @@
   Expect.equals(reflectClass(I), reflectClass(I).originalDeclaration);
 
   // Instantiations.
-  typeParameters(reflect(new A<num>()).type, ['T']);
+  typeParameters(reflect(new A<num>()).type, [#T]);
   typeParameters(reflect(new B<num>()).type, []);
   typeParameters(reflect(new C()).type, []);
   typeParameters(reflect(new D()).type, []);
-  typeParameters(reflect(new E()).type, ['S']);
-  typeParameters(reflect(new F<num>()).type, ['R']);
+  typeParameters(reflect(new E()).type, [#S]);
+  typeParameters(reflect(new F<num>()).type, [#R]);
   typeParameters(reflect(new G()).type, []);
-  typeParameters(reflect(new H()).type, ['A', 'B', 'C']);
+  typeParameters(reflect(new H()).type, [#A, #B, #C]);
   typeParameters(reflect(new I()).type, []);
 
   var numMirror = reflectClass(num);
@@ -154,7 +154,7 @@
   // Library members are all uninstantaited generics or non-generics.
   currentMirrorSystem().libraries.values.forEach((libraryMirror) {
     libraryMirror.classes.values.forEach((classMirror) {
-      // TODO(12282): Deal with generic typedefs.
+      // Generic typedefs are considered in a separate test.
       if (classMirror is! TypedefMirror) {
         Expect.isTrue(classMirror.isOriginalDeclaration);
         Expect.equals(classMirror, classMirror.originalDeclaration);
diff --git a/tests/lib/mirrors/initializing_formals_test.dart b/tests/lib/mirrors/initializing_formals_test.dart
new file mode 100644
index 0000000..6dcfce1
--- /dev/null
+++ b/tests/lib/mirrors/initializing_formals_test.dart
@@ -0,0 +1,110 @@
+// 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 test.initializing_formals;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  int intField;
+  bool boolField;
+  String stringField;
+  T tField;
+  dynamic _privateField;
+
+  Class.nongeneric(this.intField);
+  Class.named({this.boolField});
+  Class.optPos([this.stringField = 'default']);
+  Class.generic(this.tField);
+  Class.private(this._privateField);
+}
+
+class Constant {
+  final value;
+  const Constant(this.value);
+  const Constant.marked(final this.value);
+}
+
+main() {
+  ParameterMirror pm;
+
+  pm = reflectClass(Class).constructors[#Class.nongeneric].parameters.single;
+  Expect.equals(#intField, pm.simpleName);
+  Expect.equals(reflectClass(int), pm.type);  /// 01: ok
+  Expect.isFalse(pm.isNamed);
+  Expect.isFalse(pm.isFinal);
+  Expect.isFalse(pm.isOptional);
+  Expect.isFalse(pm.hasDefaultValue);
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+  
+  pm = reflectClass(Class).constructors[#Class.named].parameters.single;
+  Expect.equals(#boolField, pm.simpleName);
+  Expect.equals(reflectClass(bool), pm.type);  /// 01: ok
+  Expect.isTrue(pm.isNamed);
+  Expect.isFalse(pm.isFinal);
+  Expect.isTrue(pm.isOptional);
+  Expect.isFalse(pm.hasDefaultValue);
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+  
+  pm = reflectClass(Class).constructors[#Class.optPos].parameters.single;
+  Expect.equals(#stringField, pm.simpleName);
+  Expect.equals(reflectClass(String), pm.type);  /// 01: ok
+  Expect.isFalse(pm.isNamed);
+  Expect.isFalse(pm.isFinal);
+  Expect.isTrue(pm.isOptional);
+  Expect.isTrue(pm.hasDefaultValue);
+  Expect.equals('default', pm.defaultValue.reflectee);
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+  
+  pm = reflectClass(Class).constructors[#Class.generic].parameters.single;
+  Expect.equals(#tField, pm.simpleName);
+  Expect.equals(reflectClass(Class).typeVariables.single, pm.type);  /// 01: ok
+  Expect.isFalse(pm.isNamed);
+  Expect.isFalse(pm.isFinal);
+  Expect.isFalse(pm.isOptional);
+  Expect.isFalse(pm.hasDefaultValue);
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  pm = reflectClass(Class).constructors[#Class.private].parameters.single;
+  Expect.equals(#_privateField, pm.simpleName);
+  Expect.equals(currentMirrorSystem().dynamicType, pm.type);
+  Expect.isFalse(pm.isNamed);
+  Expect.isFalse(pm.isFinal);
+  Expect.isFalse(pm.isOptional);
+  Expect.isFalse(pm.hasDefaultValue);
+  Expect.isTrue(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  pm = reflectClass(Constant).constructors[#Constant].parameters.single;
+  Expect.equals(#value, pm.simpleName);
+  Expect.equals(currentMirrorSystem().dynamicType, pm.type);
+  Expect.isFalse(pm.isNamed);
+  Expect.isFalse(pm.isFinal);  // N.B.
+  Expect.isFalse(pm.isOptional);
+  Expect.isFalse(pm.hasDefaultValue);
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+
+  pm = reflectClass(Constant).constructors[#Constant.marked].parameters.single;
+  Expect.equals(#value, pm.simpleName);
+  Expect.equals(currentMirrorSystem().dynamicType, pm.type);
+  Expect.isFalse(pm.isNamed);
+  Expect.isTrue(pm.isFinal);  // N.B.
+  Expect.isFalse(pm.isOptional);
+  Expect.isFalse(pm.hasDefaultValue);
+  Expect.isFalse(pm.isPrivate);
+  Expect.isFalse(pm.isStatic);
+  Expect.isFalse(pm.isTopLevel);
+}
diff --git a/tests/lib/mirrors/reflect_class_test.dart b/tests/lib/mirrors/reflect_class_test.dart
new file mode 100644
index 0000000..c556ba8
--- /dev/null
+++ b/tests/lib/mirrors/reflect_class_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:expect/expect.dart";
+
+typedef void FooFunction(int a, double b);
+
+main() {
+  Function expectedError = (e) => e is ArgumentError || e is TypeError;
+
+  Expect.throws(() => reflectClass(dynamic), expectedError);
+  Expect.throws(() => reflectClass(1), expectedError);
+  Expect.throws(() => reflectClass("string"), expectedError);
+
+  // reflectClass() on a function type should fail once typedefs are represented
+  // by TypedefMirrors instead of ClassMirrors.
+  // Expect.throws(() => reflectClass(FooFunction), expectedError);
+}
diff --git a/tests/lib/mirrors/type_argument_is_type_variable_test.dart b/tests/lib/mirrors/type_argument_is_type_variable_test.dart
new file mode 100644
index 0000000..90ae8fe
--- /dev/null
+++ b/tests/lib/mirrors/type_argument_is_type_variable_test.dart
@@ -0,0 +1,52 @@
+// 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 test.type_argument_is_type_variable;
+
+import 'dart:mirrors';
+
+import 'package:expect/expect.dart';
+
+import 'generics_test.dart';
+
+class SuperSuper<SS> {}
+class Super<S> extends SuperSuper<S> {}
+class Generic<G> extends Super<G> {}
+
+main() {
+  // Declarations.
+  ClassMirror generic = reflectClass(Generic);
+  ClassMirror superOfGeneric = generic.superclass;
+  ClassMirror superOfSuperOfGeneric = superOfGeneric.superclass;
+