Version 0.3.3.0

svn merge -r 17651:17990 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 18009 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@18016 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/compiler/eclipse.workspace/dartc/.gitignore b/compiler/eclipse.workspace/dartc/.gitignore
new file mode 100644
index 0000000..1f57b97
--- /dev/null
+++ b/compiler/eclipse.workspace/dartc/.gitignore
@@ -0,0 +1 @@
+/output
diff --git a/compiler/eclipse.workspace/tests/.gitignore b/compiler/eclipse.workspace/tests/.gitignore
new file mode 100644
index 0000000..4ab5c99
--- /dev/null
+++ b/compiler/eclipse.workspace/tests/.gitignore
@@ -0,0 +1,2 @@
+/output
+/.settings
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
index f85ccd5..9a4cbf1 100644
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
@@ -372,6 +372,7 @@
         }
         onError(errorTarget, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getName());
       }
+      checkMixinObjectIsSupertype(cls.getMixins());
       checkMixinNoConstructors(cls.getMixins());
       checkMixinNoSuperInvocations(cls.getMixins());
       return classElement;
@@ -490,6 +491,7 @@
       }
 
       // check mixins
+      checkMixinObjectIsSupertype(cls.getMixins());
       checkMixinNoConstructors(cls.getMixins());
       checkMixinNoSuperInvocations(cls.getMixins());
 
@@ -517,7 +519,27 @@
     }
     
     /**
-     * Checks that the types of the given mixin type node don't have super invocations.
+     * Checks that the types of the given mixin type nodes se subtypes of Object.
+     */
+    private void checkMixinObjectIsSupertype(List<DartTypeNode> mixins) {
+      for (DartTypeNode mixNode : mixins) {
+        if (mixNode.getType() instanceof InterfaceType) {
+          InterfaceType mixType = (InterfaceType) mixNode.getType();
+          ClassElement mixElement = mixType.getElement();
+          if (!mixElement.getMixins().isEmpty()) {
+            topLevelContext.onError(mixNode, ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS);
+            continue;
+          }
+          if (!Objects.equal(mixElement.getSupertype(), typeProvider.getObjectType())) {
+            topLevelContext.onError(mixNode, ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS);
+            continue;
+          }
+        }
+      }
+    }
+    
+    /**
+     * Checks that the types of the given mixin type nodes don't have super invocations.
      */
     private void checkMixinNoSuperInvocations(List<DartTypeNode> mixins) {
       for (DartTypeNode mixNode : mixins) {
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
index 093334d..1087830 100644
--- a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
+++ b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
@@ -33,6 +33,7 @@
   CANNOT_HIDE_IMPORT_PREFIX("Cannot hide import prefix '%s'"),
   CANNOT_INIT_STATIC_FIELD_IN_INITIALIZER("Cannot initialize a static field in an initializer list"),
   CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR("Cannot use class with constructor as a mixin."),
+  CANNOT_MIXIN_CLASS_WITH_MIXINS("Cannot use class with mixins as a mixin."),
   CANNOT_MIXIN_CLASS_WITH_SUPER("Cannot use class with super invocation as a mixin."),
   CANNOT_OVERRIDE_INSTANCE_MEMBER("static member cannot override instance member %s of %s"),
   CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS(
diff --git a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
index 6f13767..ed9505e 100644
--- a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
+++ b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
@@ -177,10 +177,6 @@
             topLevelContext.onError(mixNode, ResolverErrorCode.SUPER_CLASS_IN_WITH);
             continue;
           }
-          if (!Objects.equal(mixType.getElement().getSupertype(), typeProvider.getObjectType())) {
-            topLevelContext.onError(mixNode, ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS);
-            continue;
-          }
           seenMixin.add(mixType);
           // OK, add
           Elements.addMixin(classElement, mixType);
diff --git a/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
index 7467104..f439eef 100644
--- a/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
+++ b/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
@@ -4,6 +4,7 @@
 
 package com.google.dart.compiler.type;
 
+import com.google.common.collect.Lists;
 import com.google.dart.compiler.resolver.ClassElement;
 import com.google.dart.compiler.resolver.DynamicElement;
 import com.google.dart.compiler.resolver.Element;
@@ -144,7 +145,7 @@
   }
 
   @Override
-  public Member lookupSubTypeMember(String name) {
-    return null;
+  public List<Member> lookupSubTypeMembers(String name) {
+    return Lists.newArrayList();
   }
 }
diff --git a/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java b/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
index d8a6be2..fb6b481 100644
--- a/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
+++ b/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
@@ -154,7 +154,7 @@
       // OK, we know more specific return type
       Type tagType = tagTypeElement.getType();
       if (tagType != null) {
-        return tagType;
+        return Types.makeInferred(tagType, TypeQuality.INFERRED_EXACT);
       }
     }
     // no guess
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceType.java b/compiler/java/com/google/dart/compiler/type/InterfaceType.java
index 99b7c9d..2f76916 100644
--- a/compiler/java/com/google/dart/compiler/type/InterfaceType.java
+++ b/compiler/java/com/google/dart/compiler/type/InterfaceType.java
@@ -35,11 +35,12 @@
   
   void registerSubClass(ClassElement subClass);
   void unregisterSubClass(ClassElement subClass);
+
   /**
-   * @return the unique {@link Member} with given name, defined in one of the subtypes. May be
-   *         <code>null</code> if not found or not unique.
+   * @return the {@link Member}s with given name, defined in one of the subtypes. May be empty, but
+   *         not <code>null</code>.
    */
-  Member lookupSubTypeMember(String name);
+  List<Member> lookupSubTypeMembers(String name);
 
   interface Member {
     InterfaceType getHolder();
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
index 5bb25bf3..d1dad43 100644
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
+++ b/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
@@ -4,6 +4,7 @@
 
 package com.google.dart.compiler.type;
 
+import com.google.common.collect.Lists;
 import com.google.common.collect.MapMaker;
 import com.google.dart.compiler.resolver.ClassElement;
 import com.google.dart.compiler.resolver.Element;
@@ -255,33 +256,24 @@
   }
   
   @Override
-  public Member lookupSubTypeMember(String name) {
-    Member foundMember = null;
-    for (ClassElement subClass : subClasses.keySet()) {
-      // find one or more members in subClass elements
-      {
-        Element element = subClass.lookupLocalElement(name);
-        if (element != null) {
-          if (foundMember != null) {
-            return null;
-          }
-          foundMember = new MemberImplementation(this, element);
-          continue;
-        }
-      }
-      // try to find deeper
-      InterfaceType type = subClass.getType();
-      if (type != null) {
-        Member member = type.lookupSubTypeMember(name);
-        if (member != null) {
-          if (foundMember != null) {
-            return null;
-          }
-          foundMember = member;
-        }
+  public List<Member> lookupSubTypeMembers(String name) {
+    List<Member> members = Lists.newArrayList();
+    fillSubTypeMember(members, name);
+    return members;
+  }
+  
+  private void fillSubTypeMember(List<Member> members, String name) {
+    {
+      Member member = lookupMember(name);
+      if (member != null) {
+        members.add(member);
       }
     }
-    // may be found
-    return foundMember;
+    for (ClassElement subClass : subClasses.keySet()) {
+      InterfaceType type = subClass.getType();
+      if (type instanceof InterfaceTypeImplementation) {
+        ((InterfaceTypeImplementation)type).fillSubTypeMember(members, name);
+      }
+    }
   }
 }
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
index b17a4d3..50f0006 100644
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
+++ b/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
@@ -5,6 +5,7 @@
 package com.google.dart.compiler.type;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import com.google.dart.compiler.resolver.ClassElement;
 import com.google.dart.compiler.resolver.ClassElementUnion;
 
@@ -105,8 +106,8 @@
   }
 
   @Override
-  public Member lookupSubTypeMember(String name) {
-    return null;
+  public List<Member> lookupSubTypeMembers(String name) {
+    return Lists.newArrayList();
   }
 
   public List<InterfaceType> getTypes() {
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index cd9238e..a2d1272 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -656,16 +656,21 @@
         member = itype.lookupMember("setter " + methodName);
       }
       // is "receiver" is inferred, attempt to find member in one of the subtypes
+      boolean hasMemberInSubClasses = false;
       if (member == null) {
         if (TypeQuality.of(receiver) == TypeQuality.INFERRED && receiver instanceof InterfaceType) {
-          member = ((InterfaceType) receiver).lookupSubTypeMember(methodName);
+          List<Member> subMembers = ((InterfaceType) receiver).lookupSubTypeMembers(methodName);
+          hasMemberInSubClasses = !subMembers.isEmpty();
+          if (subMembers.size() == 1) {
+            member = subMembers.get(0);
+          }
         }
       }
       // report problem
       if (member == null && problemTarget != null) {
         if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(itype)) {
-          if (typeChecksForInferredTypes && !isTooGenericInferredType(receiver)
-              || !TypeQuality.isInferred(receiver)) {
+          if (typeChecksForInferredTypes && !hasMemberInSubClasses
+              && !isTooGenericInferredType(receiver) || !TypeQuality.isInferred(receiver)) {
             ErrorCode code = TypeQuality.isInferred(receiver)
                 ? TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED
                 : TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED;
@@ -2396,16 +2401,21 @@
         }
       }
       // is "receiver" is inferred, attempt to find member in one of the subtypes
+      boolean hasMemberInSubClasses = false;
       if (member == null) {
         if (TypeQuality.of(receiver) == TypeQuality.INFERRED && receiver instanceof InterfaceType) {
-          member = ((InterfaceType) receiver).lookupSubTypeMember(name);
+          List<Member> subMembers = ((InterfaceType) receiver).lookupSubTypeMembers(name);
+          hasMemberInSubClasses = !subMembers.isEmpty();
+          if (subMembers.size() == 1) {
+            member = subMembers.get(0);
+          }
         }
       }
       // report "not a member"
       if (member == null) {
         if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(cls)) {
-          if (typeChecksForInferredTypes && !isTooGenericInferredType(receiver)
-              || !TypeQuality.isInferred(receiver)) {
+          if (typeChecksForInferredTypes && !hasMemberInSubClasses
+              && !isTooGenericInferredType(receiver) || !TypeQuality.isInferred(receiver)) {
             TypeErrorCode errorCode = TypeQuality.isInferred(receiver)
                 ? TypeErrorCode.NOT_A_MEMBER_OF_INFERRED : TypeErrorCode.NOT_A_MEMBER_OF;
             typeError(node.getName(), errorCode, name, cls);
@@ -2448,7 +2458,10 @@
           {
             getterMember = cls.lookupMember(name);
             if (getterMember == null && TypeQuality.of(cls) == TypeQuality.INFERRED) {
-              getterMember = cls.lookupSubTypeMember(name);
+              List<Member> members = cls.lookupSubTypeMembers(name);
+              if (members.size() == 1) {
+                getterMember = members.get(0);
+              }
             }
           }
           {
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index f058ab1..ebf9907 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -5956,7 +5956,8 @@
         "  });",
         "}",
         "");
-    assertErrors(result.getErrors(), errEx(TypeErrorCode.NOT_A_MEMBER_OF_INFERRED, 16, 11, 7));
+    // don't report error, because there IS member, we just don't know which one
+    assertErrors(result.getErrors());
   }
   
   /**
@@ -6479,5 +6480,15 @@
         result.getErrors(),
         errEx(TypeErrorCode.NOT_A_MEMBER_OF, 13, 5, 2));
   }
+
+  public void test_mixin_disallowMixinApplication_asMixin() throws Exception {
+    AnalyzeLibraryResult result = analyzeLibrary(
+        "// filler filler filler filler filler filler filler filler filler filler",
+        "typedef M = Object with M;",
+        "");
+    assertErrors(
+        result.getErrors(),
+        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS, 2, 25, 1));
+  }
   
 }
diff --git a/pkg/analyzer-experimental/README b/pkg/analyzer-experimental/README
new file mode 100644
index 0000000..c8db3be
--- /dev/null
+++ b/pkg/analyzer-experimental/README
@@ -0,0 +1,20 @@
+This code is part of an experimental port of the Editor's analysis engine from
+Java to Dart. While we will continue to support the Java version of the analysis
+engine and the services built on it, we also intend to provide the same services
+to Dart-based applications. This is very early code and we expect it to change,
+possibly in significant ways. While we are eager to see other people make use
+of the analysis engine, we also want to be clear, in case you are interested in
+doing so, that the current API's should in no way be considered to be stable.
+
+In particular, this code was automatically translated from the Java
+implementation. The Java implementation that was translated is still under
+development and will continue to change over time. The translator that was used
+is still under development and the output produced by the translator will change
+over time. Therefore, the API presented by this code will change. In addition,
+any edits made to this code will be overwritten the next time we re-generate
+this code.
+
+If you are interested in using this code, despite the disclaimer above,
+fantastic! Please let the editor team know so that we can get a sense of the
+interest in it. Also, feel free to ask questions and make requests for
+additional functionality.
\ No newline at end of file
diff --git a/pkg/analyzer-experimental/bin/analyzer.dart b/pkg/analyzer-experimental/bin/analyzer.dart
index 6ccf8ab..da405db 100644
--- a/pkg/analyzer-experimental/bin/analyzer.dart
+++ b/pkg/analyzer-experimental/bin/analyzer.dart
@@ -36,7 +36,7 @@
  */
 Future<AnalysisResult> run(List<String> args) {
 
-  var options = CommandLineOptions.parse(args);
+  var options = new CommandLineOptions.parse(args);
   if (options == null) {
     return new Future.immediate(new AnalysisResult.forFailure());
   }
diff --git a/pkg/analyzer-experimental/lib/options.dart b/pkg/analyzer-experimental/lib/options.dart
index c480a34..b426129 100644
--- a/pkg/analyzer-experimental/lib/options.dart
+++ b/pkg/analyzer-experimental/lib/options.dart
@@ -163,6 +163,10 @@
       return args;
     }
 
+    //TODO(pquitslund): replace w/ the following once library skew issues are sorted out
+    //return args.where((arg) => !arg.startsWith('--') ||
+    //  _knownFlags.contains(arg.substring(2)));
+
     // Filter all unrecognized flags and options.
     var filtered = <String>[];
     for (var i=0; i < args.length; ++i) {
diff --git a/pkg/http/lib/src/base_request.dart b/pkg/http/lib/src/base_request.dart
index 943f1f6..ffff471 100644
--- a/pkg/http/lib/src/base_request.dart
+++ b/pkg/http/lib/src/base_request.dart
@@ -82,7 +82,7 @@
 
   /// Creates a new HTTP request.
   BaseRequest(this.method, this.url)
-    : headers = {};
+    : headers = <String, String>{};
 
   /// Finalizes the HTTP request in preparation for it being sent. This freezes
   /// all mutable fields and returns a single-subscription [ByteStream] that
diff --git a/pkg/http/lib/src/io_client.dart b/pkg/http/lib/src/io_client.dart
index 1a432d6..47fb1f0 100644
--- a/pkg/http/lib/src/io_client.dart
+++ b/pkg/http/lib/src/io_client.dart
@@ -57,7 +57,9 @@
 
     connection.onResponse = (response) {
       var headers = {};
-      response.headers.forEach((key, value) => headers[key] = value);
+      response.headers.forEach((key, values) {
+        headers[key] = values.join(',');
+      });
 
       if (completed) return;
 
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index e1b952e..c61733e 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -38,7 +38,7 @@
   var pairs = <List<String>>[];
   map.forEach((key, value) =>
       pairs.add([encodeUriComponent(key), encodeUriComponent(value)]));
-  return Strings.join(pairs.mappedBy((pair) => "${pair[0]}=${pair[1]}"), "&");
+  return Strings.join(pairs.map((pair) => "${pair[0]}=${pair[1]}"), "&");
 }
 
 /// Adds all key/value pairs from [source] to [destination], overwriting any
diff --git a/pkg/http/test/client_test.dart b/pkg/http/test/client_test.dart
index e29cef5..fd056c9 100644
--- a/pkg/http/test/client_test.dart
+++ b/pkg/http/test/client_test.dart
@@ -25,6 +25,11 @@
     expect(client.send(request).then((response) {
       expect(response.request, equals(request));
       expect(response.statusCode, equals(200));
+      expect(response.headers['single'], equals('value'));
+      // dart:io internally normalizes outgoing headers so that they never have
+      // multiple headers with the same name, so there's no way to test whether
+      // we handle that case correctly.
+
       return response.stream.bytesToString();
     }).whenComplete(client.close), completion(parse(equals({
       'method': 'POST',
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index 5fc267e..10067d2 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -55,6 +55,7 @@
     consumeInputStream(request.inputStream).then((requestBodyBytes) {
       response.statusCode = 200;
       response.headers.contentType = new ContentType("application", "json");
+      response.headers.set('single', 'value');
 
       var requestBody;
       if (requestBodyBytes.isEmpty) {
@@ -138,19 +139,6 @@
   }
 }
 
-// TODO(nweiz): remove this once it's built in to unittest (issue 7922).
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
-    const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
-  const _StateError() : super("StateError");
-  bool matches(item, MatchState matchState) => item is StateError;
-}
-
 /// A matcher for HttpExceptions.
 const isHttpException = const _HttpException();
 
diff --git a/pkg/intl/lib/intl_standalone.dart b/pkg/intl/lib/intl_standalone.dart
index fc22cf9..e40126f 100644
--- a/pkg/intl/lib/intl_standalone.dart
+++ b/pkg/intl/lib/intl_standalone.dart
@@ -35,12 +35,10 @@
 Future<String> findSystemLocale() {
   // On *nix systems we expect this is an environment variable, which is the
   // easiest thing to check. On a Mac the environment variable may be present
-  // so always check it first.
+  // so always check it first. We have no mechanism for this right now on
+  // Windows, so it will just fail.
   String baseLocale = _checkEnvironmentVariable();
   if (baseLocale != null) return _setLocale(baseLocale);
-  if (Platform.operatingSystem == 'windows') {
-    return _getWindowsSystemInfo();
-  }
   if (Platform.operatingSystem == 'macos') {
     return _getAppleDefaults();
   }
@@ -49,12 +47,6 @@
 }
 
 /**
- * Regular expression to match the expected output of systeminfo on
- * Windows. e.g. System Locale:<tab>en_US;English (United States)
- */
-RegExp sysInfoRegex = new RegExp(r"System Locale:\s+((\w\w;)|(\w\w-\w+;))");
-
-/**
  * Regular expression to match the expected output of reading the defaults
  * database for AppleLanguages on Mac systems.
  * e.g. {
@@ -86,15 +78,6 @@
 }
 
 /**
- * Run the "systemlocale" command and return the output in a future.
- */
-Future _getWindowsSystemInfo() {
-  var p = Process.run('systeminfo', []);
-  var myResult = p.then((result) => _checkResult(result, sysInfoRegex));
-  return myResult;
-}
-
-/**
  * Given [result], find its text and extract the locale from it using
  * [regex], and set it as the system locale. If the process didn't run correctly
  * then don't set the variable and return a future that completes with null.
diff --git a/pkg/intl/lib/src/http_request_data_reader.dart b/pkg/intl/lib/src/http_request_data_reader.dart
index 6cf14c7..530dce6 100644
--- a/pkg/intl/lib/src/http_request_data_reader.dart
+++ b/pkg/intl/lib/src/http_request_data_reader.dart
@@ -19,12 +19,5 @@
   String url;
   HTTPRequestDataReader(this.url);
 
-  Future read(String locale) {
-    var completer = new Completer();
-    var source = '$url$locale.json';
-    var request = new HttpRequest.get(
-        source,
-        (req) => completer.complete(req.responseText));
-    return completer.future;
- }
+  Future read(String locale) => HttpRequest.getString('$url$locale.json');
 }
diff --git a/pkg/intl/test/date_time_format_http_request_test.dart b/pkg/intl/test/date_time_format_http_request_test.dart
index e74448d..139cf6d 100644
--- a/pkg/intl/test/date_time_format_http_request_test.dart
+++ b/pkg/intl/test/date_time_format_http_request_test.dart
@@ -30,7 +30,7 @@
 void runEverything(_) {
   // Initialize all locales and wait for them to finish before running tests.
   var futures = DateFormat.allLocalesWithSymbols()
-      .mappedBy((locale) => initializeDateFormatting(locale, url))
+      .map((locale) => initializeDateFormatting(locale, url))
       .toList();
   Future.wait(futures).then(expectAsync1((_) {
       runDateTests(smallSetOfLocales());
diff --git a/pkg/intl/test/date_time_format_local_test_stub.dart b/pkg/intl/test/date_time_format_local_test_stub.dart
index cd938c8..1b9bfc2 100644
--- a/pkg/intl/test/date_time_format_local_test_stub.dart
+++ b/pkg/intl/test/date_time_format_local_test_stub.dart
@@ -26,7 +26,7 @@
 void runEverything(Function getSubset) {
   // Initialize all locales and wait for them to finish before running tests.
   var futures = DateFormat.allLocalesWithSymbols()
-      .mappedBy((locale) => initializeDateFormatting(locale, null))
+      .map((locale) => initializeDateFormatting(locale, null))
       .toList();
   Future.wait(futures).then((results) => runDateTests(getSubset()));
 }
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index 94f9bcf..fce9e6e 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -218,12 +218,12 @@
     var date_format = new DateFormat("d");
     expect(
         date_format.parsePattern("hh:mm:ss")
-            .mappedBy((x) => x.pattern)
+            .map((x) => x.pattern)
             .toList(),
         orderedEquals(["hh",":", "mm",":","ss"]));
     expect(
         date_format.parsePattern("hh:mm:ss")
-            .mappedBy((x) => x.pattern)
+            .map((x) => x.pattern)
             .toList(),
         orderedEquals(["hh",":", "mm",":","ss"]));
   });
diff --git a/pkg/intl/test/find_default_locale_standalone_test.dart b/pkg/intl/test/find_default_locale_standalone_test.dart
index 50167c6..80bb454 100644
--- a/pkg/intl/test/find_default_locale_standalone_test.dart
+++ b/pkg/intl/test/find_default_locale_standalone_test.dart
@@ -7,22 +7,18 @@
 import 'package:intl/intl.dart';
 import 'package:intl/intl_standalone.dart';
 import 'package:unittest/unittest.dart';
+import 'dart:io';
 
 main() {
   test("Find system locale standalone", () {
     // TODO (alanknight): This only verifies that we found some locale. We
     // should find a way to force the system locale before the test is run
     // and then verify that it's actually the correct value.
+    // We have no way of getting this reliably for Windows, so it will fail.
     Intl.systemLocale = "xx_YY";
     var callback = expectAsync1(verifyLocale);
     findSystemLocale().then(callback);
     });
-
-  test("Test windows regex", () {
-    expect(sysInfoRegex.hasMatch("System Locale:   en-US;blah blah"), isTrue);
-    expect(sysInfoRegex.hasMatch("System Locale:   ru;sdfadsf"), isTrue);
-    expect(sysInfoRegex.hasMatch("System Locale:   ru;"), isTrue);
-  });
 }
 
 verifyLocale(_) {
diff --git a/pkg/oauth2/lib/src/utils.dart b/pkg/oauth2/lib/src/utils.dart
index 85a9f67..bcff589 100644
--- a/pkg/oauth2/lib/src/utils.dart
+++ b/pkg/oauth2/lib/src/utils.dart
@@ -39,7 +39,7 @@
     value = (value == null || value.isEmpty) ? null : encodeUriComponent(value);
     pairs.add([key, value]);
   });
-  return Strings.join(pairs.mappedBy((pair) {
+  return Strings.join(pairs.map((pair) {
     if (pair[1] == null) return pair[0];
     return "${pair[0]}=${pair[1]}";
   }), "&");
diff --git a/pkg/oauth2/test/utils.dart b/pkg/oauth2/test/utils.dart
index 2b6c1a7..0935658 100644
--- a/pkg/oauth2/test/utils.dart
+++ b/pkg/oauth2/test/utils.dart
@@ -45,19 +45,6 @@
   }
 }
 
-// TODO(nweiz): remove this once it's built in to unittest
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
-    const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
-  const _StateError() : super("StateError");
-  bool matches(item, MatchState matchState) => item is StateError;
-}
-
 /// A matcher for AuthorizationExceptions.
 const isAuthorizationException = const _AuthorizationException();
 
diff --git a/pkg/path/lib/path.dart b/pkg/path/lib/path.dart
index 854d4da..3bd2332 100644
--- a/pkg/path/lib/path.dart
+++ b/pkg/path/lib/path.dart
@@ -179,7 +179,7 @@
     var message = new StringBuffer();
     message.add("$method(");
     message.add(args.take(numArgs)
-        .mappedBy((arg) => arg == null ? "null" : '"$arg"')
+        .map((arg) => arg == null ? "null" : '"$arg"')
         .join(", "));
     message.add("): part ${i - 1} was null, but part $i was not.");
     throw new ArgumentError(message.toString());
diff --git a/pkg/pkg.status b/pkg/pkg.status
index bc2bd16..e621a2b 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -37,8 +37,8 @@
 intl/test/find_default_locale_browser_test: Skip
 intl/test/date_time_format_http_request_test: Skip
 
-[ $runtime == vm && $system == windows ]   
-intl/test/find_default_locale_standalone_test: Pass, Fail  # Issue 7722
+[ $runtime == vm && $system == windows ]
+intl/test/find_default_locale_standalone_test: Fail # Issue 8110
 
 # Skip http request tests on Dartium while resolving an odd
 # error there that causes the tests to timeout.
diff --git a/pkg/serialization/lib/serialization.dart b/pkg/serialization/lib/serialization.dart
index 8a95659..3f2146d 100644
--- a/pkg/serialization/lib/serialization.dart
+++ b/pkg/serialization/lib/serialization.dart
@@ -183,7 +183,7 @@
 import 'src/serialization_helpers.dart';
 import 'dart:async';
 import 'dart:json' as json;
-import 'dart:collection' show Queue;
+import 'dart:collection';
 
 part 'src/reader_writer.dart';
 part 'src/serialization_rule.dart';
@@ -311,6 +311,7 @@
     // Both these rules apply to lists, so unless otherwise indicated,
     // it will always find the first one.
     addRule(new ListRuleEssential());
+    addRule(new MapRule());
   }
 
   /**
@@ -426,6 +427,7 @@
     var meta = new Serialization()
       ..selfDescribing = false
       ..addRuleFor(new ListRule())
+      ..addRuleFor(new MapRule())
       ..addRuleFor(new PrimitiveRule())
       ..addRuleFor(new ListRuleEssential())
       ..addRuleFor(basicRule,
@@ -463,4 +465,5 @@
 class SerializationException implements Exception {
   final String message;
   const SerializationException([this.message]);
+  toString() => "SerializationException($message)";
 }
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index adbd9ea..d8f1ebe 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -137,9 +137,25 @@
    createStateHolder() =>
      useMaps ? new _MapWrapper(fields.contents) : new List(fields.length);
 
-  /** Wrap the state if it's passed in as a map. */
-  makeIndexableByNumber(state) =>
-      (state is Map) ? new _MapWrapper.fromMap(state, fields.contents) : state;
+  /**
+   * Wrap the state if it's passed in as a map, and if the keys are references,
+   * resolve them to the strings we expect. We leave the previous keys in there
+   * as well, as they shouldn't be harmful, and it costs more to remove them.
+   */
+   makeIndexableByNumber(state) {
+     if (!(state is Map)) return state;
+     // TODO(alanknight): This is quite inefficient, and we do it twice per
+     // instance. If the keys are references, we need to turn them into strings
+     // before we can look at indexing them by field position. It's also eager,
+     // but we know our keys are always primitives, so we don't have to worry
+     // about their instances not having been created yet.
+     var newState = new Map();
+     for (var each in state.keys) {
+       var newKey = (each is Reference) ? each.inflated() : each;
+       newState[newKey] = state[each];
+     }
+     return new _MapWrapper.fromMap(newState, fields.contents);
+   }
 
   /**
    * Extract the state from [object] using an instanceMirror and the field
@@ -152,12 +168,27 @@
     keysAndValues(fields).forEach(
         (index, field) {
           var value = _value(mirror, field);
+          callback(field.name);
           callback(checkForEssentialLists(index, value));
           result[index] = value;
         });
     return _unwrap(result);
   }
 
+  flatten(state, Writer writer) {
+    if (state is List) {
+      keysAndValues(state).forEach((index, value) {
+        state[index] = writer._referenceFor(value);
+      });
+    } else {
+      var newState = new Map();
+      keysAndValues(state).forEach((key, value) {
+        newState[writer._referenceFor(key)] = writer._referenceFor(value);
+      });
+      return newState;
+    }
+  }
+
   /**
    * If the value is a List, and the field is a constructor field or
    * otherwise specially designated, we wrap it in something that indicates
@@ -219,8 +250,12 @@
     fields.figureOutFields();
   }
 
+  bool get hasVariableLengthEntries => false;
+
+  int get dataLength => fields.length;
+
   /**
-   * Extract the value of the field [fieldName] from the object reflected
+   * Extract the value of [field] from the object reflected
    * by [mirror].
    */
   // TODO(alanknight): The framework should be resilient if there are fields
@@ -498,13 +533,13 @@
 
   List get constructorFields => _constructorFields;
   List constructorFieldNames() =>
-      constructorFields.mappedBy((x) => x.name).toList();
+      constructorFields.map((x) => x.name).toList();
   List constructorFieldIndices() =>
-      constructorFields.mappedBy((x) => x.index).toList();
+      constructorFields.map((x) => x.index).toList();
   List regularFields() => contents.where((x) => !x.usedInConstructor).toList();
-  List regularFieldNames() => regularFields().mappedBy((x) => x.name).toList();
+  List regularFieldNames() => regularFields().map((x) => x.name).toList();
   List regularFieldIndices() =>
-      regularFields().mappedBy((x) => x.index).toList();
+      regularFields().map((x) => x.index).toList();
 
   /**
    * If we weren't given any non-constructor fields to use, figure out what
@@ -514,7 +549,7 @@
    */
   void figureOutFields() {
     Iterable names(Iterable<DeclarationMirror> mirrors) =>
-        mirrors.mappedBy((each) => each.simpleName);
+        mirrors.map((each) => each.simpleName).toList();
 
     if (!_shouldFigureOutFields || !regularFields().isEmpty) return;
     var fields = publicFields(mirror);
@@ -528,6 +563,8 @@
     addAllNotExplicitlyExcluded(names(gettersWithSetters));
     addAllNotExplicitlyExcluded(names(gettersThatMatchConstructor));
   }
+
+  toString() => "FieldList($contents)";
 }
 
 /**
@@ -569,10 +606,9 @@
    */
   constructFrom(state, Reader r) {
     // TODO(alanknight): Handle named parameters
-    Collection inflated = fieldNumbers.mappedBy(
-        (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x))
-            .toList();
-    var result = type.newInstance(name, inflated);
+    Iterable inflated = fieldNumbers.map(
+        (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x));
+    var result = type.newInstance(name, inflated.toList());
     return deprecatedFutureValue(result);
   }
 }
@@ -582,12 +618,13 @@
  * from the index into a field name and then looks it up in the map.
  */
 class _MapWrapper {
-  Map<String, dynamic> _map = new Map<String, dynamic>();
+  final _map;
   List fieldList;
-  _MapWrapper(this.fieldList);
+  _MapWrapper(this.fieldList) : _map = new Map();
   _MapWrapper.fromMap(this._map, this.fieldList);
 
   operator [](key) => _map[fieldList[key].name];
+
   operator []=(key, value) { _map[fieldList[key].name] = value; }
   get length => _map.length;
 
diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart
index 4ab20d4..c1d122e 100644
--- a/pkg/serialization/lib/src/format.dart
+++ b/pkg/serialization/lib/src/format.dart
@@ -95,6 +95,11 @@
    */
   final bool storeRoundTripInfo;
 
+  /**
+   * If we store the rule numbers, what key should we use to store them.
+   */
+  String ruleIdentifier = "__rule";
+
   SimpleJsonFormat({this.storeRoundTripInfo : false});
 
   /**
@@ -129,7 +134,7 @@
         if (storeRoundTripInfo) ruleData[i].add(rule.number);
       } else if (each is Map) {
         jsonifyEntry(each, w);
-        if (storeRoundTripInfo) each["__rule"] = rule.number;
+        if (storeRoundTripInfo) each[ruleIdentifier] = rule.number;
       }
     }
   }
@@ -156,8 +161,7 @@
     var result = {};
     result["rules"] = null;
     var ruleData =
-        new List(r.serialization.rules.length).mappedBy((x) => []).toList();
-    var rootRule = data["__rule"];
+        new List(r.serialization.rules.length).map((x) => []).toList();
     var top = recursivelyFixUp(data, r, ruleData);
     result["data"] = ruleData;
     result["roots"] = [top];
@@ -172,12 +176,17 @@
       result[r._primitiveRule().number].add(data);
       return data;
     }
-    var ruleNumber =
-        (data is List) ? data.removeLast() : data.remove("__rule");
-    var newData = values(data).mappedBy(
-        (x) => recursivelyFixUp(x, r, result));
+    var ruleNumber;
+    if (data is List) {
+      ruleNumber = data.removeLast();
+    } else if (data is Map) {
+      ruleNumber = data.remove(ruleIdentifier);
+    } else {
+      throw new SerializationException("Invalid data format");
+    }
+    var newData = mapValues(data, (x) => recursivelyFixUp(x, r, result));
     result[ruleNumber].add(newData);
-    return new Reference(this, ruleNumber, result[ruleNumber].length - 1);
+    return new Reference(r, ruleNumber, result[ruleNumber].length - 1);
   }
 }
 
@@ -225,12 +234,14 @@
   void writeStateInto(SerializationRule rule, List ruleData, List target) {
     if (!ruleData.isEmpty) {
       var sample = ruleData.first;
-      if (sample is List) {
+      if (rule.storesStateAsLists || sample is List) {
         writeLists(rule, ruleData, target);
-      } else if (sample is Map) {
+      } else if (rule.storesStateAsMaps || sample is Map) {
         writeMaps(rule, ruleData, target);
-      } else {
+      } else if (rule.storesStateAsPrimitives || isPrimitive(sample)) {
         writeObjects(ruleData, target);
+      } else {
+        throw new SerializationException("Invalid data format");
       }
     } else {
       // If there is no data, write a zero for the length.
@@ -271,13 +282,8 @@
       if (rule.hasVariableLengthEntries) {
         target.add(eachEntry.length);
       }
-      // We take advantage of this being only a semi-flat format, and expecting
-      // that the keys here are field names, i.e. strings. So we write
-      // the keys as literals and the values as references. This duplicates the
-      // keys, so is quite inefficient. But generating maps rather than lists is
-      // not very efficient in the first place.
       eachEntry.forEach((key, value) {
-        target.add(key);
+        writeReference(key, target);
         writeReference(value, target);
       });
     }
@@ -289,6 +295,9 @@
    */
   writeObjects(List entries, List target) {
     target.add(STORED_AS_PRIMITIVE);
+    for (var each in entries) {
+      if (!isPrimitive(each)) throw new SerializationException("Invalid data");
+    }
     target.addAll(entries);
   }
 
@@ -312,6 +321,9 @@
    * format.
    */
   Map<String, dynamic> read(List rawInput, Reader r) {
+    // TODO(alanknight): It's annoying to have to pass the reader around so
+    // much, consider having the format be specific to a particular
+    // serialization operation along with the reader and having it as a field.
     var input = {};
     input["rules"] = rawInput[0];
     r.readRules(input["rules"]);
@@ -320,14 +332,14 @@
     var stream = flatData.iterator;
     var tempData = new List(r.rules.length);
     for (var eachRule in r.rules) {
-       tempData[eachRule.number] = readRuleDataFrom(stream, eachRule);
+       tempData[eachRule.number] = readRuleDataFrom(stream, eachRule, r);
     }
     input["data"] = tempData;
 
     var roots = [];
     var rootsAsInts = rawInput[2].iterator;
     do {
-      roots.add(nextReferenceFrom(rootsAsInts));
+      roots.add(nextReferenceFrom(rootsAsInts, r));
     } while (rootsAsInts.current != null);
 
     input["roots"] = roots;
@@ -337,14 +349,14 @@
   /**
    * Read the data for [rule] from [input] and return it.
    */
-  readRuleDataFrom(Iterator input, SerializationRule rule) {
+  readRuleDataFrom(Iterator input, SerializationRule rule, Reader r) {
     var numberOfEntries = _next(input);
     var entryType = _next(input);
     if (entryType == STORED_AS_LIST) {
-      return readLists(input, rule, numberOfEntries);
+      return readLists(input, rule, numberOfEntries, r);
     }
     if (entryType == STORED_AS_MAP) {
-      return readMaps(input, rule, numberOfEntries);
+      return readMaps(input, rule, numberOfEntries, r);
     }
     if (entryType == STORED_AS_PRIMITIVE) {
       return readPrimitives(input, rule, numberOfEntries);
@@ -360,7 +372,7 @@
    * Read data for [rule] from [input] with [length] number of entries,
    * creating lists from the results.
    */
-  readLists(Iterator input, SerializationRule rule, int length) {
+  readLists(Iterator input, SerializationRule rule, int length, Reader r) {
     var ruleData = [];
     for (var i = 0; i < length; i++) {
       var subLength =
@@ -368,7 +380,7 @@
       var subList = [];
       ruleData.add(subList);
       for (var j = 0; j < subLength; j++) {
-        subList.add(nextReferenceFrom(input));
+        subList.add(nextReferenceFrom(input, r));
       }
     }
     return ruleData;
@@ -378,15 +390,17 @@
    * Read data for [rule] from [input] with [length] number of entries,
    * creating maps from the results.
    */
-  readMaps(Iterator input, SerializationRule rule, int length) {
+  readMaps(Iterator input, SerializationRule rule, int length, Reader r) {
     var ruleData = [];
     for (var i = 0; i < length; i++) {
       var subLength =
           rule.hasVariableLengthEntries ? _next(input) : rule.dataLength;
-      var map = {};
+      var map = new Map();
       ruleData.add(map);
       for (var j = 0; j < subLength; j++) {
-        map[_next(input)] = nextReferenceFrom(input);
+        var key = nextReferenceFrom(input, r);
+        var value = nextReferenceFrom(input, r);
+        map[key] = value;
       }
     }
     return ruleData;
@@ -405,13 +419,13 @@
   }
 
   /** Read the next Reference from the input. */
-  nextReferenceFrom(Iterator input) {
+  nextReferenceFrom(Iterator input, Reader r) {
     var a = _next(input);
     var b = _next(input);
     if (a == null) {
       return null;
     } else {
-      return new Reference(this, a, b);
+      return new Reference(r, a, b);
     }
   }
 
@@ -420,4 +434,4 @@
     input.moveNext();
     return input.current;
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/serialization/lib/src/reader_writer.dart b/pkg/serialization/lib/src/reader_writer.dart
index 87535ce..146255d 100644
--- a/pkg/serialization/lib/src/reader_writer.dart
+++ b/pkg/serialization/lib/src/reader_writer.dart
@@ -13,7 +13,7 @@
 // that isn't necessary, e.g. detecting cycles and maintaining references.
 // Consider having an abstract superclass with the basic functionality and
 // simple serialization subclasses where we know there aren't cycles.
-class Writer {
+class Writer implements ReaderOrWriter {
   /**
    * The [serialization] holds onto the rules that define how objects
    * are serialized.
@@ -88,8 +88,13 @@
     for (var eachRule in rules) {
       _growStates(eachRule);
       var index = eachRule.number;
-      for (var eachState in states[index]) {
-        eachRule.flatten(eachState, this);
+      var statesForThisRule = states[index];
+      for (var i = 0; i < statesForThisRule.length; i++) {
+        var eachState = statesForThisRule[i];
+        var newState = eachRule.flatten(eachState, this);
+        if (newState != null) {
+          statesForThisRule[i] = newState;
+        }
       }
     }
   }
@@ -192,15 +197,18 @@
    * Return a list of [Reference] objects pointing to our roots. This will be
    * stored in the output under "roots" in the default format.
    */
-  _rootReferences() => trace.roots.mappedBy(_referenceFor).toList();
+  _rootReferences() => trace.roots.map(_referenceFor).toList();
 
   /**
    * Given an object, return a reference for it if one exists. If there's
-   * no reference, return null. Once we have finished the tracing step, all
-   * objects that should have a reference (roughly speaking, non-primitives)
-   * can be relied on to have a reference.
+   * no reference, return the object itself. Once we have finished the tracing
+   * step, all objects that should have a reference (roughly speaking,
+   * non-primitives) can be relied on to have a reference.
    */
-  _referenceFor(object) => references[object];
+  _referenceFor(object) {
+    var result = references[object];
+    return (result == null) ? object : result;
+  }
 
   /**
    * Return true if the [namedObjects] collection has a reference to [object].
@@ -217,13 +225,32 @@
 
   // For debugging/testing purposes. Find what state a reference points to.
   stateForReference(Reference r) => states[r.ruleNumber][r.objectNumber];
+
+  /** Return the state pointed to by [reference]. */
+  resolveReference(reference) => stateForReference(reference);
+}
+
+/**
+ * An abstract class for Reader and Writer, which primarily exists so we can
+ * type things that will refer to one or the other, depending on which
+ * operation we're doing.
+ */
+abstract class ReaderOrWriter {
+  /** Return the list of serialization rules we are using.*/
+  List<SerializationRule> get rules;
+
+  /**
+   * Return the object, or state, that ref points to, depending on which
+   * we're generating.
+   */
+  resolveReference(Reference ref);
 }
 
 /**
  * The main class responsible for reading. It holds
  * onto the necessary state and to the objects that have been inflated.
  */
-class Reader {
+class Reader implements ReaderOrWriter {
 
   /**
    * The serialization that specifies how we read. Note that in contrast
@@ -304,7 +331,7 @@
   // When we set the data, initialize the object storage to a matching size.
   void set data(List<List> newData) {
     _data = newData;
-    objects = _data.mappedBy((x) => new List(x.length)).toList();
+    objects = _data.map((x) => new List(x.length)).toList();
   }
 
   /**
@@ -388,6 +415,9 @@
         });
   }
 
+  /** Return the object pointed to by [reference]. */
+  resolveReference(reference) => inflateReference(reference);
+
   /**
    * Given [reference], return what we have stored as an object for it. Note
    * that, depending on the current state, this might be null or a Sentinel.
@@ -518,13 +548,27 @@
  */
 class Reference {
   /** The [Reader] or [Writer] that owns this reference. */
-  final parent;
+  final ReaderOrWriter parent;
   /** The position of the rule that controls this reference in [parent]. */
   final int ruleNumber;
   /** The index of the referred-to object in the storage of [parent] */
   final int objectNumber;
 
-  const Reference(this.parent, this.ruleNumber, this.objectNumber);
+  Reference(this.parent, this.ruleNumber, this.objectNumber) {
+    if (ruleNumber == null || objectNumber == null) {
+      throw new SerializationException("Invalid Reference");
+    }
+    if (parent.rules.length < ruleNumber) {
+      throw new SerializationException("Invalid Reference");
+    }
+  }
+
+  /**
+   * Return the thing this reference points to. Assumes that we have a valid
+   * parent and that it is a Reader, as inflating is not meaningful when
+   * writing.
+   */
+  inflated() => parent.resolveReference(this);
 
   /**
    * Convert the reference to a map in JSON format. This is specific to the
@@ -545,7 +589,7 @@
     list.add(objectNumber);
   }
 
-  toString() => "Reference $ruleNumber, $objectNumber";
+  toString() => "Reference($ruleNumber, $objectNumber)";
 }
 
 /**
diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
index a995473..9568c24 100644
--- a/pkg/serialization/lib/src/serialization_helpers.dart
+++ b/pkg/serialization/lib/src/serialization_helpers.dart
@@ -77,7 +77,7 @@
    * [collection] is a List, it will be the same as the map() method if the
    * [key] parameter wasn't passed.
    */
-  mappedBy(Function f) {
+  map(Function f) {
     var result = copyEmpty();
     forEach((key, value) {
        result[key] = f(key, value);
@@ -131,9 +131,9 @@
 }
 
 mapValues(x, f) {
-  if (x is Set) return x.mappedBy(f).toSet();
-  if (x is Iterable) return x.mappedBy(f).toList();
-  if (x is Map) return new ListLikeIterable(x).mappedBy(f);
+  if (x is Set) return x.map(f).toSet();
+  if (x is Iterable) return x.map(f).toList();
+  if (x is Map) return new ListLikeIterable(x).map(f);
   throw new ArgumentError("Invalid argument");
 }
 
@@ -158,7 +158,7 @@
    * [collection] is a List, it will be the same as if map() had been called
    * directly on [collection].
    */
-  mappedBy(Function f) {
+  map(Function f) {
       var result = new Map();
       collection.forEach((key, value) => result[key] = f(value));
       return result;
@@ -251,4 +251,4 @@
 
   // Note that this is doing an equality comparison.
   bool containsValue(x) => values.contains(x);
-}
\ No newline at end of file
+}
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index b040796..5c397b0 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -28,7 +28,7 @@
    * be identified within it by number.
    */
   void set number(x) {
-    if (_number != null) throw
+    if (_number != null && _number != x) throw
         new SerializationException("Rule numbers cannot be changed, once set");
     _number = x;
   }
@@ -48,23 +48,32 @@
   extractState(object, void f(value));
 
   /**
+   * Allows rules to tell us how they expect to store their state. If this
+   * isn't specified we can also just look at the data to tell.
+   */
+  bool get storesStateAsLists => false;
+  bool get storesStateAsMaps => false;
+  bool get storesStateAsPrimitives => false;
+
+  /**
    * Given the variables representing the state of an object, flatten it
    * by turning object pointers into Reference objects where needed. This
    * destructively modifies the state object.
    *
    * This has a default implementation which assumes that object is indexable,
    * so either conforms to Map or List. Subclasses may override to do something
-   * different.
+   * different, including returning a new state object to be used in place
+   * of the original.
    */
   // This has to be a separate operation from extracting, because we extract
   // as we are traversing the objects, so we don't yet have the objects to
   // generate references for them. It might be possible to avoid that by
   // doing a depth-first rather than breadth-first traversal, but I'm not
   // sure it's worth it.
-  void flatten(state, Writer writer) {
+  flatten(state, Writer writer) {
     keysAndValues(state).forEach((key, value) {
       var reference = writer._referenceFor(value);
-      state[key] = (reference == null) ? value : reference;
+      state[key] = reference;
     });
   }
 
@@ -131,7 +140,7 @@
 
   appliesTo(object, Writer w) => object is List;
 
-  state(List list) => new List.from(list);
+  bool get storesStateAsLists => true;
 
   List extractState(List list, f) {
     var result = new List();
@@ -180,6 +189,84 @@
 }
 
 /**
+ * This rule handles things that implement Map. It will recreate them as
+ * whatever the default implemenation of Map is on the target platform. If a
+ * map has string keys it will attempt to retain it as a map for JSON formats,
+ * otherwise it will store it as a list of references to keys and values.
+ */
+class MapRule extends SerializationRule {
+
+  appliesTo(object, Writer w) => object is Map;
+
+  bool get storesStateAsMaps => true;
+
+  extractState(Map map, f) {
+    // Note that we make a copy here because flattening may be destructive.
+    var newMap = new Map.from(map);
+    newMap.forEach((key, value) {
+      f(key);
+      f(value);
+    });
+    return newMap;
+  }
+
+  /**
+   * Change the keys and values of [state] into references in [writer].
+   * If [state] is a map whose keys are all strings then we leave the keys
+   * as is so that JSON formats will be more readable. If the keys are
+   * arbitrary then we need to turn them into references and replace the
+   * state with a new Map whose keys are the references.
+   */
+  flatten(Map state, Writer writer) {
+    bool keysAreAllStrings = state.keys.every((x) => x is String);
+    if (keysAreAllStrings) {
+      keysAndValues(state).forEach(
+          (key, value) => state[key] = writer._referenceFor(value));
+      return state;
+    } else {
+      var newState = [];
+      keysAndValues(state).forEach((key, value) {
+        newState.add(writer._referenceFor(key));
+        newState.add(writer._referenceFor(value));
+      });
+      return newState;
+    }
+  }
+
+  inflateEssential(state, Reader r) => new Map();
+
+  // For a map, we consider all of its state non-essential and add it
+  // after creation.
+  inflateNonEssential(state, Map newMap, Reader r) {
+    if (state is List) {
+      inflateNonEssentialFromList(state, newMap, r);
+    } else {
+      inflateNonEssentialFromMap(state, newMap, r);
+    }
+  }
+
+  void inflateNonEssentialFromList(List state, Map newMap, Reader r) {
+    var key;
+    for (var each in state) {
+      if (key == null) {
+        key = each;
+      } else {
+        newMap[r.inflateReference(key)] = r.inflateReference(each);
+        key = null;
+      }
+    }
+  }
+
+  void inflateNonEssentialFromMap(Map state, Map newMap, Reader r) {
+    state.forEach((key, value) {
+      newMap[r.inflateReference(key)] = r.inflateReference(value);
+    });
+  }
+
+  bool get hasVariableLengthEntries => true;
+}
+
+/**
  * This rule handles primitive types, defined as those that we can normally
  * represent directly in the output format. We hard-code that to mean
  * num, String, and bool.
@@ -189,10 +276,12 @@
     return isPrimitive(object);
   }
   extractState(object, Function f) => object;
-  void flatten(object, Writer writer) {}
+  flatten(object, Writer writer) {}
   inflateEssential(state, Reader r) => state;
   inflateNonEssential(object, _, Reader r) {}
 
+  bool get storesStateAsPrimitives => true;
+
   /**
    * Indicate whether we should save pointers to this object as references
    * or store the object directly. For primitives this depends on the format,
@@ -274,7 +363,7 @@
   // reference to that. But that requires adding the Writer as a parameter to
   // extractState, and I'm reluctant to add yet another parameter until
   // proven necessary.
-  void flatten(state, Writer writer) {
+  flatten(state, Writer writer) {
     state[0] = nameFor(state.first, writer);
   }
 
@@ -390,7 +479,7 @@
 
   // These operations will work, but may be expensive, and are probably
   // best avoided.
-  get _inflated => keysAndValues(_raw).mappedBy(_reader.inflateReference);
+  get _inflated => keysAndValues(_raw).map(_reader.inflateReference);
   bool containsValue(x) => _inflated.containsValue(x);
   Iterable get values => _inflated.values;
   void forEach(f) => _inflated.forEach(f);
@@ -429,7 +518,7 @@
   // These operations, and other inherited methods that iterate over the whole
   // list will work, but may be expensive, and are probably
   // best avoided.
-  List get _inflated => _raw.mappedBy(_reader.inflateReference);
+  List get _inflated => _raw.map(_reader.inflateReference);
   Iterator get iterator => _inflated.iterator;
   indexOf(x, [pos = 0]) => _inflated.toList().indexOf(x);
   lastIndexOf(x, [pos]) => _inflated.toList().lastIndexOf(x);
@@ -445,8 +534,8 @@
   sort([f]) => _throw();
   clear() => _throw();
   removeAt(x) => _throw();
-  removeLast() => _throw();
   remove(x) => _throw();
+  removeLast() => _throw();
   removeAll(x) => _throw();
   retainAll(x) => _throw();
   removeMatching(x) => _throw();
@@ -455,6 +544,6 @@
   setRange(x, y, z, [a]) => _throw();
   removeRange(x, y) => _throw();
   insertRange(x, y, [z]) => _throw();
+  get reversed => _throw();
   void set length(x) => _throw();
-  List get reversed => _throw();
 }
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 73e2e13..f4713a2 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -47,15 +47,19 @@
     // actually writing.
     var w = new Writer(s);
     w.write(p1);
-    var flatPerson = w.states[3].first;
+    var personRule = s.rules.firstMatching(
+        (x) => x is BasicRule && x.type == reflect(p1).type);
+    var flatPerson = w.states[personRule.number].first;
     var primStates = w.states.first;
     expect(primStates.isEmpty, true);
     expect(flatPerson["name"], "Alice");
     var ref = flatPerson["address"];
     expect(ref is Reference, true);
-    expect(ref.ruleNumber, 4);
+    var addressRule = s.rules.firstMatching(
+        (x) => x is BasicRule && x.type == reflect(a1).type);
+    expect(ref.ruleNumber, addressRule.number);
     expect(ref.objectNumber, 0);
-    expect(w.states[4].first['street'], 'N 34th');
+    expect(w.states[addressRule.number].first['street'], 'N 34th');
   });
 
   test('exclude fields', () {
@@ -206,9 +210,11 @@
     var w = new Writer(s);
     w.trace = new Trace(w);
     w.write(n1);
-    expect(w.states.length, 4); // prims, lists, essential lists, basic
+    expect(w.states.length, 5); // prims, lists, essential lists, basic
     var children = 0, name = 1, parent = 2;
-    List rootNode = w.states[3].where((x) => x[name] == "1").toList();
+    var nodeRule = s.rules.firstMatching((x) => x is BasicRule);
+    List rootNode = w.states[nodeRule.number].where(
+        (x) => x[name] == "1").toList();
     rootNode = rootNode.first;
     expect(rootNode[parent], isNull);
     var list = w.states[1].first;
@@ -372,6 +378,25 @@
     expect(a2.city, "Seattle");
   });
 
+  test("Straight JSON format, root is a Map", () {
+    // Note that we can't use the usual round-trip test because it has cycles.
+    var p1 = new Person()..name = 'Alice'..address = a1;
+    // Use maps for one rule, lists for the other.
+    var s = new Serialization()
+      ..addRuleFor(a1)
+      ..addRuleFor(p1).configureForMaps();
+    var format = new SimpleJsonFormat(storeRoundTripInfo: true);
+    var writer = s.newWriter(format);
+    var out = writer.write({"stuff" : p1});
+    var reader = s.newReader(format);
+    var p2 = reader.read(out)["stuff"];
+    expect(p2.name, "Alice");
+    var a2 = p2.address;
+    expect(a2.street, "N 34th");
+    expect(a2.city, "Seattle");
+  });
+
+
   test("Straight JSON format, round-trip with named objects", () {
     // Note that we can't use the usual round-trip test because it has cycles.
     var p1 = new Person()..name = 'Alice'..address = a1;
@@ -389,6 +414,54 @@
     var a2 = p2.address;
     expect(a2, 12);
   });
+
+  test("Maps", () {
+    var s = new Serialization()..selfDescribing = false;
+    var p1 = new Person()..name = 'Alice'..address = a1;
+    var data = new Map();
+    data["simple data"] = 1;
+    data[p1] = a1;
+    data[a1] = p1;
+    var formats = [new SimpleFlatFormat(), new SimpleMapFormat(),
+        new SimpleJsonFormat(storeRoundTripInfo: true)];
+    for (var eachFormat in formats) {
+      var output = s.write(data, eachFormat);
+      var reader = s.newReader(eachFormat);
+      var input = reader.read(output);
+      expect(input["simple data"], data["simple data"]);
+      var p2 = input.keys.firstMatching((x) => x is Person);
+      var a2 = input.keys.firstMatching((x) => x is Address);
+      if (eachFormat is SimpleJsonFormat) {
+        // JSON doesn't handle cycles, so these won't be identical.
+        expect(input[p2] is Address, isTrue);
+        expect(input[a2] is Person, isTrue);
+        var a3 = input[p2];
+        expect(a3.city, a2.city);
+        expect(a3.state, a2.state);
+        expect(a3.state, a2.state);
+        var p3 = input[a2];
+        expect(p3.name, p2.name);
+        expect(p3.rank, p2.rank);
+        expect(p3.address.city, a2.city);
+      } else {
+        expect(input[p2], same(a2));
+        expect(input[a2], same(p2));
+      }
+    }
+  });
+
+  test("Map with string keys stays that way", () {
+    var s = new Serialization()..addRuleFor(new Person());
+    var data = {"abc" : 1, "def" : "ghi"};
+    data["person"] = new Person()..name = "Foo";
+    var output = s.write(data, new SimpleMapFormat());
+    var mapRule = s.rules.firstMatching((x) => x is MapRule);
+    var map = json.parse(output)["data"][mapRule.number][0];
+    expect(map is Map, isTrue);
+    expect(map["abc"], 1);
+    expect(map["def"], "ghi");
+    expect(new Reader(s).asReference(map["person"]) is Reference, isTrue);
+  });
 }
 
 /******************************************************************************
@@ -413,10 +486,11 @@
           'constructorName',
           'constructorFields', 'regularFields', []],
         fields: [])
-     ..addRuleFor(new Serialization()).setFieldWith('rules',
-         (InstanceMirror s, List rules) {
+     ..addRuleFor(new Serialization(), constructor: "blank")
+         .setFieldWith('rules',
+           (InstanceMirror s, List rules) {
              rules.forEach((x) => s.reflectee.addRule(x));
-         })
+           })
     ..addRule(new NamedObjectRule())
     ..addRule(new MirrorRule());
   return meta;
@@ -441,7 +515,12 @@
   var reader = new Reader(aSerialization);
   // We're not sure which rule needs the sample data, so put it everywhere
   // and trust that the extra will just be ignored.
-  reader.data = [[sampleData], [sampleData], [sampleData], [sampleData]];
+  var fillValue = [sampleData];
+  var data = [];
+  for (int i = 0; i < 10; i++) {
+    data.add(fillValue);
+  }
+  reader.data = data;
   return reader;
 }
 
@@ -562,7 +641,7 @@
 /** Extract the state from [object] using the rules in [s] and return it. */
 states(object, Serialization s) {
   var rules = s.rulesFor(object, null);
-  return rules.mappedBy((x) => x.extractState(object, doNothing)).toList();
+  return rules.map((x) => x.extractState(object, doNothing)).toList();
 }
 
 /** A hard-coded rule for serializing Node instances. */
diff --git a/pkg/unittest/lib/compact_vm_config.dart b/pkg/unittest/lib/compact_vm_config.dart
index cb21d4d..6b46a65 100644
--- a/pkg/unittest/lib/compact_vm_config.dart
+++ b/pkg/unittest/lib/compact_vm_config.dart
@@ -58,7 +58,7 @@
   }
 
   String _indent(String str) {
-    return str.split("\n").mappedBy((line) => "  $line").join("\n");
+    return str.split("\n").map((line) => "  $line").join("\n");
   }
 
   void onSummary(int passed, int failed, int errors, List<TestCase> results,
diff --git a/pkg/unittest/lib/html_config.dart b/pkg/unittest/lib/html_config.dart
index a4a1f9f..d4c9cdb 100644
--- a/pkg/unittest/lib/html_config.dart
+++ b/pkg/unittest/lib/html_config.dart
@@ -7,6 +7,7 @@
  */
 library unittest_html_config;
 
+import 'dart:async';
 import 'dart:html';
 import 'unittest.dart';
 
@@ -89,32 +90,28 @@
   final bool _isLayoutTest;
   HtmlConfiguration(this._isLayoutTest);
 
-  // TODO(rnystrom): Get rid of this if we get canonical closures for methods.
-  EventListener _onErrorClosure;
-  EventListener _onMessageClosure;
+  StreamSubscription<Event> _onErrorSubscription;
+  StreamSubscription<Event> _onMessageSubscription;
 
   void _installHandlers() {
-    if (_onErrorClosure == null) {
-      _onErrorClosure =
-          (e) => handleExternalError(e, '(DOM callback has errors)');
-      // Listen for uncaught errors.
-      window.on.error.add(_onErrorClosure);
+    if (_onErrorSubscription == null) {
+      _onErrorSubscription = window.onError.listen(
+        (e) => handleExternalError(e, '(DOM callback has errors)'));
     }
-    if (_onMessageClosure == null) {
-      _onMessageClosure = (e) => processMessage(e);
-      // Listen for errors from JS.
-      window.on.message.add(_onMessageClosure);
+    if (_onMessageSubscription == null) {
+      _onMessageSubscription = window.onMessage.listen(
+        (e) => processMessage(e));
     }
   }
 
   void _uninstallHandlers() {
-    if (_onErrorClosure != null) {
-      window.on.error.remove(_onErrorClosure);
-      _onErrorClosure = null;
+    if (_onErrorSubscription != null) {
+      _onErrorSubscription.cancel();
+      _onErrorSubscription = null;
     }
-    if (_onMessageClosure != null) {
-      window.on.message.remove(_onMessageClosure);
-      _onMessageClosure = null;
+    if (_onMessageSubscription != null) {
+      _onMessageSubscription.cancel();
+      _onMessageSubscription = null;
     }
   }
 
diff --git a/pkg/unittest/lib/html_individual_config.dart b/pkg/unittest/lib/html_individual_config.dart
index 2de4ed2..f722a6d 100644
--- a/pkg/unittest/lib/html_individual_config.dart
+++ b/pkg/unittest/lib/html_individual_config.dart
@@ -24,11 +24,15 @@
   HtmlIndividualConfiguration(isLayoutTest): super(isLayoutTest);
 
   void onStart() {
-    var testGroupName = window.location.hash;
+    var testGroupName = window.location.search;
     if (testGroupName != '') {
       try {
-        testGroupName = testGroupName.substring(1); // cut off the #
-        unittest.filterTests('^$testGroupName');
+        for (var parameter in testGroupName.substring(1).split('&')) {
+          if (parameter.startsWith('group=')) {
+            testGroupName = parameter.split('=')[1];
+          }
+        }
+        unittest.filterTests('^$testGroupName${unittest.groupSep}');
       } catch (e) {
         print('tried to match "$testGroupName"');
         print('NO_SUCH_TEST');
diff --git a/pkg/unittest/lib/src/config.dart b/pkg/unittest/lib/src/config.dart
index c77019b..73de212 100644
--- a/pkg/unittest/lib/src/config.dart
+++ b/pkg/unittest/lib/src/config.dart
@@ -146,7 +146,7 @@
     // TODO(nweiz): Use this simpler code once issue 2980 is fixed.
     // return str.replaceAll(new RegExp("^", multiLine: true), "  ");
 
-    return Strings.join(str.split("\n").mappedBy((line) => "  $line"), "\n");
+    return Strings.join(str.split("\n").map((line) => "  $line"), "\n");
   }
 
   /** Handle errors that happen outside the tests. */
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index fbf1465..489fecd 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -504,6 +504,19 @@
   bool matches(item, MatchState matchState) => item is UnsupportedError;
 }
 
+/** A matcher for StateErrors. */
+const isStateError = const _StateError();
+
+/** A matcher for functions that throw StateError. */
+const Matcher throwsStateError =
+    const Throws(isStateError);
+
+class _StateError extends TypeMatcher {
+  const _StateError() : super("StateError");
+  bool matches(item, MatchState matchState) => item is StateError;
+}
+
+
 /** A matcher for Map types. */
 const isMap = const _IsMap();
 
diff --git a/pkg/yaml/README.md b/pkg/yaml/README.md
new file mode 100644
index 0000000..ad7678f
--- /dev/null
+++ b/pkg/yaml/README.md
@@ -0,0 +1,24 @@
+A parser for [YAML](http://www.yaml.org/).
+
+Use `loadYaml` to load a single document, or `loadYamlStream` to load a
+stream of documents. For example:
+
+    import 'package:yaml/yaml.dart';
+    main() {
+      var doc = loadYaml("YAML: YAML Ain't Markup Language");
+      print(doc['YAML']);
+    }
+
+This library currently doesn't support dumping to YAML. You should use
+`stringify` from `dart:json` instead:
+
+    import 'dart:json' as json;
+    import 'package:yaml/yaml.dart';
+    main() {
+      var doc = loadYaml("YAML: YAML Ain't Markup Language");
+      print(json.stringify(doc));
+    }
+
+The source code for this package is at <http://code.google.com/p/dart>.
+Please file issues at <http://dartbug.com>. Other questions or comments can be
+directed to the Dart mailing list at <mailto:misc@dartlang.org>.
diff --git a/utils/pub/yaml/composer.dart b/pkg/yaml/lib/composer.dart
similarity index 100%
rename from utils/pub/yaml/composer.dart
rename to pkg/yaml/lib/composer.dart
diff --git a/utils/pub/yaml/constructor.dart b/pkg/yaml/lib/constructor.dart
similarity index 100%
rename from utils/pub/yaml/constructor.dart
rename to pkg/yaml/lib/constructor.dart
diff --git a/utils/pub/yaml/deep_equals.dart b/pkg/yaml/lib/deep_equals.dart
similarity index 100%
rename from utils/pub/yaml/deep_equals.dart
rename to pkg/yaml/lib/deep_equals.dart
diff --git a/utils/pub/yaml/model.dart b/pkg/yaml/lib/model.dart
similarity index 97%
rename from utils/pub/yaml/model.dart
rename to pkg/yaml/lib/model.dart
index 8c111af..7a609b9 100644
--- a/utils/pub/yaml/model.dart
+++ b/pkg/yaml/lib/model.dart
@@ -91,7 +91,7 @@
   }
 
   String toString() =>
-      '$tag [${Strings.join(content.mappedBy((e) => '$e'), ', ')}]';
+      '$tag [${Strings.join(content.map((e) => '$e'), ', ')}]';
 
   int get hashCode => super.hashCode ^ _hashCode(content);
 
@@ -150,7 +150,7 @@
       // TODO(nweiz): This could be faster if we used a RegExp to check for
       // special characters and short-circuited if they didn't exist.
 
-      var escapedValue = value.charCodes.mappedBy((c) {
+      var escapedValue = value.charCodes.map((c) {
         switch (c) {
         case _Parser.TAB: return "\\t";
         case _Parser.LF: return "\\n";
@@ -223,7 +223,7 @@
 
   String toString() {
     var strContent = content.keys
-        .mappedBy((k) => '${k}: ${content[k]}')
+        .map((k) => '${k}: ${content[k]}')
         .join(', ');
     return '$tag {$strContent}';
   }
diff --git a/utils/pub/yaml/parser.dart b/pkg/yaml/lib/parser.dart
similarity index 100%
rename from utils/pub/yaml/parser.dart
rename to pkg/yaml/lib/parser.dart
diff --git a/utils/pub/yaml/visitor.dart b/pkg/yaml/lib/visitor.dart
similarity index 92%
rename from utils/pub/yaml/visitor.dart
rename to pkg/yaml/lib/visitor.dart
index b5c14c9..42dbb22 100644
--- a/utils/pub/yaml/visitor.dart
+++ b/pkg/yaml/lib/visitor.dart
@@ -14,7 +14,7 @@
 
   /// Visits each node in [seq] and returns a list of the results.
   visitSequence(_SequenceNode seq)
-      => seq.content.mappedBy((e) => e.visit(this)).toList();
+      => seq.content.map((e) => e.visit(this)).toList();
 
   /// Visits each key and value in [map] and returns a map of the results.
   visitMapping(_MappingNode map) {
diff --git a/utils/pub/yaml/yaml.dart b/pkg/yaml/lib/yaml.dart
similarity index 69%
rename from utils/pub/yaml/yaml.dart
rename to pkg/yaml/lib/yaml.dart
index a73736d..e905e76 100644
--- a/utils/pub/yaml/yaml.dart
+++ b/pkg/yaml/lib/yaml.dart
@@ -2,6 +2,26 @@
 // for 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 parser for [YAML](http://www.yaml.org/).
+///
+/// Use [loadYaml] to load a single document, or [loadYamlStream] to load a
+/// stream of documents. For example:
+///
+///     import 'package:yaml/yaml.dart';
+///     main() {
+///       var doc = loadYaml("YAML: YAML Ain't Markup Language");
+///       print(doc['YAML']);
+///     }
+///
+/// This library currently doesn't support dumping to YAML. You should use
+/// `stringify` from `dart:json` instead:
+///
+///     import 'dart:json' as json;
+///     import 'package:yaml/yaml.dart';
+///     main() {
+///       var doc = loadYaml("YAML: YAML Ain't Markup Language");
+///       print(json.stringify(doc));
+///     }
 library yaml;
 
 import 'dart:math' as Math;
@@ -40,8 +60,8 @@
 /// are YamlMaps. These have a few small behavioral differences from the default
 /// Map implementation; for details, see the YamlMap class.
 List loadYamlStream(String yaml) {
-  return new _Parser(yaml).l_yamlStream().mappedBy((doc) =>
-      new _Constructor(new _Composer(doc).compose()).construct())
+  return new _Parser(yaml).l_yamlStream()
+      .map((doc) => new _Constructor(new _Composer(doc).compose()).construct())
       .toList();
 }
 
diff --git a/utils/pub/yaml/yaml_map.dart b/pkg/yaml/lib/yaml_map.dart
similarity index 97%
rename from utils/pub/yaml/yaml_map.dart
rename to pkg/yaml/lib/yaml_map.dart
index 65dd119..cbf18e5 100644
--- a/utils/pub/yaml/yaml_map.dart
+++ b/pkg/yaml/lib/yaml_map.dart
@@ -29,7 +29,7 @@
   void clear() => _map.clear();
   void forEach(void f(key, value)) =>
     _map.forEach((k, v) => f(_unwrapKey(k), v));
-  Iterable get keys => _map.keys.mappedBy(_unwrapKey);
+  Iterable get keys => _map.keys.map(_unwrapKey);
   Iterable get values => _map.values;
   int get length => _map.length;
   bool get isEmpty => _map.isEmpty;
diff --git a/pkg/yaml/pubspec.yaml b/pkg/yaml/pubspec.yaml
new file mode 100644
index 0000000..7c944d2
--- /dev/null
+++ b/pkg/yaml/pubspec.yaml
@@ -0,0 +1,7 @@
+name: yaml
+author: "Dart Team <misc@dartlang.org>"
+homepage: http://www.dartlang.org
+description: A parser for YAML.
+dependencies:
+  unittest:
+    sdk: unittest
diff --git a/utils/tests/pub/yaml_test.dart b/pkg/yaml/test/yaml_test.dart
similarity index 99%
rename from utils/tests/pub/yaml_test.dart
rename to pkg/yaml/test/yaml_test.dart
index 50c0214..b939b67 100644
--- a/utils/tests/pub/yaml_test.dart
+++ b/pkg/yaml/test/yaml_test.dart
@@ -4,9 +4,11 @@
 
 library yaml_test;
 
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../pub/yaml/yaml.dart';
-import '../../pub/yaml/deep_equals.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/yaml.dart';
+import 'package:yaml/deep_equals.dart';
+// TODO(jmesserly): we should not be reaching outside the YAML package
+// The http package has a similar problem.
 import '../../../tests/utils/test_utils.dart';
 
 /// Constructs a new yaml.YamlMap, optionally from a normal Map.
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 5269d6d..7eac81a 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -664,10 +664,9 @@
 }
 
 
-Dart_CObject* CObject::NewExternalUint8Array(int64_t length,
-                                             uint8_t* data,
-                                             void* peer,
-                                             Dart_PeerFinalizer callback) {
+Dart_CObject* CObject::NewExternalUint8Array(
+    int64_t length, uint8_t* data, void* peer,
+    Dart_WeakPersistentHandleFinalizer callback) {
   Dart_CObject* cobject = New(Dart_CObject::kExternalUint8Array);
   cobject->value.as_external_byte_array.length = length;
   cobject->value.as_external_byte_array.data = data;
@@ -679,14 +678,14 @@
 
 Dart_CObject* CObject::NewIOBuffer(int64_t length) {
   uint8_t* data = IOBuffer::Allocate(length);
-  return NewExternalUint8Array(length, data, data, IOBuffer::Free);
+  return NewExternalUint8Array(length, data, data, IOBuffer::Finalizer);
 }
 
 
 void CObject::FreeIOBufferData(Dart_CObject* cobject) {
   ASSERT(cobject->type == Dart_CObject::kExternalUint8Array);
   cobject->value.as_external_byte_array.callback(
-      cobject->value.as_external_byte_array.peer);
+      NULL, cobject->value.as_external_byte_array.peer);
   cobject->value.as_external_byte_array.data = NULL;
 }
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index ce9f3f4..03c9477 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -228,10 +228,9 @@
   static Dart_CObject* NewString(const char* str);
   static Dart_CObject* NewArray(int length);
   static Dart_CObject* NewUint8Array(int length);
-  static Dart_CObject* NewExternalUint8Array(int64_t length,
-                                             uint8_t* data,
-                                             void* peer,
-                                             Dart_PeerFinalizer callback);
+  static Dart_CObject* NewExternalUint8Array(
+      int64_t length, uint8_t* data, void* peer,
+      Dart_WeakPersistentHandleFinalizer callback);
   static Dart_CObject* NewIOBuffer(int64_t length);
   static void FreeIOBufferData(Dart_CObject* object);
 
@@ -412,7 +411,7 @@
   }
   uint8_t* Data() const { return cobject_->value.as_external_byte_array.data; }
   void* Peer() const { return cobject_->value.as_external_byte_array.peer; }
-  Dart_PeerFinalizer Callback() const {
+  Dart_WeakPersistentHandleFinalizer Callback() const {
     return cobject_->value.as_external_byte_array.callback;
   }
 
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index c0ca3de..f5e53ee 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -31,7 +31,6 @@
 // Global state that indicates whether a snapshot is to be created and
 // if so which file to write the snapshot into.
 static const char* snapshot_filename = NULL;
-static bool script_snapshot = false;
 static const char* package_root = NULL;
 static uint8_t* snapshot_buffer = NULL;
 
@@ -66,13 +65,6 @@
 static bool ProcessSnapshotOption(const char* option) {
   const char* name = ProcessOption(option, "--snapshot=");
   if (name != NULL) {
-    script_snapshot = false;
-    snapshot_filename = name;
-    return true;
-  }
-  name = ProcessOption(option, "--script_snapshot=");
-  if (name != NULL) {
-    script_snapshot = true;
     snapshot_filename = name;
     return true;
   }
@@ -367,14 +359,12 @@
 "Usage:\n"
 "\n"
 "  gen_snapshot [<vm-flags>] [<options>] \\\n"
-"               {--script_snapshot=<out-file> | --snapshot=<out-file>} \\\n"
-"               [<dart-script-file>]\n"
+"               --snapshot=<out-file> [<dart-script-file>]\n"
 "\n"
 "  Writes a snapshot of <dart-script-file> to <out-file>. If no\n"
 "  <dart-script-file> is passed, a generic snapshot of all the corelibs is\n"
-"  created. One of the following is required:\n"
+"  created. It is required to specify an output file name:\n"
 "\n"
-"    --script_snapshot=<file>   Generates a script snapshot.\n"
 "    --snapshot=<file>          Generates a complete snapshot. Uses the url\n"
 "                               mapping specified on the command line to load\n"
 "                               the libraries.\n"
@@ -401,19 +391,13 @@
 }
 
 
-static void CreateAndWriteSnapshot(bool script_snapshot) {
+static void CreateAndWriteSnapshot() {
   Dart_Handle result;
   uint8_t* buffer = NULL;
   intptr_t size = 0;
 
   // First create a snapshot.
-  if (script_snapshot) {
-    // Script snapshot specified so create a script snapshot.
-    result = Dart_CreateScriptSnapshot(&buffer, &size);
-  } else {
-    // Create a full snapshot.
-    result = Dart_CreateSnapshot(&buffer, &size);
-  }
+  result = Dart_CreateSnapshot(&buffer, &size);
   CHECK_RESULT(result);
 
   // Now write the snapshot out to specified file and exit.
@@ -505,103 +489,49 @@
   ASSERT(snapshot_filename != NULL);
   // Load up the script before a snapshot is created.
   if (app_script_name != NULL) {
-    if (!script_snapshot) {
-      // This is the case of a custom embedder (e.g: dartium) trying to
-      // create a full snapshot. The current isolate is set up so that we can
-      // invoke the dart uri resolution code like _resolveURI. App script is
-      // loaded into a separate isolate.
+    // This is the case of a custom embedder (e.g: dartium) trying to
+    // create a full snapshot. The current isolate is set up so that we can
+    // invoke the dart uri resolution code like _resolveURI. App script is
+    // loaded into a separate isolate.
 
-      SetupForUriResolution();
+    SetupForUriResolution();
 
-      // Get handle to builtin library.
-      Dart_Handle builtin_lib =
-          Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
-      CHECK_RESULT(builtin_lib);
+    // Get handle to builtin library.
+    Dart_Handle builtin_lib =
+        Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+    CHECK_RESULT(builtin_lib);
 
-      // Prepare for script loading by setting up the 'print' and 'timer'
-      // closures and setting up 'package root' for URI resolution.
-      result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
-      CHECK_RESULT(result);
-      Dart_ExitScope();
+    // Prepare for script loading by setting up the 'print' and 'timer'
+    // closures and setting up 'package root' for URI resolution.
+    result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
+    CHECK_RESULT(result);
+    Dart_ExitScope();
 
-      UriResolverIsolateScope::isolate = isolate;
+    UriResolverIsolateScope::isolate = isolate;
 
-      // Now we create an isolate into which we load all the code that needs to
-      // be in the snapshot.
-      if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error) == NULL) {
-        fprintf(stderr, "%s", error);
-        free(error);
-        exit(255);
-      }
-      Dart_EnterScope();
-
-      // Set up the library tag handler in such a manner that it will use the
-      // URL mapping specified on the command line to load the libraries.
-      result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
-      CHECK_RESULT(result);
-      // Load the specified script.
-      library = LoadSnapshotCreationScript(app_script_name);
-      VerifyLoaded(library);
-      CreateAndWriteSnapshot(false);
-
-      Dart_EnterIsolate(UriResolverIsolateScope::isolate);
-      Dart_ShutdownIsolate();
-    } else {
-      // This is the case where we want to create a script snapshot of
-      // the specified script. There will be no URL mapping specified for
-      // this case, use the generic library tag handler.
-
-      // First setup and create a generic full snapshot.
-      SetupForGenericSnapshotCreation();
-      uint8_t* buffer = NULL;
-      intptr_t size = 0;
-      result = Dart_CreateSnapshot(&buffer, &size);
-      CHECK_RESULT(result);
-
-      // Save the snapshot buffer as we are about to shutdown the isolate.
-      snapshot_buffer = reinterpret_cast<uint8_t*>(malloc(size));
-      ASSERT(snapshot_buffer != NULL);
-      memmove(snapshot_buffer, buffer, size);
-
-      // Shutdown the isolate.
-      Dart_ExitScope();
-      Dart_ShutdownIsolate();
-
-      // Now load the specified script and create a script snapshot.
-      if (Dart_CreateIsolate(
-              NULL, NULL, snapshot_buffer, NULL, &error) == NULL) {
-        Log::PrintErr("%s", error);
-        free(error);
-        free(snapshot_buffer);
-        exit(255);
-      }
-      Dart_EnterScope();
-
-      // Setup generic library tag handler.
-      result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
-      CHECK_RESULT(result);
-
-      // Get handle to builtin library.
-      Dart_Handle builtin_lib =
-          Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
-      CHECK_RESULT(builtin_lib);
-
-      // Prepare for script loading by setting up the 'print' and 'timer'
-      // closures and setting up 'package root' for URI resolution.
-      result = DartUtils::PrepareForScriptLoading(package_root, builtin_lib);
-      CHECK_RESULT(result);
-
-      // Load specified script.
-      library = DartUtils::LoadScript(app_script_name, builtin_lib);
-
-      // Now create and write snapshot of script.
-      CreateAndWriteSnapshot(true);
-
-      free(snapshot_buffer);
+    // Now we create an isolate into which we load all the code that needs to
+    // be in the snapshot.
+    if (Dart_CreateIsolate(NULL, NULL, NULL, NULL, &error) == NULL) {
+      fprintf(stderr, "%s", error);
+      free(error);
+      exit(255);
     }
+    Dart_EnterScope();
+
+    // Set up the library tag handler in such a manner that it will use the
+    // URL mapping specified on the command line to load the libraries.
+    result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
+    CHECK_RESULT(result);
+    // Load the specified script.
+    library = LoadSnapshotCreationScript(app_script_name);
+    VerifyLoaded(library);
+    CreateAndWriteSnapshot();
+
+    Dart_EnterIsolate(UriResolverIsolateScope::isolate);
+    Dart_ShutdownIsolate();
   } else {
     SetupForGenericSnapshotCreation();
-    CreateAndWriteSnapshot(false);
+    CreateAndWriteSnapshot();
   }
   return 0;
 }
diff --git a/runtime/bin/io_buffer.cc b/runtime/bin/io_buffer.cc
index a07559d..5f40478 100644
--- a/runtime/bin/io_buffer.cc
+++ b/runtime/bin/io_buffer.cc
@@ -6,7 +6,8 @@
 
 Dart_Handle IOBuffer::Allocate(intptr_t size, uint8_t **buffer) {
   uint8_t* data = Allocate(size);
-  Dart_Handle result = Dart_NewExternalByteArray(data, size, data, Free);
+  Dart_Handle result = Dart_NewExternalByteArray(data, size,
+                                                 data, IOBuffer::Finalizer);
   if (Dart_IsError(result)) {
     Free(data);
     Dart_PropagateError(result);
diff --git a/runtime/bin/io_buffer.h b/runtime/bin/io_buffer.h
index 69a5c09..0c73164 100644
--- a/runtime/bin/io_buffer.h
+++ b/runtime/bin/io_buffer.h
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef IO_BUFFER_H_
-#define IO_BUFFER_H_
+#ifndef BIN_IO_BUFFER_H_
+#define BIN_IO_BUFFER_H_
 
 #include "platform/globals.h"
 
@@ -24,9 +24,17 @@
     delete[] reinterpret_cast<uint8_t*>(buffer);
   }
 
+  // Function for finalizing external byte arrays used as IO buffers.
+  static void Finalizer(Dart_Handle handle, void* buffer) {
+    Free(buffer);
+    if (handle != NULL) {
+      Dart_DeletePersistentHandle(handle);
+    }
+  }
+
  private:
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(IOBuffer);
 };
 
-#endif  // IO_BUFFER_H_
+#endif  // BIN_IO_BUFFER_H_
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 1adb208..6d263ef 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -29,6 +29,7 @@
 
 // Global state that stores a pointer to the application script snapshot.
 static bool use_script_snapshot = false;
+static bool generate_script_snapshot = false;
 static File* snapshot_file = NULL;
 
 
@@ -144,10 +145,45 @@
 }
 
 
-static bool ProcessScriptSnapshotOption(const char* filename) {
+static bool ProcessUseScriptSnapshotOption(const char* filename) {
   if (filename != NULL && strlen(filename) != 0) {
     use_script_snapshot = true;
+    if (generate_script_snapshot) {
+      Log::PrintErr("Incompatible options specified --generate-script-snapshot "
+                    "and --use-script-snapshot\n");
+      return false;
+    }
     snapshot_file = File::Open(filename, File::kRead);
+    if (snapshot_file == NULL) {
+      Log::PrintErr("Unable to open file %s for reading the snapshot\n",
+                    filename);
+      return false;
+    }
+  }
+  return true;
+}
+
+
+static bool ProcessGenScriptSnapshotOption(const char* filename) {
+  if (filename != NULL && strlen(filename) != 0) {
+    // Ensure that are already running using a full snapshot.
+    if (snapshot_buffer == NULL) {
+      Log::PrintErr("Script snapshots cannot be generated in this version of"
+                    " dart\n");
+      return false;
+    }
+    if (use_script_snapshot) {
+      Log::PrintErr("Incompatible options specified --use-script-snapshot "
+                    "and --generate-script-snapshot\n");
+      return false;
+    }
+    snapshot_file = File::Open(filename, File::kWriteTruncate);
+    if (snapshot_file == NULL) {
+      Log::PrintErr("Unable to open file %s for writing the snapshot\n",
+                    filename);
+      return false;
+    }
+    generate_script_snapshot = true;
   }
   return true;
 }
@@ -169,7 +205,8 @@
   { "--break_at=", ProcessBreakpointOption },
   { "--compile_all", ProcessCompileAllOption },
   { "--debug", ProcessDebugOption },
-  { "--use_script_snapshot=", ProcessScriptSnapshotOption },
+  { "--use-script-snapshot=", ProcessUseScriptSnapshotOption },
+  { "--generate-script-snapshot=", ProcessGenScriptSnapshotOption },
   { NULL, NULL }
 };
 
@@ -507,9 +544,12 @@
 "  url:<line_num> e.g. test.dart:10\n"
 "  [<class_name>.]<function_name> e.g. B.foo\n"
 "\n"
-"--use_script_snapshot=<file_name>\n"
+"--use-script-snapshot=<file_name>\n"
 "  executes Dart script present in the specified snapshot file\n"
 "\n"
+"--generate-script-snapshot=<file_name>\n"
+"  loads Dart script and generates a snapshot in the specified file\n"
+"\n"
 "The following options are only used for VM development and may\n"
 "be changed in any future version:\n");
     const char* print_flags = "--print_flags";
@@ -673,46 +713,65 @@
 
   Dart_EnterScope();
 
-  if (has_compile_all) {
-    result = Dart_CompileAll();
+  if (generate_script_snapshot) {
+    // First create a snapshot.
+    Dart_Handle result;
+    uint8_t* buffer = NULL;
+    intptr_t size = 0;
+    result = Dart_CreateScriptSnapshot(&buffer, &size);
+    if (Dart_IsError(result)) {
+      Log::PrintErr("%s\n", Dart_GetError(result));
+      Dart_ExitScope();
+      Dart_ShutdownIsolate();
+      return kErrorExitCode;  // Indicates we encountered an error.
+    }
+
+    // Now write the snapshot out to specified file.
+    bool bytes_written = snapshot_file->WriteFully(buffer, size);
+    ASSERT(bytes_written);
+    delete snapshot_file;
+  } else {
+    if (has_compile_all) {
+      result = Dart_CompileAll();
+      if (Dart_IsError(result)) {
+        return ErrorExit("%s\n", Dart_GetError(result));
+      }
+    }
+
+    // Create a dart options object that can be accessed from dart code.
+    Dart_Handle options_result =
+        SetupRuntimeOptions(&dart_options, executable_name, script_name);
+    if (Dart_IsError(options_result)) {
+      return ErrorExit("%s\n", Dart_GetError(options_result));
+    }
+    // Lookup the library of the root script.
+    Dart_Handle library = Dart_RootLibrary();
+    if (Dart_IsNull(library)) {
+      return ErrorExit("Unable to find root library for '%s'\n",
+                       script_name);
+    }
+    // Set debug breakpoint if specified on the command line.
+    if (breakpoint_at != NULL) {
+      result = SetBreakpoint(breakpoint_at, library);
+      if (Dart_IsError(result)) {
+        return ErrorExit("Error setting breakpoint at '%s': %s\n",
+                         breakpoint_at,
+                         Dart_GetError(result));
+      }
+    }
+
+    // Lookup and invoke the top level main function.
+    result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
     if (Dart_IsError(result)) {
       return ErrorExit("%s\n", Dart_GetError(result));
     }
-  }
-
-  // Create a dart options object that can be accessed from dart code.
-  Dart_Handle options_result =
-      SetupRuntimeOptions(&dart_options, executable_name, script_name);
-  if (Dart_IsError(options_result)) {
-    return ErrorExit("%s\n", Dart_GetError(options_result));
-  }
-  // Lookup the library of the root script.
-  Dart_Handle library = Dart_RootLibrary();
-  if (Dart_IsNull(library)) {
-    return ErrorExit("Unable to find root library for '%s'\n",
-                     script_name);
-  }
-  // Set debug breakpoint if specified on the command line.
-  if (breakpoint_at != NULL) {
-    result = SetBreakpoint(breakpoint_at, library);
+    // Keep handling messages until the last active receive port is closed.
+    result = Dart_RunLoop();
     if (Dart_IsError(result)) {
-      return ErrorExit("Error setting breakpoint at '%s': %s\n",
-                       breakpoint_at,
-                       Dart_GetError(result));
+      return ErrorExit("%s\n", Dart_GetError(result));
     }
   }
 
-  // Lookup and invoke the top level main function.
-  result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
-  if (Dart_IsError(result)) {
-    return ErrorExit("%s\n", Dart_GetError(result));
-  }
-  // Keep handling messages until the last active receive port is closed.
-  result = Dart_RunLoop();
-  if (Dart_IsError(result)) {
-    return ErrorExit("%s\n", Dart_GetError(result));
-  }
-
   Dart_ExitScope();
   // Shutdown the isolate.
   Dart_ShutdownIsolate();
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 1285f13..dfde8f3 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -186,6 +186,7 @@
     if (Dart_IsError(result)) {
       Dart_PropagateError(result);
     }
+    buffer = static_cast<void*>((static_cast<uint8_t*>(buffer) + offset));
     bytes_written = Socket::Write(socket, buffer, length);
     if (bytes_written > 0) total_bytes_written = bytes_written;
   } else {
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 2966135..2e53b34 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -958,7 +958,7 @@
       int length;
       uint8_t* data;
       void* peer;
-      Dart_PeerFinalizer callback;
+      Dart_WeakPersistentHandleFinalizer callback;
     } as_external_byte_array;
   } value;
 } Dart_CObject;
@@ -1631,7 +1631,22 @@
                                             uint8_t* native_array,
                                             intptr_t length);
 
-// --- Byte Arrays ---
+// --- Scalar Lists ---
+
+typedef enum {
+  kByteArray = 0,
+  kInt8,
+  kUint8,
+  kUint8Clamped,
+  kInt16,
+  kUint16,
+  kInt32,
+  kUint32,
+  kInt64,
+  kUint64,
+  kFloat32,
+  kFloat64
+} Dart_Scalar_Type;
 
 /**
  * Is this object a ByteArray?
@@ -1664,12 +1679,15 @@
  * \param peer An external pointer to associate with this byte array.
  *
  * \return The ByteArray object if no error occurs. Otherwise returns
- *   an error handle.
+ *   an error handle. The ByteArray object is returned in a
+ *   WeakPersistentHandle which needs to be deleted in the specified callback
+ *   using Dart_DeletePersistentHandle.
  */
-DART_EXPORT Dart_Handle Dart_NewExternalByteArray(uint8_t* data,
-                                                  intptr_t length,
-                                                  void* peer,
-                                                  Dart_PeerFinalizer callback);
+DART_EXPORT Dart_Handle Dart_NewExternalByteArray(
+    uint8_t* data,
+    intptr_t length,
+    void* peer,
+    Dart_WeakPersistentHandleFinalizer callback);
 
 /**
  * Returns a clamped ByteArray which references an external array of
@@ -1683,13 +1701,15 @@
  * \param peer An external pointer to associate with this byte array.
  *
  * \return The clamped ByteArray object if no error occurs. Otherwise returns
- *   an error handle.
+ *   an error handle. The clamped ByteArray object is returned in a
+ *   WeakPersistentHandle which needs to be deleted in the specified callback
+ *   using Dart_DeletePersistentHandle.
  */
 DART_EXPORT Dart_Handle Dart_NewExternalClampedByteArray(
     uint8_t* data,
     intptr_t length,
     void* peer,
-    Dart_PeerFinalizer callback);
+    Dart_WeakPersistentHandleFinalizer callback);
 
 /**
  * Retrieves the data pointer associated with an external ByteArray.
@@ -1704,304 +1724,38 @@
                                                       void** peer);
 
 /**
- * Gets an int8_t at some byte offset in a ByteArray.
+ * Acquires access to the internal data address of a scalar list object.
  *
- * If the byte offset is out of bounds, an error occurs.
+ * \param array The scalar list object whose internal data address is to
+ *    be accessed.
+ * \param type The scalar type of the object is returned here.
+ * \param data The internal data address is returned here.
+ * \param len Size of the byte array is returned here.
  *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int8_t.
+ * Note: When the internal address of the object is acquired any calls to a
+ *       Dart API function that could potentially allocate an object or run
+ *       any Dart code will return an error.
  *
- * \return A valid handle if no error occurs during the operation.
+ * \return Success if the internal data address is acquired successfully.
+ *   Otherwise, returns an error handle.
  */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt8At(Dart_Handle array,
-                                                intptr_t offset,
-                                                int8_t* value);
+DART_EXPORT Dart_Handle Dart_ScalarListAcquireData(Dart_Handle array,
+                                                   Dart_Scalar_Type* type,
+                                                   void** data,
+                                                   intptr_t* len);
 
 /**
- * Sets an int8_t at some byte offset in a ByteArray.
+ * Releases access to the internal data address that was acquired earlier using
+ * Dart_ByteArrayAcquireData.
  *
- * If the byte offset is out of bounds, an error occurs.
+ * \param array The scalar list object whose internal data address is to be
+ *   released.
  *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int8_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
+ * \return Success if the internal data address is released successfully.
+ *   Otherwise, returns an error handle.
  */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt8At(Dart_Handle array,
-                                                intptr_t offset,
-                                                int8_t value);
+DART_EXPORT Dart_Handle Dart_ScalarListReleaseData(Dart_Handle array);
 
-/**
- * Gets a uint8_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint8_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint8At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 uint8_t* value);
-
-/**
- * Sets a uint8_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint8_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint8At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 uint8_t value);
-
-/**
- * Gets an int16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int16_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt16At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 int16_t* value);
-
-/**
- * Sets an int16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int16_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt16At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 int16_t value);
-
-/**
- * Gets a uint16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint16_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint16At(Dart_Handle array,
-                                                  intptr_t offset,
-                                                  uint16_t* value);
-
-/**
- * Sets a uint16_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint16_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint16At(Dart_Handle array,
-                                                  intptr_t offset,
-                                                  uint16_t value);
-
-/**
- * Gets an int32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int32_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt32At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 int32_t* value);
-
-/**
- * Sets an int32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int32_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt32At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 int32_t value);
-
-/**
- * Gets a uint32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint32_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint32At(Dart_Handle array,
-                                                  intptr_t offset,
-                                                  uint32_t* value);
-
-/**
- * Sets a uint32_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint32_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint32At(Dart_Handle array,
-                                                  intptr_t offset,
-                                                  uint32_t value);
-
-/**
- * Gets an int64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the int64_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt64At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 int64_t* value);
-
-/**
- * Sets an int64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The int64_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt64At(Dart_Handle array,
-                                                 intptr_t offset,
-                                                 int64_t value);
-
-/**
- * Gets a uint64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the uint64_t.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint64At(Dart_Handle array,
-                                                  intptr_t offset,
-                                                  uint64_t* value);
-
-/**
- * Sets a uint64_t at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The uint64_t to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint64At(Dart_Handle array,
-                                                  intptr_t offset,
-                                                  uint64_t value);
-
-/**
- * Gets a float at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the float.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat32At(Dart_Handle array,
-                                                   intptr_t offset,
-                                                   float* value);
-
-/**
- * Sets a float at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The float to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat32At(Dart_Handle array,
-                                                   intptr_t offset,
-                                                   float value);
-
-/**
- * Gets a double from some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the List.
- * \param value Returns the value of the double.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat64At(Dart_Handle array,
-                                                   intptr_t offset,
-                                                   double* value);
-
-/**
- * Sets a double at some byte offset in a ByteArray.
- *
- * If the byte offset is out of bounds, an error occurs.
- *
- * \param array A ByteArray.
- * \param offset A valid byte offset into the ByteArray.
- * \param value The double to put into the ByteArray.
- *
- * \return A valid handle if no error occurs during the operation.
- */
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat64At(Dart_Handle array,
-                                                   intptr_t offset,
-                                                   double value);
 
 // --- Closures ---
 
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index e7c4bee..f72191d 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -34,6 +34,7 @@
         "Cannot remove element of a non-extendable array");
   }
 
+  // Collection interface.
   void removeAll(Iterable elements) {
     throw new UnsupportedError(
         "Cannot remove element of a non-extendable array");
@@ -54,6 +55,7 @@
         "Cannot remove element of a non-extendable array");
   }
 
+  // List interface.
   void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
     if (length < 0) {
       throw new ArgumentError("negative length $length");
@@ -84,7 +86,7 @@
     return list;
   }
 
-  // Collection interface.
+  // Iterable interface.
 
   bool contains(E element) {
     return IterableMixinWorkaround.contains(this, element);
@@ -98,8 +100,12 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(E element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(E element)) {
-    return IterableMixinWorkaround.mappedByList(this, f);
+    IterableMixinWorkaround.mappedByList(this, f);
   }
 
   reduce(initialValue, combine(previousValue, E element)) {
@@ -110,7 +116,7 @@
     return IterableMixinWorkaround.where(this, f);
   }
 
-  List<E> take(int n) {
+  Iterable<E> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -118,7 +124,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<E> skip(int n) {
+  Iterable<E> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -324,6 +330,10 @@
     IterableMixinWorkaround.forEach(this, f);
   }
 
+  Iterable map(f(E element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(E element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -340,7 +350,7 @@
     return IterableMixinWorkaround.where(this, f);
   }
 
-  List<E> take(int n) {
+  Iterable<E> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -348,7 +358,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<E> skip(int n) {
+  Iterable<E> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index 109d951..da5bf73 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -27,21 +27,6 @@
     return result;
   }
 
-  /* patch */ factory List.filled(int length, E fill) {
-    if ((length is! int) || (length < 0)) {
-      _throwArgumentError(length);
-    }
-    _GrowableObjectArray<E> result =
-        new _GrowableObjectArray<E>.withCapacity(length < 4 ? 4 : length);
-    result.length = length;
-    if (fill != null) {
-      for (int i = 0; i < length; i++) {
-        result[i] = fill;
-      }
-    }
-    return result;
-  }
-
   // Factory constructing a mutable List from a parser generated List literal.
   // [elements] contains elements that are already type checked.
   factory List._fromLiteral(List elements) {
diff --git a/runtime/lib/byte_array.cc b/runtime/lib/byte_array.cc
index 361c883..a96d211 100644
--- a/runtime/lib/byte_array.cc
+++ b/runtime/lib/byte_array.cc
@@ -4,6 +4,8 @@
 
 #include "vm/bootstrap_natives.h"
 
+#include "include/dart_api.h"
+
 #include "vm/bigint_operations.h"
 #include "vm/exceptions.h"
 #include "vm/native_entry.h"
@@ -292,6 +294,12 @@
 }
 
 
+static void PeerFinalizer(Dart_Handle handle, void* peer) {
+  Dart_DeletePersistentHandle(handle);
+  OS::AlignedFree(peer);
+}
+
+
 // Int8Array
 
 DEFINE_NATIVE_ENTRY(Int8Array_new, 1) {
@@ -303,16 +311,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Int8List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Int8Array::kMaxElements);
-  int8_t* bytes = OS::AllocateAlignedArray<int8_t>(
-      len,
-      ExternalByteArrayData<int8_t>::kAlignment);
-  return ExternalInt8Array::New(bytes,
-                                len,
-                                bytes,
-                                OS::AlignedFree);
+  int8_t* bytes = OS::AllocateAlignedArray<int8_t>(len, kAlignment);
+  const ExternalInt8Array& obj =
+      ExternalInt8Array::Handle(ExternalInt8Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -337,16 +344,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Uint8List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Uint8Array::kMaxElements);
-  uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(
-      len,
-      ExternalByteArrayData<uint8_t>::kAlignment);
-  return ExternalUint8Array::New(bytes,
-                                 len,
-                                 bytes,
-                                 OS::AlignedFree);
+  uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(len, kAlignment);
+  const ExternalUint8Array& obj =
+      ExternalUint8Array::Handle(ExternalUint8Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -371,16 +377,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Uint8ClampedList_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Uint8ClampedArray::kMaxElements);
-  uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(
-      len,
-      ExternalByteArrayData<uint8_t>::kAlignment);
-  return ExternalUint8ClampedArray::New(bytes,
-                                        len,
-                                        bytes,
-                                        OS::AlignedFree);
+  uint8_t* bytes = OS::AllocateAlignedArray<uint8_t>(len, kAlignment);
+  const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle(
+      ExternalUint8ClampedArray::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -405,16 +410,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Int16List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Int16Array::kMaxElements);
-  int16_t* bytes = OS::AllocateAlignedArray<int16_t>(
-      len,
-      ExternalByteArrayData<int16_t>::kAlignment);
-  return ExternalInt16Array::New(bytes,
-                                 len,
-                                 bytes,
-                                 OS::AlignedFree);
+  int16_t* bytes = OS::AllocateAlignedArray<int16_t>(len, kAlignment);
+  const ExternalInt16Array& obj =
+      ExternalInt16Array::Handle(ExternalInt16Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -439,16 +443,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Uint16List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Uint16Array::kMaxElements);
-  uint16_t* bytes = OS::AllocateAlignedArray<uint16_t>(
-      len,
-      ExternalByteArrayData<uint16_t>::kAlignment);
-  return ExternalUint16Array::New(bytes,
-                                  len,
-                                  bytes,
-                                  OS::AlignedFree);
+  uint16_t* bytes = OS::AllocateAlignedArray<uint16_t>(len, kAlignment);
+  const ExternalUint16Array& obj =
+      ExternalUint16Array::Handle(ExternalUint16Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -473,16 +476,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Int32List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Int32Array::kMaxElements);
-  int32_t* bytes = OS::AllocateAlignedArray<int32_t>(
-      len,
-      ExternalByteArrayData<int32_t>::kAlignment);
-  return ExternalInt32Array::New(bytes,
-                                 len,
-                                 bytes,
-                                 OS::AlignedFree);
+  int32_t* bytes = OS::AllocateAlignedArray<int32_t>(len, kAlignment);
+  const ExternalInt32Array& obj =
+      ExternalInt32Array::Handle(ExternalInt32Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -507,16 +509,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Uint32List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Uint32Array::kMaxElements);
-  uint32_t* bytes = OS::AllocateAlignedArray<uint32_t>(
-      len,
-      ExternalByteArrayData<uint32_t>::kAlignment);
-  return ExternalUint32Array::New(bytes,
-                                  len,
-                                  bytes,
-                                  OS::AlignedFree);
+  uint32_t* bytes = OS::AllocateAlignedArray<uint32_t>(len, kAlignment);
+  const ExternalUint32Array& obj =
+      ExternalUint32Array::Handle(ExternalUint32Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -541,16 +542,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Int64List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Int64Array::kMaxElements);
-  int64_t* bytes = OS::AllocateAlignedArray<int64_t>(
-      len,
-      ExternalByteArrayData<int64_t>::kAlignment);
-  return ExternalInt64Array::New(bytes,
-                                 len,
-                                 bytes,
-                                 OS::AlignedFree);
+  int64_t* bytes = OS::AllocateAlignedArray<int64_t>(len, kAlignment);
+  const ExternalInt64Array& obj =
+      ExternalInt64Array::Handle(ExternalInt64Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -575,16 +575,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Uint64List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Uint64Array::kMaxElements);
-  uint64_t* bytes = OS::AllocateAlignedArray<uint64_t>(
-      len,
-      ExternalByteArrayData<uint64_t>::kAlignment);
-  return ExternalUint64Array::New(bytes,
-                                  len,
-                                  bytes,
-                                  OS::AlignedFree);
+  uint64_t* bytes = OS::AllocateAlignedArray<uint64_t>(len, kAlignment);
+  const ExternalUint64Array& obj =
+      ExternalUint64Array::Handle(ExternalUint64Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -609,16 +608,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Float32List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Float32Array::kMaxElements);
-  float* bytes = OS::AllocateAlignedArray<float>(
-      len,
-      ExternalByteArrayData<float>::kAlignment);
-  return ExternalFloat32Array::New(bytes,
-                                   len,
-                                   bytes,
-                                   OS::AlignedFree);
+  float* bytes = OS::AllocateAlignedArray<float>(len, kAlignment);
+  const ExternalFloat32Array& obj =
+      ExternalFloat32Array::Handle(ExternalFloat32Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
@@ -643,16 +641,15 @@
 
 
 DEFINE_NATIVE_ENTRY(Float64List_newTransferable, 1) {
+  const int kAlignment = 16;
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0));
   intptr_t len = length.Value();
   LengthCheck(len, Float64Array::kMaxElements);
-  double* bytes = OS::AllocateAlignedArray<double>(
-      len,
-      ExternalByteArrayData<double>::kAlignment);
-  return ExternalFloat64Array::New(bytes,
-                                   len,
-                                   bytes,
-                                   OS::AlignedFree);
+  double* bytes = OS::AllocateAlignedArray<double>(len, kAlignment);
+  const ExternalFloat64Array& obj =
+      ExternalFloat64Array::Handle(ExternalFloat64Array::New(bytes, len));
+  obj.AddFinalizer(bytes, PeerFinalizer);
+  return obj.raw();
 }
 
 
diff --git a/runtime/lib/byte_array.dart b/runtime/lib/byte_array.dart
index 9794eba4c..74e2c3a 100644
--- a/runtime/lib/byte_array.dart
+++ b/runtime/lib/byte_array.dart
@@ -229,6 +229,10 @@
     }
   }
 
+  Iterable map(f(int element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(int element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -246,7 +250,7 @@
     return IterableMixinWorkaround.where(this, f);
   }
 
-  List<int> take(int n) {
+  Iterable<int> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -254,7 +258,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) {
+  Iterable<int> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index 7067658..2d3c5f8 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -7,6 +7,7 @@
 #include "vm/bootstrap_natives.h"
 
 #include "vm/bigint_operations.h"
+#include "vm/code_generator.h"  // DartModulo.
 #include "vm/double_conversion.h"
 #include "vm/exceptions.h"
 #include "vm/native_entry.h"
@@ -103,19 +104,7 @@
   double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
   double right = right_object.value();
-
-  double remainder = fmod_ieee(left, right);
-  if (remainder == 0.0) {
-    // We explicitely switch to the positive 0.0 (just in case it was negative).
-    remainder = +0.0;
-  } else if (remainder < 0) {
-    if (right < 0) {
-      remainder -= right;
-    } else {
-      remainder += right;
-    }
-  }
-  return Double::New(remainder);
+  return Double::New(DartModulo(left, right));
 }
 
 
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 39e35fd..cd31864 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -242,6 +242,10 @@
     return buffer.toString();
   }
 
+  Iterable map(f(T element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(T element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -254,7 +258,7 @@
     return IterableMixinWorkaround.where(this, f);
   }
 
-  List<T> take(int n) {
+  Iterable<T> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -262,7 +266,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<T> skip(int n) {
+  Iterable<T> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
diff --git a/runtime/tests/vm/dart/optimized_stacktrace_test.dart b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
new file mode 100644
index 0000000..c3e24ba
--- /dev/null
+++ b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
@@ -0,0 +1,78 @@
+// 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 correct source positions in stack trace with optimized functions.
+
+// (1) Test normal exception. 
+foo(x) => bar(x);
+
+bar(x) {
+  if (x == null) throw 42;  // throw at position 11:18
+  return x + 1;
+}
+
+test1() {
+  // First unoptimized.
+  try {
+    foo(null);
+    Expect.fail("Unreachable");
+  } catch (e, stacktrace) {
+    String s = stacktrace.toString();
+    Expect.equals(-1, s.indexOf("-1:-1"));
+    Expect.notEquals(-1, s.indexOf("11:18"));
+  }
+
+  // Optimized.
+  for (var i=0; i<10000; i++) foo(42);
+  try {
+    foo(null);
+    Expect.fail("Unreachable");
+  } catch (e, stacktrace) {
+    String s = stacktrace.toString();
+    Expect.equals(-1, s.indexOf("-1:-1"));
+    Expect.notEquals(-1, s.indexOf("11:18"));
+  }
+}
+
+
+// (2) Test checked mode exceptions.
+maximus(x) => moritz(x);
+
+moritz(x) {
+  if (x == 333)  return 42 ? 0 : 1;  // Throws in checked mode.
+  if (x == 777)   {
+    bool b = x;  // Throws in checked mode.
+    return b;
+  }
+
+  return x + 1;
+}
+
+test2() {
+  for (var i=0; i<100000; i++) maximus(42);
+  try {
+    maximus(333);
+  } catch (e, stacktrace) {
+    String s = stacktrace.toString();
+    print(s);
+    Expect.notEquals(-1, s.indexOf("maximus"));
+    Expect.notEquals(-1, s.indexOf("moritz"));
+    Expect.equals(-1, s.indexOf("-1:-1"));
+  }
+
+  try {
+    maximus(777);
+  } catch (e, stacktrace) {
+    String s = stacktrace.toString();
+    print(s);
+    Expect.notEquals(-1, s.indexOf("maximus"));
+    Expect.notEquals(-1, s.indexOf("moritz"));
+    Expect.equals(-1, s.indexOf("-1:-1"));
+  }
+}
+
+main() {
+  test1();
+  test2();
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index c88b455..c944645 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -34,6 +34,10 @@
 dart/byte_array_test: Skip # compilers not aware of byte arrays
 dart/isolate_unhandled*: Skip
 
+[ $compiler == dart2js ]
+# The source positions do not match with dart2js.
+dart/optimized_stacktrace_test: Fail
+
 [ $compiler == dart2js && $minified ]
 # Methods in stack traces are renamed.
 dart/inline_stack_frame_test: Fail # Issue 7953.
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index 261fdaf..64a7716 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -13,6 +13,10 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool, code_comments, false,
+            "Include comments into code and disassembly");
+
+
 static uword NewContents(intptr_t capacity) {
   Zone* zone = Isolate::Current()->current_zone();
   uword result = zone->AllocUnsafe(capacity);
@@ -185,4 +189,31 @@
   Stop(buffer);
 }
 
+
+void Assembler::Comment(const char* format, ...) {
+  if (FLAG_code_comments) {
+    char buffer[1024];
+
+    va_list args;
+    va_start(args, format);
+    OS::VSNPrint(buffer, sizeof(buffer), format, args);
+    va_end(args);
+
+    comments_.Add(new CodeComment(buffer_.GetPosition(),
+                                  String::Handle(String::New(buffer))));
+  }
+}
+
+
+const Code::Comments& Assembler::GetCodeComments() const {
+  Code::Comments& comments = Code::Comments::New(comments_.length());
+
+  for (intptr_t i = 0; i < comments_.length(); i++) {
+    comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
+    comments.SetCommentAt(i, comments_[i]->comment());
+  }
+
+  return comments;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 4a64fc3..817a58f 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -10,8 +10,1489 @@
 namespace dart {
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
-            "Include comments into code and disassembly");
+
+
+// Instruction encoding bits.
+enum {
+  H   = 1 << 5,   // halfword (or byte)
+  L   = 1 << 20,  // load (or store)
+  S   = 1 << 20,  // set condition code (or leave unchanged)
+  W   = 1 << 21,  // writeback base register (or leave unchanged)
+  A   = 1 << 21,  // accumulate in multiply instruction (or not)
+  B   = 1 << 22,  // unsigned byte (or word)
+  N   = 1 << 22,  // long (or short)
+  U   = 1 << 23,  // positive (or negative) offset/index
+  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
+  I   = 1 << 25,  // immediate shifter operand (or not)
+
+  B0 = 1,
+  B1 = 1 << 1,
+  B2 = 1 << 2,
+  B3 = 1 << 3,
+  B4 = 1 << 4,
+  B5 = 1 << 5,
+  B6 = 1 << 6,
+  B7 = 1 << 7,
+  B8 = 1 << 8,
+  B9 = 1 << 9,
+  B10 = 1 << 10,
+  B11 = 1 << 11,
+  B12 = 1 << 12,
+  B16 = 1 << 16,
+  B17 = 1 << 17,
+  B18 = 1 << 18,
+  B19 = 1 << 19,
+  B20 = 1 << 20,
+  B21 = 1 << 21,
+  B22 = 1 << 22,
+  B23 = 1 << 23,
+  B24 = 1 << 24,
+  B25 = 1 << 25,
+  B26 = 1 << 26,
+  B27 = 1 << 27,
+
+  // ldrex/strex register field encodings.
+  kLdExRnShift = 16,
+  kLdExRtShift = 12,
+  kStrExRnShift = 16,
+  kStrExRdShift = 12,
+  kStrExRtShift = 0,
+};
+
+
+uint32_t Address::encoding3() const {
+  const uint32_t offset_mask = (1 << 12) - 1;
+  uint32_t offset = encoding_ & offset_mask;
+  ASSERT(offset < 256);
+  return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
+}
+
+
+uint32_t Address::vencoding() const {
+  const uint32_t offset_mask = (1 << 12) - 1;
+  uint32_t offset = encoding_ & offset_mask;
+  ASSERT(offset < (1 << 10));  // In the range 0 to +1020.
+  ASSERT(Utils::Utils::IsAligned(offset, 2));  // Multiple of 4.
+  int mode = encoding_ & ((8|4|1) << 21);
+  ASSERT((mode == Offset) || (mode == NegOffset));
+  uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
+  if (mode == Offset) {
+    vencoding |= 1 << 23;
+  }
+  return vencoding;
+}
+
+
+void Assembler::Emit(int32_t value) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  buffer_.Emit<int32_t>(value);
+}
+
+
+void Assembler::EmitType01(Condition cond,
+                           int type,
+                           Opcode opcode,
+                           int set_cc,
+                           Register rn,
+                           Register rd,
+                           ShifterOperand so) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+                     type << kTypeShift |
+                     static_cast<int32_t>(opcode) << kOpcodeShift |
+                     set_cc << kSShift |
+                     static_cast<int32_t>(rn) << kRnShift |
+                     static_cast<int32_t>(rd) << kRdShift |
+                     so.encoding();
+  Emit(encoding);
+}
+
+
+void Assembler::EmitType5(Condition cond, int offset, bool link) {
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+                     5 << kTypeShift |
+                     (link ? 1 : 0) << kLinkShift;
+  Emit(Assembler::EncodeBranchOffset(offset, encoding));
+}
+
+
+void Assembler::EmitMemOp(Condition cond,
+                          bool load,
+                          bool byte,
+                          Register rd,
+                          Address ad) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B26 |
+                     (load ? L : 0) |
+                     (byte ? B : 0) |
+                     (static_cast<int32_t>(rd) << kRdShift) |
+                     ad.encoding();
+  Emit(encoding);
+}
+
+
+void Assembler::EmitMemOpAddressMode3(Condition cond,
+                                      int32_t mode,
+                                      Register rd,
+                                      Address ad) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B22  |
+                     mode |
+                     (static_cast<int32_t>(rd) << kRdShift) |
+                     ad.encoding3();
+  Emit(encoding);
+}
+
+
+void Assembler::EmitMultiMemOp(Condition cond,
+                               BlockAddressMode am,
+                               bool load,
+                               Register base,
+                               RegList regs) {
+  ASSERT(base != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 |
+                     am |
+                     (load ? L : 0) |
+                     (static_cast<int32_t>(base) << kRnShift) |
+                     regs;
+  Emit(encoding);
+}
+
+
+void Assembler::EmitShiftImmediate(Condition cond,
+                                   Shift opcode,
+                                   Register rd,
+                                   Register rm,
+                                   ShifterOperand so) {
+  ASSERT(cond != kNoCondition);
+  ASSERT(so.type() == 1);
+  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+                     static_cast<int32_t>(MOV) << kOpcodeShift |
+                     static_cast<int32_t>(rd) << kRdShift |
+                     so.encoding() << kShiftImmShift |
+                     static_cast<int32_t>(opcode) << kShiftShift |
+                     static_cast<int32_t>(rm);
+  Emit(encoding);
+}
+
+
+void Assembler::EmitShiftRegister(Condition cond,
+                                  Shift opcode,
+                                  Register rd,
+                                  Register rm,
+                                  ShifterOperand so) {
+  ASSERT(cond != kNoCondition);
+  ASSERT(so.type() == 0);
+  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+                     static_cast<int32_t>(MOV) << kOpcodeShift |
+                     static_cast<int32_t>(rd) << kRdShift |
+                     so.encoding() << kShiftRegisterShift |
+                     static_cast<int32_t>(opcode) << kShiftShift |
+                     B4 |
+                     static_cast<int32_t>(rm);
+  Emit(encoding);
+}
+
+
+void Assembler::EmitBranch(Condition cond, Label* label, bool link) {
+  if (label->IsBound()) {
+    EmitType5(cond, label->Position() - buffer_.Size(), link);
+  } else {
+    int position = buffer_.Size();
+    // Use the offset field of the branch instruction for linking the sites.
+    EmitType5(cond, label->position_, link);
+    label->LinkTo(position);
+  }
+}
+
+
+void Assembler::and_(Register rd, Register rn, ShifterOperand so,
+                     Condition cond) {
+  EmitType01(cond, so.type(), AND, 0, rn, rd, so);
+}
+
+
+void Assembler::eor(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
+}
+
+
+void Assembler::sub(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
+}
+
+void Assembler::rsb(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
+}
+
+void Assembler::rsbs(Register rd, Register rn, ShifterOperand so,
+                     Condition cond) {
+  EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
+}
+
+
+void Assembler::add(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
+}
+
+
+void Assembler::adds(Register rd, Register rn, ShifterOperand so,
+                     Condition cond) {
+  EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
+}
+
+
+void Assembler::subs(Register rd, Register rn, ShifterOperand so,
+                     Condition cond) {
+  EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
+}
+
+
+void Assembler::adc(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
+}
+
+
+void Assembler::sbc(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
+}
+
+
+void Assembler::rsc(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
+}
+
+
+void Assembler::tst(Register rn, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), TST, 1, rn, R0, so);
+}
+
+
+void Assembler::teq(Register rn, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
+}
+
+
+void Assembler::cmp(Register rn, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
+}
+
+
+void Assembler::cmn(Register rn, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
+}
+
+
+void Assembler::orr(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
+}
+
+
+void Assembler::orrs(Register rd, Register rn, ShifterOperand so,
+                     Condition cond) {
+  EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
+}
+
+
+void Assembler::mov(Register rd, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
+}
+
+
+void Assembler::movs(Register rd, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
+}
+
+
+void Assembler::bic(Register rd, Register rn, ShifterOperand so,
+                    Condition cond) {
+  EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
+}
+
+
+void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
+}
+
+
+void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) {
+  EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
+}
+
+
+void Assembler::clz(Register rd, Register rm, Condition cond) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(rm != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  ASSERT(rd != PC);
+  ASSERT(rm != PC);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B24 | B22 | B21 | (0xf << 16) |
+                     (static_cast<int32_t>(rd) << kRdShift) |
+                     (0xf << 8) | B4 | static_cast<int32_t>(rm);
+  Emit(encoding);
+}
+
+
+void Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+                     B25 | B24 | ((imm16 >> 12) << 16) |
+                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
+  Emit(encoding);
+}
+
+
+void Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
+                     B25 | B24 | B22 | ((imm16 >> 12) << 16) |
+                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
+  Emit(encoding);
+}
+
+
+void Assembler::EmitMulOp(Condition cond, int32_t opcode,
+                          Register rd, Register rn,
+                          Register rm, Register rs) {
+  ASSERT(rd != kNoRegister);
+  ASSERT(rn != kNoRegister);
+  ASSERT(rm != kNoRegister);
+  ASSERT(rs != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = opcode |
+      (static_cast<int32_t>(cond) << kConditionShift) |
+      (static_cast<int32_t>(rn) << kRnShift) |
+      (static_cast<int32_t>(rd) << kRdShift) |
+      (static_cast<int32_t>(rs) << kRsShift) |
+      B7 | B4 |
+      (static_cast<int32_t>(rm) << kRmShift);
+  Emit(encoding);
+}
+
+
+void Assembler::mul(Register rd, Register rn,
+                    Register rm, Condition cond) {
+  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
+  EmitMulOp(cond, 0, R0, rd, rn, rm);
+}
+
+
+void Assembler::mla(Register rd, Register rn,
+                    Register rm, Register ra, Condition cond) {
+  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
+  EmitMulOp(cond, B21, ra, rd, rn, rm);
+}
+
+
+void Assembler::mls(Register rd, Register rn,
+                    Register rm, Register ra, Condition cond) {
+  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
+  EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
+}
+
+
+void Assembler::umull(Register rd_lo, Register rd_hi,
+                      Register rn, Register rm, Condition cond) {
+  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
+  EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
+}
+
+
+void Assembler::ldr(Register rd, Address ad, Condition cond) {
+  EmitMemOp(cond, true, false, rd, ad);
+}
+
+
+void Assembler::str(Register rd, Address ad, Condition cond) {
+  EmitMemOp(cond, false, false, rd, ad);
+}
+
+
+void Assembler::ldrb(Register rd, Address ad, Condition cond) {
+  EmitMemOp(cond, true, true, rd, ad);
+}
+
+
+void Assembler::strb(Register rd, Address ad, Condition cond) {
+  EmitMemOp(cond, false, true, rd, ad);
+}
+
+
+void Assembler::ldrh(Register rd, Address ad, Condition cond) {
+  EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
+}
+
+
+void Assembler::strh(Register rd, Address ad, Condition cond) {
+  EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
+}
+
+
+void Assembler::ldrsb(Register rd, Address ad, Condition cond) {
+  EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
+}
+
+
+void Assembler::ldrsh(Register rd, Address ad, Condition cond) {
+  EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
+}
+
+
+void Assembler::ldrd(Register rd, Address ad, Condition cond) {
+  ASSERT((rd % 2) == 0);
+  EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
+}
+
+
+void Assembler::strd(Register rd, Address ad, Condition cond) {
+  ASSERT((rd % 2) == 0);
+  EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
+}
+
+
+void Assembler::ldm(BlockAddressMode am, Register base, RegList regs,
+                    Condition cond) {
+  EmitMultiMemOp(cond, am, true, base, regs);
+}
+
+
+void Assembler::stm(BlockAddressMode am, Register base, RegList regs,
+                    Condition cond) {
+  EmitMultiMemOp(cond, am, false, base, regs);
+}
+
+
+void Assembler::ldrex(Register rt, Register rn, Condition cond) {
+  ASSERT(rn != kNoRegister);
+  ASSERT(rt != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B24 |
+                     B23 |
+                     L   |
+                     (static_cast<int32_t>(rn) << kLdExRnShift) |
+                     (static_cast<int32_t>(rt) << kLdExRtShift) |
+                     B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
+  Emit(encoding);
+}
+
+
+void Assembler::strex(Register rd, Register rt, Register rn, Condition cond) {
+  ASSERT(rn != kNoRegister);
+  ASSERT(rd != kNoRegister);
+  ASSERT(rt != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B24 |
+                     B23 |
+                     (static_cast<int32_t>(rn) << kStrExRnShift) |
+                     (static_cast<int32_t>(rd) << kStrExRdShift) |
+                     B11 | B10 | B9 | B8 | B7 | B4 |
+                     (static_cast<int32_t>(rt) << kStrExRtShift);
+  Emit(encoding);
+}
+
+
+void Assembler::clrex() {
+  int32_t encoding = (kSpecialCondition << kConditionShift) |
+                     B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
+  Emit(encoding);
+}
+
+
+void Assembler::nop(Condition cond) {
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B25 | B24 | B21 | (0xf << 12);
+  Emit(encoding);
+}
+
+
+void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
+  ASSERT(sn != kNoSRegister);
+  ASSERT(rt != kNoRegister);
+  ASSERT(rt != SP);
+  ASSERT(rt != PC);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 |
+                     ((static_cast<int32_t>(sn) >> 1)*B16) |
+                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
+  Emit(encoding);
+}
+
+
+void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
+  ASSERT(sn != kNoSRegister);
+  ASSERT(rt != kNoRegister);
+  ASSERT(rt != SP);
+  ASSERT(rt != PC);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B20 |
+                     ((static_cast<int32_t>(sn) >> 1)*B16) |
+                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
+  Emit(encoding);
+}
+
+
+void Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
+                        Condition cond) {
+  ASSERT(sm != kNoSRegister);
+  ASSERT(sm != S31);
+  ASSERT(rt != kNoRegister);
+  ASSERT(rt != SP);
+  ASSERT(rt != PC);
+  ASSERT(rt2 != kNoRegister);
+  ASSERT(rt2 != SP);
+  ASSERT(rt2 != PC);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B22 |
+                     (static_cast<int32_t>(rt2)*B16) |
+                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
+                     (static_cast<int32_t>(sm) >> 1);
+  Emit(encoding);
+}
+
+
+void Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
+                        Condition cond) {
+  ASSERT(sm != kNoSRegister);
+  ASSERT(sm != S31);
+  ASSERT(rt != kNoRegister);
+  ASSERT(rt != SP);
+  ASSERT(rt != PC);
+  ASSERT(rt2 != kNoRegister);
+  ASSERT(rt2 != SP);
+  ASSERT(rt2 != PC);
+  ASSERT(rt != rt2);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B22 | B20 |
+                     (static_cast<int32_t>(rt2)*B16) |
+                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
+                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
+                     (static_cast<int32_t>(sm) >> 1);
+  Emit(encoding);
+}
+
+
+void Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
+                        Condition cond) {
+  ASSERT(dm != kNoDRegister);
+  ASSERT(rt != kNoRegister);
+  ASSERT(rt != SP);
+  ASSERT(rt != PC);
+  ASSERT(rt2 != kNoRegister);
+  ASSERT(rt2 != SP);
+  ASSERT(rt2 != PC);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B22 |
+                     (static_cast<int32_t>(rt2)*B16) |
+                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
+                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
+                     (static_cast<int32_t>(dm) & 0xf);
+  Emit(encoding);
+}
+
+
+void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
+                        Condition cond) {
+  ASSERT(dm != kNoDRegister);
+  ASSERT(rt != kNoRegister);
+  ASSERT(rt != SP);
+  ASSERT(rt != PC);
+  ASSERT(rt2 != kNoRegister);
+  ASSERT(rt2 != SP);
+  ASSERT(rt2 != PC);
+  ASSERT(rt != rt2);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B22 | B20 |
+                     (static_cast<int32_t>(rt2)*B16) |
+                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
+                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
+                     (static_cast<int32_t>(dm) & 0xf);
+  Emit(encoding);
+}
+
+
+void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
+  ASSERT(sd != kNoSRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B24 | B20 |
+                     ((static_cast<int32_t>(sd) & 1)*B22) |
+                     ((static_cast<int32_t>(sd) >> 1)*B12) |
+                     B11 | B9 | ad.vencoding();
+  Emit(encoding);
+}
+
+
+void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
+  ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
+  ASSERT(sd != kNoSRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B24 |
+                     ((static_cast<int32_t>(sd) & 1)*B22) |
+                     ((static_cast<int32_t>(sd) >> 1)*B12) |
+                     B11 | B9 | ad.vencoding();
+  Emit(encoding);
+}
+
+
+void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
+  ASSERT(dd != kNoDRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B24 | B20 |
+                     ((static_cast<int32_t>(dd) >> 4)*B22) |
+                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
+                     B11 | B9 | B8 | ad.vencoding();
+  Emit(encoding);
+}
+
+
+void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
+  ASSERT(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)) != PC);
+  ASSERT(dd != kNoDRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B24 |
+                     ((static_cast<int32_t>(dd) >> 4)*B22) |
+                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
+                     B11 | B9 | B8 | ad.vencoding();
+  Emit(encoding);
+}
+
+
+void Assembler::EmitVFPsss(Condition cond, int32_t opcode,
+                           SRegister sd, SRegister sn, SRegister sm) {
+  ASSERT(sd != kNoSRegister);
+  ASSERT(sn != kNoSRegister);
+  ASSERT(sm != kNoSRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B11 | B9 | opcode |
+                     ((static_cast<int32_t>(sd) & 1)*B22) |
+                     ((static_cast<int32_t>(sn) >> 1)*B16) |
+                     ((static_cast<int32_t>(sd) >> 1)*B12) |
+                     ((static_cast<int32_t>(sn) & 1)*B7) |
+                     ((static_cast<int32_t>(sm) & 1)*B5) |
+                     (static_cast<int32_t>(sm) >> 1);
+  Emit(encoding);
+}
+
+
+void Assembler::EmitVFPddd(Condition cond, int32_t opcode,
+                           DRegister dd, DRegister dn, DRegister dm) {
+  ASSERT(dd != kNoDRegister);
+  ASSERT(dn != kNoDRegister);
+  ASSERT(dm != kNoDRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
+                     ((static_cast<int32_t>(dd) >> 4)*B22) |
+                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
+                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
+                     ((static_cast<int32_t>(dn) >> 4)*B7) |
+                     ((static_cast<int32_t>(dm) >> 4)*B5) |
+                     (static_cast<int32_t>(dm) & 0xf);
+  Emit(encoding);
+}
+
+
+void Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
+  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
+}
+
+
+bool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
+  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
+  if (((imm32 & ((1 << 19) - 1)) == 0) &&
+      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
+       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
+    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
+        ((imm32 >> 19) & ((1 << 6) -1));
+    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
+               sd, S0, S0);
+    return true;
+  }
+  return false;
+}
+
+
+bool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
+  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
+  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
+      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
+       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
+    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
+        ((imm64 >> 48) & ((1 << 6) -1));
+    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
+               dd, D0, D0);
+    return true;
+  }
+  return false;
+}
+
+
+void Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
+                      Condition cond) {
+  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
+}
+
+
+void Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
+                      Condition cond) {
+  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
+}
+
+
+void Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
+                      Condition cond) {
+  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
+}
+
+
+void Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
+                      Condition cond) {
+  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
+}
+
+
+void Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
+                      Condition cond) {
+  EmitVFPsss(cond, B21, sd, sn, sm);
+}
+
+
+void Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
+                      Condition cond) {
+  EmitVFPddd(cond, B21, dd, dn, dm);
+}
+
+
+void Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
+                      Condition cond) {
+  EmitVFPsss(cond, 0, sd, sn, sm);
+}
+
+
+void Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
+                      Condition cond) {
+  EmitVFPddd(cond, 0, dd, dn, dm);
+}
+
+
+void Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
+                      Condition cond) {
+  EmitVFPsss(cond, B6, sd, sn, sm);
+}
+
+
+void Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
+                      Condition cond) {
+  EmitVFPddd(cond, B6, dd, dn, dm);
+}
+
+
+void Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
+                      Condition cond) {
+  EmitVFPsss(cond, B23, sd, sn, sm);
+}
+
+
+void Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
+                      Condition cond) {
+  EmitVFPddd(cond, B23, dd, dn, dm);
+}
+
+
+void Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
+  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
+}
+
+
+void Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
+  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
+}
+
+
+void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
+}
+
+void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
+  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
+}
+
+
+void Assembler::EmitVFPsd(Condition cond, int32_t opcode,
+                          SRegister sd, DRegister dm) {
+  ASSERT(sd != kNoSRegister);
+  ASSERT(dm != kNoDRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B11 | B9 | opcode |
+                     ((static_cast<int32_t>(sd) & 1)*B22) |
+                     ((static_cast<int32_t>(sd) >> 1)*B12) |
+                     ((static_cast<int32_t>(dm) >> 4)*B5) |
+                     (static_cast<int32_t>(dm) & 0xf);
+  Emit(encoding);
+}
+
+
+void Assembler::EmitVFPds(Condition cond, int32_t opcode,
+                          DRegister dd, SRegister sm) {
+  ASSERT(dd != kNoDRegister);
+  ASSERT(sm != kNoSRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B11 | B9 | opcode |
+                     ((static_cast<int32_t>(dd) >> 4)*B22) |
+                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
+                     ((static_cast<int32_t>(sm) & 1)*B5) |
+                     (static_cast<int32_t>(sm) >> 1);
+  Emit(encoding);
+}
+
+
+void Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
+  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
+}
+
+
+void Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
+  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
+}
+
+
+void Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
+  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
+}
+
+
+void Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
+  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
+}
+
+
+void Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
+  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
+}
+
+
+void Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
+  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
+}
+
+
+void Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
+}
+
+
+void Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
+  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
+}
+
+
+void Assembler::vcmpsz(SRegister sd, Condition cond) {
+  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
+}
+
+
+void Assembler::vcmpdz(DRegister dd, Condition cond) {
+  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
+}
+
+
+void Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
+                     (static_cast<int32_t>(PC)*B12) |
+                     B11 | B9 | B4;
+  Emit(encoding);
+}
+
+
+void Assembler::svc(uint32_t imm24) {
+  ASSERT(imm24 < (1 << 24));
+  int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
+  Emit(encoding);
+}
+
+
+void Assembler::bkpt(uint16_t imm16) {
+  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
+                     ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
+  Emit(encoding);
+}
+
+
+void Assembler::b(Label* label, Condition cond) {
+  EmitBranch(cond, label, false);
+}
+
+
+void Assembler::bl(Label* label, Condition cond) {
+  EmitBranch(cond, label, true);
+}
+
+
+void Assembler::blx(Register rm, Condition cond) {
+  ASSERT(rm != kNoRegister);
+  ASSERT(cond != kNoCondition);
+  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
+                     B24 | B21 | (0xfff << 8) | B5 | B4 |
+                     (static_cast<int32_t>(rm) << kRmShift);
+  Emit(encoding);
+}
+
+
+void Assembler::MarkExceptionHandler(Label* label) {
+  EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
+  Label l;
+  b(&l);
+  EmitBranch(AL, label, false);
+  Bind(&l);
+}
+
+
+void Assembler::LoadObject(Register rd, const Object& object) {
+  UNIMPLEMENTED();
+}
+
+
+void Assembler::Bind(Label* label) {
+  ASSERT(!label->IsBound());
+  int bound_pc = buffer_.Size();
+  while (label->IsLinked()) {
+    int32_t position = label->Position();
+    int32_t next = buffer_.Load<int32_t>(position);
+    int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next);
+    buffer_.Store<int32_t>(position, encoded);
+    label->position_ = Assembler::DecodeBranchOffset(next);
+  }
+  label->BindTo(bound_pc);
+}
+
+
+bool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
+  switch (type) {
+    case kLoadSignedByte:
+    case kLoadSignedHalfword:
+    case kLoadUnsignedHalfword:
+    case kLoadWordPair:
+      return Utils::IsAbsoluteUint(8, offset);  // Addressing mode 3.
+    case kLoadUnsignedByte:
+    case kLoadWord:
+      return Utils::IsAbsoluteUint(12, offset);  // Addressing mode 2.
+    case kLoadSWord:
+    case kLoadDWord:
+      return Utils::IsAbsoluteUint(10, offset);  // VFP addressing mode.
+    default:
+      UNREACHABLE();
+      return false;
+  }
+}
+
+
+bool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
+  switch (type) {
+    case kStoreHalfword:
+    case kStoreWordPair:
+      return Utils::IsAbsoluteUint(8, offset);  // Addressing mode 3.
+    case kStoreByte:
+    case kStoreWord:
+      return Utils::IsAbsoluteUint(12, offset);  // Addressing mode 2.
+    case kStoreSWord:
+    case kStoreDWord:
+      return Utils::IsAbsoluteUint(10, offset);  // VFP addressing mode.
+    default:
+      UNREACHABLE();
+      return false;
+  }
+}
+
+
+void Assembler::Push(Register rd, Condition cond) {
+  str(rd, Address(SP, -kWordSize, Address::PreIndex), cond);
+}
+
+
+void Assembler::Pop(Register rd, Condition cond) {
+  ldr(rd, Address(SP, kWordSize, Address::PostIndex), cond);
+}
+
+
+void Assembler::PushList(RegList regs, Condition cond) {
+  stm(DB_W, SP, regs, cond);
+}
+
+
+void Assembler::PopList(RegList regs, Condition cond) {
+  ldm(IA_W, SP, regs, cond);
+}
+
+
+void Assembler::Mov(Register rd, Register rm, Condition cond) {
+  if (rd != rm) {
+    mov(rd, ShifterOperand(rm), cond);
+  }
+}
+
+
+void Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
+                    Condition cond) {
+  ASSERT(shift_imm != 0);  // Do not use Lsl if no shift is wanted.
+  mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
+}
+
+
+void Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
+                    Condition cond) {
+  ASSERT(shift_imm != 0);  // Do not use Lsr if no shift is wanted.
+  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
+  mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
+}
+
+
+void Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
+                    Condition cond) {
+  ASSERT(shift_imm != 0);  // Do not use Asr if no shift is wanted.
+  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
+  mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
+}
+
+
+void Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
+                    Condition cond) {
+  ASSERT(shift_imm != 0);  // Use Rrx instruction.
+  mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
+}
+
+
+void Assembler::Rrx(Register rd, Register rm, Condition cond) {
+  mov(rd, ShifterOperand(rm, ROR, 0), cond);
+}
+
+
+void Assembler::Branch(const ExternalLabel* label) {
+  // TODO(regis): Revisit this code sequence.
+  LoadImmediate(IP, label->address());  // Target address is never patched.
+  mov(PC, ShifterOperand(IP));
+}
+
+
+void Assembler::BranchLink(const ExternalLabel* label) {
+  // TODO(regis): Revisit this code sequence.
+  // Make sure that CodePatcher is able to patch this code sequence.
+  // For added code robustness, use 'blx lr' in a patchable sequence and
+  // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
+  ldr(LR, Address(PC));
+  Label skip;
+  b(&skip);
+  Emit(label->address());  // May get patched.
+  Bind(&skip);
+  blx(LR);  // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) {
+  // TODO(regis): Revisit this code sequence.
+  LoadImmediate(IP, label->address());  // Target address is never patched.
+  str(PC, ad);
+  blx(IP);  // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::BranchLinkOffset(Register base, int offset) {
+  ASSERT(base != PC);
+  ASSERT(base != IP);
+  if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
+    ldr(IP, Address(base, offset));
+  } else {
+    int offset_hi = offset & ~kOffset12Mask;
+    int offset_lo = offset & kOffset12Mask;
+    ShifterOperand offset_hi_op;
+    if (ShifterOperand::CanHold(offset_hi, &offset_hi_op)) {
+      add(IP, base, offset_hi_op);
+      ldr(IP, Address(IP, offset_lo));
+    } else {
+      LoadImmediate(IP, offset_hi);
+      add(IP, IP, ShifterOperand(base));
+      ldr(IP, Address(IP, offset_lo));
+    }
+  }
+  blx(IP);  // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
+  ShifterOperand shifter_op;
+  if (ShifterOperand::CanHold(value, &shifter_op)) {
+    mov(rd, shifter_op, cond);
+  } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
+    mvn(rd, shifter_op, cond);
+  } else {
+    movw(rd, Utils::Low16Bits(value), cond);
+    uint16_t value_high = Utils::High16Bits(value);
+    if (value_high != 0) {
+      movt(rd, value_high, cond);
+    }
+  }
+}
+
+
+void Assembler::LoadSImmediate(SRegister sd, float value, Condition cond) {
+  if (!vmovs(sd, value, cond)) {
+    LoadImmediate(IP, bit_cast<int32_t, float>(value), cond);
+    vmovsr(sd, IP, cond);
+  }
+}
+
+
+void Assembler::LoadDImmediate(DRegister dd,
+                               double value,
+                               Register scratch,
+                               Condition cond) {
+  // TODO(regis): Revisit this code sequence.
+  ASSERT(scratch != PC);
+  ASSERT(scratch != IP);
+  if (!vmovd(dd, value, cond)) {
+    // A scratch register and IP are needed to load an arbitrary double.
+    ASSERT(scratch != kNoRegister);
+    int64_t imm64 = bit_cast<int64_t, double>(value);
+    LoadImmediate(IP, Utils::Low32Bits(imm64), cond);
+    LoadImmediate(scratch, Utils::High32Bits(imm64), cond);
+    vmovdrr(dd, IP, scratch, cond);
+  }
+}
+
+
+void Assembler::LoadFromOffset(LoadOperandType type,
+                               Register reg,
+                               Register base,
+                               int32_t offset,
+                               Condition cond) {
+  if (!Address::CanHoldLoadOffset(type, offset)) {
+    ASSERT(base != IP);
+    LoadImmediate(IP, offset, cond);
+    add(IP, IP, ShifterOperand(base), cond);
+    base = IP;
+    offset = 0;
+  }
+  ASSERT(Address::CanHoldLoadOffset(type, offset));
+  switch (type) {
+    case kLoadSignedByte:
+      ldrsb(reg, Address(base, offset), cond);
+      break;
+    case kLoadUnsignedByte:
+      ldrb(reg, Address(base, offset), cond);
+      break;
+    case kLoadSignedHalfword:
+      ldrsh(reg, Address(base, offset), cond);
+      break;
+    case kLoadUnsignedHalfword:
+      ldrh(reg, Address(base, offset), cond);
+      break;
+    case kLoadWord:
+      ldr(reg, Address(base, offset), cond);
+      break;
+    case kLoadWordPair:
+      ldrd(reg, Address(base, offset), cond);
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void Assembler::StoreToOffset(StoreOperandType type,
+                              Register reg,
+                              Register base,
+                              int32_t offset,
+                              Condition cond) {
+  if (!Address::CanHoldStoreOffset(type, offset)) {
+    ASSERT(reg != IP);
+    ASSERT(base != IP);
+    LoadImmediate(IP, offset, cond);
+    add(IP, IP, ShifterOperand(base), cond);
+    base = IP;
+    offset = 0;
+  }
+  ASSERT(Address::CanHoldStoreOffset(type, offset));
+  switch (type) {
+    case kStoreByte:
+      strb(reg, Address(base, offset), cond);
+      break;
+    case kStoreHalfword:
+      strh(reg, Address(base, offset), cond);
+      break;
+    case kStoreWord:
+      str(reg, Address(base, offset), cond);
+      break;
+    case kStoreWordPair:
+      strd(reg, Address(base, offset), cond);
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void Assembler::LoadSFromOffset(SRegister reg,
+                                Register base,
+                                int32_t offset,
+                                Condition cond) {
+  if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) {
+    ASSERT(base != IP);
+    LoadImmediate(IP, offset, cond);
+    add(IP, IP, ShifterOperand(base), cond);
+    base = IP;
+    offset = 0;
+  }
+  ASSERT(Address::CanHoldLoadOffset(kLoadSWord, offset));
+  vldrs(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::StoreSToOffset(SRegister reg,
+                               Register base,
+                               int32_t offset,
+                               Condition cond) {
+  if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) {
+    ASSERT(base != IP);
+    LoadImmediate(IP, offset, cond);
+    add(IP, IP, ShifterOperand(base), cond);
+    base = IP;
+    offset = 0;
+  }
+  ASSERT(Address::CanHoldStoreOffset(kStoreSWord, offset));
+  vstrs(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::LoadDFromOffset(DRegister reg,
+                                Register base,
+                                int32_t offset,
+                                Condition cond) {
+  if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) {
+    ASSERT(base != IP);
+    LoadImmediate(IP, offset, cond);
+    add(IP, IP, ShifterOperand(base), cond);
+    base = IP;
+    offset = 0;
+  }
+  ASSERT(Address::CanHoldLoadOffset(kLoadDWord, offset));
+  vldrd(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::StoreDToOffset(DRegister reg,
+                               Register base,
+                               int32_t offset,
+                               Condition cond) {
+  if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) {
+    ASSERT(base != IP);
+    LoadImmediate(IP, offset, cond);
+    add(IP, IP, ShifterOperand(base), cond);
+    base = IP;
+    offset = 0;
+  }
+  ASSERT(Address::CanHoldStoreOffset(kStoreDWord, offset));
+  vstrd(reg, Address(base, offset), cond);
+}
+
+
+void Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
+  AddConstant(rd, rd, value, cond);
+}
+
+
+void Assembler::AddConstant(Register rd, Register rn, int32_t value,
+                            Condition cond) {
+  if (value == 0) {
+    if (rd != rn) {
+      mov(rd, ShifterOperand(rn), cond);
+    }
+    return;
+  }
+  // We prefer to select the shorter code sequence rather than selecting add for
+  // positive values and sub for negatives ones, which would slightly improve
+  // the readability of generated code for some constants.
+  ShifterOperand shifter_op;
+  if (ShifterOperand::CanHold(value, &shifter_op)) {
+    add(rd, rn, shifter_op, cond);
+  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
+    sub(rd, rn, shifter_op, cond);
+  } else {
+    ASSERT(rn != IP);
+    if (ShifterOperand::CanHold(~value, &shifter_op)) {
+      mvn(IP, shifter_op, cond);
+      add(rd, rn, ShifterOperand(IP), cond);
+    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
+      mvn(IP, shifter_op, cond);
+      sub(rd, rn, ShifterOperand(IP), cond);
+    } else {
+      movw(IP, Utils::Low16Bits(value), cond);
+      uint16_t value_high = Utils::High16Bits(value);
+      if (value_high != 0) {
+        movt(IP, value_high, cond);
+      }
+      add(rd, rn, ShifterOperand(IP), cond);
+    }
+  }
+}
+
+
+void Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
+                                    Condition cond) {
+  ShifterOperand shifter_op;
+  if (ShifterOperand::CanHold(value, &shifter_op)) {
+    adds(rd, rn, shifter_op, cond);
+  } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
+    subs(rd, rn, shifter_op, cond);
+  } else {
+    ASSERT(rn != IP);
+    if (ShifterOperand::CanHold(~value, &shifter_op)) {
+      mvn(IP, shifter_op, cond);
+      adds(rd, rn, ShifterOperand(IP), cond);
+    } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
+      mvn(IP, shifter_op, cond);
+      subs(rd, rn, ShifterOperand(IP), cond);
+    } else {
+      movw(IP, Utils::Low16Bits(value), cond);
+      uint16_t value_high = Utils::High16Bits(value);
+      if (value_high != 0) {
+        movt(IP, value_high, cond);
+      }
+      adds(rd, rn, ShifterOperand(IP), cond);
+    }
+  }
+}
+
+
+void Assembler::AddConstantWithCarry(Register rd, Register rn, int32_t value,
+                                     Condition cond) {
+  ShifterOperand shifter_op;
+  if (ShifterOperand::CanHold(value, &shifter_op)) {
+    adc(rd, rn, shifter_op, cond);
+  } else if (ShifterOperand::CanHold(-value - 1, &shifter_op)) {
+    sbc(rd, rn, shifter_op, cond);
+  } else {
+    ASSERT(rn != IP);
+    if (ShifterOperand::CanHold(~value, &shifter_op)) {
+      mvn(IP, shifter_op, cond);
+      adc(rd, rn, ShifterOperand(IP), cond);
+    } else if (ShifterOperand::CanHold(~(-value - 1), &shifter_op)) {
+      mvn(IP, shifter_op, cond);
+      sbc(rd, rn, ShifterOperand(IP), cond);
+    } else {
+      movw(IP, Utils::Low16Bits(value), cond);
+      uint16_t value_high = Utils::High16Bits(value);
+      if (value_high != 0) {
+        movt(IP, value_high, cond);
+      }
+      adc(rd, rn, ShifterOperand(IP), cond);
+    }
+  }
+}
+
+
+void Assembler::Stop(const char* message) {
+  if (FLAG_print_stop_message) {
+    UNIMPLEMENTED();  // Emit call to StubCode::PrintStopMessage().
+  }
+  // Emit the message address before the svc instruction, so that we can
+  // 'unstop' and continue execution in the simulator or jump to the next
+  // instruction in gdb.
+  Label stop;
+  b(&stop);
+  Emit(reinterpret_cast<int32_t>(message));
+  Bind(&stop);
+  svc(kStopMessageSvcCode);
+}
+
+
+int32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) {
+  // The offset is off by 8 due to the way the ARM CPUs read PC.
+  offset -= 8;
+  ASSERT(Utils::IsAligned(offset, 4));
+  ASSERT(Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset));
+
+  // Properly preserve only the bits supported in the instruction.
+  offset >>= 2;
+  offset &= kBranchOffsetMask;
+  return (inst & ~kBranchOffsetMask) | offset;
+}
+
+
+int Assembler::DecodeBranchOffset(int32_t inst) {
+  // Sign-extend, left-shift by 2, then add 8.
+  return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
+}
 
 }  // namespace dart
 
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 0661a8a..b998894e 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -10,55 +10,11 @@
 #endif
 
 #include "platform/assert.h"
+#include "platform/utils.h"
 #include "vm/constants_arm.h"
 
 namespace dart {
 
-class Operand : public ValueObject {
- public:
-  Operand(const Operand& other) : ValueObject() {
-    UNIMPLEMENTED();
-  }
-
-  Operand& operator=(const Operand& other) {
-    UNIMPLEMENTED();
-    return *this;
-  }
-
- protected:
-  Operand() { }  // Needed by subclass Address.
-};
-
-
-class Address : public Operand {
- public:
-  Address(Register base, int32_t disp) {
-    UNIMPLEMENTED();
-  }
-
-  Address(const Address& other) : Operand(other) { }
-
-  Address& operator=(const Address& other) {
-    Operand::operator=(other);
-    return *this;
-  }
-};
-
-
-class FieldAddress : public Address {
- public:
-  FieldAddress(Register base, int32_t disp)
-      : Address(base, disp - kHeapObjectTag) { }
-
-  FieldAddress(const FieldAddress& other) : Address(other) { }
-
-  FieldAddress& operator=(const FieldAddress& other) {
-    Address::operator=(other);
-    return *this;
-  }
-};
-
-
 class Label : public ValueObject {
  public:
   Label() : position_(0) { }
@@ -113,38 +69,219 @@
 };
 
 
+// Encodes Addressing Mode 1 - Data-processing operands.
+class ShifterOperand : public ValueObject {
+ public:
+  // Data-processing operands - Uninitialized.
+  ShifterOperand() : type_(-1) { }
+
+  // Data-processing operands - Copy constructor.
+  ShifterOperand(const ShifterOperand& other)
+      : ValueObject(), type_(other.type_), encoding_(other.encoding_) { }
+
+  // Data-processing operands - Assignment operator.
+  ShifterOperand& operator=(const ShifterOperand& other) {
+    type_ = other.type_;
+    encoding_ = other.encoding_;
+    return *this;
+  }
+
+  // Data-processing operands - Immediate.
+  explicit ShifterOperand(uint32_t immediate) {
+    ASSERT(immediate < (1 << kImmed8Bits));
+    type_ = 1;
+    encoding_ = immediate;
+  }
+
+  // Data-processing operands - Rotated immediate.
+  ShifterOperand(uint32_t rotate, uint32_t immed8) {
+    ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
+    type_ = 1;
+    encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
+  }
+
+  // Data-processing operands - Register.
+  explicit ShifterOperand(Register rm) {
+    type_ = 0;
+    encoding_ = static_cast<uint32_t>(rm);
+  }
+
+  // Data-processing operands - Logical shift/rotate by immediate.
+  ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) {
+    ASSERT(shift_imm < (1 << kShiftImmBits));
+    type_ = 0;
+    encoding_ = shift_imm << kShiftImmShift |
+                static_cast<uint32_t>(shift) << kShiftShift |
+                static_cast<uint32_t>(rm);
+  }
+
+  // Data-processing operands - Logical shift/rotate by register.
+  ShifterOperand(Register rm, Shift shift, Register rs) {
+    type_ = 0;
+    encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift |
+                static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) |
+                static_cast<uint32_t>(rm);
+  }
+
+  static bool CanHold(uint32_t immediate, ShifterOperand* shifter_op) {
+    // Avoid the more expensive test for frequent small immediate values.
+    if (immediate < (1 << kImmed8Bits)) {
+      shifter_op->type_ = 1;
+      shifter_op->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
+      return true;
+    }
+    // Note that immediate must be unsigned for the test to work correctly.
+    for (int rot = 0; rot < 16; rot++) {
+      uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot));
+      if (imm8 < (1 << kImmed8Bits)) {
+        shifter_op->type_ = 1;
+        shifter_op->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
+        return true;
+      }
+    }
+    return false;
+  }
+
+ private:
+  bool is_valid() const { return (type_ == 0) || (type_ == 1); }
+
+  uint32_t type() const {
+    ASSERT(is_valid());
+    return type_;
+  }
+
+  uint32_t encoding() const {
+    ASSERT(is_valid());
+    return encoding_;
+  }
+
+  uint32_t type_;  // Encodes the type field (bits 27-25) in the instruction.
+  uint32_t encoding_;
+
+  friend class Assembler;
+};
+
+
+enum LoadOperandType {
+  kLoadSignedByte,
+  kLoadUnsignedByte,
+  kLoadSignedHalfword,
+  kLoadUnsignedHalfword,
+  kLoadWord,
+  kLoadWordPair,
+  kLoadSWord,
+  kLoadDWord
+};
+
+
+enum StoreOperandType {
+  kStoreByte,
+  kStoreHalfword,
+  kStoreWord,
+  kStoreWordPair,
+  kStoreSWord,
+  kStoreDWord
+};
+
+
+// Load/store multiple addressing mode.
+enum BlockAddressMode {
+  // bit encoding P U W
+  DA           = (0|0|0) << 21,  // decrement after
+  IA           = (0|4|0) << 21,  // increment after
+  DB           = (8|0|0) << 21,  // decrement before
+  IB           = (8|4|0) << 21,  // increment before
+  DA_W         = (0|0|1) << 21,  // decrement after with writeback to base
+  IA_W         = (0|4|1) << 21,  // increment after with writeback to base
+  DB_W         = (8|0|1) << 21,  // decrement before with writeback to base
+  IB_W         = (8|4|1) << 21   // increment before with writeback to base
+};
+
+
+class Address : public ValueObject {
+ public:
+  // Memory operand addressing mode
+  enum Mode {
+    // bit encoding P U W
+    Offset       = (8|4|0) << 21,  // offset (w/o writeback to base)
+    PreIndex     = (8|4|1) << 21,  // pre-indexed addressing with writeback
+    PostIndex    = (0|4|0) << 21,  // post-indexed addressing with writeback
+    NegOffset    = (8|0|0) << 21,  // negative offset (w/o writeback to base)
+    NegPreIndex  = (8|0|1) << 21,  // negative pre-indexed with writeback
+    NegPostIndex = (0|0|0) << 21   // negative post-indexed with writeback
+  };
+
+  Address(const Address& other) : ValueObject(), encoding_(other.encoding_) { }
+
+  Address& operator=(const Address& other) {
+    encoding_ = other.encoding_;
+    return *this;
+  }
+
+  explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
+    ASSERT(Utils::IsAbsoluteUint(12, offset));
+    if (offset < 0) {
+      encoding_ = (am ^ (1 << kUShift)) | -offset;  // Flip U to adjust sign.
+    } else {
+      encoding_ = am | offset;
+    }
+    encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
+  }
+
+  static bool CanHoldLoadOffset(LoadOperandType type, int offset);
+  static bool CanHoldStoreOffset(StoreOperandType type, int offset);
+
+ private:
+  uint32_t encoding() const { return encoding_; }
+
+  // Encoding for addressing mode 3.
+  uint32_t encoding3() const;
+
+  // Encoding for vfp load/store addressing.
+  uint32_t vencoding() const;
+
+  uint32_t encoding_;
+
+  friend class Assembler;
+};
+
+
+class FieldAddress : public Address {
+ public:
+  FieldAddress(Register base, int32_t disp)
+      : Address(base, disp - kHeapObjectTag) { }
+
+  FieldAddress(const FieldAddress& other) : Address(other) { }
+
+  FieldAddress& operator=(const FieldAddress& other) {
+    Address::operator=(other);
+    return *this;
+  }
+};
+
+
 class Assembler : public ValueObject {
  public:
-  Assembler() { UNIMPLEMENTED(); }
+  Assembler() : buffer_(), prologue_offset_(-1), comments_() { }
   ~Assembler() { }
 
-  void PopRegister(Register r) {
-    UNIMPLEMENTED();
-  }
+  void PopRegister(Register r) { Pop(r); }
 
-  void Bind(Label* label) {
-    UNIMPLEMENTED();
-  }
+  void Bind(Label* label);
 
   // Misc. functionality
-  int CodeSize() const {
-    UNIMPLEMENTED();
-    return 0;
-  }
-  int prologue_offset() const {
-    UNIMPLEMENTED();
-    return 0;
-  }
+  int CodeSize() const { return buffer_.Size(); }
+  int prologue_offset() const { return prologue_offset_; }
   const ZoneGrowableArray<int>& GetPointerOffsets() const {
-    UNIMPLEMENTED();
-    return *pointer_offsets_;
+    return buffer_.pointer_offsets();
   }
+
   void FinalizeInstructions(const MemoryRegion& region) {
-    UNIMPLEMENTED();
+    buffer_.FinalizeInstructions(region);
   }
 
   // Debugging and bringup support.
-  void Stop(const char* message) { UNIMPLEMENTED(); }
+  void Stop(const char* message);
   void Unimplemented(const char* message);
   void Untested(const char* message);
   void Unreachable(const char* message);
@@ -153,14 +290,9 @@
     UNIMPLEMENTED();
   }
 
-  void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
-    UNIMPLEMENTED();
-  }
+  void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
 
-  const Code::Comments& GetCodeComments() const {
-    UNIMPLEMENTED();
-    return Code::Comments::New(0);
-  }
+  const Code::Comments& GetCodeComments() const;
 
   static const char* RegisterName(Register reg) {
     UNIMPLEMENTED();
@@ -172,8 +304,327 @@
     return NULL;
   }
 
+  // Data-processing instructions.
+  void and_(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void eor(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void sub(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+  void subs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void rsb(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+  void rsbs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void add(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void adds(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void adc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void sbc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void rsc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void tst(Register rn, ShifterOperand so, Condition cond = AL);
+
+  void teq(Register rn, ShifterOperand so, Condition cond = AL);
+
+  void cmp(Register rn, ShifterOperand so, Condition cond = AL);
+
+  void cmn(Register rn, ShifterOperand so, Condition cond = AL);
+
+  void orr(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+  void orrs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void mov(Register rd, ShifterOperand so, Condition cond = AL);
+  void movs(Register rd, ShifterOperand so, Condition cond = AL);
+
+  void bic(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
+
+  void mvn(Register rd, ShifterOperand so, Condition cond = AL);
+  void mvns(Register rd, ShifterOperand so, Condition cond = AL);
+
+  // Miscellaneous data-processing instructions.
+  void clz(Register rd, Register rm, Condition cond = AL);
+  void movw(Register rd, uint16_t imm16, Condition cond = AL);
+  void movt(Register rd, uint16_t imm16, Condition cond = AL);
+
+  // Multiply instructions.
+  void mul(Register rd, Register rn, Register rm, Condition cond = AL);
+  void mla(Register rd, Register rn, Register rm, Register ra,
+           Condition cond = AL);
+  void mls(Register rd, Register rn, Register rm, Register ra,
+           Condition cond = AL);
+  void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
+             Condition cond = AL);
+
+  // Load/store instructions.
+  void ldr(Register rd, Address ad, Condition cond = AL);
+  void str(Register rd, Address ad, Condition cond = AL);
+
+  void ldrb(Register rd, Address ad, Condition cond = AL);
+  void strb(Register rd, Address ad, Condition cond = AL);
+
+  void ldrh(Register rd, Address ad, Condition cond = AL);
+  void strh(Register rd, Address ad, Condition cond = AL);
+
+  void ldrsb(Register rd, Address ad, Condition cond = AL);
+  void ldrsh(Register rd, Address ad, Condition cond = AL);
+
+  void ldrd(Register rd, Address ad, Condition cond = AL);
+  void strd(Register rd, Address ad, Condition cond = AL);
+
+  void ldm(BlockAddressMode am, Register base,
+           RegList regs, Condition cond = AL);
+  void stm(BlockAddressMode am, Register base,
+           RegList regs, Condition cond = AL);
+
+  void ldrex(Register rd, Register rn, Condition cond = AL);
+  void strex(Register rd, Register rt, Register rn, Condition cond = AL);
+
+  // Miscellaneous instructions.
+  void clrex();
+  void nop(Condition cond = AL);
+
+  // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
+  void bkpt(uint16_t imm16);
+  void svc(uint32_t imm24);
+
+  // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
+  void vmovsr(SRegister sn, Register rt, Condition cond = AL);
+  void vmovrs(Register rt, SRegister sn, Condition cond = AL);
+  void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
+  void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
+  void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
+  void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
+  void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
+  void vmovd(DRegister dd, DRegister dm, Condition cond = AL);
+
+  // Returns false if the immediate cannot be encoded.
+  bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
+  bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
+
+  void vldrs(SRegister sd, Address ad, Condition cond = AL);
+  void vstrs(SRegister sd, Address ad, Condition cond = AL);
+  void vldrd(DRegister dd, Address ad, Condition cond = AL);
+  void vstrd(DRegister dd, Address ad, Condition cond = AL);
+
+  void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+  void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+  void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+  void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+  void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+  void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+  void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+  void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+  void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+  void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+  void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
+  void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
+
+  void vabss(SRegister sd, SRegister sm, Condition cond = AL);
+  void vabsd(DRegister dd, DRegister dm, Condition cond = AL);
+  void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
+  void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
+  void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
+  void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);
+
+  void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
+  void vcvtds(DRegister dd, SRegister sm, Condition cond = AL);
+  void vcvtis(SRegister sd, SRegister sm, Condition cond = AL);
+  void vcvtid(SRegister sd, DRegister dm, Condition cond = AL);
+  void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL);
+  void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL);
+  void vcvtus(SRegister sd, SRegister sm, Condition cond = AL);
+  void vcvtud(SRegister sd, DRegister dm, Condition cond = AL);
+  void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL);
+  void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL);
+
+  void vcmps(SRegister sd, SRegister sm, Condition cond = AL);
+  void vcmpd(DRegister dd, DRegister dm, Condition cond = AL);
+  void vcmpsz(SRegister sd, Condition cond = AL);
+  void vcmpdz(DRegister dd, Condition cond = AL);
+  void vmstat(Condition cond = AL);  // VMRS APSR_nzcv, FPSCR
+
+  // Branch instructions.
+  void b(Label* label, Condition cond = AL);
+  void bl(Label* label, Condition cond = AL);
+  void blx(Register rm, Condition cond = AL);
+
+  // Macros.
+  // Branch to an entry address that can be patched at runtime.
+  void Branch(const ExternalLabel* label);
+  void BranchLink(const ExternalLabel* label);
+
+  // Branch to entry after setting LR and storing LR at ad.
+  void BranchLinkStore(const ExternalLabel* label, Address ad);
+
+  // Branch to [base + offset] after setting LR.
+  void BranchLinkOffset(Register base, int offset);
+
+  // Add signed constant value to rd. May clobber IP.
+  void AddConstant(Register rd, int32_t value, Condition cond = AL);
+  void AddConstant(Register rd, Register rn, int32_t value,
+                   Condition cond = AL);
+  void AddConstantSetFlags(Register rd, Register rn, int32_t value,
+                           Condition cond = AL);
+  void AddConstantWithCarry(Register rd, Register rn, int32_t value,
+                            Condition cond = AL);
+
+  // Load and Store. May clobber IP.
+  void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
+  void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
+  void LoadDImmediate(DRegister dd, double value,
+                      Register scratch, Condition cond = AL);
+  void MarkExceptionHandler(Label* label);
+  void LoadObject(Register rd, const Object& object);
+  void LoadFromOffset(LoadOperandType type,
+                      Register reg,
+                      Register base,
+                      int32_t offset,
+                      Condition cond = AL);
+  void StoreToOffset(StoreOperandType type,
+                     Register reg,
+                     Register base,
+                     int32_t offset,
+                     Condition cond = AL);
+  void LoadSFromOffset(SRegister reg,
+                       Register base,
+                       int32_t offset,
+                       Condition cond = AL);
+  void StoreSToOffset(SRegister reg,
+                      Register base,
+                      int32_t offset,
+                      Condition cond = AL);
+  void LoadDFromOffset(DRegister reg,
+                       Register base,
+                       int32_t offset,
+                       Condition cond = AL);
+  void StoreDToOffset(DRegister reg,
+                      Register base,
+                      int32_t offset,
+                      Condition cond = AL);
+
+  void Push(Register rd, Condition cond = AL);
+  void Pop(Register rd, Condition cond = AL);
+
+  void PushList(RegList regs, Condition cond = AL);
+  void PopList(RegList regs, Condition cond = AL);
+
+  void Mov(Register rd, Register rm, Condition cond = AL);
+
+  // Convenience shift instructions. Use mov instruction with shifter operand
+  // for variants setting the status flags or using a register shift count.
+  void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+  void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+  void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+  void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
+  void Rrx(Register rd, Register rm, Condition cond = AL);
+
+  // Emit data (e.g encoded instruction or immediate) in instruction stream.
+  void Emit(int32_t value);
+
  private:
+  AssemblerBuffer buffer_;
   ZoneGrowableArray<int>* pointer_offsets_;
+  int prologue_offset_;
+
+  class CodeComment : public ZoneAllocated {
+   public:
+    CodeComment(intptr_t pc_offset, const String& comment)
+        : pc_offset_(pc_offset), comment_(comment) { }
+
+    intptr_t pc_offset() const { return pc_offset_; }
+    const String& comment() const { return comment_; }
+
+   private:
+    intptr_t pc_offset_;
+    const String& comment_;
+
+    DISALLOW_COPY_AND_ASSIGN(CodeComment);
+  };
+
+  GrowableArray<CodeComment*> comments_;
+
+  void EmitType01(Condition cond,
+                  int type,
+                  Opcode opcode,
+                  int set_cc,
+                  Register rn,
+                  Register rd,
+                  ShifterOperand so);
+
+  void EmitType5(Condition cond, int offset, bool link);
+
+  void EmitMemOp(Condition cond,
+                 bool load,
+                 bool byte,
+                 Register rd,
+                 Address ad);
+
+  void EmitMemOpAddressMode3(Condition cond,
+                             int32_t mode,
+                             Register rd,
+                             Address ad);
+
+  void EmitMultiMemOp(Condition cond,
+                      BlockAddressMode am,
+                      bool load,
+                      Register base,
+                      RegList regs);
+
+  void EmitShiftImmediate(Condition cond,
+                          Shift opcode,
+                          Register rd,
+                          Register rm,
+                          ShifterOperand so);
+
+  void EmitShiftRegister(Condition cond,
+                         Shift opcode,
+                         Register rd,
+                         Register rm,
+                         ShifterOperand so);
+
+  void EmitMulOp(Condition cond,
+                 int32_t opcode,
+                 Register rd,
+                 Register rn,
+                 Register rm,
+                 Register rs);
+
+  void EmitVFPsss(Condition cond,
+                  int32_t opcode,
+                  SRegister sd,
+                  SRegister sn,
+                  SRegister sm);
+
+  void EmitVFPddd(Condition cond,
+                  int32_t opcode,
+                  DRegister dd,
+                  DRegister dn,
+                  DRegister dm);
+
+  void EmitVFPsd(Condition cond,
+                 int32_t opcode,
+                 SRegister sd,
+                 DRegister dm);
+
+  void EmitVFPds(Condition cond,
+                 int32_t opcode,
+                 DRegister dd,
+                 SRegister sm);
+
+  void EmitBranch(Condition cond, Label* label, bool link);
+  static int32_t EncodeBranchOffset(int offset, int32_t inst);
+  static int DecodeBranchOffset(int32_t inst);
+  int32_t EncodeTstOffset(int offset, int32_t inst);
+  int DecodeTstOffset(int32_t inst);
+
+  // Returns whether or not the given register is used for passing parameters.
+  static int RegisterCompare(const Register* reg1, const Register* reg2) {
+    return *reg1 - *reg2;
+  }
+
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index ec581e9..1e23316 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -16,8 +16,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
-            "Include comments into code and disassembly");
 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
 
 
@@ -2052,33 +2050,6 @@
 }
 
 
-void Assembler::Comment(const char* format, ...) {
-  if (FLAG_code_comments) {
-    char buffer[1024];
-
-    va_list args;
-    va_start(args, format);
-    OS::VSNPrint(buffer, sizeof(buffer), format, args);
-    va_end(args);
-
-    comments_.Add(new CodeComment(buffer_.GetPosition(),
-                                  String::Handle(String::New(buffer))));
-  }
-}
-
-
-const Code::Comments& Assembler::GetCodeComments() const {
-  Code::Comments& comments = Code::Comments::New(comments_.length());
-
-  for (intptr_t i = 0; i < comments_.length(); i++) {
-    comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
-    comments.SetCommentAt(i, comments_[i]->comment());
-  }
-
-  return comments;
-}
-
-
 static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
   "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
 };
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 6885019..d6db404 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -10,8 +10,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
-            "Include comments into code and disassembly");
 
 }  // namespace dart
 
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index f2a0f34..9ad8b88 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -153,14 +153,9 @@
     UNIMPLEMENTED();
   }
 
-  void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
-    UNIMPLEMENTED();
-  }
+  void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
 
-  const Code::Comments& GetCodeComments() const {
-    UNIMPLEMENTED();
-    return Code::Comments::New(0);
-  }
+  const Code::Comments& GetCodeComments() const;
 
   static const char* RegisterName(Register reg) {
     UNIMPLEMENTED();
@@ -173,7 +168,27 @@
   }
 
  private:
+  AssemblerBuffer buffer_;
   ZoneGrowableArray<int>* pointer_offsets_;
+  int prologue_offset_;
+
+  class CodeComment : public ZoneAllocated {
+   public:
+    CodeComment(intptr_t pc_offset, const String& comment)
+        : pc_offset_(pc_offset), comment_(comment) { }
+
+    intptr_t pc_offset() const { return pc_offset_; }
+    const String& comment() const { return comment_; }
+
+   private:
+    intptr_t pc_offset_;
+    const String& comment_;
+
+    DISALLOW_COPY_AND_ASSIGN(CodeComment);
+  };
+
+  GrowableArray<CodeComment*> comments_;
+
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 9e5dcbb..1b270aa 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -14,8 +14,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message.");
-DEFINE_FLAG(bool, code_comments, false,
-            "Include comments into code and disassembly");
 DEFINE_FLAG(bool, use_sse41, true, "Use SSE 4.1 if available");
 
 
@@ -2139,33 +2137,6 @@
 }
 
 
-void Assembler::Comment(const char* format, ...) {
-  if (FLAG_code_comments) {
-    char buffer[1024];
-
-    va_list args;
-    va_start(args, format);
-    OS::VSNPrint(buffer, sizeof(buffer), format, args);
-    va_end(args);
-
-    comments_.Add(new CodeComment(buffer_.GetPosition(),
-                                  String::Handle(String::New(buffer))));
-  }
-}
-
-
-const Code::Comments& Assembler::GetCodeComments() const {
-  Code::Comments& comments = Code::Comments::New(comments_.length());
-
-  for (intptr_t i = 0; i < comments_.length(); i++) {
-    comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
-    comments.SetCommentAt(i, comments_[i]->comment());
-  }
-
-  return comments;
-}
-
-
 static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
   "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index f52c1b0..687054f 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -80,6 +80,20 @@
 #endif
   }
 
+  int32_t no_callback_scope_depth() const {
+    return no_callback_scope_depth_;
+  }
+
+  void IncrementNoCallbackScopeDepth() {
+    ASSERT(no_callback_scope_depth_ < INT_MAX);
+    no_callback_scope_depth_ += 1;
+  }
+
+  void DecrementNoCallbackScopeDepth() {
+    ASSERT(no_callback_scope_depth_ > 0);
+    no_callback_scope_depth_ -= 1;
+  }
+
 #if defined(DEBUG)
   static void AssertCurrent(BaseIsolate* isolate);
 #endif
@@ -87,14 +101,13 @@
  protected:
   BaseIsolate()
       : top_resource_(NULL),
-#if defined(DEBUG)
         current_zone_(NULL),
+#if defined(DEBUG)
         top_handle_scope_(NULL),
         no_handle_scope_depth_(0),
-        no_gc_scope_depth_(0)
-#else
-        current_zone_(NULL)
+        no_gc_scope_depth_(0),
 #endif
+        no_callback_scope_depth_(0)
   {}
 
   ~BaseIsolate() {
@@ -108,6 +121,7 @@
   int32_t no_handle_scope_depth_;
   int32_t no_gc_scope_depth_;
 #endif
+  int32_t no_callback_scope_depth_;
 
   DISALLOW_COPY_AND_ASSIGN(BaseIsolate);
 };
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index c18860d..08ff160 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1717,4 +1717,20 @@
 }
 END_LEAF_RUNTIME_ENTRY
 
+
+double DartModulo(double left, double right) {
+  double remainder = fmod_ieee(left, right);
+  if (remainder == 0.0) {
+    // We explicitely switch to the positive 0.0 (just in case it was negative).
+    remainder = +0.0;
+  } else if (remainder < 0.0) {
+    if (right < 0) {
+      remainder -= right;
+    } else {
+      remainder += right;
+    }
+  }
+  return remainder;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 7bf4e99..7946dc2 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -73,6 +73,8 @@
   V(CheckArrayBound)                                                           \
   V(AtCall)                                                                    \
   V(DoubleToSmi)                                                               \
+  V(Int32Load)                                                                 \
+  V(Uint32Load)                                                                \
   V(NumReasons)                                                                \
 
 enum DeoptReasonId {
@@ -93,6 +95,8 @@
 void DeoptimizeAll();
 void DeoptimizeIfOwner(const GrowableArray<intptr_t>& classes);
 
+double DartModulo(double a, double b);
+
 }  // namespace dart
 
 #endif  // VM_CODE_GENERATOR_H_
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index aca46da..4d477db 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -133,7 +133,8 @@
 
 // Register aliases.
 const Register TMP = kNoRegister;  // No scratch register used by assembler.
-const Register CTX = R9;           // Caches current context in generated code.
+const Register CTX = R9;  // Caches current context in generated code.
+const Register CP = R10;  // Caches constant pool base in generated code.
 const Register SPREG = SP;
 const Register FPREG = FP;
 
@@ -143,6 +144,17 @@
 const Register kExceptionObjectReg = R0;  // Unimplemented.
 
 
+// List of registers used in load/store multiple.
+typedef uint16_t RegList;
+const RegList kAllCoreRegistersList = 0xFFFF;
+
+
+// C++ ABI call registers
+const int kAbiRegisterCount = 4;
+const Register kAbiRegisters[kAbiRegisterCount] = { R0, R1, R2, R3 };
+const RegList kAbiRegisterList = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3);
+
+
 // Values for the condition field as defined in section A3.2.
 enum Condition {
   kNoCondition = -1,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 95d3f0c..ed4fd7b 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -192,7 +192,8 @@
 
 Dart_Handle Api::NewError(const char* format, ...) {
   Isolate* isolate = Isolate::Current();
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
 
   va_list args;
   va_start(args, format);
@@ -210,6 +211,23 @@
 }
 
 
+void Api::SetupCallbackError(Isolate* isolate) {
+  ASSERT(isolate != NULL);
+  ApiState* state = isolate->api_state();
+  ASSERT(state != NULL);
+  state->SetupCallbackError();
+}
+
+
+Dart_Handle Api::CallbackError(Isolate* isolate) {
+  ASSERT(isolate != NULL);
+  ApiState* state = isolate->api_state();
+  ASSERT(state != NULL);
+  PersistentHandle* callback_error_handle = state->CallbackError();
+  return reinterpret_cast<Dart_Handle>(callback_error_handle);
+}
+
+
 Dart_Handle Api::Null(Isolate* isolate) {
   ASSERT(isolate != NULL);
   ApiState* state = isolate->api_state();
@@ -396,6 +414,7 @@
 DART_EXPORT Dart_Handle Dart_Error(const char* format, ...) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
 
   va_list args;
   va_start(args, format);
@@ -418,6 +437,7 @@
 DART_EXPORT Dart_Handle Dart_NewApiError(const char* format, ...) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
 
   va_list args;
   va_start(args, format);
@@ -438,6 +458,8 @@
 DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
+
   const Instance& obj = Api::UnwrapInstanceHandle(isolate, exception);
   if (obj.IsNull()) {
     RETURN_TYPE_ERROR(isolate, exception, Instance);
@@ -501,9 +523,11 @@
   if (obj.IsString()) {
     return Api::NewHandle(isolate, obj.raw());
   } else if (obj.IsInstance()) {
+    CHECK_CALLBACK_STATE(isolate);
     const Instance& receiver = Instance::Cast(obj);
     return Api::NewHandle(isolate, DartLibraryCalls::ToString(receiver));
   } else {
+    CHECK_CALLBACK_STATE(isolate);
     // This is a VM internal object. Call the C++ method of printing.
     return Api::NewHandle(isolate, String::New(obj.ToCString()));
   }
@@ -520,8 +544,7 @@
 
 DART_EXPORT Dart_Handle Dart_NewPersistentHandle(Dart_Handle object) {
   Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   const Object& old_ref = Object::Handle(isolate, Api::UnwrapHandle(object));
@@ -550,8 +573,7 @@
     void* peer,
     Dart_WeakPersistentHandleFinalizer callback) {
   Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   return AllocateFinalizableHandle(isolate,
@@ -567,8 +589,7 @@
     void* peer,
     Dart_WeakPersistentHandleFinalizer callback) {
   Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   return AllocateFinalizableHandle(isolate,
@@ -810,7 +831,7 @@
   free(isolate_name);
   {
     StackZone zone(isolate);
-    DARTSCOPE_NOCHECKS(isolate);
+    HANDLESCOPE(isolate);
     const Error& error_obj =
         Error::Handle(isolate,
                       Dart::InitializeIsolate(snapshot, callback_data));
@@ -964,6 +985,7 @@
   Isolate* isolate = Isolate::Current();
 
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   Monitor monitor;
   MonitorLocker ml(&monitor);
   {
@@ -1046,8 +1068,7 @@
 
 DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
   Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   const Object& object = Object::Handle(isolate, Api::UnwrapHandle(handle));
   uint8_t* data = NULL;
   MessageWriter writer(&data, &allocator);
@@ -1093,6 +1114,7 @@
 DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, DartLibraryCalls::NewSendPort(port_id));
 }
 
@@ -1100,6 +1122,8 @@
 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
+
   Library& isolate_lib = Library::Handle(isolate, Library::IsolateLibrary());
   ASSERT(!isolate_lib.IsNull());
   const String& class_name = String::Handle(
@@ -1138,7 +1162,7 @@
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
   ApiLocalScope* new_scope = new ApiLocalScope(state->top_scope(),
-                                               reinterpret_cast<uword>(&state));
+                                               isolate->top_exit_frame_info());
   ASSERT(new_scope != NULL);
   state->set_top_scope(new_scope);  // New scope is now the top scope.
 }
@@ -1191,6 +1215,7 @@
                                           bool* value) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   const Instance& expected =
       Instance::CheckedHandle(isolate, Api::UnwrapHandle(obj1));
   const Instance& actual =
@@ -1235,6 +1260,7 @@
     return Api::NewError("%s", msg);
   }
   if (obj.IsInstance()) {
+    CHECK_CALLBACK_STATE(isolate);
     const Type& type = Type::Handle(isolate,
                                     Type::NewNonParameterizedType(cls));
     Error& malformed_type_error = Error::Handle(isolate);
@@ -1299,7 +1325,7 @@
     return Api::Success(isolate);
   }
   // Slow path for Mints and Bigints.
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
   if (int_obj.IsNull()) {
     RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1320,7 +1346,7 @@
     return Api::Success(isolate);
   }
   // Slow path for Mints and Bigints.
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
   if (int_obj.IsNull()) {
     RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1344,7 +1370,8 @@
     return Api::NewHandle(isolate, Smi::New(static_cast<intptr_t>(value)));
   }
   // Slow path for Mints and Bigints.
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, Integer::New(value));
 }
 
@@ -1352,6 +1379,7 @@
 DART_EXPORT Dart_Handle Dart_NewIntegerFromHexCString(const char* str) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   const String& str_obj = String::Handle(isolate, String::New(str));
   return Api::NewHandle(isolate, Integer::New(str_obj));
 }
@@ -1367,7 +1395,7 @@
     return Api::Success(isolate);
   }
   // Slow path for Mints and Bigints.
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
   if (int_obj.IsNull()) {
     RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1401,7 +1429,7 @@
     }
   }
   // Slow path for Mints and Bigints.
-  DARTSCOPE_NOCHECKS(isolate);
+  DARTSCOPE(isolate);
   const Integer& int_obj = Api::UnwrapIntegerHandle(isolate, integer);
   if (int_obj.IsNull()) {
     RETURN_TYPE_ERROR(isolate, integer, Integer);
@@ -1500,6 +1528,7 @@
 DART_EXPORT Dart_Handle Dart_NewDouble(double value) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, Double::New(value));
 }
 
@@ -1548,6 +1577,7 @@
   if (str == NULL) {
     RETURN_NULL_ERROR(str);
   }
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, String::New(str));
 }
 
@@ -1564,6 +1594,7 @@
     return Api::NewError("%s expects argument 'str' to be valid UTF-8.",
                          CURRENT_FUNC);
   }
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, String::FromUTF8(utf8_array, length));
 }
 
@@ -1576,6 +1607,7 @@
     RETURN_NULL_ERROR(utf16_array);
   }
   CHECK_LENGTH(length, String::kMaxElements);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, String::FromUTF16(utf16_array, length));
 }
 
@@ -1588,6 +1620,7 @@
     RETURN_NULL_ERROR(utf32_array);
   }
   CHECK_LENGTH(length, String::kMaxElements);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, String::FromUTF32(utf32_array, length));
 }
 
@@ -1630,6 +1663,7 @@
     RETURN_NULL_ERROR(latin1_array);
   }
   CHECK_LENGTH(length, String::kMaxElements);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate,
                         String::NewExternal(latin1_array, length, peer, cback));
 }
@@ -1645,6 +1679,7 @@
     RETURN_NULL_ERROR(utf16_array);
   }
   CHECK_LENGTH(length, String::kMaxElements);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate,
                         String::NewExternal(utf16_array, length, peer, cback));
 }
@@ -1853,6 +1888,7 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   CHECK_LENGTH(length, Array::kMaxElements);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, Array::New(length));
 }
 
@@ -1881,6 +1917,8 @@
   if (obj.IsGrowableObjectArray()) {
     GET_LIST_LENGTH(isolate, GrowableObjectArray, obj, len);
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   // Now check and handle a dart object that implements the List interface.
   const Instance& instance =
       Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -1948,6 +1986,8 @@
   } else if (obj.IsError()) {
     return list;
   } else {
+    CHECK_CALLBACK_STATE(isolate);
+
     // Check and handle a dart object that implements the List interface.
     const Instance& instance =
         Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -1989,16 +2029,17 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(list));
-  if (obj.IsArray()) {
-    if (obj.IsImmutableArray()) {
-      return Api::NewError("Cannot modify immutable array");
-    }
+  // If the list is immutable we call into Dart for the indexed setter to
+  // get the unsupported operation exception as the result.
+  if (obj.IsArray() && !obj.IsImmutableArray()) {
     SET_LIST_ELEMENT(isolate, Array, obj, index, value);
   } else if (obj.IsGrowableObjectArray()) {
     SET_LIST_ELEMENT(isolate, GrowableObjectArray, obj, index, value);
   } else if (obj.IsError()) {
     return list;
   } else {
+    CHECK_CALLBACK_STATE(isolate);
+
     // Check and handle a dart object that implements the List interface.
     const Instance& instance =
         Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -2085,6 +2126,8 @@
   } else if (obj.IsError()) {
     return list;
   } else {
+    CHECK_CALLBACK_STATE(isolate);
+
     // Check and handle a dart object that implements the List interface.
     const Instance& instance =
         Instance::Handle(isolate, GetListInstance(isolate, obj));
@@ -2153,10 +2196,9 @@
       return Api::Success(isolate);
     }
     return Api::NewError("Invalid length passed in to set list elements");
-  } else if (obj.IsArray()) {
-    if (obj.IsImmutableArray()) {
-      return Api::NewError("Cannot modify immutable array");
-    }
+  } else if (obj.IsArray() && !obj.IsImmutableArray()) {
+    // If the list is immutable we call into Dart for the indexed setter to
+    // get the unsupported operation exception as the result.
     SET_LIST_ELEMENT_AS_BYTES(isolate,
                               Array,
                               obj,
@@ -2173,7 +2215,9 @@
   } else if (obj.IsError()) {
     return list;
   } else {
-  // Check and handle a dart object that implements the List interface.
+    CHECK_CALLBACK_STATE(isolate);
+
+    // Check and handle a dart object that implements the List interface.
     const Instance& instance =
         Instance::Handle(isolate, GetListInstance(isolate, obj));
     if (!instance.IsNull()) {
@@ -2225,22 +2269,26 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   CHECK_LENGTH(length, Uint8Array::kMaxElements);
+  CHECK_CALLBACK_STATE(isolate);
   return Api::NewHandle(isolate, Uint8Array::New(length));
 }
 
 
-DART_EXPORT Dart_Handle Dart_NewExternalByteArray(uint8_t* data,
-                                                  intptr_t length,
-                                                  void* peer,
-                                                  Dart_PeerFinalizer callback) {
+DART_EXPORT Dart_Handle Dart_NewExternalByteArray(
+    uint8_t* data,
+    intptr_t length,
+    void* peer,
+    Dart_WeakPersistentHandleFinalizer callback) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   if (data == NULL && length != 0) {
     RETURN_NULL_ERROR(data);
   }
   CHECK_LENGTH(length, ExternalUint8Array::kMaxElements);
-  return Api::NewHandle(
-      isolate, ExternalUint8Array::New(data, length, peer, callback));
+  CHECK_CALLBACK_STATE(isolate);
+  const ExternalUint8Array& obj = ExternalUint8Array::Handle(
+      ExternalUint8Array::New(data, length));
+  return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback));
 }
 
 
@@ -2248,15 +2296,17 @@
     uint8_t* data,
     intptr_t length,
     void* peer,
-    Dart_PeerFinalizer callback) {
+    Dart_WeakPersistentHandleFinalizer callback) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   if (data == NULL && length != 0) {
     RETURN_NULL_ERROR(data);
   }
   CHECK_LENGTH(length, ExternalUint8ClampedArray::kMaxElements);
-  return Api::NewHandle(
-      isolate, ExternalUint8ClampedArray::New(data, length, peer, callback));
+  CHECK_CALLBACK_STATE(isolate);
+  const ExternalUint8ClampedArray& obj = ExternalUint8ClampedArray::Handle(
+      ExternalUint8ClampedArray::New(data, length));
+  return reinterpret_cast<Dart_Handle>(obj.AddFinalizer(peer, callback));
 }
 
 
@@ -2294,182 +2344,46 @@
 }
 
 
-template<typename T>
-Dart_Handle ByteArrayGetAt(T* value, Dart_Handle array, intptr_t offset) {
+DART_EXPORT Dart_Handle Dart_ScalarListAcquireData(Dart_Handle array,
+                                                   Dart_Scalar_Type* type,
+                                                   void** data,
+                                                   intptr_t* len) {
   Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  const ByteArray& array_obj = Api::UnwrapByteArrayHandle(isolate, array);
-  if (array_obj.IsNull()) {
-    RETURN_TYPE_ERROR(isolate, array, ByteArray);
+  DARTSCOPE(isolate);
+  if (!RawObject::IsByteArrayClassId(Api::ClassId(array))) {
+    RETURN_TYPE_ERROR(isolate, array, 'scalar list');
   }
-  intptr_t length = sizeof(T);
-  if (!Utils::RangeCheck(offset, length, array_obj.ByteLength())) {
-    return Api::NewError("Invalid index passed in to get byte array element");
+  if (type == NULL) {
+    RETURN_NULL_ERROR(type);
   }
-  uint8_t* dst = reinterpret_cast<uint8_t*>(value);
-  ByteArray::Copy(dst, array_obj, offset, length);
+  if (data == NULL) {
+    RETURN_NULL_ERROR(data);
+  }
+  if (len == NULL) {
+    RETURN_NULL_ERROR(len);
+  }
+  isolate->IncrementNoGCScopeDepth();
+  START_NO_CALLBACK_SCOPE(isolate);
+
+  UNIMPLEMENTED();
   return Api::Success(isolate);
 }
 
 
-template<typename T>
-Dart_Handle ByteArraySetAt(Dart_Handle array, intptr_t offset, T value) {
+DART_EXPORT Dart_Handle Dart_ScalarListReleaseData(Dart_Handle array) {
   Isolate* isolate = Isolate::Current();
-  CHECK_ISOLATE(isolate);
-  const ByteArray& array_obj = Api::UnwrapByteArrayHandle(isolate, array);
-  if (array_obj.IsNull()) {
-    RETURN_TYPE_ERROR(isolate, array, ByteArray);
+  DARTSCOPE(isolate);
+  if (!RawObject::IsByteArrayClassId(Api::ClassId(array))) {
+    RETURN_TYPE_ERROR(isolate, array, 'scalar list');
   }
-  intptr_t length = sizeof(T);
-  if (!Utils::RangeCheck(offset, length, array_obj.ByteLength())) {
-    return Api::NewError("Invalid index passed in to get byte array element");
-  }
-  const uint8_t* src = reinterpret_cast<uint8_t*>(&value);
-  ByteArray::Copy(array_obj, offset, src, length);
+
+  UNIMPLEMENTED();
+  isolate->DecrementNoGCScopeDepth();
+  END_NO_CALLBACK_SCOPE(isolate);
   return Api::Success(isolate);
 }
 
 
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt8At(Dart_Handle array,
-                                                intptr_t byte_offset,
-                                                int8_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt8At(Dart_Handle array,
-                                                intptr_t byte_offset,
-                                                int8_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint8At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 uint8_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint8At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 uint8_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt16At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 int16_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt16At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 int16_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint16At(Dart_Handle array,
-                                                  intptr_t byte_offset,
-                                                  uint16_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint16At(Dart_Handle array,
-                                                  intptr_t byte_offset,
-                                                  uint16_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt32At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 int32_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt32At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 int32_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint32At(Dart_Handle array,
-                                                  intptr_t byte_offset,
-                                                  uint32_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint32At(Dart_Handle array,
-                                                  intptr_t byte_offset,
-                                                  uint32_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetInt64At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 int64_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetInt64At(Dart_Handle array,
-                                                 intptr_t byte_offset,
-                                                 int64_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetUint64At(Dart_Handle array,
-                                                  intptr_t byte_offset,
-                                                  uint64_t* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetUint64At(Dart_Handle array,
-                                                  intptr_t byte_offset,
-                                                  uint64_t value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat32At(Dart_Handle array,
-                                                   intptr_t byte_offset,
-                                                   float* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat32At(Dart_Handle array,
-                                                   intptr_t byte_offset,
-                                                   float value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArrayGetFloat64At(Dart_Handle array,
-                                                   intptr_t byte_offset,
-                                                   double* value) {
-  return ByteArrayGetAt(value, array, byte_offset);
-}
-
-
-DART_EXPORT Dart_Handle Dart_ByteArraySetFloat64At(Dart_Handle array,
-                                                   intptr_t byte_offset,
-                                                   double value) {
-  return ByteArraySetAt(array, byte_offset, value);
-}
-
-
 // --- Closures ---
 
 
@@ -2503,6 +2417,7 @@
                                            Dart_Handle* arguments) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
   if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) {
     RETURN_TYPE_ERROR(isolate, closure, Instance);
@@ -3351,6 +3266,7 @@
                                  Dart_Handle* arguments) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   Object& result = Object::Handle(isolate);
 
   if (number_of_arguments < 0) {
@@ -3365,6 +3281,7 @@
   if (cls.IsNull()) {
     RETURN_TYPE_ERROR(isolate, clazz, Class);
   }
+
   String& base_constructor_name = String::Handle();
   base_constructor_name = cls.Name();
 
@@ -3451,6 +3368,7 @@
                                     Dart_Handle* arguments) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
 
   const String& function_name = Api::UnwrapStringHandle(isolate, name);
   if (function_name.IsNull()) {
@@ -3594,6 +3512,7 @@
 DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
 
   const String& field_name = Api::UnwrapStringHandle(isolate, name);
   if (field_name.IsNull()) {
@@ -3708,6 +3627,7 @@
                                       Dart_Handle value) {
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
 
   const String& field_name = Api::UnwrapStringHandle(isolate, name);
   if (field_name.IsNull()) {
@@ -3861,6 +3781,7 @@
     return Api::NewError(
         "Negative field_count passed to Dart_CreateNativeWrapperClass");
   }
+  CHECK_CALLBACK_STATE(isolate);
 
   String& cls_symbol = String::Handle(isolate, Symbols::New(cls_name));
   const Class& cls = Class::Handle(
@@ -3931,6 +3852,7 @@
 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
   Isolate* isolate = Isolate::Current();
   CHECK_ISOLATE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   {
     const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception);
     if (excp.IsNull()) {
@@ -3942,6 +3864,7 @@
     // throw an exception here.
     return Api::NewError("No Dart frames on stack, cannot throw exception");
   }
+
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
   ApiState* state = isolate->api_state();
@@ -3963,6 +3886,7 @@
                                               Dart_Handle stacktrace) {
   Isolate* isolate = Isolate::Current();
   CHECK_ISOLATE(isolate);
+  CHECK_CALLBACK_STATE(isolate);
   {
     const Instance& excp = Api::UnwrapInstanceHandle(isolate, exception);
     if (excp.IsNull()) {
@@ -3978,6 +3902,7 @@
     // throw an exception here.
     return Api::NewError("No Dart frames on stack, cannot throw exception");
   }
+
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
   ApiState* state = isolate->api_state();
@@ -4094,6 +4019,8 @@
     return Api::NewError("%s: A script has already been loaded from '%s'.",
                          CURRENT_FUNC, library_url.ToCString());
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   library = Library::New(url_str);
   library.set_debuggable(true);
   library.Register();
@@ -4137,6 +4064,7 @@
     return Api::NewError("%s: argument 'col_offset' must be positive number",
                          CURRENT_FUNC);
   }
+  CHECK_CALLBACK_STATE(isolate);
 
   library = Library::New(url_str);
   library.set_debuggable(true);
@@ -4171,6 +4099,8 @@
     return Api::NewError("%s: A script has already been loaded from '%s'.",
                          CURRENT_FUNC, library_url.ToCString());
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   SnapshotReader reader(snapshot->content(),
                         snapshot->length(),
                         snapshot->kind(),
@@ -4215,6 +4145,7 @@
   if (msg != NULL) {
     return Api::NewError("%s", msg);
   }
+  CHECK_CALLBACK_STATE(isolate);
   CompileAll(isolate, &result);
   return result;
 }
@@ -4338,6 +4269,8 @@
   if (source_str.IsNull()) {
     RETURN_TYPE_ERROR(isolate, source, String);
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   Library& library = Library::Handle(isolate, Library::LookupLibrary(url_str));
   if (library.IsNull()) {
     library = Library::New(url_str);
@@ -4390,6 +4323,8 @@
   if (prefix_vm.IsNull()) {
     RETURN_TYPE_ERROR(isolate, prefix, String);
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   const String& prefix_symbol =
       String::Handle(isolate, Symbols::New(prefix_vm));
   const Namespace& import_ns = Namespace::Handle(
@@ -4428,6 +4363,8 @@
   if (source_str.IsNull()) {
     RETURN_TYPE_ERROR(isolate, source, String);
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   const Script& script = Script::Handle(
       isolate, Script::New(url_str, source_str, RawScript::kSourceTag));
   Dart_Handle result;
@@ -4454,6 +4391,8 @@
   if (source_str.IsNull()) {
     RETURN_TYPE_ERROR(isolate, patch_source, String);
   }
+  CHECK_CALLBACK_STATE(isolate);
+
   const Script& script = Script::Handle(
       isolate, Script::New(url_str, source_str, RawScript::kPatchTag));
   Dart_Handle result;
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 674b643c..2b574f6 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -52,11 +52,6 @@
     }                                                                          \
   } while (0)
 
-#define DARTSCOPE_NOCHECKS(isolate)                                            \
-  Isolate* __temp_isolate__ = (isolate);                                       \
-  ASSERT(__temp_isolate__ != NULL);                                            \
-  HANDLESCOPE(__temp_isolate__);
-
 #define DARTSCOPE(isolate)                                                     \
   Isolate* __temp_isolate__ = (isolate);                                       \
   CHECK_ISOLATE_SCOPE(__temp_isolate__);                                       \
@@ -109,6 +104,16 @@
   // Gets the handle used to designate successful return.
   static Dart_Handle Success(Isolate* isolate);
 
+  // Sets up the callback error object after initializing an Isolate. This
+  // object is pre-created because we will not be able to allocate this
+  // object when the error actually occurs. When the error occurs there will
+  // be outstanding acquires to internal data pointers making it unsafe to
+  // allocate objects on the dart heap.
+  static void SetupCallbackError(Isolate* isolate);
+
+  // Gets the handle which holds the pre-created callback error object.
+  static Dart_Handle CallbackError(Isolate* isolate);
+
   // Returns true if the handle holds a Smi.
   static bool IsSmi(Dart_Handle handle) {
     // TODO(turnidge): Assumes RawObject* is at offset zero.  Fix.
@@ -175,6 +180,19 @@
   DISALLOW_COPY_AND_ASSIGN(IsolateSaver);
 };
 
+// Start a scope in which no Dart API call backs are allowed.
+#define START_NO_CALLBACK_SCOPE(isolate)                                       \
+  isolate->IncrementNoCallbackScopeDepth()
+
+// End a no Dart API call backs Scope.
+#define END_NO_CALLBACK_SCOPE(isolate)                                         \
+  isolate->DecrementNoCallbackScopeDepth()
+
+#define CHECK_CALLBACK_STATE(isolate)                                          \
+  if (isolate->no_callback_scope_depth() != 0) {                               \
+    return reinterpret_cast<Dart_Handle>(Api::CallbackError(isolate));         \
+  }                                                                            \
+
 }  // namespace dart.
 
 #endif  // VM_DART_API_IMPL_H_
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 625d603..df08036 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -204,7 +204,7 @@
   // Non-instance objects.
   {
     Isolate* isolate = Isolate::Current();
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     Dart_Handle class1 = Api::NewHandle(isolate, Object::null_class());
     Dart_Handle class2 = Api::NewHandle(isolate, Object::class_class());
 
@@ -695,6 +695,10 @@
       "  a.add(20);"
       "  a.add(30);"
       "  return a;"
+      "}"
+      ""
+      "List immutable() {"
+      "  return const [0, 1, 2];"
       "}";
   Dart_Handle result;
 
@@ -706,71 +710,71 @@
   EXPECT_VALID(result);
 
   // First ensure that the returned object is an array.
-  Dart_Handle ListAccessTestObj = result;
+  Dart_Handle list_access_test_obj = result;
 
-  EXPECT(Dart_IsList(ListAccessTestObj));
+  EXPECT(Dart_IsList(list_access_test_obj));
 
   // Get length of array object.
   intptr_t len = 0;
-  result = Dart_ListLength(ListAccessTestObj, &len);
+  result = Dart_ListLength(list_access_test_obj, &len);
   EXPECT_VALID(result);
   EXPECT_EQ(3, len);
 
   // Access elements in the array.
   int64_t value;
 
-  result = Dart_ListGetAt(ListAccessTestObj, 0);
+  result = Dart_ListGetAt(list_access_test_obj, 0);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(10, value);
 
-  result = Dart_ListGetAt(ListAccessTestObj, 1);
+  result = Dart_ListGetAt(list_access_test_obj, 1);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(20, value);
 
-  result = Dart_ListGetAt(ListAccessTestObj, 2);
+  result = Dart_ListGetAt(list_access_test_obj, 2);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(30, value);
 
   // Set some elements in the array.
-  result = Dart_ListSetAt(ListAccessTestObj, 0, Dart_NewInteger(0));
+  result = Dart_ListSetAt(list_access_test_obj, 0, Dart_NewInteger(0));
   EXPECT_VALID(result);
-  result = Dart_ListSetAt(ListAccessTestObj, 1, Dart_NewInteger(1));
+  result = Dart_ListSetAt(list_access_test_obj, 1, Dart_NewInteger(1));
   EXPECT_VALID(result);
-  result = Dart_ListSetAt(ListAccessTestObj, 2, Dart_NewInteger(2));
+  result = Dart_ListSetAt(list_access_test_obj, 2, Dart_NewInteger(2));
   EXPECT_VALID(result);
 
   // Get length of array object.
-  result = Dart_ListLength(ListAccessTestObj, &len);
+  result = Dart_ListLength(list_access_test_obj, &len);
   EXPECT_VALID(result);
   EXPECT_EQ(3, len);
 
   // Now try and access these elements in the array.
-  result = Dart_ListGetAt(ListAccessTestObj, 0);
+  result = Dart_ListGetAt(list_access_test_obj, 0);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(0, value);
 
-  result = Dart_ListGetAt(ListAccessTestObj, 1);
+  result = Dart_ListGetAt(list_access_test_obj, 1);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(1, value);
 
-  result = Dart_ListGetAt(ListAccessTestObj, 2);
+  result = Dart_ListGetAt(list_access_test_obj, 2);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(2, value);
 
   uint8_t native_array[3];
-  result = Dart_ListGetAsBytes(ListAccessTestObj, 0, native_array, 3);
+  result = Dart_ListGetAsBytes(list_access_test_obj, 0, native_array, 3);
   EXPECT_VALID(result);
   EXPECT_EQ(0, native_array[0]);
   EXPECT_EQ(1, native_array[1]);
@@ -779,22 +783,36 @@
   native_array[0] = 10;
   native_array[1] = 20;
   native_array[2] = 30;
-  result = Dart_ListSetAsBytes(ListAccessTestObj, 0, native_array, 3);
+  result = Dart_ListSetAsBytes(list_access_test_obj, 0, native_array, 3);
   EXPECT_VALID(result);
-  result = Dart_ListGetAsBytes(ListAccessTestObj, 0, native_array, 3);
+  result = Dart_ListGetAsBytes(list_access_test_obj, 0, native_array, 3);
   EXPECT_VALID(result);
   EXPECT_EQ(10, native_array[0]);
   EXPECT_EQ(20, native_array[1]);
   EXPECT_EQ(30, native_array[2]);
-  result = Dart_ListGetAt(ListAccessTestObj, 2);
+  result = Dart_ListGetAt(list_access_test_obj, 2);
   EXPECT_VALID(result);
   result = Dart_IntegerToInt64(result, &value);
   EXPECT_VALID(result);
   EXPECT_EQ(30, value);
 
   // Check if we get an exception when accessing beyond limit.
-  result = Dart_ListGetAt(ListAccessTestObj, 4);
+  result = Dart_ListGetAt(list_access_test_obj, 4);
   EXPECT(Dart_IsError(result));
+
+  // Check that we get an exception (and not a fatal error) when
+  // calling ListSetAt and ListSetAsBytes with an immutable list.
+  list_access_test_obj = Dart_Invoke(lib, NewString("immutable"), 0, NULL);
+  EXPECT_VALID(list_access_test_obj);
+  EXPECT(Dart_IsList(list_access_test_obj));
+
+  result = Dart_ListSetAsBytes(list_access_test_obj, 0, native_array, 3);
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_IsUnhandledExceptionError(result));
+
+  result = Dart_ListSetAt(list_access_test_obj, 0, Dart_NewInteger(42));
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_IsUnhandledExceptionError(result));
 }
 
 
@@ -812,13 +830,9 @@
 
   result = Dart_ListSetAt(byte_array1, -1, Dart_NewInteger(1));
   EXPECT(Dart_IsError(result));
-  result = Dart_ByteArraySetUint8At(byte_array1, -1, 1);
-  EXPECT(Dart_IsError(result));
 
   result = Dart_ListSetAt(byte_array1, 10, Dart_NewInteger(1));
   EXPECT(Dart_IsError(result));
-  result = Dart_ByteArraySetUint8At(byte_array1, 10, 1);
-  EXPECT(Dart_IsError(result));
 
   // Set through the List API.
   for (intptr_t i = 0; i < 10; ++i) {
@@ -831,27 +845,6 @@
     int64_t int64_t_value = -1;
     EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
     EXPECT_EQ(i + 1, int64_t_value);
-    // Get through the ByteArray API.
-    uint8_t uint8_t_value = 0xFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
-    EXPECT_EQ(i + 1, uint8_t_value);
-  }
-
-  // Set through the ByteArray API.
-  for (intptr_t i = 0; i < 10; ++i) {
-    EXPECT_VALID(Dart_ByteArraySetUint8At(byte_array1, i, i + 2));
-  }
-  for (intptr_t i = 0; i < 10; ++i) {
-    // Get through the List API.
-    Dart_Handle integer_obj = Dart_ListGetAt(byte_array1, i);
-    EXPECT_VALID(integer_obj);
-    int64_t int64_t_value = -1;
-    EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
-    EXPECT_EQ(i + 2, int64_t_value);
-    // Get through the ByteArray API.
-    uint8_t uint8_t_value = 0xFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
-    EXPECT_EQ(i + 2, uint8_t_value);
   }
 
   Dart_Handle byte_array2 = Dart_NewByteArray(10);
@@ -861,6 +854,8 @@
 
   // Set through the List API.
   for (intptr_t i = 0; i < 10; ++i) {
+    result = Dart_ListSetAt(byte_array1, i, Dart_NewInteger(i + 2));
+    EXPECT_VALID(result);
     result = Dart_ListSetAt(byte_array2, i, Dart_NewInteger(i + 2));
     EXPECT_VALID(result);
   }
@@ -871,57 +866,9 @@
     is_equal = false;
     Dart_ObjectEquals(e1, e2, &is_equal);
     EXPECT(is_equal);
-    // Get through the ByteArray API.
-    uint8_t v1 = 0xFF;
-    uint8_t v2 = 0XFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &v1));
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array2, i, &v2));
-    EXPECT_NE(v1, 0xFF);
-    EXPECT_NE(v2, 0xFF);
-    EXPECT_EQ(v1, v2);
-  }
-
-  byte_array2 = Dart_NewByteArray(10);
-  is_equal = false;
-  Dart_ObjectEquals(byte_array1, byte_array2, &is_equal);
-  EXPECT(!is_equal);
-
-  // Set through the ByteArray API.
-  for (intptr_t i = 0; i < 10; ++i) {
-    result = Dart_ByteArraySetUint8At(byte_array2, i, i + 2);
-    EXPECT_VALID(result);
-  }
-  for (intptr_t i = 0; i < 10; ++i) {
-    // Get through the List API.
-    Dart_Handle e1 = Dart_ListGetAt(byte_array1, i);
-    Dart_Handle e2 = Dart_ListGetAt(byte_array2, i);
-    is_equal = false;
-    Dart_ObjectEquals(e1, e2, &is_equal);
-    EXPECT(is_equal);
-    // Get through the ByteArray API.
-    uint8_t v1 = 0xFF;
-    uint8_t v2 = 0XFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &v1));
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array2, i, &v2));
-    EXPECT_NE(v1, 0xFF);
-    EXPECT_NE(v2, 0xFF);
-    EXPECT_EQ(v1, v2);
   }
 
   uint8_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-  result = Dart_ListSetAsBytes(byte_array1, 0, data, 10);
-  EXPECT_VALID(result);
-  for (intptr_t i = 0; i < 10; ++i) {
-    Dart_Handle integer_obj = Dart_ListGetAt(byte_array1, i);
-    EXPECT_VALID(integer_obj);
-    int64_t int64_t_value = -1;
-    EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
-    EXPECT_EQ(i, int64_t_value);
-    uint8_t uint8_t_value = 0xFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
-    EXPECT_EQ(i, uint8_t_value);
-  }
-
   for (intptr_t i = 0; i < 10; ++i) {
     EXPECT_VALID(Dart_ListSetAt(byte_array1, i, Dart_NewInteger(10 - i)));
   }
@@ -932,160 +879,40 @@
     int64_t int64_t_value = -1;
     EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
     EXPECT_EQ(10 - i, int64_t_value);
-    uint8_t uint8_t_value = 0xFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
-    EXPECT_EQ(10 - i, uint8_t_value);
-  }
-
-  for (intptr_t i = 0; i < 10; ++i) {
-    EXPECT_VALID(Dart_ByteArraySetUint8At(byte_array1, i, 10 + i));
-  }
-  Dart_ListGetAsBytes(byte_array1, 0, data, 10);
-  for (intptr_t i = 0; i < 10; ++i) {
-    Dart_Handle integer_obj = Dart_ListGetAt(byte_array1, i);
-    EXPECT_VALID(integer_obj);
-    int64_t int64_t_value = -1;
-    EXPECT_VALID(Dart_IntegerToInt64(integer_obj, &int64_t_value));
-    EXPECT_EQ(10 + i, int64_t_value);
-    uint8_t uint8_t_value = 0xFF;
-    EXPECT_VALID(Dart_ByteArrayGetUint8At(byte_array1, i, &uint8_t_value));
-    EXPECT_EQ(10 + i, uint8_t_value);
   }
 }
 
 
-TEST_CASE(ByteArrayAlignedMultiByteAccess) {
-  intptr_t length = 16;
-  Dart_Handle byte_array = Dart_NewByteArray(length);
-  intptr_t api_length = 0;
-  EXPECT_VALID(Dart_ListLength(byte_array, &api_length));
-  EXPECT_EQ(length, api_length);
+TEST_CASE(ScalarListDirectAccess) {
+  Dart_Handle str = Dart_NewStringFromCString("junk");
+  Dart_Handle byte_array = Dart_NewByteArray(10);
+  EXPECT_VALID(byte_array);
+  Dart_Handle result;
+  result = Dart_ScalarListAcquireData(byte_array, NULL, NULL, NULL);
+  EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'type'"
+                       " to be non-null.");
+  Dart_Scalar_Type type;
+  result = Dart_ScalarListAcquireData(byte_array, &type, NULL, NULL);
+  EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'data'"
+                       " to be non-null.");
+  void* data;
+  result = Dart_ScalarListAcquireData(byte_array, &type, &data, NULL);
+  EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'len'"
+                       " to be non-null.");
+  intptr_t len;
+  result = Dart_ScalarListAcquireData(Dart_Null(), &type, &data, &len);
+  EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'array'"
+                       " to be non-null.");
+  result = Dart_ScalarListAcquireData(str, &type, &data, &len);
+  EXPECT_ERROR(result, "Dart_ScalarListAcquireData expects argument 'array'"
+                       " to be of type 'scalar list'.");
 
-  // 4-byte aligned sets.
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 0, FLT_MIN));
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 4, FLT_MAX));
-
-  float float_value = 0.0f;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 0, &float_value));
-  EXPECT_EQ(FLT_MIN, float_value);
-
-  float_value = 0.0f;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 4, &float_value));
-  EXPECT_EQ(FLT_MAX, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 0, 0.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 0, &float_value));
-  EXPECT_EQ(0.0f, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 4, 1.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 4, &float_value));
-  EXPECT_EQ(1.0f, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 0, -1.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 0, &float_value));
-  EXPECT_EQ(-1.0f, float_value);
-
-  // 8-byte aligned sets.
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 0, DBL_MIN));
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 8, DBL_MAX));
-
-  double double_value = 0.0;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 0, &double_value));
-  EXPECT_EQ(DBL_MIN, double_value);
-
-  double_value = 0.0;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 8, &double_value));
-  EXPECT_EQ(DBL_MAX, double_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 0, 0.0));
-  double_value = DBL_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 0, &double_value));
-  EXPECT_EQ(0.0, double_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 8, 1.0));
-  double_value = DBL_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 8, &double_value));
-  EXPECT_EQ(1.0, double_value);
-}
-
-
-TEST_CASE(ByteArrayMisalignedMultiByteAccess) {
-  intptr_t length = 17;
-  Dart_Handle byte_array = Dart_NewByteArray(length);
-  intptr_t api_length = 0;
-  EXPECT_VALID(Dart_ListLength(byte_array, &api_length));
-  EXPECT_EQ(length, api_length);
-
-  // 4-byte misaligned sets.
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 1, FLT_MIN));
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 5, FLT_MAX));
-
-  float float_value = 0.0f;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 1, &float_value));
-  EXPECT_EQ(FLT_MIN, float_value);
-
-  float_value = 0.0f;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 5, &float_value));
-  EXPECT_EQ(FLT_MAX, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 1, 0.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 1, &float_value));
-  EXPECT_EQ(0.0f, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 5, -0.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 5, &float_value));
-  EXPECT_EQ(-0.0f, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 5, 1.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 5, &float_value));
-  EXPECT_EQ(1.0f, float_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat32At(byte_array, 1, -1.0f));
-  float_value = FLT_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat32At(byte_array, 1, &float_value));
-  EXPECT_EQ(-1.0f, float_value);
-
-  // 8-byte misaligned sets.
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 1, DBL_MIN));
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 9, DBL_MAX));
-
-  double double_value = 0.0;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 1, &double_value));
-  EXPECT_EQ(DBL_MIN, double_value);
-
-  double_value = 0.0;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 9, &double_value));
-  EXPECT_EQ(DBL_MAX, double_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 1, 0.0));
-  double_value = DBL_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 1, &double_value));
-  EXPECT_EQ(0.0, double_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 9, -0.0));
-  double_value = DBL_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 9, &double_value));
-  EXPECT_EQ(-0.0, double_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 9, 1.0));
-  double_value = DBL_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 9, &double_value));
-  EXPECT_EQ(1.0, double_value);
-
-  EXPECT_VALID(Dart_ByteArraySetFloat64At(byte_array, 1, -1.0));
-  double_value = DBL_MAX;
-  EXPECT_VALID(Dart_ByteArrayGetFloat64At(byte_array, 1, &double_value));
-  EXPECT_EQ(-1.0, double_value);
+  result = Dart_ScalarListReleaseData(Dart_Null());
+  EXPECT_ERROR(result, "Dart_ScalarListReleaseData expects argument 'array'"
+                       " to be non-null.");
+  result = Dart_ScalarListReleaseData(str);
+  EXPECT_ERROR(result, "Dart_ScalarListReleaseData expects argument 'array'"
+                       " to be of type 'scalar list'.");
 }
 
 
@@ -1199,8 +1026,8 @@
 }
 
 
-
-static void ExternalByteArrayCallbackFinalizer(void* peer) {
+static void ExternalByteArrayCallbackFinalizer(Dart_Handle handle, void* peer) {
+  Dart_DeletePersistentHandle(handle);
   *static_cast<int*>(peer) = 42;
 }
 
@@ -1244,7 +1071,7 @@
   Dart_EnterScope();
   {
     EXPECT(state->top_scope() != NULL);
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     const String& str1 = String::Handle(String::New("Test String"));
     Dart_Handle ref = Api::NewHandle(isolate, str1.raw());
     String& str2 = String::Handle();
@@ -1269,7 +1096,7 @@
   Dart_Handle handles[2000];
   Dart_EnterScope();
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     Dart_Handle ref1 = Api::NewHandle(isolate, String::New(kTestString1));
     for (int i = 0; i < 1000; i++) {
       handles[i] = Dart_NewPersistentHandle(ref1);
@@ -1294,7 +1121,7 @@
   Dart_ExitScope();
   {
     StackZone zone(isolate);
-    DARTSCOPE_NOCHECKS(isolate);
+    HANDLESCOPE(isolate);
     for (int i = 0; i < 500; i++) {
       String& str = String::Handle();
       str ^= Api::UnwrapHandle(handles[i]);
@@ -2245,7 +2072,7 @@
   Dart_Handle handles[300];
   {
     StackZone zone(isolate);
-    DARTSCOPE_NOCHECKS(isolate);
+    HANDLESCOPE(isolate);
     Smi& val = Smi::Handle();
 
     // Start a new scope and allocate some local handles.
@@ -2905,7 +2732,7 @@
   // Invoke a function which returns an object of type NativeFields.
   result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
   EXPECT_VALID(result);
-  DARTSCOPE_NOCHECKS(Isolate::Current());
+  DARTSCOPE(Isolate::Current());
   Instance& obj = Instance::Handle();
   obj ^= Api::UnwrapHandle(result);
   const Class& cls = Class::Handle(obj.clazz());
@@ -2974,7 +2801,7 @@
   // Invoke a function which returns an object of type NativeFields.
   result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
   EXPECT_VALID(result);
-  DARTSCOPE_NOCHECKS(Isolate::Current());
+  DARTSCOPE(Isolate::Current());
   Instance& obj = Instance::Handle();
   obj ^= Api::UnwrapHandle(result);
   const Class& cls = Class::Handle(obj.clazz());
@@ -3229,7 +3056,7 @@
       "  return () {};\n"
       "}\n";
   Dart_Handle result;
-  DARTSCOPE_NOCHECKS(Isolate::Current());
+  DARTSCOPE(Isolate::Current());
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -3305,7 +3132,7 @@
       "  });\n"
       "}\n";
 
-  DARTSCOPE_NOCHECKS(Isolate::Current());
+  DARTSCOPE(Isolate::Current());
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -3888,7 +3715,7 @@
   Dart_Handle result;
   Dart_Handle owner;
   Dart_Handle defining_function;
-  DARTSCOPE_NOCHECKS(Isolate::Current());
+  DARTSCOPE(Isolate::Current());
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -4056,7 +3883,7 @@
       "  return InvokeClosure.method2(10);\n"
       "}\n";
   Dart_Handle result;
-  DARTSCOPE_NOCHECKS(Isolate::Current());
+  DARTSCOPE(Isolate::Current());
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -6919,7 +6746,7 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     Dart_Handle str = NewString("a string");
     EXPECT_VALID(str);
     EXPECT(Dart_IsString(str));
@@ -6992,7 +6819,7 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     Dart_Handle s1 = NewString("s1");
     EXPECT_VALID(s1);
     EXPECT(Dart_IsString(s1));
@@ -7076,7 +6903,7 @@
   isolate->heap()->CollectGarbage(Heap::kNew);
   isolate->heap()->CollectGarbage(Heap::kNew);
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     String& handle = String::Handle();
     handle ^= Api::UnwrapHandle(str);
     EXPECT(handle.IsOld());
@@ -7129,7 +6956,7 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     Dart_Handle str = Api::NewHandle(isolate, String::New("str", Heap::kOld));
     EXPECT_VALID(str);
     EXPECT(Dart_IsString(str));
@@ -7205,7 +7032,7 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     Dart_Handle s1 = Api::NewHandle(isolate, String::New("s1", Heap::kOld));
     EXPECT_VALID(s1);
     EXPECT(Dart_IsString(s1));
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index b306b96..61a9fc6 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -870,7 +870,7 @@
       int length = object->value.as_external_byte_array.length;
       uint8_t* data = object->value.as_external_byte_array.data;
       void* peer = object->value.as_external_byte_array.peer;
-      Dart_PeerFinalizer callback =
+      Dart_WeakPersistentHandleFinalizer callback =
           object->value.as_external_byte_array.callback;
       WriteSmi(length);
       WriteIntptrValue(reinterpret_cast<intptr_t>(data));
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index debb26a..57e62c0 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -526,7 +526,8 @@
 class ApiState {
  public:
   ApiState() : top_scope_(NULL), delayed_weak_reference_sets_(NULL),
-               null_(NULL), true_(NULL), false_(NULL) { }
+               null_(NULL), true_(NULL), false_(NULL),
+               callback_error_(NULL) {}
   ~ApiState() {
     while (top_scope_ != NULL) {
       ApiLocalScope* scope = top_scope_;
@@ -569,7 +570,9 @@
   }
 
   void UnwindScopes(uword sp) {
-    while (top_scope_ != NULL && top_scope_->stack_marker() < sp) {
+    while (top_scope_ != NULL &&
+           top_scope_->stack_marker() != 0 &&
+           top_scope_->stack_marker() <= sp) {
       ApiLocalScope* scope = top_scope_;
       top_scope_ = top_scope_->previous();
       delete scope;
@@ -675,6 +678,19 @@
     return false_;
   }
 
+  void SetupCallbackError() {
+    ASSERT(callback_error_ == NULL);
+    callback_error_ = persistent_handles().AllocateHandle();
+    callback_error_->set_raw(
+        String::New("Internal Dart data pointers have been acquired, "
+                    "please release them using Dart_ByteArrayReleaseData."));
+  }
+
+  PersistentHandle* CallbackError() const {
+    ASSERT(callback_error_ != NULL);
+    return callback_error_;
+  }
+
   void DelayWeakReferenceSet(WeakReferenceSet* reference_set) {
     WeakReferenceSet::Push(reference_set, &delayed_weak_reference_sets_);
   }
@@ -690,6 +706,7 @@
   PersistentHandle* null_;
   PersistentHandle* true_;
   PersistentHandle* false_;
+  PersistentHandle* callback_error_;
 
   DISALLOW_COPY_AND_ASSIGN(ApiState);
 };
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 47cb5b7..e4924c8 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -46,6 +46,7 @@
   ASSERT(context.isolate() == Isolate::Current());
   const Code& code = Code::Handle(function.CurrentCode());
   ASSERT(!code.IsNull());
+  ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
   return entrypoint(code.EntryPoint(),
                     arguments_descriptor,
                     arguments,
@@ -82,6 +83,7 @@
   ASSERT(context.isolate() == Isolate::Current());
   const Code& code = Code::Handle(function.CurrentCode());
   ASSERT(!code.IsNull());
+  ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
   return entrypoint(code.EntryPoint(),
                     arguments_descriptor,
                     arguments,
@@ -127,6 +129,7 @@
       ASSERT(context.isolate() == Isolate::Current());
       const Code& code = Code::Handle(function.CurrentCode());
       ASSERT(!code.IsNull());
+      ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
       return entrypoint(code.EntryPoint(),
                         arguments_descriptor,
                         arguments,
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 37d6e23..035cc65 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -210,12 +210,8 @@
     *to_addr = continue_at_pc;
   }
 
-  static void GetEncodedValues(intptr_t from_index,
-                               intptr_t* object_table_index,
-                               intptr_t* deopt_id) {
-    *object_table_index = ObjectTableIndex::decode(from_index);
-    *deopt_id = DeoptId::decode(from_index);
-  }
+  intptr_t object_table_index() const { return object_table_index_; }
+  intptr_t deopt_id() const { return deopt_id_; }
 
  private:
   static const intptr_t kFieldWidth = kBitsPerWord / 2;
@@ -548,7 +544,7 @@
   }
 
   void Execute(DeoptimizationContext* deopt_context, intptr_t to_index) {
-    // The deoptimization info is uncompresses by translating away suffixes
+    // The deoptimization info is uncompressed by translating away suffixes
     // before executing the instructions.
     UNREACHABLE();
   }
@@ -575,19 +571,17 @@
 }
 
 
-uword DeoptInstr::GetRetAfterAddress(intptr_t from_index,
+uword DeoptInstr::GetRetAfterAddress(DeoptInstr* instr,
                                      const Array& object_table,
                                      Function* func) {
+  ASSERT(instr->kind() == kRetAfterAddress);
+  DeoptRetAfterAddressInstr* ret_after_instr =
+      static_cast<DeoptRetAfterAddressInstr*>(instr);
   ASSERT(!object_table.IsNull());
   ASSERT(func != NULL);
-  intptr_t object_table_index;
-  intptr_t deopt_id;
-  DeoptRetAfterAddressInstr::GetEncodedValues(from_index,
-                                              &object_table_index,
-                                              &deopt_id);
-  *func ^= object_table.At(object_table_index);
+  *func ^= object_table.At(ret_after_instr->object_table_index());
   const Code& code = Code::Handle(func->unoptimized_code());
-  return code.GetDeoptAfterPcAtDeoptId(deopt_id);
+  return code.GetDeoptAfterPcAtDeoptId(ret_after_instr->deopt_id());
 }
 
 
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 74a919a..134d33d 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -115,6 +115,8 @@
   virtual void Execute(DeoptimizationContext* deopt_context,
                        intptr_t to_index) = 0;
 
+  virtual DeoptInstr::Kind kind() const = 0;
+
   bool Equals(const DeoptInstr& other) const {
     return (kind() == other.kind()) && (from_index() == other.from_index());
   }
@@ -125,12 +127,11 @@
 
   // Get the function and return address which is encoded in this
   // kRetAfterAddress deopt instruction.
-  static uword GetRetAfterAddress(intptr_t deopt_from_index,
+  static uword GetRetAfterAddress(DeoptInstr* instr,
                                   const Array& object_table,
                                   Function* func);
 
  protected:
-  virtual DeoptInstr::Kind kind() const = 0;
   virtual intptr_t from_index() const = 0;
 
   friend class DeoptInfoBuilder;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 167b74b..98f2d04 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -55,17 +55,15 @@
       if (code.is_optimized()) {
         // For optimized frames, extract all the inlined functions if any
         // into the stack trace.
-        InlinedFunctionsInDartFrameIterator optimized_frames(frame);
-        while (true) {
-          uword pc = 0;
-          func = optimized_frames.GetNextFunction(&pc);
-          if (func.IsNull()) {
-            break;
-          }
+        for (InlinedFunctionsIterator it(frame); !it.Done(); it.Advance()) {
+          func = it.function();
+          code = it.code();
+          uword pc = it.pc();
           ASSERT(pc != 0);
-          code = func.unoptimized_code();
-          offset = Smi::New(pc - code.EntryPoint());
+          ASSERT(code.EntryPoint() <= pc);
+          ASSERT(pc < (code.EntryPoint() + code.Size()));
           if (ShouldShowFunction(func)) {
+            offset = Smi::New(pc - code.EntryPoint());
             func_list.Add(func);
             code_list.Add(code);
             pc_offset_list.Add(offset);
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index e2e114e..2ea9813 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -107,15 +107,15 @@
     Value* use = instr->InputAt(i);
     use->set_instruction(NULL);
     use->set_use_index(-1);
+    use->set_previous_use(NULL);
     use->set_next_use(NULL);
   }
-  if (instr->env() != NULL) {
-    for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
-      Value* use = it.CurrentValue();
-      use->set_instruction(NULL);
-      use->set_use_index(-1);
-      use->set_next_use(NULL);
-    }
+  for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
+    Value* use = it.CurrentValue();
+    use->set_instruction(NULL);
+    use->set_use_index(-1);
+    use->set_previous_use(NULL);
+    use->set_next_use(NULL);
   }
 }
 
@@ -164,18 +164,25 @@
   }
   Definition* defn = instr->AsDefinition();
   if (defn != NULL) {
-    for (Value* use = defn->input_use_list();
-         use != NULL;
-         use = use->next_use()) {
-      ASSERT(defn == use->definition());
-      ASSERT(use == use->instruction()->InputAt(use->use_index()));
+    Value* prev = NULL;
+    Value* curr = defn->input_use_list();
+    while (curr != NULL) {
+      ASSERT(prev == curr->previous_use());
+      ASSERT(defn == curr->definition());
+      ASSERT(curr == curr->instruction()->InputAt(curr->use_index()));
+      prev = curr;
+      curr = curr->next_use();
     }
-    for (Value* use = defn->env_use_list();
-         use != NULL;
-         use = use->next_use()) {
-      ASSERT(defn == use->definition());
-      ASSERT(use ==
-             use->instruction()->env()->ValueAtUseIndex(use->use_index()));
+
+    prev = NULL;
+    curr = defn->env_use_list();
+    while (curr != NULL) {
+      ASSERT(prev == curr->previous_use());
+      ASSERT(defn == curr->definition());
+      ASSERT(curr ==
+             curr->instruction()->env()->ValueAtUseIndex(curr->use_index()));
+      prev = curr;
+      curr = curr->next_use();
     }
   }
 }
@@ -220,6 +227,7 @@
     Value* use = instr->InputAt(i);
     ASSERT(use->instruction() == NULL);
     ASSERT(use->use_index() == -1);
+    ASSERT(use->previous_use() == NULL);
     ASSERT(use->next_use() == NULL);
     DEBUG_ASSERT(!FLAG_verify_compiler ||
         (0 == MembershipCount(use, use->definition()->input_use_list())));
@@ -238,6 +246,7 @@
     Value* use = it.CurrentValue();
     ASSERT(use->instruction() == NULL);
     ASSERT(use->use_index() == -1);
+    ASSERT(use->previous_use() == NULL);
     ASSERT(use->next_use() == NULL);
     DEBUG_ASSERT(!FLAG_verify_compiler ||
         (0 == MembershipCount(use, use->definition()->env_use_list())));
@@ -282,6 +291,7 @@
         Value* use = phi->InputAt(pred_index);
         ASSERT(use->instruction() == NULL);
         ASSERT(use->use_index() == -1);
+        ASSERT(use->previous_use() == NULL);
         ASSERT(use->next_use() == NULL);
         DEBUG_ASSERT(!FLAG_verify_compiler ||
             (0 == MembershipCount(use, use->definition()->input_use_list())));
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 9d04729..88c7c9e 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1786,6 +1786,34 @@
 }
 
 
+static intptr_t GetResultCidOfNative(const Function& function) {
+  const Class& function_class = Class::Handle(function.Owner());
+  if (function_class.library() == Library::ScalarlistLibrary()) {
+    const String& function_name = String::Handle(function.name());
+    if (!String::EqualsIgnoringPrivateKey(function_name, Symbols::_New())) {
+      return kDynamicCid;
+    }
+    switch (function_class.id()) {
+      case kInt8ArrayCid:
+      case kUint8ArrayCid:
+      case kUint8ClampedArrayCid:
+      case kInt16ArrayCid:
+      case kUint16ArrayCid:
+      case kInt32ArrayCid:
+      case kUint32ArrayCid:
+      case kInt64ArrayCid:
+      case kUint64ArrayCid:
+      case kFloat32ArrayCid:
+      case kFloat64ArrayCid:
+        return function_class.id();
+      default:
+        return kDynamicCid;  // Unknown.
+    }
+  }
+  return kDynamicCid;
+}
+
+
 // <Expression> ::= StaticCall { function: Function
 //                               arguments: <ArgumentList> }
 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
@@ -1821,6 +1849,10 @@
                           node->function(),
                           node->arguments()->names(),
                           arguments);
+  if (node->function().is_native()) {
+    const intptr_t result_cid = GetResultCidOfNative(node->function());
+    call->set_result_cid(result_cid);
+  }
   ReturnDefinition(call);
 }
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index a55ae09..11349ad 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -152,7 +152,8 @@
       may_reoptimize_(false),
       double_class_(Class::ZoneHandle(
           Isolate::Current()->object_store()->double_class())),
-      parallel_move_resolver_(this) {
+      parallel_move_resolver_(this),
+      pending_deoptimization_env_(NULL) {
   ASSERT(assembler != NULL);
 }
 
@@ -224,8 +225,10 @@
       } else {
         ASSERT(instr->locs() != NULL);
         EmitInstructionPrologue(instr);
+        ASSERT(pending_deoptimization_env_ == NULL);
         pending_deoptimization_env_ = instr->env();
         instr->EmitNativeCode(this);
+        pending_deoptimization_env_ = NULL;
         EmitInstructionEpilogue(instr);
       }
     }
@@ -535,7 +538,7 @@
       return;
     }
     // Emit IC call that will count and thus may need reoptimization at
-    // return instruction.
+    // function entry.
     ASSERT(!is_optimizing() || may_reoptimize());
     switch (ic_data.num_args_tested()) {
       case 1:
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 3bed948..eb7181f 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -220,6 +220,7 @@
   bool TryIntrinsify();
 
   void GenerateCallRuntime(intptr_t token_pos,
+                           intptr_t deopt_id,
                            const RuntimeEntry& entry,
                            LocationSummary* locs);
 
@@ -235,11 +236,13 @@
                         LocationSummary* locs);
 
   void GenerateAssertAssignable(intptr_t token_pos,
+                                intptr_t deopt_id,
                                 const AbstractType& dst_type,
                                 const String& dst_name,
                                 LocationSummary* locs);
 
   void GenerateInstanceOf(intptr_t token_pos,
+                          intptr_t deopt_id,
                           const AbstractType& type,
                           bool negate_result,
                           LocationSummary* locs);
@@ -394,6 +397,8 @@
                                                    Register index);
 
  private:
+  friend class CheckStackOverflowSlowPath;  // For pending_deoptimization_env_.
+
   void EmitFrameEntry();
 
   void AddStaticCallTarget(const Function& function);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 3bd8df5..38b9901 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -110,6 +110,7 @@
 
 
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+                                           intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
@@ -118,6 +119,7 @@
 
 
 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+                                                 intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
@@ -178,6 +180,7 @@
 
 
 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+                                            intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             LocationSummary* locs) {
   UNIMPLEMENTED();
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index a8d383d..102f205 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -459,6 +459,7 @@
 // Returns:
 // - true or false in EAX.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+                                           intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
@@ -501,7 +502,7 @@
     __ pushl(EDX);  // Instantiator type arguments.
     __ LoadObject(EAX, test_cache);
     __ pushl(EAX);
-    GenerateCallRuntime(token_pos, kInstanceofRuntimeEntry, locs);
+    GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
     __ Drop(5);
@@ -541,6 +542,7 @@
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+                                                 intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
@@ -569,6 +571,7 @@
     __ PushObject(dst_name);  // Push the name of the destination.
     __ PushObject(error_message);
     GenerateCallRuntime(token_pos,
+                        deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
                         locs);
     // We should never return here.
@@ -596,7 +599,7 @@
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(EAX, test_cache);
   __ pushl(EAX);
-  GenerateCallRuntime(token_pos, kTypeCheckRuntimeEntry, locs);
+  GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
   __ Drop(6);
@@ -1091,11 +1094,25 @@
 
 
 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+                                            intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             LocationSummary* locs) {
   __ CallRuntime(entry);
-  AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
+  AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
   RecordSafepoint(locs);
+  if (deopt_id != Isolate::kNoDeoptId) {
+    // Marks either the continuation point in unoptimized code or the
+    // deoptimization point in optimized code, after call.
+    if (is_optimizing()) {
+      AddDeoptIndexAtCall(deopt_id, token_pos);
+    } else {
+      // Add deoptimization continuation point after the call and before the
+      // arguments are removed.
+      AddCurrentDescriptor(PcDescriptors::kDeoptAfter,
+                           deopt_id,
+                           token_pos);
+    }
+  }
 }
 
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index c6243bc..6ff3a8c 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -110,6 +110,7 @@
 
 
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+                                           intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
@@ -118,6 +119,7 @@
 
 
 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+                                                 intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
@@ -178,6 +180,7 @@
 
 
 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+                                            intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             LocationSummary* locs) {
   UNIMPLEMENTED();
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 1abf729..4e1b9aa 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -459,6 +459,7 @@
 // Returns:
 // - true or false in RAX.
 void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+                                           intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
                                            LocationSummary* locs) {
@@ -501,7 +502,7 @@
     __ pushq(RDX);  // Instantiator type arguments.
     __ LoadObject(RAX, test_cache);
     __ pushq(RAX);
-    GenerateCallRuntime(token_pos, kInstanceofRuntimeEntry, locs);
+    GenerateCallRuntime(token_pos, deopt_id, kInstanceofRuntimeEntry, locs);
     // Pop the parameters supplied to the runtime entry. The result of the
     // instanceof runtime call will be left as the result of the operation.
     __ Drop(5);
@@ -541,6 +542,7 @@
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+                                                 intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
@@ -569,6 +571,7 @@
     __ PushObject(dst_name);  // Push the name of the destination.
     __ PushObject(error_message);
     GenerateCallRuntime(token_pos,
+                        deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
                         locs);
     // We should never return here.
@@ -596,7 +599,7 @@
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(RAX, test_cache);
   __ pushq(RAX);
-  GenerateCallRuntime(token_pos, kTypeCheckRuntimeEntry, locs);
+  GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
   __ Drop(6);
@@ -1095,11 +1098,25 @@
 
 
 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos,
+                                            intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             LocationSummary* locs) {
   __ CallRuntime(entry);
-  AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos);
+  AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
   RecordSafepoint(locs);
+  if (deopt_id != Isolate::kNoDeoptId) {
+    // Marks either the continuation point in unoptimized code or the
+    // deoptimization point in optimized code, after call.
+    if (is_optimizing()) {
+      AddDeoptIndexAtCall(deopt_id, token_pos);
+    } else {
+      // Add deoptimization continuation point after the call and before the
+      // arguments are removed.
+      AddCurrentDescriptor(PcDescriptors::kDeoptAfter,
+                           deopt_id,
+                           token_pos);
+    }
+  }
 }
 
 
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 29ff1e1..3a2d5df 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -551,9 +551,19 @@
     }
   }
   if (!skip_check) {
-    // Insert array bounds check.
+    // Insert array length load and bounds check.
+    const bool is_immutable = (class_id != kGrowableObjectArrayCid);
+    LoadFieldInstr* length = new LoadFieldInstr(
+        (*array)->Copy(),
+        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((*array)->Copy(),
+                 new CheckArrayBoundInstr(new Value(length),
                                           (*index)->Copy(),
                                           class_id,
                                           call),
@@ -690,7 +700,11 @@
                                   type_args,
                                   value_type,
                                   Symbols::Value());
-    InsertBefore(call, assert_value, NULL, Definition::kValue);
+    // Newly inserted instructions that can deoptimize or throw an exception
+    // 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);
   }
 
   Value* array = NULL;
@@ -729,6 +743,8 @@
 
 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
   const intptr_t class_id = ReceiverClassId(call);
+  // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt.
+  intptr_t deopt_id = Isolate::kNoDeoptId;
   switch (class_id) {
     case kArrayCid:
     case kImmutableArrayCid:
@@ -749,6 +765,14 @@
       if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) {
         return false;
       }
+      {
+        // Set deopt_id if we can optimistically assume that the result is Smi.
+        // Assume mixed Mint/Smi if this instruction caused deoptimization once.
+        ASSERT(call->HasICData());
+        const ICData& ic_data = *call->ic_data();
+        deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ?
+            call->deopt_id() : Isolate::kNoDeoptId;
+      }
       break;
     default:
       return false;
@@ -756,7 +780,8 @@
   Value* array = NULL;
   Value* index = NULL;
   intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index);
-  Definition* array_op = new LoadIndexedInstr(array, index, array_cid);
+  Definition* array_op =
+      new LoadIndexedInstr(array, index, array_cid, deopt_id);
   call->ReplaceWith(array_op, current_iterator());
   RemovePushArguments(call);
   return true;
@@ -960,6 +985,13 @@
                  new CheckSmiInstr(right->Copy(), call->deopt_id()),
                  call->env(),
                  Definition::kEffect);
+    if (left->BindsToConstant() &&
+        ((op_kind == Token::kADD) || (op_kind == Token::kMUL))) {
+      // Constant should be on the right side.
+      Value* temp = left;
+      left = right;
+      right = temp;
+    }
     BinarySmiOpInstr* bin_op = new BinarySmiOpInstr(op_kind, call, left, right);
     call->ReplaceWith(bin_op, current_iterator());
     RemovePushArguments(call);
@@ -1277,15 +1309,24 @@
   }
   if (!skip_check) {
     // Insert bounds check.
+    const bool is_immutable = true;
+    LoadFieldInstr* length = new LoadFieldInstr(
+        str->Copy(),
+        CheckArrayBoundInstr::LengthOffsetFor(cid),
+        Type::ZoneHandle(Type::SmiType()),
+        is_immutable);
+    length->set_result_cid(kSmiCid);
+    length->set_recognized_kind(MethodRecognizer::kStringBaseLength);
+    InsertBefore(call, length, NULL, Definition::kValue);
     InsertBefore(call,
-                 new CheckArrayBoundInstr(str->Copy(),
+                 new CheckArrayBoundInstr(new Value(length),
                                           index->Copy(),
                                           cid,
                                           call),
                  call->env(),
                  Definition::kEffect);
   }
-  return new LoadIndexedInstr(str, index, cid);
+  return new LoadIndexedInstr(str, index, cid, Isolate::kNoDeoptId);
 }
 
 
@@ -2023,7 +2064,6 @@
   void ConstrainValueAfterBranch(Definition* defn, Value* use);
   void ConstrainValueAfterCheckArrayBound(Definition* defn,
                                           CheckArrayBoundInstr* check);
-  Definition* LoadArrayLength(CheckArrayBoundInstr* check);
 
   // Replace uses of the definition def that are dominated by instruction dom
   // with uses of other definition.
@@ -2083,53 +2123,6 @@
   GrowableArray<Definition*> worklist_;
   BitVector* marked_defns_;
 
-  class ArrayLengthData : public ValueObject {
-   public:
-    ArrayLengthData(Definition* array, Definition* array_length)
-        : array_(array), array_length_(array_length) { }
-
-    ArrayLengthData(const ArrayLengthData& other)
-        : ValueObject(),
-          array_(other.array_),
-          array_length_(other.array_length_) { }
-
-    ArrayLengthData& operator=(const ArrayLengthData& other) {
-      array_ = other.array_;
-      array_length_ = other.array_length_;
-      return *this;
-    }
-
-    Definition* array() const { return array_; }
-    Definition* array_length() const { return array_length_; }
-
-    typedef Definition* Value;
-    typedef Definition* Key;
-    typedef class ArrayLengthData Pair;
-
-    // KeyValueTrait members.
-    static Key KeyOf(const ArrayLengthData& data) {
-      return data.array();
-    }
-
-    static Value ValueOf(const ArrayLengthData& data) {
-      return data.array_length();
-    }
-
-    static inline intptr_t Hashcode(Key key) {
-      return reinterpret_cast<intptr_t>(key);
-    }
-
-    static inline bool IsKeyEqual(const ArrayLengthData& kv, Key key) {
-      return kv.array() == key;
-    }
-
-   private:
-    Definition* array_;
-    Definition* array_length_;
-  };
-
-  DirectChainedHashMap<ArrayLengthData> array_lengths_;
-
   DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
 };
 
@@ -2207,29 +2200,19 @@
                                         Instruction* dom,
                                         Definition* other) {
   Value* next_use = NULL;
-  Value* prev_use = NULL;
   for (Value* use = def->input_use_list();
        use != NULL;
        use = next_use) {
     next_use = use->next_use();
 
     // Skip dead phis.
-    if (use->instruction()->IsPhi() &&
-        !use->instruction()->AsPhi()->is_alive()) {
-      prev_use = use;
-      continue;
-    }
+    PhiInstr* phi = use->instruction()->AsPhi();
+    if ((phi != NULL) && !phi->is_alive()) continue;
 
     if (IsDominatedUse(dom, use)) {
-      if (prev_use != NULL) {
-        prev_use->set_next_use(next_use);
-      } else {
-        def->set_input_use_list(next_use);
-      }
+      use->RemoveFromInputUseList();
       use->set_definition(other);
       use->AddToInputUseList();
-    } else {
-      prev_use = use;
     }
   }
 }
@@ -2373,47 +2356,13 @@
 }
 
 
-Definition* RangeAnalysis::LoadArrayLength(CheckArrayBoundInstr* check) {
-  Definition* array = check->array()->definition();
-
-  Definition* length = array_lengths_.Lookup(array);
-  if (length != NULL) return length;
-
-  StaticCallInstr* allocation = array->AsStaticCall();
-  if ((allocation != NULL) &&
-      allocation->is_known_constructor() &&
-      (allocation->ResultCid() == kArrayCid)) {
-    // For fixed length arrays check if array is the result of a constructor
-    // call. In this case we can use the length passed to the constructor
-    // instead of loading it from array itself.
-    length = allocation->ArgumentAt(1)->value()->definition();
-  } else {
-    // Load length from the array. Do not insert instruction into the graph.
-    // It will only be used in range boundaries.
-    LoadFieldInstr* length_load = new LoadFieldInstr(
-        check->array()->Copy(),
-        CheckArrayBoundInstr::LengthOffsetFor(check->array_type()),
-        Type::ZoneHandle(Type::SmiType()),
-        true);  // Immutable.
-    length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
-    length_load->set_result_cid(kSmiCid);
-    length_load->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
-    length = length_load;
-  }
-
-  ASSERT(length != NULL);
-  array_lengths_.Insert(ArrayLengthData(array, length));
-  return length;
-}
-
-
 void RangeAnalysis::ConstrainValueAfterCheckArrayBound(
     Definition* defn, CheckArrayBoundInstr* check) {
   if (!CheckArrayBoundInstr::IsFixedLengthArrayType(check->array_type())) {
     return;
   }
 
-  Definition* length = LoadArrayLength(check);
+  Definition* length = check->length()->definition();
 
   Range* constraint_range = new Range(
       RangeBoundary::FromConstant(0),
@@ -2610,7 +2559,7 @@
                current->IsCheckArrayBound()) {
       CheckArrayBoundInstr* check = current->AsCheckArrayBound();
       RangeBoundary array_length =
-          RangeBoundary::FromDefinition(LoadArrayLength(check));
+          RangeBoundary::FromDefinition(check->length()->definition());
       if (check->IsRedundant(array_length)) it.RemoveCurrentFromGraph();
     }
   }
@@ -4200,9 +4149,25 @@
         instr->value()->definition()->AsCreateArray()->ArgumentCount();
     const Object& result = Smi::ZoneHandle(Smi::New(length));
     SetValue(instr, result);
-  } else {
-    SetValue(instr, non_constant_);
+    return;
   }
+
+  if (instr->IsImmutableLengthLoad()) {
+    ConstantInstr* constant = instr->value()->definition()->AsConstant();
+    if (constant != NULL) {
+      if (constant->value().IsString()) {
+        SetValue(instr, Smi::ZoneHandle(
+            Smi::New(String::Cast(constant->value()).Length())));
+        return;
+      }
+      if (constant->value().IsArray()) {
+        SetValue(instr, Smi::ZoneHandle(
+            Smi::New(Array::Cast(constant->value()).Length())));
+        return;
+      }
+    }
+  }
+  SetValue(instr, non_constant_);
 }
 
 
@@ -4523,13 +4488,9 @@
       // Replace constant-valued instructions without observable side
       // effects.  Do this for smis only to avoid having to copy other
       // objects into the heap's old generation.
-      //
-      // TODO(kmillikin): Extend this to handle booleans, other number
-      // types, etc.
       if ((defn != NULL) &&
-          (defn->constant_value().IsSmi() ||
-           defn->constant_value().IsNull() ||
-           defn->constant_value().IsTypeArguments()) &&
+          IsConstant(defn->constant_value()) &&
+          (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) &&
           !defn->IsConstant() &&
           !defn->IsPushArgument() &&
           !defn->IsStoreIndexed() &&
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 41d3091..7cf859f 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -158,7 +158,8 @@
       RecordAfterGC();
       PrintStats();
       if (new_space_->HadPromotionFailure()) {
-        CollectGarbage(kOld, api_callbacks);
+        // Old collections should call the API callbacks.
+        CollectGarbage(kOld, kInvokeApiCallbacks);
       }
       break;
     }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index c7f87b1..d5284b7 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -627,47 +627,57 @@
 
 
 void Value::AddToInputUseList() {
-  set_next_use(definition()->input_use_list());
+  Value* next = definition()->input_use_list();
   definition()->set_input_use_list(this);
+  set_next_use(next);
+  set_previous_use(NULL);
+  if (next != NULL) next->set_previous_use(this);
 }
 
 
 void Value::AddToEnvUseList() {
-  set_next_use(definition()->env_use_list());
+  Value* next = definition()->env_use_list();
   definition()->set_env_use_list(this);
+  set_next_use(next);
+  set_previous_use(NULL);
+  if (next != NULL) next->set_previous_use(this);
 }
 
 
 void Value::RemoveFromInputUseList() {
-  if (definition_->input_use_list() == this) {
-    definition_->set_input_use_list(next_use_);
-    return;
+  Value* previous = previous_use();
+  Value* next = next_use();
+  if (previous == NULL) {
+    definition()->set_input_use_list(next);
+  } else {
+    previous->set_next_use(next);
   }
-
-  Value* prev = definition_->input_use_list();
-  while (prev->next_use_ != this) {
-    prev = prev->next_use_;
-  }
-  prev->next_use_ = next_use_;
-  definition_ = NULL;
+  if (next != NULL) next->set_previous_use(previous);
+  set_definition(NULL);
 }
 
 
 void Definition::ReplaceUsesWith(Definition* other) {
   ASSERT(other != NULL);
   ASSERT(this != other);
-  while (input_use_list_ != NULL) {
-    Value* current = input_use_list_;
-    input_use_list_ = input_use_list_->next_use();
+  Value* next = input_use_list();
+  while (next != NULL) {
+    Value* current = next;
+    next = current->next_use();
     current->set_definition(other);
     current->AddToInputUseList();
   }
-  while (env_use_list_ != NULL) {
-    Value* current = env_use_list_;
-    env_use_list_ = env_use_list_->next_use();
+
+  next = env_use_list();
+  while (next != NULL) {
+    Value* current = next;
+    next = current->next_use();
     current->set_definition(other);
     current->AddToEnvUseList();
   }
+
+  set_input_use_list(NULL);
+  set_env_use_list(NULL);
 }
 
 
@@ -1654,6 +1664,64 @@
 }
 
 
+bool LoadFieldInstr::IsImmutableLengthLoad() const {
+  switch (recognized_kind()) {
+    case MethodRecognizer::kObjectArrayLength:
+    case MethodRecognizer::kImmutableArrayLength:
+    case MethodRecognizer::kByteArrayBaseLength:
+    case MethodRecognizer::kStringBaseLength:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+MethodRecognizer::Kind LoadFieldInstr::RecognizedKindFromArrayCid(
+    intptr_t cid) {
+  switch (cid) {
+    case kArrayCid:
+      return MethodRecognizer::kObjectArrayLength;
+    case kImmutableArrayCid:
+      return MethodRecognizer::kImmutableArrayLength;
+    case kGrowableObjectArrayCid:
+      return MethodRecognizer::kGrowableArrayLength;
+    case kInt8ArrayCid:
+    case kUint8ArrayCid:
+    case kUint8ClampedArrayCid:
+    case kExternalUint8ArrayCid:
+    case kInt16ArrayCid:
+    case kUint16ArrayCid:
+    case kInt32ArrayCid:
+    case kUint32ArrayCid:
+    case kInt64ArrayCid:
+    case kUint64ArrayCid:
+    case kFloat32ArrayCid:
+    case kFloat64ArrayCid:
+      return MethodRecognizer::kByteArrayBaseLength;
+    default:
+      UNREACHABLE();
+      return MethodRecognizer::kUnknown;
+  }
+}
+
+
+Definition* LoadFieldInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
+  if (!IsImmutableLengthLoad()) return this;
+
+  // For fixed length arrays if the array is the result of a known constructor
+  // call we can replace the length load with the length argument passed to
+  // the constructor.
+  StaticCallInstr* call = value()->definition()->AsStaticCall();
+  if (call != NULL &&
+      call->is_known_constructor() &&
+      call->ResultCid() == kArrayCid) {
+    return call->ArgumentAt(1)->value()->definition();
+  }
+  return this;
+}
+
+
 Definition* AssertBooleanInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
   const intptr_t value_cid = value()->ResultCid();
   return (value_cid == kBoolCid) ? value()->definition() : this;
@@ -2010,6 +2078,7 @@
 void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   if (!is_eliminated()) {
     compiler->GenerateAssertAssignable(token_pos(),
+                                       deopt_id(),
                                        dst_type(),
                                        dst_name(),
                                        locs());
@@ -2123,7 +2192,10 @@
 static bool AreEqualDefinitions(Definition* a, Definition* b) {
   a = UnwrapConstraint(a);
   b = UnwrapConstraint(b);
-  return (a == b) || (!a->AffectedBySideEffect() && a->Equals(b));
+  return (a == b) ||
+      (!a->AffectedBySideEffect() &&
+       !b->AffectedBySideEffect() &&
+       a->Equals(b));
 }
 
 
@@ -2497,9 +2569,7 @@
 
 static bool IsArrayLength(Definition* defn) {
   LoadFieldInstr* load = defn->AsLoadField();
-  return (load != NULL) &&
-      ((load->recognized_kind() == MethodRecognizer::kObjectArrayLength) ||
-       (load->recognized_kind() == MethodRecognizer::kImmutableArrayLength));
+  return (load != NULL) && load->IsImmutableLengthLoad();
 }
 
 
@@ -2718,8 +2788,8 @@
         static_cast<BinaryMathCFunction>(&pow)), 0, true);
 
 extern const RuntimeEntry kModRuntimeEntry(
-    "libc_fmod", reinterpret_cast<RuntimeFunction>(
-        static_cast<BinaryMathCFunction>(&fmod)), 0, true);
+    "DartModulo", reinterpret_cast<RuntimeFunction>(
+        static_cast<BinaryMathCFunction>(&DartModulo)), 0, true);
 
 extern const RuntimeEntry kFloorRuntimeEntry(
     "libc_floor", reinterpret_cast<RuntimeFunction>(
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index c00b43c..d2ae0d0 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -73,6 +73,7 @@
  public:
   explicit Value(Definition* definition)
       : definition_(definition),
+        previous_use_(NULL),
         next_use_(NULL),
         instruction_(NULL),
         use_index_(-1),
@@ -81,6 +82,9 @@
   Definition* definition() const { return definition_; }
   void set_definition(Definition* definition) { definition_ = definition; }
 
+  Value* previous_use() const { return previous_use_; }
+  void set_previous_use(Value* previous) { previous_use_ = previous; }
+
   Value* next_use() const { return next_use_; }
   void set_next_use(Value* next) { next_use_ = next; }
 
@@ -133,6 +137,7 @@
 
  private:
   Definition* definition_;
+  Value* previous_use_;
   Value* next_use_;
   Instruction* instruction_;
   intptr_t use_index_;
@@ -519,6 +524,8 @@
   friend class DoubleToSmiInstr;
   friend class DoubleToDoubleInstr;
   friend class InvokeMathCFunctionInstr;
+  friend class FlowGraphOptimizer;
+  friend class LoadIndexedInstr;
 
   intptr_t deopt_id_;
   intptr_t lifetime_position_;  // Position used by register allocator.
@@ -1407,7 +1414,7 @@
 
   intptr_t token_pos() const { return token_pos_; }
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return true; }
 
@@ -1428,7 +1435,7 @@
 
   intptr_t token_pos() const { return token_pos_; }
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return true; }
 
@@ -1905,7 +1912,7 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return false; }
 
@@ -1952,7 +1959,7 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return false; }
 
@@ -1994,7 +2001,7 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return true; }
 
@@ -2224,7 +2231,9 @@
 
 
 inline bool BranchInstr::CanDeoptimize() const {
-  return comparison()->CanDeoptimize();
+  // Branches need a deoptimization info in checked mode if they
+  // can throw a type check error.
+  return comparison()->CanDeoptimize() || is_checked();
 }
 
 
@@ -2692,12 +2701,16 @@
 
 class LoadIndexedInstr : public TemplateDefinition<2> {
  public:
-  LoadIndexedInstr(Value* array, Value* index, intptr_t class_id)
+  LoadIndexedInstr(Value* array,
+                   Value* index,
+                   intptr_t class_id,
+                   intptr_t deopt_id)
       : class_id_(class_id) {
     ASSERT(array != NULL);
     ASSERT(index != NULL);
     inputs_[0] = array;
     inputs_[1] = index;
+    deopt_id_ = deopt_id;
   }
 
   DECLARE_INSTRUCTION(LoadIndexed)
@@ -2707,7 +2720,9 @@
   Value* index() const { return inputs_[1]; }
   intptr_t class_id() const { return class_id_; }
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const {
+    return deopt_id_ != Isolate::kNoDeoptId;
+  }
 
   virtual bool HasSideEffect() const { return false; }
 
@@ -2872,7 +2887,7 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return true; }
 
@@ -2949,7 +2964,7 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return true; }
 
@@ -3093,6 +3108,12 @@
     return recognized_kind_;
   }
 
+  bool IsImmutableLengthLoad() const;
+
+  virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
+
+  static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid);
+
  private:
   const intptr_t offset_in_bytes_;
   const AbstractType& type_;
@@ -3166,7 +3187,7 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return true; }
 
@@ -3315,7 +3336,7 @@
   DECLARE_INSTRUCTION(CloneContext)
   virtual RawAbstractType* CompileType() const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return false; }
 
@@ -3915,7 +3936,7 @@
 
   virtual intptr_t ArgumentCount() const { return 0; }
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const { return true; }
 
   virtual bool HasSideEffect() const { return false; }
 
@@ -4193,14 +4214,14 @@
 
 class CheckArrayBoundInstr : public TemplateInstruction<2> {
  public:
-  CheckArrayBoundInstr(Value* array,
+  CheckArrayBoundInstr(Value* length,
                        Value* index,
                        intptr_t array_type,
                        InstanceCallInstr* instance_call)
       : array_type_(array_type) {
-    ASSERT(array != NULL);
+    ASSERT(length != NULL);
     ASSERT(index != NULL);
-    inputs_[0] = array;
+    inputs_[0] = length;
     inputs_[1] = index;
     deopt_id_ = instance_call->deopt_id();
   }
@@ -4218,7 +4239,7 @@
 
   virtual bool AffectedBySideEffect() const { return false; }
 
-  Value* array() const { return inputs_[0]; }
+  Value* length() const { return inputs_[0]; }
   Value* index() const { return inputs_[1]; }
 
   intptr_t array_type() const { return array_type_; }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index ca21720..62d423d 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -185,6 +185,7 @@
 
 static void EmitAssertBoolean(Register reg,
                               intptr_t token_pos,
+                              intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
   // Check that the type of the value is allowed in conditional context.
@@ -198,6 +199,7 @@
 
   __ pushl(reg);  // Push the source object.
   compiler->GenerateCallRuntime(token_pos,
+                                deopt_id,
                                 kConditionTypeErrorRuntimeEntry,
                                 locs);
   // We should never return here.
@@ -211,7 +213,7 @@
   Register result = locs()->out().reg();
 
   if (!is_eliminated()) {
-    EmitAssertBoolean(obj, token_pos(), locs(), compiler);
+    EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
   }
   ASSERT(obj == result);
 }
@@ -238,6 +240,7 @@
   __ PushObject(formal_parameter_name());
   __ pushl(saved_args_desc);
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kArgumentDefinitionTestRuntimeEntry,
                                 locs());
   __ Drop(3);
@@ -498,7 +501,7 @@
         }
       } else {
         if (branch->is_checked()) {
-          EmitAssertBoolean(EAX, token_pos, locs, compiler);
+          EmitAssertBoolean(EAX, token_pos, deopt_id, locs, compiler);
         }
         __ CompareObject(EAX, Bool::True());
         branch->EmitBranchOnCondition(compiler, cond);
@@ -869,7 +872,7 @@
                              locs(),
                              *ic_data());
   if (branch->is_checked()) {
-    EmitAssertBoolean(EAX, token_pos(), locs(), compiler);
+    EmitAssertBoolean(EAX, token_pos(), deopt_id(), locs(), compiler);
   }
   Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
   __ CompareObject(EAX, Bool::True());
@@ -1110,8 +1113,10 @@
       return kSmiCid;
     case kInt32ArrayCid:
     case kUint32ArrayCid:
-      // Result can be smi or mint when boxed.
-      return kDynamicCid;
+      // Result can be Smi or Mint when boxed.
+      // Instruction can deoptimize if we optimistically assumed that the result
+      // fits into Smi.
+      return CanDeoptimize() ? kSmiCid : kDynamicCid;
     default:
       UNIMPLEMENTED();
       return kDynamicCid;
@@ -1134,7 +1139,9 @@
       return kTagged;
     case kInt32ArrayCid:
     case kUint32ArrayCid:
-      return kUnboxedMint;
+      // Instruction can deoptimize if we optimistically assumed that the result
+      // fits into Smi.
+      return CanDeoptimize() ? kTagged : kUnboxedMint;
     case kFloat32ArrayCid :
     case kFloat64ArrayCid :
       return kUnboxedDouble;
@@ -1181,9 +1188,7 @@
       __ SmiUntag(index.reg());
     }
     __ movl(result,
-            FieldAddress(array, ExternalUint8Array::external_data_offset()));
-    __ movl(result,
-            Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
+            FieldAddress(array, ExternalUint8Array::data_offset()));
     __ movzxb(result, element_address);
     __ SmiTag(result);
     if (index.IsRegister()) {
@@ -1250,6 +1255,24 @@
       __ movzxw(result, element_address);
       __ SmiTag(result);
       break;
+    case kInt32ArrayCid: {
+        Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
+        __ movl(result, element_address);
+        // Verify that the signed value in 'result' can fit inside a Smi.
+        __ cmpl(result, Immediate(0xC0000000));
+        __ j(NEGATIVE, deopt);
+        __ SmiTag(result);
+      }
+      break;
+    case kUint32ArrayCid: {
+        Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
+        __ movl(result, element_address);
+        // Verify that the unsigned value in 'result' can fit inside a Smi.
+        __ testl(result, Immediate(0xC0000000));
+        __ j(NOT_ZERO, deopt);
+        __ SmiTag(result);
+      }
+      break;
     default:
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
       __ movl(result, element_address);
@@ -1523,6 +1546,7 @@
   ASSERT(locs()->in(2).reg() == EDX);  // Instantiator type arguments.
 
   compiler->GenerateInstanceOf(token_pos(),
+                               deopt_id(),
                                type(),
                                negate_result(),
                                locs());
@@ -1585,6 +1609,7 @@
   __ pushl(type_arguments);
   __ pushl(instantiator_type_arguments);
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kAllocateObjectWithBoundsCheckRuntimeEntry,
                                 locs());
   // Pop instantiator type arguments, type arguments, and class.
@@ -1660,6 +1685,7 @@
   __ PushObject(type_arguments());
   __ pushl(instantiator_reg);  // Push instantiator type arguments.
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kInstantiateTypeArgumentsRuntimeEntry,
                                 locs());
   __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
@@ -1838,6 +1864,7 @@
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ pushl(context_value);
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kCloneContextRuntimeEntry,
                                 locs());
   __ popl(result);  // Remove argument.
@@ -1892,9 +1919,15 @@
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
     compiler->SaveLiveRegisters(instruction_->locs());
+    // pending_deoptimization_env_ is needed to generate a runtime call that
+    // may throw an exception.
+    ASSERT(compiler->pending_deoptimization_env_ == NULL);
+    compiler->pending_deoptimization_env_ = instruction_->env();
     compiler->GenerateCallRuntime(instruction_->token_pos(),
+                                  instruction_->deopt_id(),
                                   kStackOverflowRuntimeEntry,
                                   instruction_->locs());
+    compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
     __ jmp(exit_label());
   }
@@ -2679,7 +2712,7 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RegisterOrSmiConstant(array()));
+  locs->set_in(0, Location::RegisterOrSmiConstant(length()));
   locs->set_in(1, Location::RegisterOrSmiConstant(index()));
   return locs;
 }
@@ -2695,29 +2728,24 @@
     return;
   }
 
-  intptr_t length_offset = LengthOffsetFor(array_type());
   if (locs()->in(1).IsConstant()) {
-    Register receiver = locs()->in(0).reg();
+    Register length = locs()->in(0).reg();
     const Object& constant = locs()->in(1).constant();
     ASSERT(constant.IsSmi());
     const int32_t imm =
         reinterpret_cast<int32_t>(constant.raw());
-    __ cmpl(FieldAddress(receiver, length_offset), Immediate(imm));
+    __ cmpl(length, Immediate(imm));
     __ j(BELOW_EQUAL, deopt);
   } else if (locs()->in(0).IsConstant()) {
-    ASSERT(locs()->in(0).constant().IsArray() ||
-           locs()->in(0).constant().IsString());
-    intptr_t length = locs()->in(0).constant().IsArray()
-        ? Array::Cast(locs()->in(0).constant()).Length()
-        : String::Cast(locs()->in(0).constant()).Length();
+    ASSERT(locs()->in(0).constant().IsSmi());
+    const Smi& smi_const = Smi::Cast(locs()->in(0).constant());
     Register index = locs()->in(1).reg();
-    __ cmpl(index,
-        Immediate(reinterpret_cast<int32_t>(Smi::New(length))));
+    __ cmpl(index, Immediate(reinterpret_cast<int32_t>(smi_const.raw())));
     __ j(ABOVE_EQUAL, deopt);
   } else {
-    Register receiver = locs()->in(0).reg();
+    Register length = locs()->in(0).reg();
     Register index = locs()->in(1).reg();
-    __ cmpl(index, FieldAddress(receiver, length_offset));
+    __ cmpl(index, length);
     __ j(ABOVE_EQUAL, deopt);
   }
 }
@@ -3030,6 +3058,7 @@
 
 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kThrowRuntimeEntry,
                                 locs());
   __ int3();
@@ -3043,6 +3072,7 @@
 
 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kReThrowRuntimeEntry,
                                 locs());
   __ int3();
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 14fbd2a..59b9855 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -192,6 +192,7 @@
 
 static void EmitAssertBoolean(Register reg,
                               intptr_t token_pos,
+                              intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
   // Check that the type of the value is allowed in conditional context.
@@ -205,6 +206,7 @@
 
   __ pushq(reg);  // Push the source object.
   compiler->GenerateCallRuntime(token_pos,
+                                deopt_id,
                                 kConditionTypeErrorRuntimeEntry,
                                 locs);
   // We should never return here.
@@ -218,7 +220,7 @@
   Register result = locs()->out().reg();
 
   if (!is_eliminated()) {
-    EmitAssertBoolean(obj, token_pos(), locs(), compiler);
+    EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
   }
   ASSERT(obj == result);
 }
@@ -245,6 +247,7 @@
   __ PushObject(formal_parameter_name());
   __ pushq(saved_args_desc);
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kArgumentDefinitionTestRuntimeEntry,
                                 locs());
   __ Drop(3);
@@ -496,7 +499,7 @@
         }
       } else {
         if (branch->is_checked()) {
-          EmitAssertBoolean(RAX, token_pos, locs, compiler);
+          EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler);
         }
         __ CompareObject(RAX, Bool::True());
         branch->EmitBranchOnCondition(compiler, cond);
@@ -751,7 +754,7 @@
                              locs(),
                              *ic_data());
   if (branch->is_checked()) {
-    EmitAssertBoolean(RAX, token_pos(), locs(), compiler);
+    EmitAssertBoolean(RAX, token_pos(), deopt_id(), locs(), compiler);
   }
   Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
   __ CompareObject(RAX, Bool::True());
@@ -1042,9 +1045,7 @@
       __ SmiUntag(index.reg());
     }
     __ movq(result,
-            FieldAddress(array, ExternalUint8Array::external_data_offset()));
-    __ movq(result,
-            Address(result, ExternalByteArrayData<uint8_t>::data_offset()));
+            FieldAddress(array, ExternalUint8Array::data_offset()));
     __ movzxb(result, element_address);
     __ SmiTag(result);
     if (index.IsRegister()) {
@@ -1382,6 +1383,7 @@
   ASSERT(locs()->in(2).reg() == RDX);  // Instantiator type arguments.
 
   compiler->GenerateInstanceOf(token_pos(),
+                               deopt_id(),
                                type(),
                                negate_result(),
                                locs());
@@ -1444,6 +1446,7 @@
   __ pushq(type_arguments);
   __ pushq(instantiator_type_arguments);
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kAllocateObjectWithBoundsCheckRuntimeEntry,
                                 locs());
   // Pop instantiator type arguments, type arguments, and class.
@@ -1516,6 +1519,7 @@
   __ PushObject(type_arguments());
   __ pushq(instantiator_reg);  // Push instantiator type arguments.
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kInstantiateTypeArgumentsRuntimeEntry,
                                 locs());
   __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
@@ -1690,6 +1694,7 @@
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ pushq(context_value);
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kCloneContextRuntimeEntry,
                                 locs());
   __ popq(result);  // Remove argument.
@@ -1745,9 +1750,15 @@
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
     compiler->SaveLiveRegisters(instruction_->locs());
+    // pending_deoptimization_env_ is needed to generate a runtime call that
+    // may throw an exception.
+    ASSERT(compiler->pending_deoptimization_env_ == NULL);
+    compiler->pending_deoptimization_env_ = instruction_->env();
     compiler->GenerateCallRuntime(instruction_->token_pos(),
+                                  instruction_->deopt_id(),
                                   kStackOverflowRuntimeEntry,
                                   instruction_->locs());
+    compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
     __ jmp(exit_label());
   }
@@ -2571,7 +2582,7 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RegisterOrSmiConstant(array()));
+  locs->set_in(0, Location::RegisterOrSmiConstant(length()));
   locs->set_in(1, Location::RegisterOrSmiConstant(index()));
   return locs;
 }
@@ -2587,30 +2598,24 @@
     return;
   }
 
-
-  intptr_t length_offset = LengthOffsetFor(array_type());
   if (locs()->in(1).IsConstant()) {
-    Register receiver = locs()->in(0).reg();
+    Register length = locs()->in(0).reg();
     const Object& constant = locs()->in(1).constant();
     ASSERT(constant.IsSmi());
     const int64_t imm =
         reinterpret_cast<int64_t>(constant.raw());
-    __ cmpq(FieldAddress(receiver, length_offset), Immediate(imm));
+    __ cmpq(length, Immediate(imm));
     __ j(BELOW_EQUAL, deopt);
   } else if (locs()->in(0).IsConstant()) {
-    ASSERT(locs()->in(0).constant().IsArray() ||
-           locs()->in(0).constant().IsString());
-    intptr_t length = locs()->in(0).constant().IsArray()
-        ? Array::Cast(locs()->in(0).constant()).Length()
-        : String::Cast(locs()->in(0).constant()).Length();
+    ASSERT(locs()->in(0).constant().IsSmi());
+    const Smi& smi_const = Smi::Cast(locs()->in(0).constant());
     Register index = locs()->in(1).reg();
-    __ cmpq(index,
-        Immediate(reinterpret_cast<int64_t>(Smi::New(length))));
+    __ cmpq(index, Immediate(reinterpret_cast<int64_t>(smi_const.raw())));
     __ j(ABOVE_EQUAL, deopt);
   } else {
-    Register receiver = locs()->in(0).reg();
+    Register length = locs()->in(0).reg();
     Register index = locs()->in(1).reg();
-    __ cmpq(index, FieldAddress(receiver, length_offset));
+    __ cmpq(index, length);
     __ j(ABOVE_EQUAL, deopt);
   }
 }
@@ -2678,6 +2683,7 @@
 
 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kThrowRuntimeEntry,
                                 locs());
   __ int3();
@@ -2691,6 +2697,7 @@
 
 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   compiler->GenerateCallRuntime(token_pos(),
+                                deopt_id(),
                                 kReThrowRuntimeEntry,
                                 locs());
   __ int3();
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 9231d26..a82f317 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -95,6 +95,7 @@
   V(_Int16Array, [], Int16Array_getIndexed, 870098766)                         \
   V(_Int16Array, _new, Int16Array_new, 903723993)                              \
   V(_Uint16Array, [], Uint16Array_getIndexed, 1019828411)                      \
+  V(_Uint16Array, []=, Uint16Array_setIndexed, 1457955615)                     \
   V(_Uint16Array, _new, Uint16Array_new, 133542762)                            \
   V(_Int32Array, [], Int32Array_getIndexed, 1999321436)                        \
   V(_Int32Array, _new, Int32Array_new, 8218286)                                \
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index de3defe..5de8051 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -94,6 +94,11 @@
 }
 
 
+bool Intrinsifier::Int8Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -104,6 +109,11 @@
 }
 
 
+bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -114,36 +124,76 @@
 }
 
 
+bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int16Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int32Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int64Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -154,6 +204,11 @@
 }
 
 
+bool Intrinsifier::Float32Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -164,6 +219,11 @@
 }
 
 
+bool Intrinsifier::Float64Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
   return false;
 }
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index fe89c8c..114a1b2 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -468,13 +468,11 @@
 }
 
 
-// Places the address of the ByteArray in EAX.
-// Places the Smi index in EBX.
-// Tests if EBX contains an Smi, jumps to label fall_through if false.
-// Tests if index in EBX is within bounds, jumps to label fall_through if not.
-// Leaves the index as an Smi in EBX.
-// Leaves the ByteArray address in EAX.
-static void TestByteArrayIndex(Assembler* assembler, Label* fall_through) {
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in EBX, array in EAX.
+// This should be used only on getIndexed intrinsics.
+static void TestByteArrayGetIndex(Assembler* assembler, Label* fall_through) {
   __ movl(EAX, Address(ESP, + 2 * kWordSize));  // Array.
   __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
   __ testl(EBX, Immediate(kSmiTagMask));
@@ -486,7 +484,9 @@
 }
 
 
-// Operates in the same manner as TestByteArrayIndex.
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in EBX, array in EAX.
 // This should be used only for setIndexed intrinsics.
 static void TestByteArraySetIndex(Assembler* assembler, Label* fall_through) {
   __ movl(EAX, Address(ESP, + 3 * kWordSize));  // Array.
@@ -502,7 +502,9 @@
 
 bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
   __ movsxb(EAX, FieldAddress(EAX,
                               EBX,
@@ -517,12 +519,9 @@
 
 bool Intrinsifier::Int8Array_setIndexed(Assembler* assembler) {
   Label fall_through;
-  // Verify that the array index is valid.
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted by 1.
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
   // Free EBX for the value since we want a byte register.
   __ movl(EDI, EBX);
@@ -638,7 +637,9 @@
 
 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
   __ movzxb(EAX, FieldAddress(EAX,
                               EBX,
@@ -653,12 +654,9 @@
 
 bool Intrinsifier::Uint8Array_setIndexed(Assembler* assembler) {
   Label fall_through;
-  // Verify that the array index is valid.
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted by 1.
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
   // Free EBX for the value since we want a byte register.
   __ movl(EDI, EBX);
@@ -684,7 +682,9 @@
 
 bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
   __ movzxb(EAX, FieldAddress(EAX,
                               EBX,
@@ -699,12 +699,9 @@
 
 bool Intrinsifier::Uint8ClampedArray_setIndexed(Assembler* assembler) {
   Label fall_through, store_value, load_0xff;
-  // Verify that the array index is valid.
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted by 1.
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
   // Free EBX for the value since we need a byte register.
   __ leal(EAX, FieldAddress(EAX, EBX, TIMES_1,
@@ -739,7 +736,9 @@
 
 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ movsxw(EAX, FieldAddress(EAX,
                               EBX,
                               TIMES_1,
@@ -759,7 +758,9 @@
 
 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ movzxw(EAX, FieldAddress(EAX,
                               EBX,
                               TIMES_1,
@@ -771,6 +772,23 @@
 }
 
 
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+  Label fall_through;
+  TestByteArraySetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
+  __ movl(EDI, Address(ESP, + 1 * kWordSize));
+  __ SmiUntag(EDI);
+  // EDI: undtagged value.
+  __ testl(EDI, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+  __ movw(FieldAddress(EAX, EBX, TIMES_1, Uint16Array::data_offset()), EDI);
+  __ ret();
+  __ Bind(&fall_through);
+  return false;
+}
+
+
 bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
   TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
   return false;
@@ -779,12 +797,9 @@
 
 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
-  // After TestByteArrayIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted left by 1.
-  // This shift means we only multiply the index by 2 not 4 (sizeof Int32).
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ movl(EAX, FieldAddress(EAX,
                             EBX,
                             TIMES_2,
@@ -807,17 +822,14 @@
 
 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
-  // After TestByteArrayIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted left by 1.
-  // This shift means we only multiply the index by 2 not 4 (sizeof Uint32).
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ movl(EAX, FieldAddress(EAX,
                             EBX,
                             TIMES_2,
                             Uint32Array::data_offset()));
-    // Verify that the unsigned value in EAX can be stored in a Smi.
+  // Verify that the unsigned value in EAX can be stored in a Smi.
   __ testl(EAX,  Immediate(0xC0000000));
   __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Won't fit Smi.
   __ SmiTag(EAX);
@@ -857,12 +869,9 @@
 
 bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
-  // After TestByteArrayIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted left by 1.
-  // This shift means we only multiply the index by 2 not 4 (sizeof float).
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   // Load single precision float into XMM7.
   __ movss(XMM7, FieldAddress(EAX, EBX, TIMES_2,
                               Float32Array::data_offset()));
@@ -895,11 +904,8 @@
   // Load double value into XMM7.
   __ movsd(XMM7, FieldAddress(EAX, Double::value_offset()));
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted by 1.
-  // This shift means we only multiply the index by 2 not 4 (sizeof float).
+  // EBX: index as Smi.
+  // EAX: array.
   // Convert from double precision float to single precision float.
   __ cvtsd2ss(XMM7, XMM7);
   // Store into array.
@@ -919,12 +925,9 @@
 
 bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
-  // After TestByteArrayIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted left by 1.
-  // This shift means we only multiply the index by 4 not 8 (sizeof double).
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   // Load double precision float into XMM7.
   __ movsd(XMM7, FieldAddress(EAX, EBX, TIMES_4,
                               Float64Array::data_offset()));
@@ -954,12 +957,8 @@
   // Load double value into XMM7.
   __ movsd(XMM7, FieldAddress(EAX, Double::value_offset()));
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * EAX has the base address of the byte array.
-  // * EBX has the index into the array.
-  // EBX contains the SMI index which is shifted by 1.
-  // This shift means we only multiply the index by 4 not 8 (sizeof float).
-  // Store into array.
+  // EBX: index as Smi.
+  // EAX: array.
   __ movsd(FieldAddress(EAX, EBX, TIMES_4, Float64Array::data_offset()), XMM7);
   __ ret();
   __ Bind(&fall_through);
@@ -975,10 +974,11 @@
 
 bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // EBX: index as Smi.
+  // EAX: array.
   __ SmiUntag(EBX);
-  __ movl(EAX, FieldAddress(EAX, ExternalUint8Array::external_data_offset()));
-  __ movl(EAX, Address(EAX, ExternalByteArrayData<uint8_t>::data_offset()));
+  __ movl(EAX, FieldAddress(EAX, ExternalUint8Array::data_offset()));
   __ movzxb(EAX, Address(EAX, EBX, TIMES_1, 0));
   __ SmiTag(EAX);
   __ ret();
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index bd4d751..e71febb 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -94,6 +94,11 @@
 }
 
 
+bool Intrinsifier::Int8Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -104,6 +109,11 @@
 }
 
 
+bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -114,36 +124,76 @@
 }
 
 
+bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int16Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+  return false;
+}
+
+
+bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int32Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Int64Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   return false;
 }
 
 
+bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -154,6 +204,11 @@
 }
 
 
+bool Intrinsifier::Float32Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
   return false;
 }
@@ -164,6 +219,11 @@
 }
 
 
+bool Intrinsifier::Float64Array_new(Assembler* assembler) {
+  return false;
+}
+
+
 bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
   return false;
 }
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index df97b4e..cd1d7d2 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -423,13 +423,12 @@
 }
 
 
-// Places the address of the ByteArray in RAX.
-// Places the Smi index in R12.
-// Tests if R12 contains an Smi, jumps to label fall_through if false.
-// Tests if index in R12 is within bounds, jumps to label fall_through if not.
-// Leaves the index as an Smi in R12.
-// Leaves the ByteArray address in RAX.
-void TestByteArrayIndex(Assembler* assembler, Label* fall_through) {
+
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in R12, array in RAX.
+// This should be used only on getIndexed intrinsics.
+void TestByteArrayGetIndex(Assembler* assembler, Label* fall_through) {
   __ movq(RAX, Address(RSP, + 2 * kWordSize));  // Array.
   __ movq(R12, Address(RSP, + 1 * kWordSize));  // Index.
   __ testq(R12, Immediate(kSmiTagMask));
@@ -441,7 +440,9 @@
 }
 
 
-// Operates in the same manner as TestByteArrayIndex.
+// Tests if index is a valid length (Smi and within valid index range),
+// jumps to fall_through if it is not.
+// Returns index in R12, array in RAX.
 // This should be used only for setIndexed intrinsics.
 static void TestByteArraySetIndex(Assembler* assembler, Label* fall_through) {
   __ movq(RAX, Address(RSP, + 3 * kWordSize));  // Array.
@@ -457,7 +458,9 @@
 
 bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
   __ movsxb(RAX, FieldAddress(RAX,
                               R12,
@@ -472,12 +475,9 @@
 
 bool Intrinsifier::Int8Array_setIndexed(Assembler* assembler) {
   Label fall_through;
-  // Verify that the array index is valid.
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted by 1.
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
   __ movq(RDI, Address(RSP, + 1 * kWordSize));  // Value.
   __ testq(RDI, Immediate(kSmiTagMask));
@@ -596,7 +596,9 @@
 
 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
   __ movzxb(RAX, FieldAddress(RAX,
                               R12,
@@ -611,12 +613,9 @@
 
 bool Intrinsifier::Uint8Array_setIndexed(Assembler* assembler) {
   Label fall_through;
-  // Verify that the array index is valid.
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted by 1.
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
   __ movq(RDI, Address(RSP, + 1 * kWordSize));  // Value.
   __ testq(RDI, Immediate(kSmiTagMask));
@@ -640,7 +639,9 @@
 
 bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
   __ movzxb(RAX, FieldAddress(RAX,
                               R12,
@@ -655,12 +656,9 @@
 
 bool Intrinsifier::Uint8ClampedArray_setIndexed(Assembler* assembler) {
   Label fall_through, store_value, load_0xff;
-  // Verify that the array index is valid.
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted by 1.
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
   __ movq(RDI, Address(RSP, + 1 * kWordSize));  // Value.
   __ testq(RDI, Immediate(kSmiTagMask));
@@ -692,7 +690,9 @@
 
 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ movsxw(RAX, FieldAddress(RAX,
                               R12,
                               TIMES_1,
@@ -712,7 +712,9 @@
 
 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ movzxw(RAX, FieldAddress(RAX,
                               R12,
                               TIMES_1,
@@ -724,6 +726,23 @@
 }
 
 
+bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
+  Label fall_through;
+  TestByteArraySetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
+  __ movq(RDI, Address(RSP, + 1 * kWordSize));
+  __ SmiUntag(RDI);
+  // RDI: untagged value.
+  __ testl(RDI, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
+  __ movw(FieldAddress(RAX, R12, TIMES_1, Uint16Array::data_offset()), RDI);
+  __ ret();
+  __ Bind(&fall_through);
+  return false;
+}
+
+
 bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
   TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
   return false;
@@ -732,7 +751,9 @@
 
 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ movsxl(RAX, FieldAddress(RAX,
                               R12,
                               TIMES_2,
@@ -752,7 +773,9 @@
 
 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ movl(RAX, FieldAddress(RAX,
                             R12,
                             TIMES_2,
@@ -772,7 +795,9 @@
 
 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ movq(RAX, FieldAddress(RAX,
                             R12,
                             TIMES_4,
@@ -799,7 +824,9 @@
 
 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ movq(RAX, FieldAddress(RAX,
                             R12,
                             TIMES_4,
@@ -825,12 +852,9 @@
 
 bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
-  // After TestByteArrayIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted left by 1.
-  // This shift means we only multiply the index by 2 not 4 (sizeof float).
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   // Load single precision float into XMM7.
   __ movss(XMM7, FieldAddress(RAX, R12, TIMES_2,
                               Float32Array::data_offset()));
@@ -854,11 +878,8 @@
 bool Intrinsifier::Float32Array_setIndexed(Assembler* assembler) {
   Label fall_through;
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted by 1.
-  // This shift means we only multiply the index by 2 not 4 (sizeof float).
+  // R12: index as Smi.
+  // RAX: array.
   __ movq(RDX, Address(RSP, + 1 * kWordSize));  // Value.
   // If RDX is not an instance of double, jump to fall through.
   __ testq(RDX, Immediate(kSmiTagMask));
@@ -886,12 +907,9 @@
 
 bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
-  // After TestByteArrayIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted left by 1.
-  // This shift means we only multiply the index by 4 not 8 (sizeof double).
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   // Load double precision float into XMM7.
   __ movsd(XMM7, FieldAddress(RAX, R12, TIMES_4,
                               Float64Array::data_offset()));
@@ -913,11 +931,8 @@
 bool Intrinsifier::Float64Array_setIndexed(Assembler* assembler) {
   Label fall_through;
   TestByteArraySetIndex(assembler, &fall_through);
-  // After TestByteArraySetIndex:
-  // * RAX has the base address of the byte array.
-  // * R12 has the index into the array.
-  // R12 contains the SMI index which is shifted by 1.
-  // This shift means we only multiply the index by 4 not 8 (sizeof double).
+  // R12: index as Smi.
+  // RAX: array.
   __ movq(RDX, Address(RSP, + 1 * kWordSize));  // Value.
   // If RDX is not an instance of double, jump to fall through.
   __ testq(RDX, Immediate(kSmiTagMask));
@@ -942,10 +957,11 @@
 
 bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
   Label fall_through;
-  TestByteArrayIndex(assembler, &fall_through);
+  TestByteArrayGetIndex(assembler, &fall_through);
+  // R12: index as Smi.
+  // RAX: array.
   __ SmiUntag(R12);
-  __ movq(RAX, FieldAddress(RAX, ExternalUint8Array::external_data_offset()));
-  __ movq(RAX, Address(RAX, ExternalByteArrayData<uint8_t>::data_offset()));
+  __ movq(RAX, FieldAddress(RAX, ExternalUint8Array::data_offset()));
   __ movzxb(RAX, Address(RAX, R12, TIMES_1, 0));
   __ SmiTag(RAX);
   __ ret();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 93d2cfe..ec3cb20 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -273,6 +273,16 @@
 }
 
 
+static void DeleteWeakPersistentHandle(Dart_Handle handle) {
+  ApiState* state = Isolate::Current()->api_state();
+  ASSERT(state != NULL);
+  FinalizablePersistentHandle* weak_ref =
+      reinterpret_cast<FinalizablePersistentHandle*>(handle);
+  ASSERT(state->IsValidWeakPersistentHandle(handle));
+  state->weak_persistent_handles().FreeHandle(weak_ref);
+}
+
+
 void Object::InitOnce() {
   // TODO(iposva): NoGCScope needs to be added here.
   ASSERT(class_class() == null_);
@@ -1281,6 +1291,7 @@
                             Heap::Space space) {
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
   Isolate* isolate = Isolate::Current();
+  ASSERT(isolate->no_callback_scope_depth() == 0);
   Heap* heap = isolate->heap();
 
   uword address = heap->Allocate(size, space);
@@ -1300,14 +1311,15 @@
 }
 
 
-class StoreBufferObjectPointerVisitor : public ObjectPointerVisitor {
+class StoreBufferUpdateVisitor : public ObjectPointerVisitor {
  public:
-  explicit StoreBufferObjectPointerVisitor(Isolate* isolate) :
-      ObjectPointerVisitor(isolate) {
-  }
+  explicit StoreBufferUpdateVisitor(Isolate* isolate) :
+      ObjectPointerVisitor(isolate) { }
+
   void VisitPointers(RawObject** first, RawObject** last) {
     for (RawObject** curr = first; curr <= last; ++curr) {
-      if ((*curr)->IsNewObject()) {
+      RawObject* raw_obj = *curr;
+      if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
         uword ptr = reinterpret_cast<uword>(curr);
         isolate()->store_buffer()->AddPointer(ptr);
       }
@@ -1315,7 +1327,7 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(StoreBufferObjectPointerVisitor);
+  DISALLOW_COPY_AND_ASSIGN(StoreBufferUpdateVisitor);
 };
 
 
@@ -1337,7 +1349,7 @@
   NoGCScope no_gc;
   memmove(raw_obj->ptr(), src.raw()->ptr(), size);
   if (space == Heap::kOld) {
-    StoreBufferObjectPointerVisitor visitor(Isolate::Current());
+    StoreBufferUpdateVisitor visitor(Isolate::Current());
     raw_obj->VisitPointers(&visitor);
   }
   return raw_obj;
@@ -4748,9 +4760,10 @@
 }
 
 
-void TokenStream::DataFinalizer(void *peer) {
+void TokenStream::DataFinalizer(Dart_Handle handle, void *peer) {
   ASSERT(peer != NULL);
   ::free(peer);
+  DeleteWeakPersistentHandle(handle);
 }
 
 
@@ -4966,7 +4979,8 @@
   uint8_t* data = reinterpret_cast<uint8_t*>(::malloc(len));
   ASSERT(data != NULL);
   const ExternalUint8Array& stream = ExternalUint8Array::Handle(
-      ExternalUint8Array::New(data, len, data, DataFinalizer, Heap::kOld));
+      ExternalUint8Array::New(data, len, Heap::kOld));
+  stream.AddFinalizer(data, DataFinalizer);
   const TokenStream& result = TokenStream::Handle(TokenStream::New());
   result.SetStream(stream);
   return result.raw();
@@ -5139,11 +5153,8 @@
 
   // Create and setup the token stream object.
   const ExternalUint8Array& stream = ExternalUint8Array::Handle(
-      ExternalUint8Array::New(data.GetStream(),
-                              data.Length(),
-                              data.GetStream(),
-                              DataFinalizer,
-                              Heap::kOld));
+      ExternalUint8Array::New(data.GetStream(), data.Length(), Heap::kOld));
+  stream.AddFinalizer(data.GetStream(), DataFinalizer);
   const TokenStream& result = TokenStream::Handle(New());
   result.SetPrivateKey(private_key);
   {
@@ -9316,14 +9327,28 @@
 
 RawClass* Type::type_class() const {
   ASSERT(HasResolvedTypeClass());
+#ifdef DEBUG
+  Class& type_class = Class::Handle();
+  type_class ^= raw_ptr()->type_class_;
+  return type_class.raw();
+#else
   return reinterpret_cast<RawClass*>(raw_ptr()->type_class_);
+#endif
 }
 
 
 RawUnresolvedClass* Type::unresolved_class() const {
+  ASSERT(!HasResolvedTypeClass());
+#ifdef DEBUG
+  UnresolvedClass& unresolved_class = UnresolvedClass::Handle();
+  unresolved_class ^= raw_ptr()->type_class_;
+  ASSERT(!unresolved_class.IsNull());
+  return unresolved_class.raw();
+#else
   ASSERT(!Object::Handle(raw_ptr()->type_class_).IsNull());
   ASSERT(Object::Handle(raw_ptr()->type_class_).IsUnresolvedClass());
   return reinterpret_cast<RawUnresolvedClass*>(raw_ptr()->type_class_);
+#endif
 }
 
 
@@ -10987,10 +11012,12 @@
 }
 
 
-static void AddFinalizer(const Object& referent,
-                         void* peer,
-                         Dart_WeakPersistentHandleFinalizer callback) {
-  ASSERT(callback != NULL);
+static FinalizablePersistentHandle* AddFinalizer(
+    const Object& referent,
+    void* peer,
+    Dart_WeakPersistentHandleFinalizer callback) {
+  ASSERT((callback != NULL && peer != NULL) ||
+         (callback == NULL && peer == NULL));
   ApiState* state = Isolate::Current()->api_state();
   ASSERT(state != NULL);
   FinalizablePersistentHandle* weak_ref =
@@ -10998,6 +11025,7 @@
   weak_ref->set_raw(referent);
   weak_ref->set_peer(peer);
   weak_ref->set_callback(callback);
+  return weak_ref;
 }
 
 
@@ -11601,16 +11629,6 @@
 }
 
 
-static void DeleteWeakPersistentHandle(Dart_Handle handle) {
-  ApiState* state = Isolate::Current()->api_state();
-  ASSERT(state != NULL);
-  FinalizablePersistentHandle* weak_ref =
-      reinterpret_cast<FinalizablePersistentHandle*>(handle);
-  ASSERT(state->IsValidWeakPersistentHandle(handle));
-  state->weak_persistent_handles().FreeHandle(weak_ref);
-}
-
-
 void ExternalOneByteString::Finalize(Dart_Handle handle, void* peer) {
   delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer);
   DeleteWeakPersistentHandle(handle);
@@ -11966,19 +11984,10 @@
 }
 
 
-template<typename T>
-static void ExternalByteArrayFinalize(Dart_Handle handle, void* peer) {
-  delete reinterpret_cast<ExternalByteArrayData<T>*>(peer);
-  DeleteWeakPersistentHandle(handle);
-}
-
-
 template<typename HandleT, typename RawT, typename ElementT>
 RawT* ByteArray::NewExternalImpl(intptr_t class_id,
                                  ElementT* data,
                                  intptr_t len,
-                                 void* peer,
-                                 Dart_PeerFinalizer callback,
                                  Heap::Space space) {
   if (len < 0 || len > HandleT::kMaxElements) {
     // This should be caught before we reach here.
@@ -11986,16 +11995,13 @@
            len);
   }
   HandleT& result = HandleT::Handle();
-  ExternalByteArrayData<ElementT>* external_data =
-      new ExternalByteArrayData<ElementT>(data, peer, callback);
   {
     RawObject* raw = Object::Allocate(class_id, HandleT::InstanceSize(), space);
     NoGCScope no_gc;
     result ^= raw;
     result.SetLength(len);
-    result.SetExternalData(external_data);
+    result.SetData(data);
   }
-  AddFinalizer(result, external_data, ExternalByteArrayFinalize<ElementT>);
   return result.raw();
 }
 
@@ -12007,6 +12013,14 @@
 }
 
 
+FinalizablePersistentHandle* ByteArray::AddFinalizer(
+    void* peer,
+    Dart_WeakPersistentHandleFinalizer callback) const {
+  SetPeer(peer);
+  return dart::AddFinalizer(*this, peer, callback);
+}
+
+
 uint8_t* ByteArray::ByteAddr(intptr_t byte_offset) const {
   // ByteArray is an abstract class.
   UNREACHABLE();
@@ -12302,13 +12316,11 @@
 
 RawExternalInt8Array* ExternalInt8Array::New(int8_t* data,
                                              intptr_t len,
-                                             void* peer,
-                                             Dart_PeerFinalizer callback,
                                              Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_int8_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalInt8Array, RawExternalInt8Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalInt8Array,
+                         RawExternalInt8Array>(kClassId, data, len, space);
 }
 
 
@@ -12319,13 +12331,11 @@
 
 RawExternalUint8Array* ExternalUint8Array::New(uint8_t* data,
                                                intptr_t len,
-                                               void* peer,
-                                               Dart_PeerFinalizer callback,
                                                Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_uint8_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalUint8Array, RawExternalUint8Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalUint8Array,
+                         RawExternalUint8Array>(kClassId, data, len, space);
 }
 
 
@@ -12337,14 +12347,13 @@
 RawExternalUint8ClampedArray* ExternalUint8ClampedArray::New(
     uint8_t* data,
     intptr_t len,
-    void* peer,
-    Dart_PeerFinalizer callback,
     Heap::Space space) {
   ASSERT(Isolate::Current()->
-             object_store()->external_uint8_clamped_array_class() !=
+         object_store()->external_uint8_clamped_array_class() !=
          Class::null());
   return NewExternalImpl<ExternalUint8ClampedArray,
-      RawExternalUint8ClampedArray>(kClassId, data, len, peer, callback, space);
+                         RawExternalUint8ClampedArray>(kClassId, data,
+                                                       len, space);
 }
 
 
@@ -12355,13 +12364,11 @@
 
 RawExternalInt16Array* ExternalInt16Array::New(int16_t* data,
                                                intptr_t len,
-                                               void* peer,
-                                               Dart_PeerFinalizer callback,
                                                Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_int16_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalInt16Array, RawExternalInt16Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalInt16Array,
+                         RawExternalInt16Array>(kClassId, data, len, space);
 }
 
 
@@ -12372,13 +12379,11 @@
 
 RawExternalUint16Array* ExternalUint16Array::New(uint16_t* data,
                                                  intptr_t len,
-                                                 void* peer,
-                                                 Dart_PeerFinalizer callback,
                                                  Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_uint16_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalUint16Array, RawExternalUint16Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalUint16Array,
+                         RawExternalUint16Array>(kClassId, data, len, space);
 }
 
 
@@ -12389,13 +12394,11 @@
 
 RawExternalInt32Array* ExternalInt32Array::New(int32_t* data,
                                                intptr_t len,
-                                               void* peer,
-                                               Dart_PeerFinalizer callback,
                                                Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_int32_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalInt32Array, RawExternalInt32Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalInt32Array,
+                         RawExternalInt32Array>(kClassId, data, len, space);
 }
 
 
@@ -12406,13 +12409,11 @@
 
 RawExternalUint32Array* ExternalUint32Array::New(uint32_t* data,
                                                  intptr_t len,
-                                                 void* peer,
-                                                 Dart_PeerFinalizer callback,
                                                  Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_uint32_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalUint32Array, RawExternalUint32Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalUint32Array,
+                         RawExternalUint32Array>(kClassId, data, len, space);
 }
 
 
@@ -12423,13 +12424,11 @@
 
 RawExternalInt64Array* ExternalInt64Array::New(int64_t* data,
                                                intptr_t len,
-                                               void* peer,
-                                               Dart_PeerFinalizer callback,
                                                Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_int64_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalInt64Array, RawExternalInt64Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalInt64Array,
+                         RawExternalInt64Array>(kClassId, data, len, space);
 }
 
 
@@ -12440,13 +12439,11 @@
 
 RawExternalUint64Array* ExternalUint64Array::New(uint64_t* data,
                                                  intptr_t len,
-                                                 void* peer,
-                                                 Dart_PeerFinalizer callback,
                                                  Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_uint64_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalUint64Array, RawExternalUint64Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalUint64Array,
+                         RawExternalUint64Array>(kClassId, data, len, space);
 }
 
 
@@ -12457,13 +12454,11 @@
 
 RawExternalFloat32Array* ExternalFloat32Array::New(float* data,
                                                    intptr_t len,
-                                                   void* peer,
-                                                   Dart_PeerFinalizer callback,
                                                    Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_float32_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalFloat32Array, RawExternalFloat32Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalFloat32Array,
+                         RawExternalFloat32Array>(kClassId, data, len, space);
 }
 
 
@@ -12474,13 +12469,11 @@
 
 RawExternalFloat64Array* ExternalFloat64Array::New(double* data,
                                                    intptr_t len,
-                                                   void* peer,
-                                                   Dart_PeerFinalizer callback,
                                                    Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->external_float64_array_class() !=
          Class::null());
-  return NewExternalImpl<ExternalFloat64Array, RawExternalFloat64Array>(
-      kClassId, data, len, peer, callback, space);
+  return NewExternalImpl<ExternalFloat64Array,
+                         RawExternalFloat64Array>(kClassId, data, len, space);
 }
 
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 548a0c4..81a4f97 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -30,6 +30,7 @@
 class Closure;
 class Code;
 class DeoptInstr;
+class FinalizablePersistentHandle;
 class LocalScope;
 class Symbols;
 
@@ -1076,7 +1077,7 @@
   RawAbstractType** TypeAddr(intptr_t index) const;
   void SetLength(intptr_t value) const;
 
-  HEAP_OBJECT_IMPLEMENTATION(TypeArguments, AbstractTypeArguments);
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, AbstractTypeArguments);
   friend class Class;
 };
 
@@ -1131,7 +1132,8 @@
       const AbstractTypeArguments& value) const;
   static RawInstantiatedTypeArguments* New();
 
-  HEAP_OBJECT_IMPLEMENTATION(InstantiatedTypeArguments, AbstractTypeArguments);
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(InstantiatedTypeArguments,
+                                   AbstractTypeArguments);
   friend class Class;
 };
 
@@ -1894,7 +1896,7 @@
   void SetPrivateKey(const String& value) const;
 
   static RawTokenStream* New();
-  static void DataFinalizer(void *peer);
+  static void DataFinalizer(Dart_Handle handle, void *peer);
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(TokenStream, Object);
   friend class Class;
@@ -3558,7 +3560,7 @@
 
   static RawType* New(Heap::Space space = Heap::kOld);
 
-  HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(Type, AbstractType);
   friend class Class;
 };
 
@@ -3618,7 +3620,7 @@
   void set_type_state(int8_t state) const;
   static RawTypeParameter* New();
 
-  HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeParameter, AbstractType);
   friend class Class;
 };
 
@@ -4749,6 +4751,11 @@
 
   virtual intptr_t ByteLength() const;
 
+  virtual void* GetPeer() const { return NULL; }
+
+  FinalizablePersistentHandle* AddFinalizer(
+      void* peer, Dart_WeakPersistentHandleFinalizer callback) const;
+
   static void Copy(void* dst,
                    const ByteArray& src,
                    intptr_t src_offset,
@@ -4767,6 +4774,7 @@
 
  protected:
   virtual uint8_t* ByteAddr(intptr_t byte_offset) const;
+  virtual void SetPeer(void* peer) const { }
 
   template<typename HandleT, typename RawT>
   static RawT* NewImpl(intptr_t class_id,
@@ -4783,8 +4791,6 @@
   static RawT* NewExternalImpl(intptr_t class_id,
                                ElementT* data,
                                intptr_t len,
-                               void* peer,
-                               Dart_PeerFinalizer callback,
                                Heap::Space space);
 
   template<typename HandleT, typename RawT, typename ElementT>
@@ -5384,20 +5390,20 @@
 
   int8_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int8_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  int8_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 1;
@@ -5410,22 +5416,27 @@
     return RoundedAllocationSize(sizeof(RawExternalInt8Array));
   }
 
+  static intptr_t data_offset() {
+    return OFFSET_OF(RawExternalInt8Array, data_);
+  }
+
   static RawExternalInt8Array* New(int8_t* data,
                                    intptr_t len,
-                                   void* peer,
-                                   Dart_PeerFinalizer callback,
                                    Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<int8_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(int8_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt8Array, ByteArray);
@@ -5442,20 +5453,20 @@
 
   uint8_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, uint8_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  uint8_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 1;
@@ -5468,26 +5479,28 @@
     return RoundedAllocationSize(sizeof(RawExternalUint8Array));
   }
 
-  static intptr_t external_data_offset() {
-    return OFFSET_OF(RawExternalUint8Array, external_data_);
+  static intptr_t data_offset() {
+    return OFFSET_OF(RawExternalUint8Array, data_);
   }
 
   static RawExternalUint8Array* New(uint8_t* data,
                                     intptr_t len,
-                                    void* peer,
-                                    Dart_PeerFinalizer callback,
                                     Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
     uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+        reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<uint8_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(uint8_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   HEAP_OBJECT_IMPLEMENTATION(ExternalUint8Array, ByteArray);
@@ -5501,8 +5514,6 @@
  public:
   static RawExternalUint8ClampedArray* New(uint8_t* data,
                                            intptr_t len,
-                                           void* peer,
-                                           Dart_PeerFinalizer callback,
                                            Heap::Space space = Heap::kNew);
 
  private:
@@ -5520,20 +5531,20 @@
 
   int16_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int16_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  int16_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 2;
@@ -5548,20 +5559,21 @@
 
   static RawExternalInt16Array* New(int16_t* data,
                                     intptr_t len,
-                                    void* peer,
-                                    Dart_PeerFinalizer callback,
                                     Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<int16_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(int16_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt16Array, ByteArray);
@@ -5578,20 +5590,20 @@
 
   int16_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int16_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  uint16_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 2;
@@ -5606,20 +5618,21 @@
 
   static RawExternalUint16Array* New(uint16_t* data,
                                      intptr_t len,
-                                     void* peer,
-                                     Dart_PeerFinalizer callback,
                                      Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<uint16_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(uint16_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalUint16Array, ByteArray);
@@ -5636,20 +5649,20 @@
 
   int32_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int32_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  int32_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 4;
@@ -5664,20 +5677,21 @@
 
   static RawExternalInt32Array* New(int32_t* data,
                                     intptr_t len,
-                                    void* peer,
-                                    Dart_PeerFinalizer callback,
                                     Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<int32_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(int32_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt32Array, ByteArray);
@@ -5694,20 +5708,20 @@
 
   int32_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int32_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  uint32_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 4;
@@ -5722,20 +5736,21 @@
 
   static RawExternalUint32Array* New(uint32_t* data,
                                      intptr_t len,
-                                     void* peer,
-                                     Dart_PeerFinalizer callback,
                                      Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<uint32_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(uint32_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalUint32Array, ByteArray);
@@ -5752,20 +5767,20 @@
 
   int64_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int64_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  int64_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 8;
@@ -5780,20 +5795,21 @@
 
   static RawExternalInt64Array* New(int64_t* data,
                                     intptr_t len,
-                                    void* peer,
-                                    Dart_PeerFinalizer callback,
                                     Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<int64_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(int64_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalInt64Array, ByteArray);
@@ -5810,20 +5826,20 @@
 
   int64_t At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, int64_t value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  uint64_t* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 8;
@@ -5838,20 +5854,21 @@
 
   static RawExternalUint64Array* New(uint64_t* data,
                                      intptr_t len,
-                                     void* peer,
-                                     Dart_PeerFinalizer callback,
                                      Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<uint64_t>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(uint64_t* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalUint64Array, ByteArray);
@@ -5868,20 +5885,20 @@
 
   float At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, float value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  float* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 4;
@@ -5896,20 +5913,21 @@
 
   static RawExternalFloat32Array* New(float* data,
                                       intptr_t len,
-                                      void* peer,
-                                      Dart_PeerFinalizer callback,
                                       Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<float>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(float* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat32Array, ByteArray);
@@ -5926,20 +5944,20 @@
 
   double At(intptr_t index) const {
     ASSERT((index >= 0) && (index < Length()));
-    return raw_ptr()->external_data_->data()[index];
+    return raw_ptr()->data_[index];
   }
 
   void SetAt(intptr_t index, double value) const {
     ASSERT((index >= 0) && (index < Length()));
-    raw_ptr()->external_data_->data()[index] = value;
+    raw_ptr()->data_[index] = value;
   }
 
-  void* GetData() const {
-    return raw_ptr()->external_data_->data();
+  double* GetData() const {
+    return raw_ptr()->data_;
   }
 
   void* GetPeer() const {
-    return raw_ptr()->external_data_->peer();
+    return raw_ptr()->peer_;
   }
 
   static const intptr_t kBytesPerElement = 8;
@@ -5954,20 +5972,21 @@
 
   static RawExternalFloat64Array* New(double* data,
                                       intptr_t len,
-                                      void* peer,
-                                      Dart_PeerFinalizer callback,
                                       Heap::Space space = Heap::kNew);
 
  private:
   uint8_t* ByteAddr(intptr_t byte_offset) const {
     ASSERT((byte_offset >= 0) && (byte_offset < ByteLength()));
-    uint8_t* data =
-        reinterpret_cast<uint8_t*>(raw_ptr()->external_data_->data());
+    uint8_t* data = reinterpret_cast<uint8_t*>(raw_ptr()->data_);
     return data + byte_offset;
   }
 
-  void SetExternalData(ExternalByteArrayData<double>* data) {
-    raw_ptr()->external_data_ = data;
+  void SetData(double* data) const {
+    raw_ptr()->data_ = data;
+  }
+
+  void SetPeer(void* peer) const {
+    raw_ptr()->peer_ = peer;
   }
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat64Array, ByteArray);
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 04b4299..a2d6686 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1905,19 +1905,19 @@
   const ExternalInt8Array& int8_array =
       ExternalInt8Array::Handle(
           ExternalInt8Array::New(reinterpret_cast<int8_t*>(data),
-                                 data_length, NULL, NULL));
+                                 data_length));
   EXPECT(!int8_array.IsNull());
   EXPECT_EQ(data_length, int8_array.Length());
 
   const ExternalUint8Array& uint8_array =
       ExternalUint8Array::Handle(
-          ExternalUint8Array::New(data, data_length, NULL, NULL));
+          ExternalUint8Array::New(data, data_length));
   EXPECT(!uint8_array.IsNull());
   EXPECT_EQ(data_length, uint8_array.Length());
 
   const ExternalUint8ClampedArray& uint8_clamped_array =
       ExternalUint8ClampedArray::Handle(
-          ExternalUint8ClampedArray::New(data, data_length, NULL, NULL));
+          ExternalUint8ClampedArray::New(data, data_length));
   EXPECT(!uint8_clamped_array.IsNull());
   EXPECT_EQ(data_length, uint8_clamped_array.Length());
 
@@ -2090,7 +2090,7 @@
 
   const ExternalUint8Array& external =
       ExternalUint8Array::Handle(
-          ExternalUint8Array::New(data, ARRAY_SIZE(data), NULL, NULL));
+          ExternalUint8Array::New(data, ARRAY_SIZE(data)));
   EXPECT(!external.IsNull());
   EXPECT_EQ(4, external.Length());
   EXPECT_EQ(0, external.At(0));
@@ -2150,7 +2150,7 @@
 
   const ExternalUint8ClampedArray& external =
       ExternalUint8ClampedArray::Handle(
-          ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data), NULL, NULL));
+          ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data)));
   EXPECT(!external.IsNull());
   EXPECT_EQ(4, external.Length());
   EXPECT_EQ(0, external.At(0));
@@ -2217,7 +2217,7 @@
 
   const ExternalUint8Array& external =
       ExternalUint8Array::Handle(
-          ExternalUint8Array::New(data, ARRAY_SIZE(data), NULL, NULL));
+          ExternalUint8Array::New(data, ARRAY_SIZE(data)));
   EXPECT(!external.IsNull());
   EXPECT_EQ(4, external.Length());
   EXPECT_EQ(4, external.At(0));
@@ -2298,7 +2298,7 @@
 
   const ExternalUint8ClampedArray& external =
       ExternalUint8ClampedArray::Handle(
-          ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data), NULL, NULL));
+          ExternalUint8ClampedArray::New(data, ARRAY_SIZE(data)));
   EXPECT(!external.IsNull());
   EXPECT_EQ(4, external.Length());
   EXPECT_EQ(4, external.At(0));
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 078e07e..3478c5a 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -253,10 +253,12 @@
   }
 
   bool IsNewObject() const {
+    ASSERT(IsHeapObject());
     uword addr = reinterpret_cast<uword>(this);
     return (addr & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset;
   }
   bool IsOldObject() const {
+    ASSERT(IsHeapObject());
     uword addr = reinterpret_cast<uword>(this);
     return (addr & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset;
   }
@@ -1401,53 +1403,23 @@
 };
 
 
-template<typename T>
-class ExternalByteArrayData {
- public:
-  static const int kAlignment = 16;
-
-  ExternalByteArrayData(T* data,
-                        void* peer,
-                        Dart_PeerFinalizer callback) :
-      data_(data), peer_(peer), callback_(callback) {
-  }
-  ~ExternalByteArrayData() {
-    if (callback_ != NULL) (*callback_)(peer_);
-  }
-
-  T* data() {
-    return data_;
-  }
-  void* peer() {
-    return peer_;
-  }
-
-  static intptr_t data_offset() {
-    return OFFSET_OF(ExternalByteArrayData<T>, data_);
-  }
-
- private:
-  T* data_;
-  void* peer_;
-  Dart_PeerFinalizer callback_;
-};
-
-
 class RawExternalInt8Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt8Array);
 
-  ExternalByteArrayData<int8_t>* external_data_;
+  int8_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalUint8Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint8Array);
 
- protected:
-  ExternalByteArrayData<uint8_t>* external_data_;
+  uint8_t* data_;
+  void* peer_;
 
   friend class TokenStream;
   friend class RawTokenStream;
+  friend class RawExternalUint8ClampedArray;
 };
 
 
@@ -1459,56 +1431,64 @@
 class RawExternalInt16Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt16Array);
 
-  ExternalByteArrayData<int16_t>* external_data_;
+  int16_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalUint16Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint16Array);
 
-  ExternalByteArrayData<uint16_t>* external_data_;
+  uint16_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalInt32Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt32Array);
 
-  ExternalByteArrayData<int32_t>* external_data_;
+  int32_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalUint32Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint32Array);
 
-  ExternalByteArrayData<uint32_t>* external_data_;
+  uint32_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalInt64Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalInt64Array);
 
-  ExternalByteArrayData<int64_t>* external_data_;
+  int64_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalUint64Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalUint64Array);
 
-  ExternalByteArrayData<uint64_t>* external_data_;
+  uint64_t* data_;
+  void* peer_;
 };
 
 
 class RawExternalFloat32Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat32Array);
 
-  ExternalByteArrayData<float>* external_data_;
+  float* data_;
+  void* peer_;
 };
 
 
 class RawExternalFloat64Array : public RawByteArray {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ExternalFloat64Array);
 
-  ExternalByteArrayData<double>* external_data_;
+  double* data_;
+  void* peer_;
 };
 
 
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 7011f4b..8895007 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -767,7 +767,7 @@
   if (kind == Snapshot::kScript) {
     NoGCScope no_gc;
     RawExternalUint8Array* stream = token_stream.GetStream();
-    reader->ReadBytes(stream->ptr()->external_data_->data(), len);
+    reader->ReadBytes(stream->ptr()->data_, len);
   }
 
   // Read in the literal/identifier token array.
@@ -799,7 +799,7 @@
   RawExternalUint8Array* stream = ptr()->stream_;
   intptr_t len = Smi::Value(stream->ptr()->length_);
   writer->Write<RawObject*>(stream->ptr()->length_);
-  writer->WriteBytes(stream->ptr()->external_data_->data(), len);
+  writer->WriteBytes(stream->ptr()->data_, len);
 
   // Write out the literal/identifier token array.
   writer->WriteObjectImpl(ptr()->token_objects_);
@@ -2035,10 +2035,14 @@
   ASSERT(kind != Snapshot::kFull);                                             \
   intptr_t length = reader->ReadSmiValue();                                    \
   type* data = reinterpret_cast<type*>(reader->ReadIntptrValue());             \
+  const External##name##Array& obj = External##name##Array::Handle(            \
+      External##name##Array::New(data, length));                               \
   void* peer = reinterpret_cast<void*>(reader->ReadIntptrValue());             \
-  Dart_PeerFinalizer callback =                                                \
-      reinterpret_cast<Dart_PeerFinalizer>(reader->ReadIntptrValue());         \
-  return New(data, length, peer, callback, HEAP_SPACE(kind));                  \
+  Dart_WeakPersistentHandleFinalizer callback =                                \
+      reinterpret_cast<Dart_WeakPersistentHandleFinalizer>(                    \
+          reader->ReadIntptrValue());                                          \
+  obj.AddFinalizer(peer, callback);                                            \
+  return obj.raw();                                                            \
 }                                                                              \
 
 
@@ -2109,7 +2113,7 @@
                    k##name##ArrayCid,                                          \
                    writer->GetObjectTags(this),                                \
                    ptr()->length_,                                             \
-                   ptr()->external_data_->data());                             \
+                   ptr()->data_);                                              \
 }                                                                              \
 
 
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index c4dca42..0b4d1bc 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -790,7 +790,7 @@
   // it will be possible to disassemble the code and inspect registers.
   char buffer[128];
   snprintf(buffer, sizeof(buffer),
-           "illegal memory access at 0x%x, pc=0x%x\n",
+           "illegal memory access at 0x%"Px", pc=0x%"Px"\n",
            addr, fault_pc);
   SimulatorDebugger dbg(this);
   dbg.Stop(instr, buffer);
@@ -812,7 +812,7 @@
   // it will be possible to disassemble the code and inspect registers.
   char buffer[64];
   snprintf(buffer, sizeof(buffer),
-           "unaligned %s at 0x%x, pc=%p\n", msg, addr, instr);
+           "unaligned %s at 0x%"Px", pc=%p\n", msg, addr, instr);
   SimulatorDebugger dbg(this);
   dbg.Stop(instr, buffer);
   // The debugger will return control in non-interactive mode.
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 6538b90..1069755 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -422,12 +422,9 @@
   uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress());
   ASSERT(array != NULL);
   Advance(len);
-  ExternalByteArrayData<uint8_t>* external_data =
-      new ExternalByteArrayData<uint8_t>(array, NULL, NULL);
-  ASSERT(external_data != NULL);
   data_ = reinterpret_cast<RawExternalUint8Array*>(
       AllocateUninitialized(cls_, ExternalUint8Array::InstanceSize()));
-  data_.SetExternalData(external_data);
+  data_.SetData(array);
   data_.SetLength(len);
   stream_.SetStream(data_);
   return stream_.raw();
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 594ab31..3628e9b 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -669,7 +669,7 @@
     ctype data[] = { 0, 11, 22, 33, 44, 55, 66, 77 };                         \
     intptr_t length = ARRAY_SIZE(data);                                       \
     External##darttype& array = External##darttype::Handle(                   \
-        External##darttype::New(data, length, NULL, NULL));                   \
+        External##darttype::New(data, length));                               \
     uint8_t* buffer;                                                          \
     MessageWriter writer(&buffer, &zone_allocator);                           \
     writer.WriteMessage(array);                                               \
@@ -1384,7 +1384,7 @@
   EXPECT(Dart_IsString(crappy_string_result));
 
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
 
     {
       StackZone zone(Isolate::Current());
@@ -1475,7 +1475,7 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     {
       // Generate a list of nulls from Dart code.
       ApiNativeScope scope;
@@ -1593,7 +1593,7 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
     {
       // Generate a list of nulls from Dart code.
       ApiNativeScope scope;
@@ -1816,7 +1816,7 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
 
     {
       // Generate a list of strings from Dart code.
@@ -1991,7 +1991,7 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE_NOCHECKS(isolate);
+    DARTSCOPE(isolate);
 
     {
       // Generate a list of strings from Dart code.
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 8fb425a..d4306f5 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -280,51 +280,62 @@
 }
 
 
-InlinedFunctionsInDartFrameIterator::InlinedFunctionsInDartFrameIterator(
-    StackFrame* frame) : index_(0),
-                         frame_(frame),
-                         func_(Function::Handle()),
-                         deopt_info_(DeoptInfo::Handle()),
-                         object_table_(Array::Handle()) {
-  ASSERT(frame_ != NULL);
-  const Code& code = Code::Handle(frame_->LookupDartCode());
-  ASSERT(code.is_optimized());
-  func_ = code.function();
+InlinedFunctionsIterator::InlinedFunctionsIterator(StackFrame* frame)
+  : index_(0),
+    code_(Code::Handle()),
+    deopt_info_(DeoptInfo::Handle()),
+    function_(Function::Handle()),
+    pc_(0),
+    deopt_instructions_(),
+    object_table_(Array::Handle()) {
+  ASSERT(frame != NULL);
+  code_ = frame->LookupDartCode();
+  ASSERT(code_.is_optimized());
   intptr_t deopt_reason = kDeoptUnknown;
-  deopt_info_ = code.GetDeoptInfoAtPc(frame_->pc(), &deopt_reason);
-  object_table_ = code.object_table();
+  deopt_info_ = code_.GetDeoptInfoAtPc(frame->pc(), &deopt_reason);
+  if (deopt_info_.IsNull()) {
+    // This is the case when a call without deopt info in optimzed code
+    // throws an exception. (e.g. in the parameter copying prologue).
+    // In that case there won't be any inlined frames.
+    function_ = code_.function();
+    pc_ = frame->pc();
+    ASSERT(pc_ != 0);
+  } else {
+    // Unpack deopt info into instructions (translate away suffixes).
+    const Array& deopt_table = Array::Handle(code_.deopt_info_array());
+    ASSERT(!deopt_table.IsNull());
+    deopt_info_.ToInstructions(deopt_table, &deopt_instructions_);
+    object_table_ = code_.object_table();
+    Advance();
+  }
 }
 
 
-RawFunction* InlinedFunctionsInDartFrameIterator::GetNextFunction(uword* pc) {
-  if (index_ == -1) {
-    return Function::null();
-  }
-  if (deopt_info_.IsNull()) {
-    // We are at a PC that has no deoptimization info so there are no
-    // inlined functions to iterate over, we return the function.
-    index_ = -1;  // No more functions.
-    *pc = frame_->pc();
-    return func_.raw();
-  }
+void InlinedFunctionsIterator::Advance() {
   // Iterate over the deopt instructions and determine the inlined
   // functions if any and iterate over them.
-  ASSERT(deopt_info_.Length() != 0);
-  while (index_ < deopt_info_.Length()) {
-    intptr_t cur_index = index_;
-    index_ += 1;
-    intptr_t deopt_instr = deopt_info_.Instruction(cur_index);
-    ASSERT(deopt_instr != DeoptInstr::kRetBeforeAddress);
-    if (deopt_instr == DeoptInstr::kRetAfterAddress) {
-      intptr_t deopt_from_index = deopt_info_.FromIndex(cur_index);
-      *pc = DeoptInstr::GetRetAfterAddress(deopt_from_index,
+  ASSERT(!Done());
+
+  if (deopt_info_.IsNull()) {
+    SetDone();
+    return;
+  }
+
+  Function& func = Function::Handle();
+  ASSERT(deopt_instructions_.length() != 0);
+  while (index_ < deopt_instructions_.length()) {
+    DeoptInstr* deopt_instr = deopt_instructions_[index_++];
+    ASSERT(deopt_instr->kind() != DeoptInstr::kRetBeforeAddress);
+    if (deopt_instr->kind() == DeoptInstr::kRetAfterAddress) {
+      pc_ = DeoptInstr::GetRetAfterAddress(deopt_instr,
                                            object_table_,
-                                           &func_);
-      return func_.raw();
+                                           &func);
+      code_ = func.unoptimized_code();
+      function_ = func.raw();
+      return;
     }
   }
-  index_ = -1;
-  return Function::null();
+  SetDone();
 }
 
 }  // namespace dart
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 04a55dd..c4dd50dd 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -229,19 +229,39 @@
 // Iterator for iterating over all inlined dart functions in an optimized
 // dart frame (the iteration includes the function that is inlining the
 // other functions).
-class InlinedFunctionsInDartFrameIterator : public ValueObject {
+class InlinedFunctionsIterator : public ValueObject {
  public:
-  explicit InlinedFunctionsInDartFrameIterator(StackFrame* frame);
-  RawFunction* GetNextFunction(uword* pc);
+  explicit InlinedFunctionsIterator(StackFrame* frame);
+  bool Done() const { return index_ == -1; }
+  void Advance();
+
+  RawFunction* function() const {
+    ASSERT(!Done());
+    return function_.raw();
+  }
+
+  uword pc() const {
+    ASSERT(!Done());
+    return pc_;
+  }
+
+  RawCode* code() const {
+    ASSERT(!Done());
+    return code_.raw();
+  }
 
  private:
+  void SetDone() { index_ = -1; }
+
   intptr_t index_;
-  StackFrame* frame_;
-  Function& func_;
+  Code& code_;
   DeoptInfo& deopt_info_;
+  Function& function_;
+  uword pc_;
+  GrowableArray<DeoptInstr*> deopt_instructions_;
   Array& object_table_;
 
-  DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsInDartFrameIterator);
+  DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 3fdc4b0..660f46f 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -191,6 +191,7 @@
   V(_instanceOf, "_instanceOf")                                                \
   V(PrivateGetterPrefix, "get:_")                                              \
   V(PrivateSetterPrefix, "set:_")                                              \
+  V(_New, "_new")                                                              \
 
 
 // Contains a list of frequently used strings in a canonicalized form. This
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index 3f74135..80dabd6 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -42,7 +42,7 @@
 if test -f "$SNAPSHOT"; then
   # TODO(ahe): Remove the following line when we are relatively sure it works.
   echo Using snapshot "$SNAPSHOT" 1>&2
-  EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]="--use_script_snapshot=$SNAPSHOT"
+  EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]="--use-script-snapshot=$SNAPSHOT"
 fi
 
 # Tell the VM to grow the heap more aggressively. This should only
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 3992aa0..87584ff 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -10,6 +10,6 @@
 
 set arguments=%*
 set SNAPSHOTNAME="%SCRIPTPATH%dart2js.snapshot"
-if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+if exist %SNAPSHOTNAME% set SNAPSHOT=--use-script-snapshot=%SNAPSHOTNAME%
 
 "%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=512 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\compiler\implementation\dart2js.dart" %arguments%
diff --git a/sdk/bin/dartdoc b/sdk/bin/dartdoc
index f694a9e..74b7a8a 100755
--- a/sdk/bin/dartdoc
+++ b/sdk/bin/dartdoc
@@ -21,6 +21,6 @@
 if test -f "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"; then
   # TODO(ahe): Remove the following line when we are relatively sure it works.
   echo Using snapshot "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot" 1>&2
-  SNAPSHOT="--use_script_snapshot=$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"
+  SNAPSHOT="--use-script-snapshot=$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart.snapshot"
 fi
 exec "$BIN_DIR"/dart --no_use_inlining --heap_growth_rate=32 $SNAPSHOT "$BIN_DIR/../lib/_internal/dartdoc/bin/dartdoc.dart" $COLORS "$@"
diff --git a/sdk/bin/dartdoc.bat b/sdk/bin/dartdoc.bat
index 8fe00ea..5923d19 100644
--- a/sdk/bin/dartdoc.bat
+++ b/sdk/bin/dartdoc.bat
@@ -10,6 +10,6 @@
 
 set arguments=%*
 rem set SNAPSHOTNAME="%SCRIPTPATH%dartdoc.snapshot"
-rem if exist %SNAPSHOTNAME% set SNAPSHOT=--use_script_snapshot=%SNAPSHOTNAME%
+rem if exist %SNAPSHOTNAME% set SNAPSHOT=--use-script-snapshot=%SNAPSHOTNAME%
 
 "%SCRIPTPATH%dart" --no_use_inlining --heap_growth_rate=32 %SNAPSHOT% "%SCRIPTPATH%..\lib\_internal\dartdoc\bin\dartdoc.dart" %arguments%
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index b5dd3dd..cf7eb2a 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -16,9 +16,34 @@
  * [uri]. If an exception occurs, the future completes with this
  * exception.
  */
+typedef Future<String> CompilerInputProvider(Uri uri);
+
+/// Deprecated, please use [CompilerInputProvider] instead.
 typedef Future<String> ReadStringFromUri(Uri uri);
 
 /**
+ * Returns a [Sink] that will serve as compiler output for the given
+ * component.
+ *
+ * Components are identified by [name] and [extension]. By convention,
+ * the empty string [:"":] will represent the main script
+ * (corresponding to the script parameter of [compile]) even if the
+ * main script is a library. For libraries that are compiled
+ * separately, the library name is used.
+ *
+ * At least the following extensions can be expected:
+ *
+ * * "js" for JavaScript output.
+ * * "js.map" for source maps.
+ * * "dart" for Dart output.
+ * * "dart.map" for source maps.
+ *
+ * As more features are added to the compiler, new names and
+ * extensions may be introduced.
+ */
+typedef Sink<String> CompilerOutputProvider(String name, String extension);
+
+/**
  * Invoked by the compiler to report diagnostics. If [uri] is
  * [:null:], so are [begin] and [end]. No other arguments may be
  * [:null:]. If [uri] is not [:null:], neither are [begin] and
@@ -32,17 +57,27 @@
                                String message, Diagnostic kind);
 
 /**
- * Returns a future that completes to [script] compiled to JavaScript. If
- * the compilation fails, the future's value will be [:null:] and
+ * Returns a future that completes to a non-null String when [script]
+ * has been successfully compiled.
+ *
+ * The compiler output is obtained by providing an [outputProvider].
+ *
+ * If the compilation fails, the future's value will be [:null:] and
  * [handler] will have been invoked at least once with [:kind ==
  * Diagnostic.ERROR:] or [:kind == Diagnostic.CRASH:].
+ *
+ * Deprecated: if no [outputProvider] is given, the future completes
+ * to the compiled script. This behavior will be removed in the future
+ * as the compiler may create multiple files to support lazy loading
+ * of libraries.
  */
 Future<String> compile(Uri script,
                        Uri libraryRoot,
                        Uri packageRoot,
-                       ReadStringFromUri provider,
+                       CompilerInputProvider inputProvider,
                        DiagnosticHandler handler,
-                       [List<String> options = const []]) {
+                       [List<String> options = const [],
+                        CompilerOutputProvider outputProvider]) {
   if (!libraryRoot.path.endsWith("/")) {
     throw new ArgumentError("libraryRoot must end with a /");
   }
@@ -51,10 +86,24 @@
   }
   // TODO(ahe): Consider completing the future with an exception if
   // code is null.
-  Compiler compiler = new Compiler(provider, handler, libraryRoot, packageRoot,
+  Compiler compiler = new Compiler(inputProvider,
+                                   outputProvider,
+                                   handler,
+                                   libraryRoot,
+                                   packageRoot,
                                    options);
   compiler.run(script);
   String code = compiler.assembledCode;
+  if (code != null && outputProvider != null) {
+    String outputType = 'js';
+    if (options.contains('--output-type=dart')) {
+      outputType = 'dart';
+    }
+    outputProvider('', outputType)
+        ..add(code)
+        ..close();
+    code = ''; // Non-null signals success.
+  }
   return new Future.immediate(code);
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index fd9ccd9..663e003 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -24,12 +24,17 @@
   bool mockableLibraryUsed = false;
   final Set<String> allowedLibraryCategories;
 
-  Compiler(this.provider, this.handler, this.libraryRoot, this.packageRoot,
+  Compiler(this.provider,
+           api.CompilerOutputProvider outputProvider,
+           this.handler,
+           this.libraryRoot,
+           this.packageRoot,
            List<String> options)
       : this.options = options,
         this.allowedLibraryCategories = getAllowedLibraryCategories(options),
         super(
             tracer: new ssa.HTracer(),
+            outputProvider: outputProvider,
             enableTypeAssertions: hasOption(options, '--enable-checked-mode'),
             enableUserAssertions: hasOption(options, '--enable-checked-mode'),
             enableMinification: hasOption(options, '--minify'),
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index e400f5c..4ed1564 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -6,6 +6,7 @@
 
 import "elements/elements.dart";
 import "dart2jslib.dart";
+import "dart_types.dart";
 import "scanner/scannerlib.dart" show Token;
 import "tree/tree.dart";
 import "util/util.dart";
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index c805e1e..691cbac 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -148,7 +148,7 @@
         if (isConst) {
           MessageKind kind = MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS;
           compiler.reportError(node,
-                               new CompileTimeConstantError(kind, const []));
+                               new CompileTimeConstantError(kind));
         } else {
           lazyStatics.add(element);
           return null;
@@ -173,9 +173,9 @@
           if (elementType.isMalformed || constantType.isMalformed ||
               !constantSystem.isSubtype(compiler, constantType, elementType)) {
             if (isConst) {
-              MessageKind kind = MessageKind.NOT_ASSIGNABLE;
               compiler.reportError(node, new CompileTimeConstantError(
-                  kind, [elementType, constantType]));
+                  MessageKind.NOT_ASSIGNABLE,
+                  {'fromType': elementType, 'toType': constantType}));
             } else {
               // If the field can be lazily initialized, we will throw
               // the exception at runtime.
@@ -229,7 +229,9 @@
     return initialVariableValues.keys.where((element) {
       return element.kind == ElementKind.FIELD
           && !element.isInstanceMember()
-          && !element.modifiers.isFinal();
+          && !element.modifiers.isFinal()
+          // The const fields are all either emitted elsewhere or inlined.
+          && !element.modifiers.isConst();
     });
   }
 
@@ -354,7 +356,7 @@
       Constant key = evaluateConstant(entry.key);
       if (!key.isString() || entry.key.asStringNode() == null) {
         MessageKind kind = MessageKind.KEY_NOT_A_STRING_LITERAL;
-        compiler.reportError(entry.key, new ResolutionError(kind, const []));
+        compiler.reportError(entry.key, new ResolutionError(kind));
       }
       StringConstant keyConstant = key;
       if (!map.containsKey(key)) keys.add(key);
@@ -468,7 +470,7 @@
                  && element.isVariable()
                  && element.modifiers.isConst()) {
         Constant result = handler.compileConstant(element);
-        if (result != null) return result; 
+        if (result != null) return result;
       }
       return signalNotCompileTimeConstant(send);
     } else if (send.isCall) {
@@ -624,7 +626,7 @@
     if (!succeeded) {
       MessageKind kind = MessageKind.INVALID_ARGUMENTS;
       compiler.reportError(node,
-          new CompileTimeConstantError(kind, [target.name.slowToString()]));
+          new CompileTimeConstantError(kind, {'methodName': target.name}));
     }
     return compiledArguments;
   }
@@ -672,7 +674,7 @@
     // TODO(floitsch): get the list of constants that are currently compiled
     // and present some kind of stack-trace.
     MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
-    compiler.reportError(node, new CompileTimeConstantError(kind, const []));
+    compiler.reportError(node, new CompileTimeConstantError(kind));
   }
 
   Constant signalNotCompileTimeConstant(Node node) {
@@ -697,7 +699,7 @@
   error(Node node) {
     // Just fail without reporting it anywhere.
     throw new CompileTimeConstantError(
-        MessageKind.NOT_A_COMPILE_TIME_CONSTANT, const []);
+        MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
   }
 }
 
@@ -745,9 +747,9 @@
       if (elementType.element.isTypeVariable()) return;
       if (elementType.isMalformed || constantType.isMalformed ||
           !constantSystem.isSubtype(compiler, constantType, elementType)) {
-        MessageKind kind = MessageKind.NOT_ASSIGNABLE;
         compiler.reportError(node, new CompileTimeConstantError(
-            kind, [elementType, constantType]));
+            MessageKind.NOT_ASSIGNABLE,
+            {'fromType': elementType, 'toType': constantType}));
       }
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 0137e2f..01e5cc2 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -203,6 +203,8 @@
    */
   final bool preserveComments;
 
+  final api.CompilerOutputProvider outputProvider;
+
   bool disableInlining = false;
 
   List<Uri> librariesToAnalyzeWhenRun;
@@ -331,9 +333,13 @@
             this.rejectDeprecatedFeatures: false,
             this.checkDeprecationInSdk: false,
             this.preserveComments: false,
+            outputProvider,
             List<String> strips: const []})
       : libraries = new Map<String, LibraryElement>(),
-        progress = new Stopwatch() {
+        progress = new Stopwatch(),
+        this.outputProvider =
+            (outputProvider == null) ? NullSink.outputProvider : outputProvider
+  {
     progress.start();
     world = new World(this);
 
@@ -409,7 +415,7 @@
   }
 
   void pleaseReportCrash() {
-    print(MessageKind.PLEASE_REPORT_THE_CRASH.message([BUILD_ID]));
+    print(MessageKind.PLEASE_REPORT_THE_CRASH.message({'buildId': BUILD_ID}));
   }
 
   void cancel(String reason, {Node node, Token token,
@@ -433,6 +439,9 @@
   }
 
   SourceSpan spanFromSpannable(Spannable node, [Uri uri]) {
+    if (node == CURRENT_ELEMENT_SPANNABLE) {
+      node = currentElement;
+    }
     if (node is Node) {
       return spanFromNode(node, uri);
     } else if (node is Token) {
@@ -839,12 +848,21 @@
     reportDiagnostic(span, 'Warning: $message', api.Diagnostic.WARNING);
   }
 
+  // TODO(ahe): Remove this method.
   reportError(Node node, var message) {
     SourceSpan span = spanFromNode(node);
     reportDiagnostic(span, 'Error: $message', api.Diagnostic.ERROR);
     throw new CompilerCancelledException(message.toString());
   }
 
+  // TODO(ahe): Rename to reportError when that method has been removed.
+  void reportErrorCode(Spannable node, MessageKind errorCode,
+                       [Map arguments = const {}]) {
+    reportMessage(spanFromSpannable(node),
+                  errorCode.error(arguments),
+                  api.Diagnostic.ERROR);
+  }
+
   void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind) {
     // TODO(ahe): The names Diagnostic and api.Diagnostic are in
     // conflict. Fix it.
@@ -862,8 +880,9 @@
     var kind = rejectDeprecatedFeatures
         ? api.Diagnostic.ERROR : api.Diagnostic.WARNING;
     var message = rejectDeprecatedFeatures
-        ? MessageKind.DEPRECATED_FEATURE_ERROR.error([feature])
-        : MessageKind.DEPRECATED_FEATURE_WARNING.error([feature]);
+        ? MessageKind.DEPRECATED_FEATURE_ERROR.error({'featureName': feature})
+        : MessageKind.DEPRECATED_FEATURE_WARNING.error(
+            {'featureName': feature});
     reportMessage(spanFromSpannable(span), message, kind);
     return true;
   }
@@ -1087,3 +1106,21 @@
   }
   return true;
 }
+
+/// A sink that drains into /dev/null.
+class NullSink extends Sink<String> {
+  final String name;
+
+  NullSink(this.name);
+
+  add(String value) {}
+
+  void close() {}
+
+  toString() => name;
+
+  /// Convenience method for getting an [api.CompilerOutputProvider].
+  static NullSink outputProvider(String name, String extension) {
+    return new NullSink('$name.$extension');
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index cf774f5..d66579f 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -131,7 +131,7 @@
   setCategories(String argument) {
     List<String> categories = extractParameter(argument).split(',');
     Set<String> allowedCategories =
-        LIBRARIES.values.mappedBy((x) => x.category).toSet();
+        LIBRARIES.values.map((x) => x.category).toSet();
     allowedCategories.remove('Shared');
     allowedCategories.remove('Internal');
     List<String> allowedCategoriesList =
@@ -233,12 +233,6 @@
 
   void handler(Uri uri, int begin, int end, String message,
                api.Diagnostic kind) {
-    if (identical(kind.name, 'source map')) {
-      // TODO(podivilov): We should find a better way to return source maps from
-      // emitter. Using diagnostic handler for that purpose is a temporary hack.
-      writeString(sourceMapOut, message);
-      return;
-    }
     diagnosticHandler.diagnosticHandler(uri, begin, end, message, kind);
   }
 
@@ -249,34 +243,89 @@
 
   diagnosticHandler.info('package root is $packageRoot');
 
-  // TODO(ahe): We expect the future to be complete and call value
-  // directly. In effect, we don't support truly asynchronous API.
-  String code = deprecatedFutureValue(
-      api.compile(uri, libraryRoot, packageRoot,
-                  inputProvider.readStringFromUri,
-                  handler,
-                  options));
-  if (analyzeOnly) return;
+  int charactersWritten = 0;
 
-  if (code == null) {
-    fail('Error: Compilation failed.');
+  compilationDone(String code) {
+    if (analyzeOnly) return;
+    if (code == null) {
+      fail('Error: Compilation failed.');
+    }
+    writeString(Uri.parse('$out.deps'),
+                getDepsOutput(inputProvider.sourceFiles));
+    diagnosticHandler.info(
+         'compiled ${inputProvider.dartCharactersRead} characters Dart '
+         '-> $charactersWritten characters $outputLanguage '
+         'in ${relativize(cwd, out, isWindows)}');
+    if (!explicitOut) {
+      String input = uriPathToNative(arguments[0]);
+      String output = relativize(cwd, out, isWindows);
+      print('Dart file $input compiled to $outputLanguage: $output');
+    }
   }
-  String sourceMapFileName =
-      sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1);
-  code = '$code\n//@ sourceMappingURL=${sourceMapFileName}';
-  writeString(out, code);
-  writeString(Uri.parse('$out.deps'),
-              getDepsOutput(inputProvider.sourceFiles));
-  int dartBytesRead = inputProvider.dartBytesRead;
-  int bytesWritten = code.length;
-  diagnosticHandler.info(
-      'compiled $dartBytesRead bytes Dart -> $bytesWritten bytes '
-      '$outputLanguage in ${relativize(cwd, out, isWindows)}');
-  if (!explicitOut) {
-    String input = uriPathToNative(arguments[0]);
-    String output = relativize(cwd, out, isWindows);
-    print('Dart file $input compiled to $outputLanguage: $output');
+
+  Sink<String> outputProvider(String name, String extension) {
+    Uri uri;
+    String sourceMapFileName;
+    bool isPrimaryOutput = false;
+    if (name == '') {
+      if (extension == 'js' || extension == 'dart') {
+        isPrimaryOutput = true;
+        uri = out;
+        sourceMapFileName =
+            sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1);
+      } else if (extension == 'js.map' || extension == 'dart.map') {
+        uri = sourceMapOut;
+      } else {
+        fail('Error: Unknown extension: $extension');
+      }
+    } else {
+      uri = out.resolve('$name.$extension');
+    }
+
+    if (uri.scheme != 'file') {
+      fail('Error: Unhandled scheme ${uri.scheme} in $uri.');
+    }
+    var outputStream = new File(uriPathToNative(uri.path)).openOutputStream();
+
+    CountingSink sink;
+
+    onDone() {
+      if (sourceMapFileName != null) {
+        String sourceMapTag = '//@ sourceMappingURL=$sourceMapFileName\n';
+        sink.count += sourceMapTag.length;
+        outputStream.writeString(sourceMapTag);
+      }
+      outputStream.close();
+      if (isPrimaryOutput) {
+        charactersWritten += sink.count;
+      }
+    }
+
+    var controller = new StreamController<String>();
+    controller.stream.listen(outputStream.writeString, onDone: onDone);
+    sink = new CountingSink(controller);
+    return sink;
   }
+
+  api.compile(uri, libraryRoot, packageRoot,
+              inputProvider.readStringFromUri, handler,
+              options, outputProvider)
+      .then(compilationDone);
+}
+
+// TODO(ahe): Get rid of this class if http://dartbug.com/8118 is fixed.
+class CountingSink implements Sink<String> {
+  final Sink<String> sink;
+  int count = 0;
+
+  CountingSink(this.sink);
+
+  add(String value) {
+    sink.add(value);
+    count += value.length;
+  }
+
+  close() => sink.close();
 }
 
 class AbortLeg {
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index a5c63c37..8a1e012 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -9,6 +9,7 @@
 
 import 'closure.dart' as closureMapping;
 import 'dart_backend/dart_backend.dart' as dart_backend;
+import 'dart_types.dart';
 import 'elements/elements.dart';
 import 'elements/modelx.dart'
     show ErroneousElementX,
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index e2be554..6a3b000 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -89,7 +89,7 @@
       return false;
     }
 
-    rewiteStatement(Statement statement) {
+    rewriteStatement(Statement statement) {
       if (statement is Block) {
         Link statements = statement.statements.nodes;
         if (!statements.isEmpty && statements.tail.isEmpty) {
@@ -106,7 +106,7 @@
     LinkBuilder<Statement> builder = new LinkBuilder<Statement>();
     for (Statement statement in statements.nodes) {
       if (!shouldOmit(statement)) {
-        builder.addLast(visit(rewiteStatement(statement)));
+        builder.addLast(visit(rewriteStatement(statement)));
       }
     }
     return new Block(rewriteNodeList(statements, builder.toLink()));
@@ -137,7 +137,7 @@
     Set<DartType> processedTypes = new Set<DartType>();
     List<DartType> workQueue = new List<DartType>();
     workQueue.addAll(
-        classMembers.keys.mappedBy((classElement) => classElement.thisType));
+        classMembers.keys.map((classElement) => classElement.thisType));
     workQueue.addAll(compiler.resolverWorld.isChecks);
     Element typeErrorElement =
         compiler.coreLibrary.find(new SourceString('TypeError'));
@@ -387,8 +387,13 @@
       SynthesizedConstructorElementX constructor =
           new SynthesizedConstructorElementX(classElement);
       constructor.type = new FunctionType(
-          compiler.types.voidType, const Link<DartType>(),
-          constructor);
+          constructor,
+          compiler.types.voidType,
+          const Link<DartType>(),
+          const Link<DartType>(),
+          const Link<SourceString>(),
+          const Link<DartType>()
+          );
       constructor.cachedNode = new FunctionExpression(
           new Send(classNode.name, synthesizedIdentifier),
           new NodeList(new StringToken(OPEN_PAREN_INFO, '(', -1),
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
index cea56ff..8a8abe4 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_backend.dart
@@ -7,6 +7,7 @@
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show SynthesizedConstructorElementX;
 import '../dart2jslib.dart';
+import '../dart_types.dart';
 import '../tree/tree.dart';
 import '../util/util.dart';
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
index 4b9f3e0..886d39e 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/renamer.dart
@@ -191,7 +191,7 @@
           sorted(functionScope.localPlaceholders,
               compareBy((LocalPlaceholder ph) => -ph.nodes.length));
       List<Set<Node>> currentSortedNodes =
-          currentSortedPlaceholders.mappedBy((ph) => ph.nodes).toList();
+          currentSortedPlaceholders.map((ph) => ph.nodes).toList();
       // Make room in all sorted locals list for new stuff.
       while (currentSortedNodes.length > allSortedLocals.length) {
         allSortedLocals.add(new Set<Node>());
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
new file mode 100644
index 0000000..b43de38
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -0,0 +1,817 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart_types;
+
+import 'dart2jslib.dart' show Compiler, invariant, Script, Message;
+import 'elements/modelx.dart' show VoidElementX, LibraryElementX;
+import 'elements/elements.dart';
+import 'scanner/scannerlib.dart' show SourceString;
+import 'util/util.dart' show Link, LinkBuilder;
+
+class TypeKind {
+  final String id;
+
+  const TypeKind(String this.id);
+
+  static const TypeKind FUNCTION = const TypeKind('function');
+  static const TypeKind INTERFACE = const TypeKind('interface');
+  static const TypeKind STATEMENT = const TypeKind('statement');
+  static const TypeKind TYPEDEF = const TypeKind('typedef');
+  static const TypeKind TYPE_VARIABLE = const TypeKind('type variable');
+  static const TypeKind MALFORMED_TYPE = const TypeKind('malformed');
+  static const TypeKind VOID = const TypeKind('void');
+
+  String toString() => id;
+}
+
+abstract class DartType {
+  SourceString get name;
+
+  TypeKind get kind;
+
+  const DartType();
+
+  /**
+   * Returns the [Element] which declared this type.
+   *
+   * This can be [ClassElement] for classes, [TypedefElement] for typedefs,
+   * [TypeVariableElement] for type variables and [FunctionElement] for
+   * function types.
+   *
+   * Invariant: [element] must be a declaration element.
+   */
+  Element get element;
+
+  /**
+   * Performs the substitution [: [arguments[i]/parameters[i]]this :].
+   *
+   * The notation is known from this lambda calculus rule:
+   *
+   *     (lambda x.e0)e1 -> [e1/x]e0.
+   *
+   * See [TypeVariableType] for a motivation for this method.
+   *
+   * Invariant: There must be the same number of [arguments] and [parameters].
+   */
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters);
+
+  /**
+   * Returns the unaliased type of this type.
+   *
+   * The unaliased type of a typedef'd type is the unaliased type to which its
+   * name is bound. The unaliased version of any other type is the type itself.
+   *
+   * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the
+   * function type [: (B) -> A :] and the unaliased type of
+   * [: Func<int,String> :] is the function type [: (String) -> int :].
+   */
+  DartType unalias(Compiler compiler);
+
+  /**
+   * A type is malformed if it is itself a malformed type or contains a
+   * malformed type.
+   */
+  bool get isMalformed => false;
+
+  /**
+   * Calls [f] with each [MalformedType] within this type.
+   *
+   * If [f] returns [: false :], the traversal stops prematurely.
+   *
+   * [forEachMalformedType] returns [: false :] if the traversal was stopped
+   * prematurely.
+   */
+  bool forEachMalformedType(bool f(MalformedType type)) => true;
+
+  bool operator ==(other);
+
+  /**
+   * Is [: true :] if this type has no explict type arguments.
+   */
+  bool get isRaw => true;
+
+  DartType asRaw() => this;
+}
+
+/**
+ * Represents a type variable, that is the type parameters of a class type.
+ *
+ * For example, in [: class Array<E> { ... } :], E is a type variable.
+ *
+ * Each class should have its own unique type variables, one for each type
+ * parameter. A class with type parameters is said to be parameterized or
+ * generic.
+ *
+ * Non-static members, constructors, and factories of generic
+ * class/interface can refer to type variables of the current class
+ * (not of supertypes).
+ *
+ * When using a generic type, also known as an application or
+ * instantiation of the type, the actual type arguments should be
+ * substituted for the type variables in the class declaration.
+ *
+ * For example, given a box, [: class Box<T> { T value; } :], the
+ * type of the expression [: new Box<String>().value :] is
+ * [: String :] because we must substitute [: String :] for the
+ * the type variable [: T :].
+ */
+class TypeVariableType extends DartType {
+  final TypeVariableElement element;
+
+  TypeVariableType(this.element);
+
+  TypeKind get kind => TypeKind.TYPE_VARIABLE;
+
+  SourceString get name => element.name;
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    if (parameters.isEmpty) {
+      assert(arguments.isEmpty);
+      // Return fast on empty substitutions.
+      return this;
+    }
+    Link<DartType> parameterLink = parameters;
+    Link<DartType> argumentLink = arguments;
+    while (!argumentLink.isEmpty && !parameterLink.isEmpty) {
+      TypeVariableType parameter = parameterLink.head;
+      DartType argument = argumentLink.head;
+      if (parameter == this) {
+        assert(argumentLink.tail.isEmpty == parameterLink.tail.isEmpty);
+        return argument;
+      }
+      parameterLink = parameterLink.tail;
+      argumentLink = argumentLink.tail;
+    }
+    assert(argumentLink.isEmpty && parameterLink.isEmpty);
+    // The type variable was not substituted.
+    return this;
+  }
+
+  DartType unalias(Compiler compiler) => this;
+
+  int get hashCode => 17 * element.hashCode;
+
+  bool operator ==(other) {
+    if (other is !TypeVariableType) return false;
+    return identical(other.element, element);
+  }
+
+  String toString() => name.slowToString();
+}
+
+/**
+ * A statement type tracks whether a statement returns or may return.
+ */
+class StatementType extends DartType {
+  final String stringName;
+
+  Element get element => null;
+
+  TypeKind get kind => TypeKind.STATEMENT;
+
+  SourceString get name => new SourceString(stringName);
+
+  const StatementType(this.stringName);
+
+  static const RETURNING = const StatementType('<returning>');
+  static const NOT_RETURNING = const StatementType('<not returning>');
+  static const MAYBE_RETURNING = const StatementType('<maybe returning>');
+
+  /** Combine the information about two control-flow edges that are joined. */
+  StatementType join(StatementType other) {
+    return (identical(this, other)) ? this : MAYBE_RETURNING;
+  }
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    // Statement types are not substitutable.
+    return this;
+  }
+
+  DartType unalias(Compiler compiler) => this;
+
+  int get hashCode => 17 * stringName.hashCode;
+
+  bool operator ==(other) {
+    if (other is !StatementType) return false;
+    return other.stringName == stringName;
+  }
+
+  String toString() => stringName;
+}
+
+class VoidType extends DartType {
+  const VoidType(this.element);
+
+  TypeKind get kind => TypeKind.VOID;
+
+  SourceString get name => element.name;
+
+  final Element element;
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    // Void cannot be substituted.
+    return this;
+  }
+
+  DartType unalias(Compiler compiler) => this;
+
+  int get hashCode => 1729;
+
+  bool operator ==(other) => other is VoidType;
+
+  String toString() => name.slowToString();
+}
+
+class MalformedType extends DartType {
+  final ErroneousElement element;
+
+  /**
+   * [declaredType] holds the type which the user wrote in code.
+   *
+   * For instance, for a resolved but malformed type like [: Map<String> :] the
+   * [declaredType] is [: Map<String> :] whereas for an unresolved type
+   */
+  final DartType userProvidedBadType;
+
+  /**
+   * Type arguments for the malformed typed, if these cannot fit in the
+   * [declaredType].
+   *
+   * This field is for instance used for [: dynamic<int> :] and [: T<int> :]
+   * where [: T :] is a type variable, in which case [declaredType] holds
+   * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :]
+   * is not resolved or does not imply a type.
+   */
+  final Link<DartType> typeArguments;
+
+  MalformedType(this.element, this.userProvidedBadType,
+                [this.typeArguments = null]);
+
+  TypeKind get kind => TypeKind.MALFORMED_TYPE;
+
+  SourceString get name => element.name;
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    // Malformed types are not substitutable.
+    return this;
+  }
+
+  bool get isMalformed => true;
+
+  bool forEachMalformedType(bool f(MalformedType type)) => f(this);
+
+  DartType unalias(Compiler compiler) => this;
+
+  String toString() {
+    var sb = new StringBuffer();
+    if (typeArguments != null) {
+      if (userProvidedBadType != null) {
+        sb.add(userProvidedBadType.name.slowToString());
+      } else {
+        sb.add(element.name.slowToString());
+      }
+      if (!typeArguments.isEmpty) {
+        sb.add('<');
+        typeArguments.printOn(sb, ', ');
+        sb.add('>');
+      }
+    } else {
+      sb.add(userProvidedBadType.toString());
+    }
+    return sb.toString();
+  }
+}
+
+bool hasMalformed(Link<DartType> types) {
+  for (DartType typeArgument in types) {
+    if (typeArgument.isMalformed) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// TODO(johnniwinther): Add common supertype for InterfaceType and TypedefType.
+class InterfaceType extends DartType {
+  final ClassElement element;
+  final Link<DartType> typeArguments;
+  final bool isMalformed;
+
+  InterfaceType(this.element,
+                [Link<DartType> typeArguments = const Link<DartType>()])
+      : this.typeArguments = typeArguments,
+        this.isMalformed = hasMalformed(typeArguments) {
+    assert(invariant(element, element.isDeclaration));
+  }
+
+  TypeKind get kind => TypeKind.INTERFACE;
+
+  SourceString get name => element.name;
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    if (typeArguments.isEmpty) {
+      // Return fast on non-generic types.
+      return this;
+    }
+    if (parameters.isEmpty) {
+      assert(arguments.isEmpty);
+      // Return fast on empty substitutions.
+      return this;
+    }
+    Link<DartType> newTypeArguments =
+        Types.substTypes(typeArguments, arguments, parameters);
+    if (!identical(typeArguments, newTypeArguments)) {
+      // Create a new type only if necessary.
+      return new InterfaceType(element, newTypeArguments);
+    }
+    return this;
+  }
+
+  bool forEachMalformedType(bool f(MalformedType type)) {
+    for (DartType typeArgument in typeArguments) {
+      if (!typeArgument.forEachMalformedType(f)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Returns the type as an instance of class [other], if possible, null
+   * otherwise.
+   */
+  DartType asInstanceOf(ClassElement other) {
+    if (element == other) return this;
+    for (InterfaceType supertype in element.allSupertypes) {
+      ClassElement superclass = supertype.element;
+      if (superclass == other) {
+        Link<DartType> arguments = Types.substTypes(supertype.typeArguments,
+                                                    typeArguments,
+                                                    element.typeVariables);
+        return new InterfaceType(superclass, arguments);
+      }
+    }
+    return null;
+  }
+
+  DartType unalias(Compiler compiler) => this;
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.add(name.slowToString());
+    if (!isRaw) {
+      sb.add('<');
+      typeArguments.printOn(sb, ', ');
+      sb.add('>');
+    }
+    return sb.toString();
+  }
+
+  int get hashCode {
+    int hash = element.hashCode;
+    for (Link<DartType> arguments = this.typeArguments;
+         !arguments.isEmpty;
+         arguments = arguments.tail) {
+      int argumentHash = arguments.head != null ? arguments.head.hashCode : 0;
+      hash = 17 * hash + 3 * argumentHash;
+    }
+    return hash;
+  }
+
+  bool operator ==(other) {
+    if (other is !InterfaceType) return false;
+    if (!identical(element, other.element)) return false;
+    return typeArguments == other.typeArguments;
+  }
+
+  bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
+
+  InterfaceType asRaw() => element.rawType;
+}
+
+class FunctionType extends DartType {
+  final Element element;
+  final DartType returnType;
+  final Link<DartType> parameterTypes;
+  final Link<DartType> optionalParameterTypes;
+
+  /**
+   * The names of the named parameters ordered lexicographically.
+   */
+  final Link<SourceString> namedParameters;
+
+  /**
+   * The types of the named parameters in the order corresponding to the
+   * [namedParameters].
+   */
+  final Link<DartType> namedParameterTypes;
+  final bool isMalformed;
+
+  factory FunctionType(Element element,
+                       DartType returnType,
+                       Link<DartType> parameterTypes,
+                       Link<DartType> optionalParameterTypes,
+                       Link<SourceString> namedParameters,
+                       Link<DartType> namedParameterTypes) {
+    // Compute [isMalformed] eagerly since it is faster than a lazy computation
+    // and since [isMalformed] most likely will be accessed in [Types.isSubtype]
+    // anyway.
+    bool isMalformed = returnType != null &&
+                       returnType.isMalformed ||
+                       hasMalformed(parameterTypes) ||
+                       hasMalformed(optionalParameterTypes) ||
+                       hasMalformed(namedParameterTypes);
+    return new FunctionType.internal(element,
+                                     returnType,
+                                     parameterTypes,
+                                     optionalParameterTypes,
+                                     namedParameters,
+                                     namedParameterTypes,
+                                     isMalformed);
+  }
+
+  FunctionType.internal(Element this.element,
+                        DartType this.returnType,
+                        Link<DartType> this.parameterTypes,
+                        Link<DartType> this.optionalParameterTypes,
+                        Link<SourceString> this.namedParameters,
+                        Link<DartType> this.namedParameterTypes,
+                        bool this.isMalformed) {
+    assert(element == null || invariant(element, element.isDeclaration));
+    // Assert that optional and named parameters are not used at the same time.
+    assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty);
+    assert(namedParameters.slowLength() == namedParameterTypes.slowLength());
+  }
+
+  TypeKind get kind => TypeKind.FUNCTION;
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    if (parameters.isEmpty) {
+      assert(arguments.isEmpty);
+      // Return fast on empty substitutions.
+      return this;
+    }
+    var newReturnType = returnType.subst(arguments, parameters);
+    bool changed = !identical(newReturnType, returnType);
+    var newParameterTypes =
+        Types.substTypes(parameterTypes, arguments, parameters);
+    var newOptionalParameterTypes =
+        Types.substTypes(optionalParameterTypes, arguments, parameters);
+    var newNamedParameterTypes =
+        Types.substTypes(namedParameterTypes, arguments, parameters);
+    if (!changed &&
+        (!identical(parameterTypes, newParameterTypes) ||
+         !identical(optionalParameterTypes, newOptionalParameterTypes) ||
+         !identical(namedParameterTypes, newNamedParameterTypes))) {
+      changed = true;
+    }
+    if (changed) {
+      // Create a new type only if necessary.
+      return new FunctionType(element,
+                              newReturnType,
+                              newParameterTypes,
+                              newOptionalParameterTypes,
+                              namedParameters,
+                              newNamedParameterTypes);
+    }
+    return this;
+  }
+
+  bool forEachMalformedType(bool f(MalformedType type)) {
+    if (!returnType.forEachMalformedType(f)) {
+      return false;
+    }
+    for (DartType parameterType in parameterTypes) {
+      if (!parameterType.forEachMalformedType(f)) {
+        return false;
+      }
+    }
+    for (DartType parameterType in optionalParameterTypes) {
+      if (!parameterType.forEachMalformedType(f)) {
+        return false;
+      }
+    }
+    for (DartType parameterType in namedParameterTypes) {
+      if (!parameterType.forEachMalformedType(f)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  DartType unalias(Compiler compiler) => this;
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.add('(');
+    parameterTypes.printOn(sb, ', ');
+    bool first = parameterTypes.isEmpty;
+    if (!optionalParameterTypes.isEmpty) {
+      if (!first) {
+        sb.add(', ');
+      }
+      sb.add('[');
+      optionalParameterTypes.printOn(sb, ', ');
+      sb.add(']');
+      first = false;
+    }
+    if (!namedParameterTypes.isEmpty) {
+      if (!first) {
+        sb.add(', ');
+      }
+      sb.add('{');
+      Link<SourceString> namedParameter = namedParameters;
+      Link<DartType> namedParameterType = namedParameterTypes;
+      first = true;
+      while (!namedParameter.isEmpty && !namedParameterType.isEmpty) {
+        if (!first) {
+          sb.add(', ');
+        }
+        sb.add(namedParameterType.head);
+        sb.add(' ');
+          sb.add(namedParameter.head.slowToString());
+        namedParameter = namedParameter.tail;
+        namedParameterType = namedParameterType.tail;
+        first = false;
+      }
+      sb.add('}');
+    }
+    sb.add(') -> ${returnType}');
+    return sb.toString();
+  }
+
+  SourceString get name => const SourceString('Function');
+
+  int computeArity() {
+    int arity = 0;
+    parameterTypes.forEach((_) { arity++; });
+    return arity;
+  }
+
+  int get hashCode {
+    int hash = 17 * element.hashCode + 3 * returnType.hashCode;
+    for (DartType parameter  in parameterTypes) {
+      hash = 17 * hash + 3 * parameter.hashCode;
+    }
+    for (DartType parameter  in optionalParameterTypes) {
+      hash = 17 * hash + 3 * parameter.hashCode;
+    }
+    for (SourceString name  in namedParameters) {
+      hash = 17 * hash + 3 * name.hashCode;
+    }
+    for (DartType parameter  in namedParameterTypes) {
+      hash = 17 * hash + 3 * parameter.hashCode;
+    }
+    return hash;
+  }
+
+  bool operator ==(other) {
+    if (other is !FunctionType) return false;
+    return returnType == other.returnType
+           && parameterTypes == other.parameterTypes
+           && optionalParameterTypes == other.optionalParameterTypes
+           && namedParameters == other.namedParameters
+           && namedParameterTypes == other.namedParameterTypes;
+  }
+}
+
+class TypedefType extends DartType {
+  final TypedefElement element;
+  final Link<DartType> typeArguments;
+  final bool isMalformed;
+
+  TypedefType(this.element,
+              [Link<DartType> typeArguments = const Link<DartType>()])
+      : this.typeArguments = typeArguments,
+        this.isMalformed = hasMalformed(typeArguments);
+
+  TypeKind get kind => TypeKind.TYPEDEF;
+
+  SourceString get name => element.name;
+
+  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
+    if (typeArguments.isEmpty) {
+      // Return fast on non-generic typedefs.
+      return this;
+    }
+    if (parameters.isEmpty) {
+      assert(arguments.isEmpty);
+      // Return fast on empty substitutions.
+      return this;
+    }
+    Link<DartType> newTypeArguments = Types.substTypes(typeArguments, arguments,
+                                                       parameters);
+    if (!identical(typeArguments, newTypeArguments)) {
+      // Create a new type only if necessary.
+      return new TypedefType(element, newTypeArguments);
+    }
+    return this;
+  }
+
+  bool forEachMalformedType(bool f(MalformedType type)) {
+    for (DartType typeArgument in typeArguments) {
+      if (!typeArgument.forEachMalformedType(f)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  DartType unalias(Compiler compiler) {
+    // TODO(ahe): This should be [ensureResolved].
+    compiler.resolveTypedef(element);
+    DartType definition = element.alias.unalias(compiler);
+    TypedefType declaration = element.computeType(compiler);
+    return definition.subst(typeArguments, declaration.typeArguments);
+  }
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.add(name.slowToString());
+    if (!isRaw) {
+      sb.add('<');
+      typeArguments.printOn(sb, ', ');
+      sb.add('>');
+    }
+    return sb.toString();
+  }
+
+  int get hashCode => 17 * element.hashCode;
+
+  bool operator ==(other) {
+    if (other is !TypedefType) return false;
+    if (!identical(element, other.element)) return false;
+    return typeArguments == other.typeArguments;
+  }
+
+  bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
+
+  TypedefType asRaw() => element.rawType;
+}
+
+/**
+ * Special type to hold the [dynamic] type. Used for correctly returning
+ * 'dynamic' on [toString].
+ */
+class DynamicType extends InterfaceType {
+  DynamicType(ClassElement element) : super(element);
+
+  SourceString get name => const SourceString('dynamic');
+}
+
+class Types {
+  final Compiler compiler;
+  // TODO(karlklose): should we have a class Void?
+  final VoidType voidType;
+  final DynamicType dynamicType;
+
+  factory Types(Compiler compiler, ClassElement dynamicElement) {
+    LibraryElement library = new LibraryElementX(new Script(null, null));
+    VoidType voidType = new VoidType(new VoidElementX(library));
+    DynamicType dynamicType = new DynamicType(dynamicElement);
+    dynamicElement.rawType = dynamicElement.thisType = dynamicType;
+    return new Types.internal(compiler, voidType, dynamicType);
+  }
+
+  Types.internal(this.compiler, this.voidType, this.dynamicType);
+
+  /** Returns true if t is a subtype of s */
+  bool isSubtype(DartType t, DartType s) {
+    if (identical(t, s) ||
+        identical(t, dynamicType) ||
+        identical(s, dynamicType) ||
+        t.isMalformed ||
+        s.isMalformed ||
+        identical(s.element, compiler.objectClass) ||
+        identical(t.element, compiler.nullClass)) {
+      return true;
+    }
+    t = t.unalias(compiler);
+    s = s.unalias(compiler);
+
+    if (t is VoidType) {
+      return false;
+    } else if (t is InterfaceType) {
+      if (s is !InterfaceType) return false;
+      ClassElement tc = t.element;
+      if (identical(tc, s.element)) return true;
+      for (Link<DartType> supertypes = tc.allSupertypes;
+           supertypes != null && !supertypes.isEmpty;
+           supertypes = supertypes.tail) {
+        DartType supertype = supertypes.head;
+        if (identical(supertype.element, s.element)) return true;
+      }
+      return false;
+    } else if (t is FunctionType) {
+      if (identical(s.element, compiler.functionClass)) return true;
+      if (s is !FunctionType) return false;
+      FunctionType tf = t;
+      FunctionType sf = s;
+      Link<DartType> tps = tf.parameterTypes;
+      Link<DartType> sps = sf.parameterTypes;
+      while (!tps.isEmpty && !sps.isEmpty) {
+        if (!isAssignable(tps.head, sps.head)) return false;
+        tps = tps.tail;
+        sps = sps.tail;
+      }
+      if (!tps.isEmpty || !sps.isEmpty) return false;
+      if (!isAssignable(sf.returnType, tf.returnType)) return false;
+      if (!sf.namedParameters.isEmpty) {
+        // Since named parameters are globally ordered we can determine the
+        // subset relation with a linear search for [:sf.NamedParameters:]
+        // within [:tf.NamedParameters:].
+        Link<SourceString> tNames = tf.namedParameters;
+        Link<DartType> tTypes = tf.namedParameterTypes;
+        Link<SourceString> sNames = sf.namedParameters;
+        Link<DartType> sTypes = sf.namedParameterTypes;
+        while (!tNames.isEmpty && !sNames.isEmpty) {
+          if (sNames.head == tNames.head) {
+            if (!isAssignable(tTypes.head, sTypes.head)) return false;
+
+            sNames = sNames.tail;
+            sTypes = sTypes.tail;
+          }
+          tNames = tNames.tail;
+          tTypes = tTypes.tail;
+        }
+        if (!sNames.isEmpty) {
+          // We didn't find all names.
+          return false;
+        }
+      }
+      if (!sf.optionalParameterTypes.isEmpty) {
+        Link<DartType> tOptionalParameterType = tf.optionalParameterTypes;
+        Link<DartType> sOptionalParameterType = sf.optionalParameterTypes;
+        while (!tOptionalParameterType.isEmpty &&
+               !sOptionalParameterType.isEmpty) {
+          if (!isAssignable(tOptionalParameterType.head,
+                            sOptionalParameterType.head)) {
+            return false;
+          }
+          sOptionalParameterType = sOptionalParameterType.tail;
+          tOptionalParameterType = tOptionalParameterType.tail;
+        }
+        if (!sOptionalParameterType.isEmpty) {
+          // We didn't find enough optional parameters.
+          return false;
+        }
+      }
+      return true;
+    } else if (t is TypeVariableType) {
+      if (s is !TypeVariableType) return false;
+      return (identical(t.element, s.element));
+    } else {
+      throw 'internal error: unknown type kind';
+    }
+  }
+
+  bool isAssignable(DartType r, DartType s) {
+    return isSubtype(r, s) || isSubtype(s, r);
+  }
+
+
+  /**
+   * Helper method for performing substitution of a linked list of types.
+   *
+   * If no types are changed by the substitution, the [types] is returned
+   * instead of a newly created linked list.
+   */
+  static Link<DartType> substTypes(Link<DartType> types,
+                                   Link<DartType> arguments,
+                                   Link<DartType> parameters) {
+    bool changed = false;
+    var builder = new LinkBuilder<DartType>();
+    Link<DartType> typeLink = types;
+    while (!typeLink.isEmpty) {
+      var argument = typeLink.head.subst(arguments, parameters);
+      if (!changed && !identical(argument, typeLink.head)) {
+        changed = true;
+      }
+      builder.addLast(argument);
+      typeLink = typeLink.tail;
+    }
+    if (changed) {
+      // Create a new link only if necessary.
+      return builder.toLink();
+    }
+    return types;
+  }
+
+  /**
+   * Combine error messages in a malformed type to a single message string.
+   */
+  static String fetchReasonsFromMalformedType(DartType type) {
+    // TODO(johnniwinther): Figure out how to produce good error message in face
+    // of multiple errors, and how to ensure non-localized error messages.
+    var reasons = new List<String>();
+    type.forEachMalformedType((MalformedType malformedType) {
+      ErroneousElement error = malformedType.element;
+      Message message = error.messageKind.message(error.messageArguments);
+      reasons.add(message.toString());
+      return true;
+    });
+    return Strings.join(reasons, ', ');
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
index f80a616..1d0c2b9 100644
--- a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
@@ -16,10 +16,13 @@
                      {Node node, Token token, HInstruction instruction,
                       Element element});
 
-  SourceSpan spanFromSpannable(Node node, [Uri uri]);
+  SourceSpan spanFromSpannable(Spannable node, [Uri uri]);
 
   void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind);
 
+  // TODO(ahe): Rename to reportError when that method has been removed.
+  void reportErrorCode(Spannable node, MessageKind errorCode, [Map arguments]);
+
   /// Returns true if a diagnostic was emitted.
   bool onDeprecatedFeature(Spannable span, String feature);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 8d94a9d..81e2fc0 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -24,6 +24,8 @@
                                  Constant,
                                  Compiler;
 
+import '../dart_types.dart';
+
 import '../scanner/scannerlib.dart' show Token,
                                          isUserDefinableOperator,
                                          isMinusOperator;
@@ -444,12 +446,12 @@
 
 abstract class ErroneousElement extends Element implements FunctionElement {
   MessageKind get messageKind;
-  List get messageArguments;
+  Map get messageArguments;
 }
 
 abstract class AmbiguousElement extends Element {
   MessageKind get messageKind;
-  List get messageArguments;
+  Map get messageArguments;
   Element get existingElement;
   Element get newElement;
 }
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 2d1bf8f..8c43df5 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -26,6 +26,8 @@
                                  Constant,
                                  Compiler;
 
+import '../dart_types.dart';
+
 import '../scanner/scannerlib.dart' show Token, EOF_TOKEN;
 
 
@@ -297,7 +299,7 @@
  */
 class ErroneousElementX extends ElementX implements ErroneousElement {
   final MessageKind messageKind;
-  final List messageArguments;
+  final Map messageArguments;
 
   ErroneousElementX(this.messageKind, this.messageArguments,
                     SourceString name, Element enclosing)
@@ -324,7 +326,7 @@
   computeSignature(compiler) => unsupported();
   requiredParameterCount(compiler) => unsupported();
   optionalParameterCount(compiler) => unsupported();
-  parameterCount(copmiler) => unsupported();
+  parameterCount(compiler) => unsupported();
 
   // TODO(kasperl): These seem unnecessary.
   set patch(value) => unsupported();
@@ -357,7 +359,7 @@
   /**
    * The message arguments to report on resolving this element.
    */
-  final List messageArguments;
+  final Map messageArguments;
 
   /**
    * The first element that this ambiguous element might refer to.
@@ -491,10 +493,7 @@
       return;
     }
     if (!localMembers.isEmpty) {
-      listener.reportMessage(
-          listener.spanFromSpannable(tag),
-          MessageKind.BEFORE_TOP_LEVEL.error(),
-          api.Diagnostic.ERROR);
+      listener.reportErrorCode(tag, MessageKind.BEFORE_TOP_LEVEL);
       return;
     }
     if (partTag != null) {
@@ -512,7 +511,8 @@
       if (expectedName != actualName) {
         listener.reportMessage(
             listener.spanFromSpannable(tag.name),
-            MessageKind.LIBRARY_NAME_MISMATCH.error([expectedName]),
+            MessageKind.LIBRARY_NAME_MISMATCH.error(
+                {'libraryName': expectedName}),
             api.Diagnostic.WARNING);
       }
     }
@@ -603,7 +603,7 @@
       // TODO(johnniwinther): Provide access to the import tags from which
       // the elements came.
       importScope[element.name] = new AmbiguousElementX(
-          MessageKind.DUPLICATE_IMPORT, [element.name],
+          MessageKind.DUPLICATE_IMPORT, {'name': element.name},
           this, existing, element);
     } else {
       importScope[element.name] = element;
@@ -1257,10 +1257,12 @@
                                             Compiler compiler)
     : super(enclosing.name, ElementKind.GENERATIVE_CONSTRUCTOR,
             Modifiers.EMPTY, enclosing) {
-    type = new FunctionType(
+    type = new FunctionType(this,
         compiler.types.voidType,
         const Link<DartType>(),
-        this);
+        const Link<DartType>(),
+        const Link<SourceString>(),
+        const Link<DartType>());
     cachedNode = new FunctionExpression(
         new Identifier(enclosing.position()),
         new NodeList.empty(),
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index 8a4960a..da8cd44 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -778,7 +778,7 @@
 
   ArrayInitializer(this.length, this.elements);
 
-  factory ArrayInitializer.from(List<Expression> expressions) =>
+  factory ArrayInitializer.from(Iterable<Expression> expressions) =>
       new ArrayInitializer(expressions.length, _convert(expressions));
 
   accept(NodeVisitor visitor) => visitor.visitArrayInitializer(this);
@@ -789,9 +789,9 @@
 
   int get precedenceLevel => PRIMARY;
 
-  static List<ArrayElement> _convert(List<Expression> expressions) {
+  static List<ArrayElement> _convert(Iterable<Expression> expressions) {
     int index = 0;
-    return expressions.mappedBy(
+    return expressions.map(
         (expression) => new ArrayElement(index++, expression))
         .toList();
   }
@@ -896,8 +896,7 @@
 }
 
 Fun fun(List<String> parameterNames, Block body) {
-  return new Fun(parameterNames.mappedBy((n) => new Parameter(n)).toList(),
-                 body);
+  return new Fun(parameterNames.map((n) => new Parameter(n)).toList(), body);
 }
 
 Assignment assign(Expression leftHandSide, Expression value) {
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index 1cdfbf9..504933d 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -16,6 +16,7 @@
   bool pendingSemicolon = false;
   bool pendingSpace = false;
   static final identifierCharacterRegExp = new RegExp(r'^[a-zA-Z_0-9$]');
+  static final expressionContinuationRegExp = new RegExp(r'^[-+([]');
 
   Printer(leg.Compiler compiler, { allowVariableMinification: true })
       : shouldCompressOutput = compiler.enableMinification,
@@ -52,8 +53,23 @@
 
   void out(String str) {
     if (str != "") {
-      if (pendingSemicolon && (!shouldCompressOutput || str != "}")) {
-        outBuffer.add(";");
+      if (pendingSemicolon) {
+        if (!shouldCompressOutput) {
+          outBuffer.add(";");
+        } else if (str != "}") {
+          // We want to output newline instead of semicolon because it makes
+          // the raw stack traces much easier to read and it also makes line-
+          // based tools like diff work much better.  JavaScript will
+          // automatically insert the semicolon at the newline if it means a
+          // parsing error is avoided, so we can only do this trick if the
+          // next line is not something that can be glued onto a valid
+          // expression to make a new valid expression.
+          if (expressionContinuationRegExp.hasMatch(str)) {
+            outBuffer.add(";");
+          } else {
+            outBuffer.add("\n");
+          }
+        }
       }
       if (pendingSpace &&
           (!shouldCompressOutput || identifierCharacterRegExp.hasMatch(str))) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index a9361fa..f2e4f8f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -84,7 +84,20 @@
    * interceptor instance, and the actual receiver of the method.
    */
   final Map<int, String> interceptorClosureCache;
+
+  /**
+   * 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;
+
+  /**
+   * Raw Typedef symbols occuring in is-checks and type assertions.  If the
+   * program contains `x is F<int>` and `x is F<bool>` then the TypedefElement
+   * `F` will occur once in [checkedTypedefs].
+   */
   Set<TypedefElement> checkedTypedefs;
 
   final bool generateSourceMap;
@@ -880,10 +893,15 @@
 
     void visitField(ClassElement enclosingClass, Element member) {
       assert(invariant(classElement, member.isDeclaration));
-
       LibraryElement library = member.getLibrary();
       SourceString name = member.name;
       bool isPrivate = name.isPrivate();
+
+      // Keep track of whether or not we're dealing with a field mixin
+      // into a native class.
+      bool isMixinNativeField =
+          classElement.isNative() && enclosingClass.isMixinApplication;
+
       // See if we can dynamically create getters and setters.
       // We can only generate getters and setters for [classElement] since
       // the fields of super classes could be overwritten with getters or
@@ -893,7 +911,7 @@
       // We need to name shadowed fields differently, so they don't clash with
       // the non-shadowed field.
       bool isShadowed = false;
-      if (identical(enclosingClass, classElement)) {
+      if (isMixinNativeField || identical(enclosingClass, classElement)) {
         needsGetter = instanceFieldNeedsGetter(member);
         needsSetter = instanceFieldNeedsSetter(member);
       } else {
@@ -908,7 +926,7 @@
             : namer.getName(member);
         String fieldName = member.hasFixedBackendName()
             ? member.fixedBackendName()
-            : accessorName;
+            : (isMixinNativeField ? member.name.slowToString() : accessorName);
         bool needsCheckedSetter = false;
         if (needsSetter && compiler.enableTypeAssertions
             && canGenerateCheckedSetter(member)) {
@@ -1147,12 +1165,26 @@
 
   bool get getterAndSetterCanBeImplementedByFieldSpec => true;
 
+  int _selectorRank(Selector selector) {
+    int arity = selector.argumentCount * 3;
+    if (selector.isGetter()) return arity + 2;
+    if (selector.isSetter()) return arity + 1;
+    return arity;
+  }
+
+  int _compareSelectorNames(Selector selector1, Selector selector2) {
+    String name1 = selector1.name.toString();
+    String name2 = selector2.name.toString();
+    if (name1 != name2) return Comparable.compare(name1, name2);
+    return _selectorRank(selector1) - _selectorRank(selector2);
+  }
+
   void emitInterceptorMethods(ClassBuilder builder) {
     JavaScriptBackend backend = compiler.backend;
     // Emit forwarders for the ObjectInterceptor class. We need to
     // emit all possible sends on intercepted methods.
-    for (Selector selector in backend.usedInterceptors) {
-
+    for (Selector selector in
+         backend.usedInterceptors.toList()..sort(_compareSelectorNames)) {
       List<js.Parameter> parameters = <js.Parameter>[];
       List<js.Expression> arguments = <js.Expression>[];
       parameters.add(new js.Parameter('receiver'));
@@ -1181,11 +1213,13 @@
   }
 
   Iterable<Element> getTypedefChecksOn(DartType type) {
-    return checkedTypedefs.where((TypedefElement typedef) {
+    bool isSubtype(TypedefElement typedef) {
       FunctionType typedefType =
           typedef.computeType(compiler).unalias(compiler);
       return compiler.types.isSubtype(type, typedefType);
-    });
+    }
+    return checkedTypedefs.where(isSubtype).toList()
+        ..sort(Elements.compareByPosition);
   }
 
   /**
@@ -1815,7 +1849,7 @@
       }
 
       List<js.Expression> argNames =
-          selector.getOrderedNamedArguments().mappedBy((SourceString name) =>
+          selector.getOrderedNamedArguments().map((SourceString name) =>
               js.string(name.slowToString())).toList();
 
       String internalName = namer.invocationMirrorInternalName(selector);
@@ -1836,7 +1870,7 @@
                           js.string(internalName),
                           new js.LiteralNumber('$type'),
                           new js.ArrayInitializer.from(
-                              parameters.mappedBy((param) => js.use(param.name))
+                              parameters.map((param) => js.use(param.name))
                                         .toList()),
                           new js.ArrayInitializer.from(argNames)])]);
       js.Expression function =
@@ -2142,10 +2176,11 @@
     // If no class needs to be intercepted, just return.
     if (backend.objectInterceptorClass == null) return;
     String objectName = namer.isolateAccess(backend.objectInterceptorClass);
-    backend.specializedGetInterceptors.forEach(
-        (String key, Collection<ClassElement> classes) {
-          emitGetInterceptorMethod(buffer, objectName, key, classes);
-        });
+    var specializedGetInterceptors = backend.specializedGetInterceptors;
+    for (String name in specializedGetInterceptors.keys.toList()..sort()) {
+      Collection<ClassElement> classes = specializedGetInterceptors[name];
+      emitGetInterceptorMethod(buffer, objectName, name, classes);
+    }
   }
 
   void computeNeededClasses() {
@@ -2163,9 +2198,27 @@
     }
   }
 
+  int _compareSelectors(Selector selector1, Selector selector2) {
+    int comparison = _compareSelectorNames(selector1, selector2);
+    if (comparison != 0) return comparison;
+
+    JavaScriptBackend backend = compiler.backend;
+    Set<ClassElement> classes1 = backend.getInterceptedClassesOn(selector1);
+    Set<ClassElement> classes2 = backend.getInterceptedClassesOn(selector2);
+    if (classes1.length != classes2.length) {
+      return classes1.length - classes2.length;
+    }
+    String getInterceptor1 =
+        namer.getInterceptorName(backend.getInterceptorMethod, classes1);
+    String getInterceptor2 =
+        namer.getInterceptorName(backend.getInterceptorMethod, classes2);
+    return Comparable.compare(getInterceptor1, getInterceptor2);
+  }
+
   void emitOneShotInterceptors(CodeBuffer buffer) {
     JavaScriptBackend backend = compiler.backend;
-    for (Selector selector in backend.oneShotInterceptors) {
+    for (Selector selector in
+         backend.oneShotInterceptors.toList()..sort(_compareSelectors)) {
       Set<ClassElement> classes = backend.getInterceptedClassesOn(selector);
       String oneShotInterceptorName = namer.oneShotInterceptorName(selector);
       String getInterceptorName =
@@ -2265,11 +2318,9 @@
       if (generateSourceMap) {
         SourceFile compiledFile = new SourceFile(null, compiler.assembledCode);
         String sourceMap = buildSourceMap(mainBuffer, compiledFile);
-        // TODO(podivilov): We should find a better way to return source maps to
-        // compiler. Using diagnostic handler for that purpose is a temporary
-        // hack.
-        compiler.reportDiagnostic(
-            null, sourceMap, new api.Diagnostic(-1, 'source map'));
+        compiler.outputProvider('', 'js.map')
+            ..add(sourceMap)
+            ..close();
       }
     });
     return compiler.assembledCode;
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
index c4ff47f..06d5d01 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart
@@ -80,10 +80,10 @@
         new js.VariableDeclaration(mangledName),
         new js.Fun(
             fieldNames
-                .mappedBy((fieldName) => new js.Parameter(fieldName))
+                .map((fieldName) => new js.Parameter(fieldName))
                 .toList(),
             new js.Block(
-                fieldNames.mappedBy((fieldName) =>
+                fieldNames.map((fieldName) =>
                     new js.ExpressionStatement(
                         new js.Assignment(
                             new js.This().dot(fieldName),
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 077d897..52e6ee0 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -11,6 +11,7 @@
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show FunctionElementX;
 import '../dart2jslib.dart' hide Selector;
+import '../dart_types.dart';
 import '../js/js.dart' as js;
 import '../native_handler.dart' as native;
 import '../source_file.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
index 07ed2f8..bbe7368 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/minify_namer.dart
@@ -52,17 +52,6 @@
   // but it means that small changes in the input program will give smallish
   // changes in the output, which can be useful for diffing etc.
   String _getUnusedName(String proposedName, Set<String> usedNames) {
-    // Try single-character names with characters that occur in the
-    // input.
-    for (int i = 0; i < proposedName.length; i++) {
-      String candidate = proposedName[i];
-      int code = candidate.charCodeAt(0);
-      if (code < $A) continue;
-      if (code > $z) continue;
-      if (code > $Z && code < $a) continue;
-      if (!usedNames.contains(candidate)) return candidate;
-    }
-
     int hash = _calculateHash(proposedName);
     // Avoid very small hashes that won't try many names.
     hash = hash < 1000 ? hash * 314159 : hash;  // Yes, it's prime.
@@ -72,7 +61,7 @@
     // in a predictable order determined by the proposed name.  This is in order
     // to make the renamer stable: small changes in the input should nornally
     // result in relatively small changes in the output.
-    for (var n = 1; n <= 3; n++) {
+    for (var n = 2; n <= 3; n++) {
       int h = hash;
       while (h > 10) {
         var codes = <int>[_letterNumber(h)];
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 6a5067d..e424168 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -25,9 +25,132 @@
   ];
 
   static const reservedPropertySymbols =
-      const <String>["__proto__", "prototype", "constructor"];
+      const <String>["__proto__", "prototype", "constructor", "call"];
 
-  static Set<String> _jsReserved = null;
+  // Symbols that we might be using in our JS snippets.
+  static const reservedGlobalSymbols = const <String>[
+    // Section references are from Ecma-262
+    // (http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf)
+
+    // 15.1.1 Value Properties of the Global Object
+    "NaN", "Infinity", "undefined",
+
+    // 15.1.2 Function Properties of the Global Object
+    "eval", "parseInt", "parseFloat", "isNaN", "isFinite",
+
+    // 15.1.3 URI Handling Function Properties
+    "decodeURI", "decodeURIComponent",
+    "encodeURI",
+    "encodeURIComponent",
+
+    // 15.1.4 Constructor Properties of the Global Object
+    "Object", "Function", "Array", "String", "Boolean", "Number", "Date",
+    "RegExp", "Error", "EvalError", "RangeError", "ReferenceError",
+    "SyntaxError", "TypeError", "URIError",
+
+    // 15.1.5 Other Properties of the Global Object
+    "Math",
+
+    // 10.1.6 Activation Object
+    "arguments",
+
+    // B.2 Additional Properties (non-normative)
+    "escape", "unescape",
+
+    // Window props (https://developer.mozilla.org/en/DOM/window)
+    "applicationCache", "closed", "Components", "content", "controllers",
+    "crypto", "defaultStatus", "dialogArguments", "directories",
+    "document", "frameElement", "frames", "fullScreen", "globalStorage",
+    "history", "innerHeight", "innerWidth", "length",
+    "location", "locationbar", "localStorage", "menubar",
+    "mozInnerScreenX", "mozInnerScreenY", "mozScreenPixelsPerCssPixel",
+    "name", "navigator", "opener", "outerHeight", "outerWidth",
+    "pageXOffset", "pageYOffset", "parent", "personalbar", "pkcs11",
+    "returnValue", "screen", "scrollbars", "scrollMaxX", "scrollMaxY",
+    "self", "sessionStorage", "sidebar", "status", "statusbar", "toolbar",
+    "top", "window",
+
+    // Window methods (https://developer.mozilla.org/en/DOM/window)
+    "alert", "addEventListener", "atob", "back", "blur", "btoa",
+    "captureEvents", "clearInterval", "clearTimeout", "close", "confirm",
+    "disableExternalCapture", "dispatchEvent", "dump",
+    "enableExternalCapture", "escape", "find", "focus", "forward",
+    "GeckoActiveXObject", "getAttention", "getAttentionWithCycleCount",
+    "getComputedStyle", "getSelection", "home", "maximize", "minimize",
+    "moveBy", "moveTo", "open", "openDialog", "postMessage", "print",
+    "prompt", "QueryInterface", "releaseEvents", "removeEventListener",
+    "resizeBy", "resizeTo", "restore", "routeEvent", "scroll", "scrollBy",
+    "scrollByLines", "scrollByPages", "scrollTo", "setInterval",
+    "setResizeable", "setTimeout", "showModalDialog", "sizeToContent",
+    "stop", "uuescape", "updateCommands", "XPCNativeWrapper",
+    "XPCSafeJSOjbectWrapper",
+
+    // Mozilla Window event handlers, same cite
+    "onabort", "onbeforeunload", "onchange", "onclick", "onclose",
+    "oncontextmenu", "ondragdrop", "onerror", "onfocus", "onhashchange",
+    "onkeydown", "onkeypress", "onkeyup", "onload", "onmousedown",
+    "onmousemove", "onmouseout", "onmouseover", "onmouseup",
+    "onmozorientation", "onpaint", "onreset", "onresize", "onscroll",
+    "onselect", "onsubmit", "onunload",
+
+    // Safari Web Content Guide
+    // http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/SafariWebContent.pdf
+    // WebKit Window member data, from WebKit DOM Reference
+    // (http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/DOMWindow_idl/Classes/DOMWindow/index.html)
+    "ontouchcancel", "ontouchend", "ontouchmove", "ontouchstart",
+    "ongesturestart", "ongesturechange", "ongestureend",
+
+    // extra window methods
+    "uneval",
+
+    // keywords https://developer.mozilla.org/en/New_in_JavaScript_1.7,
+    // https://developer.mozilla.org/en/New_in_JavaScript_1.8.1
+    "getPrototypeOf", "let", "yield",
+
+    // "future reserved words"
+    "abstract", "int", "short", "boolean", "interface", "static", "byte",
+    "long", "char", "final", "native", "synchronized", "float", "package",
+    "throws", "goto", "private", "transient", "implements", "protected",
+    "volatile", "double", "public",
+
+    // IE methods
+    // (http://msdn.microsoft.com/en-us/library/ms535873(VS.85).aspx#)
+    "attachEvent", "clientInformation", "clipboardData", "createPopup",
+    "dialogHeight", "dialogLeft", "dialogTop", "dialogWidth",
+    "onafterprint", "onbeforedeactivate", "onbeforeprint",
+    "oncontrolselect", "ondeactivate", "onhelp", "onresizeend",
+
+    // Common browser-defined identifiers not defined in ECMAScript
+    "event", "external", "Debug", "Enumerator", "Global", "Image",
+    "ActiveXObject", "VBArray", "Components",
+
+    // Functions commonly defined on Object
+    "toString", "getClass", "constructor", "prototype", "valueOf",
+
+    // Client-side JavaScript identifiers
+    "Anchor", "Applet", "Attr", "Canvas", "CanvasGradient",
+    "CanvasPattern", "CanvasRenderingContext2D", "CDATASection",
+    "CharacterData", "Comment", "CSS2Properties", "CSSRule",
+    "CSSStyleSheet", "Document", "DocumentFragment", "DocumentType",
+    "DOMException", "DOMImplementation", "DOMParser", "Element", "Event",
+    "ExternalInterface", "FlashPlayer", "Form", "Frame", "History",
+    "HTMLCollection", "HTMLDocument", "HTMLElement", "IFrame", "Image",
+    "Input", "JSObject", "KeyEvent", "Link", "Location", "MimeType",
+    "MouseEvent", "Navigator", "Node", "NodeList", "Option", "Plugin",
+    "ProcessingInstruction", "Range", "RangeException", "Screen", "Select",
+    "Table", "TableCell", "TableRow", "TableSelection", "Text", "TextArea",
+    "UIEvent", "Window", "XMLHttpRequest", "XMLSerializer",
+    "XPathException", "XPathResult", "XSLTProcessor",
+
+    // These keywords trigger the loading of the java-plugin. For the
+    // next-generation plugin, this results in starting a new Java process.
+    "java", "Packages", "netscape", "sun", "JavaObject", "JavaClass",
+    "JavaArray", "JavaMember"
+  ];
+
+  Set<String> _jsReserved = null;
+  /// Names that cannot be used by members, top level and static
+  /// methods.
   Set<String> get jsReserved {
     if (_jsReserved == null) {
       _jsReserved = new Set<String>();
@@ -37,6 +160,18 @@
     return _jsReserved;
   }
 
+  Set<String> _jsVariableReserved = null;
+  /// Names that cannot be used by local variables and parameters.
+  Set<String> get jsVariableReserved {
+    if (_jsVariableReserved == null) {
+      _jsVariableReserved = new Set<String>();
+      _jsVariableReserved.addAll(javaScriptKeywords);
+      _jsVariableReserved.addAll(reservedPropertySymbols);
+      _jsVariableReserved.addAll(reservedGlobalSymbols);
+    }
+    return _jsVariableReserved;
+  }
+
   final String CURRENT_ISOLATE = r'$';
 
   /**
@@ -532,14 +667,17 @@
    * Returns a name that does not clash with reserved JS keywords,
    * and also ensures it won't clash with other identifiers.
    */
-  String safeName(String name) {
-    if (jsReserved.contains(name) || name.startsWith(r'$')) {
+  String _safeName(String name, Set<String> reserved) {
+    if (reserved.contains(name) || name.startsWith(r'$')) {
       name = '\$$name';
     }
-    assert(!jsReserved.contains(name));
+    assert(!reserved.contains(name));
     return name;
   }
 
+  String safeName(String name) => _safeName(name, jsReserved);
+  String safeVariableName(String name) => _safeName(name, jsVariableReserved);
+
   String oneShotInterceptorName(Selector selector) {
     // TODO(ngeoffray): What to do about typed selectors? We could
     // filter them out, or keep them and hope the generated one shot
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 4345861..9400f5f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/native_emitter.dart
@@ -161,7 +161,7 @@
         compiler.findHelper(const SourceString('convertDartClosureToJS'));
     String closureConverter = backend.namer.isolateAccess(converter);
     Set<String> stubParameterNames = new Set<String>.from(
-        stubParameters.mappedBy((param) => param.name));
+        stubParameters.map((param) => param.name));
     parameters.forEachParameter((Element parameter) {
       String name = parameter.name.slowToString();
       // If [name] is not in [stubParameters], then the parameter is an optional
@@ -255,7 +255,7 @@
             js.use('Object').dot('prototype').dot(methodName).dot('call')
             .callWith(
                 <js.Expression>[js.use('this')]..addAll(
-                    parameters.mappedBy((param) => js.use(param.name))))));
+                    parameters.map((param) => js.use(param.name))))));
   }
 
   js.Block generateMethodBodyWithPrototypeCheckForElement(
@@ -406,7 +406,7 @@
       //   [['Node', 'Text|HTMLElement|HTMLDivElement|...'], ...]
       js.Expression table =
           new js.ArrayInitializer.from(
-              preorderDispatchClasses.mappedBy((cls) =>
+              preorderDispatchClasses.map((cls) =>
                   new js.ArrayInitializer.from([
                       js.string(toNativeTag(cls)),
                       tagDefns[cls]])));
diff --git a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
index 625e0ed..75446c7 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
@@ -35,8 +35,7 @@
   }
 
   Iterable<V> get values {
-    // TODO(floitsch): don't wrap the map twice.
-    return keys.mappedBy((String key) => this[key]);
+    return _keys.map((String key) => this[key]);
   }
 
   bool get isEmpty => length == 0;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 4297edb..8d68c8d 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -14,13 +14,8 @@
                               stringJoinUnchecked,
                               JsStringBuffer;
 
-// Patch for 'print' function.
 patch void print(var object) {
-  if (object is String) {
-    Primitives.printString(object);
-  } else {
-    Primitives.printString(object.toString());
-  }
+  Primitives.printString(object.toString());
 }
 
 // Patch for Object implementation.
@@ -194,25 +189,6 @@
     }
     return result;
   }
-
-  /**
-   * Creates an extendable list of the given [length] where each entry is
-   * filled with [fill].
-   */
-  patch factory List.filled(int length, E fill) {
-    // Explicit type test is necessary to protect Primitives.newGrowableList in
-    // unchecked mode.
-    if ((length is !int) || (length < 0)) {
-      throw new ArgumentError("Length must be a positive integer: $length.");
-    }
-    List result = Primitives.newGrowableList(length);
-    if (length != 0 && fill != null) {
-      for (int i = 0; i < result.length; i++) {
-        result[i] = fill;
-      }
-    }
-    return result;
-  }
 }
 
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index 654edc0..3491591 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -84,6 +84,10 @@
     return IterableMixinWorkaround.forEach(this, f);
   }
 
+  Iterable map(f(E element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(E element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -97,7 +101,7 @@
     return JS('String', "#.join(#)", list, separator);
   }
 
-  List<E> take(int n) {
+  Iterable<E> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -105,7 +109,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<E> skip(int n) {
+  Iterable<E> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -222,7 +226,7 @@
 
   bool every(bool f(E element)) => IterableMixinWorkaround.every(this, f);
 
-  List<E> get reversed => new ReversedListView<E>(this, 0, null);
+  List<E> get reversed => IterableMixinWorkaround.reversedList(this);
 
   void sort([int compare(E a, E b)]) {
     checkMutable(this, 'sort');
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index 1014f04..2c80eaa 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -5,7 +5,6 @@
 library _js_helper;
 
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:_foreign_helper' show DART_CLOSURE_TO_JS,
                                    JS,
                                    JS_CALL_IN_ISOLATE,
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 39c084d..074cece 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -319,12 +319,12 @@
         Uri uri = library.entryCompilationUnit.script.uri;
         compiler.reportMessage(
             compiler.spanFromSpannable(tag.name, uri),
-            MessageKind.DUPLICATED_LIBRARY_NAME.error([name]),
+            MessageKind.DUPLICATED_LIBRARY_NAME.error({'libraryName': name}),
             api.Diagnostic.WARNING);
         Uri existingUri = existing.entryCompilationUnit.script.uri;
         compiler.reportMessage(
             compiler.spanFromSpannable(existing.libraryTag.name, existingUri),
-            MessageKind.DUPLICATED_LIBRARY_NAME.error([name]),
+            MessageKind.DUPLICATED_LIBRARY_NAME.error({'libraryName': name}),
             api.Diagnostic.WARNING);
       }
     }
@@ -374,7 +374,7 @@
         if (wasDiagnosticEmitted) {
           compiler.reportMessage(
               compiler.spanFromElement(unit),
-              MessageKind.MISSING_PART_OF_TAG.error([]),
+              MessageKind.MISSING_PART_OF_TAG.error(),
               api.Diagnostic.INFO);
         }
       }
@@ -675,17 +675,17 @@
     Element existingElement = exportScope[name];
     if (existingElement != null) {
       if (existingElement.isErroneous()) {
-        compiler.reportMessage(compiler.spanFromElement(element),
-            MessageKind.DUPLICATE_EXPORT.error([name]), api.Diagnostic.ERROR);
+        compiler.reportErrorCode(element, MessageKind.DUPLICATE_EXPORT,
+                                 {'name': name});
         element = existingElement;
       } else if (existingElement.getLibrary() != library) {
         // Declared elements hide exported elements.
-        compiler.reportMessage(compiler.spanFromElement(existingElement),
-            MessageKind.DUPLICATE_EXPORT.error([name]), api.Diagnostic.ERROR);
-        compiler.reportMessage(compiler.spanFromElement(element),
-            MessageKind.DUPLICATE_EXPORT.error([name]), api.Diagnostic.ERROR);
+        compiler.reportErrorCode(existingElement, MessageKind.DUPLICATE_EXPORT,
+                                 {'name': name});
+        compiler.reportErrorCode(element, MessageKind.DUPLICATE_EXPORT,
+                                 {'name': name});
         element = exportScope[name] = new ErroneousElementX(
-            MessageKind.DUPLICATE_EXPORT, [name], name, library);
+            MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
       }
     } else {
       exportScope[name] = element;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 8f8689d..ea9b593 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -16,6 +16,7 @@
 import '../scanner/scannerlib.dart' hide SourceString;
 import '../ssa/ssa.dart';
 import '../dart2jslib.dart';
+import '../dart_types.dart';
 import '../filenames.dart';
 import '../source_file.dart';
 import '../tree/tree.dart';
@@ -248,7 +249,7 @@
                   diagnostics.DiagnosticHandler handler,
                   Uri libraryRoot, Uri packageRoot,
                   List<String> options)
-      : super(provider, handler, libraryRoot, packageRoot, options) {
+      : super(provider, null, handler, libraryRoot, packageRoot, options) {
     checker = new LibraryTypeCheckerTask(this);
     resolver = new LibraryResolverTask(this);
   }
@@ -389,7 +390,7 @@
     } else {
       packageUri = libraryUri;
     }
-    _compiler = new api.Compiler(provider, handler,
+    _compiler = new api.Compiler(provider, null, handler,
         libraryUri, packageUri, opts);
     var scriptUri = cwd.resolve(script.toString());
     // TODO(johnniwinther): Detect file not found
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index ccef7f0..933e96d 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -7,6 +7,7 @@
 import 'dart:collection' show Queue;
 import 'dart:uri';
 import 'dart2jslib.dart' hide SourceString;
+import 'dart_types.dart';
 import 'elements/elements.dart';
 import 'js_backend/js_backend.dart';
 import 'resolution/resolution.dart' show ResolverVisitor;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index a8fa300..bc90813 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -154,8 +154,10 @@
           patchParameter.parseNode(compiler).toString();
       if (originParameterText != patchParameterText) {
         error(originParameter.parseNode(compiler),
-            MessageKind.PATCH_PARAMETER_MISMATCH,
-            [origin.name, originParameterText, patchParameterText]);
+              MessageKind.PATCH_PARAMETER_MISMATCH,
+              {'methodName': origin.name,
+               'originParameter': originParameterText,
+               'patchParameter': patchParameterText});
       }
 
       originParameters = originParameters.tail;
@@ -183,8 +185,10 @@
       compiler.withCurrentElement(patch, () {
         Node errorNode =
             patchTree.returnType != null ? patchTree.returnType : patchTree;
-        error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH, [origin.name,
-              originSignature.returnType, patchSignature.returnType]);
+        error(errorNode, MessageKind.PATCH_RETURN_TYPE_MISMATCH,
+              {'methodName': origin.name,
+               'originReturnType': originSignature.returnType,
+               'patchReturnType': patchSignature.returnType});
       });
     }
     if (originSignature.requiredParameterCount !=
@@ -192,8 +196,9 @@
       compiler.withCurrentElement(patch, () {
         error(patchTree,
               MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
-              [origin.name, originSignature.requiredParameterCount,
-               patchSignature.requiredParameterCount]);
+              {'methodName': origin.name,
+               'originParameterCount': originSignature.requiredParameterCount,
+               'patchParameterCount': patchSignature.requiredParameterCount});
       });
     } else {
       checkMatchingPatchParameters(origin,
@@ -206,8 +211,8 @@
           patchSignature.optionalParametersAreNamed) {
         compiler.withCurrentElement(patch, () {
           error(patchTree,
-              MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
-              [origin.name]);
+                MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
+                {'methodName': origin.name});
         });
       }
     }
@@ -216,8 +221,9 @@
       compiler.withCurrentElement(patch, () {
         error(patchTree,
               MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
-              [origin.name, originSignature.optionalParameterCount,
-               patchSignature.optionalParameterCount]);
+              {'methodName': origin.name,
+               'originParameterCount': originSignature.optionalParameterCount,
+               'patchParameterCount': patchSignature.optionalParameterCount});
       });
     } else {
       checkMatchingPatchParameters(origin,
@@ -243,6 +249,10 @@
       }
       return compiler.withCurrentElement(element, () {
         FunctionExpression tree = element.parseNode(compiler);
+        if (tree.modifiers.isExternal()) {
+          error(tree, MessageKind.EXTERNAL_WITHOUT_IMPLEMENTATION);
+          return;
+        }
         if (isConstructor) {
           if (tree.returnType != null) {
             error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
@@ -307,7 +317,8 @@
     if (!intrface.isInterface()) return;
     DartType defaultType = intrface.defaultClass;
     if (defaultType == null) {
-      error(node, MessageKind.NO_DEFAULT_CLASS, [intrface.name]);
+      error(node, MessageKind.NO_DEFAULT_CLASS,
+            {'interfaceName': intrface.name});
     }
     ClassElement defaultClass = defaultType.element;
     defaultClass.ensureResolved(compiler);
@@ -315,7 +326,7 @@
     assert(defaultClass.supertypeLoadState == STATE_DONE);
     if (defaultClass.isInterface()) {
       error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
-            [defaultClass.name]);
+            {'interfaceName': defaultClass.name});
     }
     // We have now established the following:
     // [intrface] is an interface, let's say "MyInterface".
@@ -356,7 +367,7 @@
       // the error message below.
       error(node,
             MessageKind.CANNOT_FIND_CONSTRUCTOR2,
-            [selector.name, defaultClass.name]);
+            {'constructorName': selector.name, 'className': defaultClass.name});
     }
   }
 
@@ -410,10 +421,8 @@
     compiler.withCurrentElement(cls, () => measure(() {
       if (cls.supertypeLoadState == STATE_DONE) return;
       if (cls.supertypeLoadState == STATE_STARTED) {
-        compiler.reportMessage(
-          compiler.spanFromSpannable(from),
-          MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]),
-          Diagnostic.ERROR);
+        compiler.reportErrorCode(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
+                                 {'className': cls.name});
         cls.supertypeLoadState = STATE_DONE;
         cls.allSupertypes = const Link<DartType>().prepend(
             compiler.objectClass.computeType(compiler));
@@ -522,11 +531,10 @@
     int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
     if (illegalFlags != 0) {
       Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
-      CompilationError error =
-          MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS.error(
-              [illegalModifiers]);
-      compiler.reportMessage(compiler.spanFromSpannable(modifiers),
-                             error, Diagnostic.ERROR);
+      compiler.reportErrorCode(
+          modifiers,
+          MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
+          {'modifiers': illegalModifiers});
     }
 
     // In case of cyclic mixin applications, the mixin chain will have
@@ -537,18 +545,14 @@
 
     // Check that the mixed in class has Object as its superclass.
     if (!mixin.superclass.isObject(compiler)) {
-      CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPERCLASS.error();
-      compiler.reportMessage(compiler.spanFromElement(mixin),
-                             error, Diagnostic.ERROR);
+      compiler.reportErrorCode(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
     }
 
     // Check that the mixed in class doesn't have any constructors and
     // make sure we aren't mixing in methods that use 'super'.
     mixin.forEachLocalMember((Element member) {
       if (member.isGenerativeConstructor() && !member.isSynthesized) {
-        CompilationError error = MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR.error();
-        compiler.reportMessage(compiler.spanFromElement(member),
-                               error, Diagnostic.ERROR);
+        compiler.reportErrorCode(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
       } else {
         // Get the resolution tree and check that the resolved member
         // doesn't use 'super'. This is the part of the 'super' mixin
@@ -568,10 +572,9 @@
     if (resolutionTree == null) return;
     Set<Node> superUses = resolutionTree.superUses;
     if (superUses.isEmpty) return;
-    CompilationError error = MessageKind.ILLEGAL_MIXIN_WITH_SUPER.error(
-        [mixin.name]);
-    compiler.reportMessage(compiler.spanFromElement(mixinApplication),
-                           error, Diagnostic.ERROR);
+    compiler.reportErrorCode(mixinApplication,
+                             MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
+                             {'className': mixin.name});
     // Show the user the problematic uses of 'super' in the mixin.
     for (Node use in superUses) {
       CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPER_USE.error();
@@ -592,10 +595,8 @@
 
         // Check modifiers.
         if (member.isFunction() && member.modifiers.isFinal()) {
-          compiler.reportMessage(
-              compiler.spanFromElement(member),
-              MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(),
-              Diagnostic.ERROR);
+          compiler.reportErrorCode(
+              member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
         }
         if (member.isConstructor()) {
           final mismatchedFlagsBits =
@@ -604,11 +605,10 @@
           if (mismatchedFlagsBits != 0) {
             final mismatchedFlags =
                 new Modifiers.withFlags(null, mismatchedFlagsBits);
-            compiler.reportMessage(
-                compiler.spanFromElement(member),
-                MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS.error(
-                    [mismatchedFlags]),
-                Diagnostic.ERROR);
+            compiler.reportErrorCode(
+                member,
+                MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
+                {'modifiers': mismatchedFlags});
           }
           checkConstructorNameHack(holder, member);
         }
@@ -641,8 +641,8 @@
       if (compiler.onDeprecatedFeature(member, 'conflicting constructor')) {
         compiler.reportMessage(
             compiler.spanFromElement(otherMember),
-            MessageKind.GENERIC.error(['This member conflicts with a'
-                                       ' constructor.']),
+            MessageKind.GENERIC.error({'text': 'This member conflicts with a'
+                                               ' constructor.'}),
             Diagnostic.INFO);
       }
     }
@@ -673,14 +673,14 @@
     if (!identical(getterFlags, setterFlags)) {
       final mismatchedFlags =
         new Modifiers.withFlags(null, getterFlags ^ setterFlags);
-      compiler.reportMessage(
-          compiler.spanFromElement(field.getter),
-          MessageKind.GETTER_MISMATCH.error([mismatchedFlags]),
-          Diagnostic.ERROR);
-      compiler.reportMessage(
-          compiler.spanFromElement(field.setter),
-          MessageKind.SETTER_MISMATCH.error([mismatchedFlags]),
-          Diagnostic.ERROR);
+      compiler.reportErrorCode(
+          field.getter,
+          MessageKind.GETTER_MISMATCH,
+          {'modifiers': mismatchedFlags});
+      compiler.reportErrorCode(
+          field.setter,
+          MessageKind.SETTER_MISMATCH,
+          {'modifiers': mismatchedFlags});
     }
   }
 
@@ -729,24 +729,22 @@
           errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
         }
       }
-      compiler.reportMessage(
-          compiler.spanFromSpannable(errorNode),
-          messageKind.error([function.name]),
-          Diagnostic.ERROR);
+      compiler.reportErrorCode(
+          errorNode, messageKind, {'operatorName': function.name});
     }
     if (signature.optionalParameterCount != 0) {
       Node errorNode =
           node.parameters.nodes.skip(signature.requiredParameterCount).head;
       if (signature.optionalParametersAreNamed) {
-        compiler.reportMessage(
-            compiler.spanFromSpannable(errorNode),
-            MessageKind.OPERATOR_NAMED_PARAMETERS.error([function.name]),
-            Diagnostic.ERROR);
+        compiler.reportErrorCode(
+            errorNode,
+            MessageKind.OPERATOR_NAMED_PARAMETERS,
+            {'operatorName': function.name});
       } else {
-        compiler.reportMessage(
-            compiler.spanFromSpannable(errorNode),
-            MessageKind.OPERATOR_OPTIONAL_PARAMETERS.error([function.name]),
-            Diagnostic.ERROR);
+        compiler.reportErrorCode(
+            errorNode,
+            MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
+            {'operatorName': function.name});
       }
     }
   }
@@ -755,11 +753,11 @@
                          MessageKind errorMessage,
                          Element contextElement,
                          MessageKind contextMessage) {
-    compiler.reportMessage(
-        compiler.spanFromElement(errorneousElement),
-        errorMessage.error([contextElement.name,
-                            contextElement.getEnclosingClass().name]),
-        Diagnostic.ERROR);
+    compiler.reportErrorCode(
+        errorneousElement,
+        errorMessage,
+        {'memberName': contextElement.name,
+         'className': contextElement.getEnclosingClass().name});
     compiler.reportMessage(
         compiler.spanFromElement(contextElement),
         contextMessage.error(),
@@ -840,16 +838,35 @@
 
   FunctionType computeFunctionType(Element element,
                                    FunctionSignature signature) {
-    LinkBuilder<DartType> parameterTypes = new LinkBuilder<DartType>();
-    for (Link<Element> link = signature.requiredParameters;
-         !link.isEmpty;
-         link = link.tail) {
-       parameterTypes.addLast(link.head.computeType(compiler));
-       // TODO(karlklose): optional parameters.
+    var parameterTypes = new LinkBuilder<DartType>();
+    for (Element parameter in signature.requiredParameters) {
+       parameterTypes.addLast(parameter.computeType(compiler));
     }
-    return new FunctionType(signature.returnType,
-                            parameterTypes.toLink(),
-                            element);
+    var optionalParameterTypes = const Link<DartType>();
+    var namedParameters = const Link<SourceString>();
+    var namedParameterTypes = const Link<DartType>();
+    if (signature.optionalParametersAreNamed) {
+      var namedParametersBuilder = new LinkBuilder<SourceString>();
+      var namedParameterTypesBuilder = new LinkBuilder<DartType>();
+      for (Element parameter in signature.orderedOptionalParameters) {
+        namedParametersBuilder.addLast(parameter.name);
+        namedParameterTypesBuilder.addLast(parameter.computeType(compiler));
+      }
+      namedParameters = namedParametersBuilder.toLink();
+      namedParameterTypes = namedParameterTypesBuilder.toLink();
+    } else {
+      var optionalParameterTypesBuilder = new LinkBuilder<DartType>();
+      for (Element parameter in signature.optionalParameters) {
+        optionalParameterTypesBuilder.addLast(parameter.computeType(compiler));
+      }
+      optionalParameterTypes = optionalParameterTypesBuilder.toLink();
+    }
+    return new FunctionType(element,
+        signature.returnType,
+        parameterTypes.toLink(),
+        optionalParameterTypes,
+        namedParameters,
+        namedParameterTypes);
   }
 
   void resolveMetadataAnnotation(PartialMetadataAnnotation annotation) {
@@ -868,7 +885,7 @@
     }));
   }
 
-  error(Node node, MessageKind kind, [arguments = const []]) {
+  error(Node node, MessageKind kind, [arguments = const {}]) {
     ResolutionError message = new ResolutionError(kind, arguments);
     compiler.reportError(node, message);
   }
@@ -883,11 +900,11 @@
   InitializerResolver(this.visitor)
     : initialized = new Map<SourceString, Node>(), hasSuper = false;
 
-  error(Node node, MessageKind kind, [arguments = const []]) {
+  error(Node node, MessageKind kind, [arguments = const {}]) {
     visitor.error(node, kind, arguments);
   }
 
-  warning(Node node, MessageKind kind, [arguments = const []]) {
+  warning(Node node, MessageKind kind, [arguments = const {}]) {
     visitor.warning(node, kind, arguments);
   }
 
@@ -900,8 +917,9 @@
 
   void checkForDuplicateInitializers(SourceString name, Node init) {
     if (initialized.containsKey(name)) {
-      error(init, MessageKind.DUPLICATE_INITIALIZER, [name]);
-      warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]);
+      error(init, MessageKind.DUPLICATE_INITIALIZER, {'fieldName': name});
+      warning(initialized[name], MessageKind.ALREADY_INITIALIZED,
+              {'fieldName': name});
     }
     initialized[name] = init;
   }
@@ -915,11 +933,11 @@
     if (isFieldInitializer(init)) {
       target = constructor.getEnclosingClass().lookupLocalMember(name);
       if (target == null) {
-        error(selector, MessageKind.CANNOT_RESOLVE, [name]);
+        error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
       } else if (target.kind != ElementKind.FIELD) {
-        error(selector, MessageKind.NOT_A_FIELD, [name]);
+        error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
       } else if (!target.isInstanceMember()) {
-        error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
+        error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
       }
     } else {
       error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
@@ -1032,7 +1050,7 @@
       MessageKind kind = isImplicitSuperCall
           ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
           : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
-      error(diagnosticNode, kind, [fullConstructorName]);
+      error(diagnosticNode, kind, {'constructorName': fullConstructorName});
     } else {
       if (!call.applies(lookedupConstructor, visitor.compiler)) {
         MessageKind kind = isImplicitSuperCall
@@ -1131,12 +1149,12 @@
   /** Convenience method for visiting nodes that may be null. */
   R visit(Node node) => (node == null) ? null : node.accept(this);
 
-  void error(Node node, MessageKind kind, [arguments = const []]) {
+  void error(Node node, MessageKind kind, [Map arguments = const {}]) {
     ResolutionError message  = new ResolutionError(kind, arguments);
     compiler.reportError(node, message);
   }
 
-  void warning(Node node, MessageKind kind, [arguments = const []]) {
+  void warning(Node node, MessageKind kind, [Map arguments = const {}]) {
     ResolutionWarning message  = new ResolutionWarning(kind, arguments);
     compiler.reportWarning(node, message);
   }
@@ -1296,7 +1314,7 @@
       TypeAnnotation node,
       Scope scope,
       Element enclosingElement,
-      {onFailure(Node node, MessageKind kind, [List arguments]),
+      {onFailure(Node node, MessageKind kind, [Map arguments]),
        whenResolved(Node node, DartType type)}) {
     if (onFailure == null) {
       onFailure = (n, k, [arguments]) {};
@@ -1329,7 +1347,7 @@
     DartType type;
 
     DartType reportFailureAndCreateType(MessageKind messageKind,
-                                        List messageArguments) {
+                                        Map messageArguments) {
       onFailure(node, messageKind, messageArguments);
       var erroneousElement = new ErroneousElementX(
           messageKind, messageArguments, typeName.source, enclosingElement);
@@ -1348,7 +1366,7 @@
       if (hashTypeArgumentMismatch) {
         type = new MalformedType(
             new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-                [node], typeName.source, enclosingElement),
+                {'type': node}, typeName.source, enclosingElement),
                 type, arguments.toLink());
       }
       return type;
@@ -1356,14 +1374,14 @@
 
     if (element == null) {
       type = reportFailureAndCreateType(
-          MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]);
+          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
     } else if (element.isAmbiguous()) {
       AmbiguousElement ambiguous = element;
       type = reportFailureAndCreateType(
           ambiguous.messageKind, ambiguous.messageArguments);
     } else if (!element.impliesType()) {
       type = reportFailureAndCreateType(
-          MessageKind.NOT_A_TYPE, [node.typeName]);
+          MessageKind.NOT_A_TYPE, {'node': node.typeName});
     } else {
       if (identical(element, compiler.types.voidType.element) ||
           identical(element, compiler.types.dynamicType.element)) {
@@ -1379,7 +1397,7 @@
         if (hashTypeArgumentMismatch) {
           type = new MalformedType(
               new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-                  [node], typeName.source, enclosingElement),
+                  {'type': node}, typeName.source, enclosingElement),
               new InterfaceType(cls.declaration, arguments.toLink()));
         } else {
           if (arguments.isEmpty) {
@@ -1399,7 +1417,7 @@
         if (hashTypeArgumentMismatch) {
           type = new MalformedType(
               new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-                  [node], typeName.source, enclosingElement),
+                  {'type': node}, typeName.source, enclosingElement),
               new TypedefType(typdef, arguments.toLink()));
         } else {
           if (arguments.isEmpty) {
@@ -1412,11 +1430,12 @@
         if (enclosingElement.isInStaticMember()) {
           compiler.reportWarning(node,
               MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
-                  [node]));
+                  {'typeVariableName': node}));
           type = new MalformedType(
               new ErroneousElementX(
                   MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-                  [node], typeName.source, enclosingElement),
+                  {'typeVariableName': node},
+                  typeName.source, enclosingElement),
                   element.computeType(compiler));
         } else {
           type = element.computeType(compiler);
@@ -1516,20 +1535,18 @@
     Element result = scope.lookup(name);
     if (!Elements.isUnresolved(result)) {
       if (!inInstanceContext && result.isInstanceMember()) {
-        compiler.reportMessage(compiler.spanFromSpannable(node),
-            MessageKind.NO_INSTANCE_AVAILABLE.error([name]),
-            Diagnostic.ERROR);
+        compiler.reportErrorCode(
+            node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
         return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
-                                    [name],
-                                    name, enclosingElement);
+                                     {'name': name},
+                                     name, enclosingElement);
       } else if (result.isAmbiguous()) {
         AmbiguousElement ambiguous = result;
-        compiler.reportMessage(compiler.spanFromSpannable(node),
-            ambiguous.messageKind.error(ambiguous.messageArguments),
-            Diagnostic.ERROR);
+        compiler.reportErrorCode(
+            node, ambiguous.messageKind, ambiguous.messageArguments);
         return new ErroneousElementX(ambiguous.messageKind,
-                                    ambiguous.messageArguments,
-                                    name, enclosingElement);
+                                     ambiguous.messageArguments,
+                                     name, enclosingElement);
       }
     }
     return result;
@@ -1570,7 +1587,7 @@
   ErroneousElement warnAndCreateErroneousElement(Node node,
                                                  SourceString name,
                                                  MessageKind kind,
-                                                 List<Node> arguments) {
+                                                 [Map arguments = const {}]) {
     ResolutionWarning warning = new ResolutionWarning(kind, arguments);
     compiler.reportWarning(node, warning);
     return new ErroneousElementX(kind, arguments, name, enclosingElement);
@@ -1579,7 +1596,7 @@
   Element visitIdentifier(Identifier node) {
     if (node.isThis()) {
       if (!inInstanceContext) {
-        error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
+        error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
       }
       return null;
     } else if (node.isSuper()) {
@@ -1594,14 +1611,15 @@
         if (!inInstanceContext) {
           element = warnAndCreateErroneousElement(node, node.source,
                                                   MessageKind.CANNOT_RESOLVE,
-                                                  [node]);
+                                                  {'name': node});
         }
       } else if (element.isErroneous()) {
         // Use the erroneous element.
       } else {
         if ((element.kind.category & allowedCategory) == 0) {
           // TODO(ahe): Improve error message. Need UX input.
-          error(node, MessageKind.GENERIC, ["is not an expression $element"]);
+          error(node, MessageKind.GENERIC,
+                {'text': "is not an expression $element"});
         }
       }
       if (!Elements.isUnresolved(element)
@@ -1631,7 +1649,7 @@
     if (doAddToScope) {
       Element existing = scope.add(element);
       if (existing != element) {
-        error(node, MessageKind.DUPLICATE_DEFINITION, [node]);
+        error(node, MessageKind.DUPLICATE_DEFINITION, {'name': node});
       }
     }
     return element;
@@ -1829,11 +1847,11 @@
         if (selector.argumentCount != 1) {
           error(node.selector,
                 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
-                [selector.argumentCount]);
+                {'argumentCount': selector.argumentCount});
         } else if (selector.namedArgumentCount != 0) {
           error(node.selector,
                 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
-                [selector.namedArgumentCount]);
+                {'argumentCount': selector.namedArgumentCount});
         }
         return compiler.assertMethod;
       }
@@ -1849,23 +1867,25 @@
     Element target;
     SourceString name = node.selector.asIdentifier().source;
     if (identical(name.stringValue, 'this')) {
-      error(node.selector, MessageKind.GENERIC, ["expected an identifier"]);
+      error(node.selector, MessageKind.GENERIC,
+            {'text': "expected an identifier"});
     } else if (node.isSuperCall) {
       if (node.isOperator) {
         if (isUserDefinableOperator(name.stringValue)) {
           name = selector.name;
         } else {
-          error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, [name]);
+          error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name});
         }
       }
       if (!inInstanceContext) {
-        error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]);
+        error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
         return null;
       }
       if (currentClass.supertype == null) {
         // This is just to guard against internal errors, so no need
         // for a real error message.
-        error(node.receiver, MessageKind.GENERIC, ["Object has no superclass"]);
+        error(node.receiver, MessageKind.GENERIC,
+              {'text': "Object has no superclass"});
       }
       // TODO(johnniwinther): Ensure correct behavior if currentClass is a
       // patch.
@@ -1897,9 +1917,12 @@
         // setters.
         return warnAndCreateErroneousElement(node, name,
                                              MessageKind.METHOD_NOT_FOUND,
-                                             [receiverClass.name, name]);
+                                             {'className': receiverClass.name,
+                                              'methodName': name});
       } else if (target.isInstanceMember()) {
-        error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]);
+        error(node, MessageKind.MEMBER_NOT_STATIC,
+              {'className': receiverClass.name,
+               'memberName': name});
       }
     } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) {
       PrefixElement prefix = resolvedReceiver;
@@ -1907,7 +1930,7 @@
       if (Elements.isUnresolved(target)) {
         return warnAndCreateErroneousElement(
             node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER,
-            [prefix.name, name]);
+            {'libraryName': prefix.name, 'memberName': name});
       } else if (target.kind == ElementKind.CLASS) {
         ClassElement classElement = target;
         classElement.ensureResolved(compiler);
@@ -1999,7 +2022,7 @@
         SourceString source = namedArgument.name.source;
         if (seenNamedArguments.contains(source)) {
           error(argument, MessageKind.DUPLICATE_DEFINITION,
-                [source.slowToString()]);
+                {'name': source});
         }
         seenNamedArguments.add(source);
       } else if (!seenNamedArguments.isEmpty) {
@@ -2017,8 +2040,7 @@
       if (target == null && !inInstanceContext) {
         target =
             warnAndCreateErroneousElement(node.selector, field.name,
-                                          MessageKind.CANNOT_RESOLVE_GETTER,
-                                          [node.selector]);
+                                          MessageKind.CANNOT_RESOLVE_GETTER);
       }
     }
 
@@ -2091,7 +2113,7 @@
     // TODO(karlklose): we can be more precise about the reason of the
     // mismatch.
     warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS,
-            [target.name]);
+            {'methodName': target.name});
   }
 
   /// Callback for native enqueuer to parse a type.  Returns [:null:] on error.
@@ -2118,14 +2140,12 @@
       if (setter == null && !inInstanceContext) {
         setter =
             warnAndCreateErroneousElement(node.selector, field.name,
-                                          MessageKind.CANNOT_RESOLVE_SETTER,
-                                          [node.selector]);
+                                          MessageKind.CANNOT_RESOLVE_SETTER);
       }
       if (isComplex && getter == null && !inInstanceContext) {
         getter =
             warnAndCreateErroneousElement(node.selector, field.name,
-                                          MessageKind.CANNOT_RESOLVE_GETTER,
-                                          [node.selector]);
+                                          MessageKind.CANNOT_RESOLVE_GETTER);
       }
     }
 
@@ -2238,14 +2258,10 @@
 
   void handleRedirectingFactoryBody(Return node) {
     if (!enclosingElement.isFactoryConstructor()) {
-      compiler.reportMessage(
-          compiler.spanFromSpannable(node),
-          MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY.error([]),
-          Diagnostic.ERROR);
-      compiler.reportMessage(
-          compiler.spanFromSpannable(enclosingElement),
-          MessageKind.MISSING_FACTORY_KEYWORD.error([]),
-          Diagnostic.INFO);
+      compiler.reportErrorCode(
+          node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
+      compiler.reportErrorCode(
+          enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
     }
     Element redirectionTarget = resolveRedirectingFactory(node);
     var type = mapping.getType(node.expression);
@@ -2420,11 +2436,11 @@
     if (arguments != null) {
       Link<Node> nodes = arguments.nodes;
       if (nodes.isEmpty) {
-        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT, []);
+        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
       } else {
         resolveTypeRequired(nodes.head);
         for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-          error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT, []);
+          error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
           resolveTypeRequired(nodes.head);
         }
       }
@@ -2459,12 +2475,12 @@
       String labelName = node.target.source.slowToString();
       LabelElement label = statementScope.lookupLabel(labelName);
       if (label == null) {
-        error(node.target, MessageKind.UNBOUND_LABEL, [labelName]);
+        error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
         return;
       }
       target = label.target;
       if (!target.statement.isValidBreakTarget()) {
-        error(node.target, MessageKind.INVALID_BREAK, [labelName]);
+        error(node.target, MessageKind.INVALID_BREAK);
         return;
       }
       label.setBreakTarget();
@@ -2492,12 +2508,12 @@
       String labelName = node.target.source.slowToString();
       LabelElement label = statementScope.lookupLabel(labelName);
       if (label == null) {
-        error(node.target, MessageKind.UNBOUND_LABEL, [labelName]);
+        error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName});
         return;
       }
       target = label.target;
       if (!target.statement.isValidContinueTarget()) {
-        error(node.target, MessageKind.INVALID_CONTINUE, [labelName]);
+        error(node.target, MessageKind.INVALID_CONTINUE);
       }
       // TODO(lrn): Handle continues to switch cases.
       if (target.statement is SwitchCase) {
@@ -2540,7 +2556,7 @@
     {
       // The variable declaration is either not an identifier, not a
       // declaration, or it's declaring more than one variable.
-      error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []);
+      error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN);
     }
   }
 
@@ -2565,7 +2581,8 @@
       if (element.isTarget) {
         mapping[element.label] = element;
       } else {
-        warning(element.label, MessageKind.UNUSED_LABEL, [labelName]);
+        warning(element.label, MessageKind.UNUSED_LABEL,
+                {'labelName': labelName});
       }
     });
     if (!targetElement.isTarget && identical(mapping[body], targetElement)) {
@@ -2603,15 +2620,17 @@
         LabelElement existingElement = continueLabels[labelName];
         if (existingElement != null) {
           // It's an error if the same label occurs twice in the same switch.
-          warning(label, MessageKind.DUPLICATE_LABEL, [labelName]);
-          error(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]);
+          warning(label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
+          error(existingElement.label, MessageKind.EXISTING_LABEL,
+                {'labelName': labelName});
         } else {
           // It's only a warning if it shadows another label.
           existingElement = statementScope.lookupLabel(labelName);
           if (existingElement != null) {
-            warning(label, MessageKind.DUPLICATE_LABEL, [labelName]);
+            warning(label, MessageKind.DUPLICATE_LABEL,
+                    {'labelName': labelName});
             warning(existingElement.label,
-                    MessageKind.EXISTING_LABEL, [labelName]);
+                    MessageKind.EXISTING_LABEL, {'labelName': labelName});
           }
         }
 
@@ -2750,7 +2769,8 @@
       SourceString typeName = typeVariable.name;
       TypeVariable typeNode = nodeLink.head;
       if (nameSet.contains(typeName)) {
-        error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
+        error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
+              {'typeVariableName': typeName});
       }
       nameSet.add(typeName);
 
@@ -2762,7 +2782,7 @@
           // TODO(johnniwinther): Check for more general cycles, like
           // [: <A extends B, B extends C, C extends B> :].
           warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
-                  [variableElement.name]);
+                  {'typeVariableName': variableElement.name});
         } else if (boundType != null) {
           variableElement.bound = boundType;
         } else {
@@ -2942,10 +2962,9 @@
     while (current != null && current.isMixinApplication) {
       MixinApplicationElement currentMixinApplication = current;
       if (currentMixinApplication == mixinApplication) {
-        CompilationError error = MessageKind.ILLEGAL_MIXIN_CYCLE.error(
-            [current.name, previous.name]);
-        compiler.reportMessage(compiler.spanFromElement(mixinApplication),
-                               error, Diagnostic.ERROR);
+        compiler.reportErrorCode(
+            mixinApplication, MessageKind.ILLEGAL_MIXIN_CYCLE,
+            {'mixinName1': current.name, 'mixinName2': previous.name});
         // We have found a cycle in the mixin chain. Return null as
         // the mixin for this application to avoid getting into
         // infinite recursion when traversing members.
@@ -2967,10 +2986,10 @@
   DartType visitIdentifier(Identifier node) {
     Element element = scope.lookup(node.source);
     if (element == null) {
-      error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
+      error(node, MessageKind.CANNOT_RESOLVE_TYPE,  {'typeName': node});
       return null;
     } else if (!element.impliesType() && !element.isTypeVariable()) {
-      error(node, MessageKind.NOT_A_TYPE, [node]);
+      error(node, MessageKind.NOT_A_TYPE, {'node': node});
       return null;
     } else {
       if (element.isTypeVariable()) {
@@ -2990,19 +3009,20 @@
   DartType visitSend(Send node) {
     Identifier prefix = node.receiver.asIdentifier();
     if (prefix == null) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
       return null;
     }
     Element element = scope.lookup(prefix.source);
     if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
       return null;
     }
     PrefixElement prefixElement = element;
     Identifier selector = node.selector.asIdentifier();
     var e = prefixElement.lookupLocalMember(selector.source);
     if (e == null || !e.impliesType()) {
-      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
+      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
+            {'typeName': node.selector});
       return null;
     }
     return e.computeType(compiler);
@@ -3017,10 +3037,10 @@
         return null;
       } else if (!identical(supertype.kind, TypeKind.INTERFACE)) {
         // TODO(johnniwinther): Handle dynamic.
-        error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED, []);
+        error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED);
         return null;
       } else if (isBlackListed(supertype)) {
-        error(superclass, MessageKind.CANNOT_EXTEND, [supertype]);
+        error(superclass, MessageKind.CANNOT_EXTEND, {'type': supertype});
         return null;
       }
     }
@@ -3039,27 +3059,28 @@
         } else if (!identical(interfaceType.kind, TypeKind.INTERFACE)) {
           // TODO(johnniwinther): Handle dynamic.
           TypeAnnotation typeAnnotation = link.head;
-          error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED, []);
+          error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
         } else {
           if (interfaceType == element.supertype) {
-            compiler.reportMessage(
-                compiler.spanFromSpannable(superclass),
-                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error([interfaceType]),
-                Diagnostic.ERROR);
-            compiler.reportMessage(
-                compiler.spanFromSpannable(link.head),
-                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS.error([interfaceType]),
-                Diagnostic.ERROR);
+            compiler.reportErrorCode(
+                superclass,
+                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+                {'type': interfaceType});
+            compiler.reportErrorCode(
+                link.head,
+                MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+                {'type': interfaceType});
           }
           if (result.contains(interfaceType)) {
-            compiler.reportMessage(
-                compiler.spanFromSpannable(link.head),
-                MessageKind.DUPLICATE_IMPLEMENTS.error([interfaceType]),
-                Diagnostic.ERROR);
+            compiler.reportErrorCode(
+                link.head,
+                MessageKind.DUPLICATE_IMPLEMENTS,
+                {'type': interfaceType});
           }
           result = result.prepend(interfaceType);
           if (isBlackListed(interfaceType)) {
-            error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]);
+            error(link.head, MessageKind.CANNOT_IMPLEMENT,
+                  {'type': interfaceType});
           }
         }
       }
@@ -3167,17 +3188,14 @@
   void visitIdentifier(Identifier node) {
     Element element = context.lookup(node.source);
     if (element == null) {
-      error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
+      error(node, MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node});
     } else if (!element.impliesType()) {
-      error(node, MessageKind.NOT_A_TYPE, [node]);
+      error(node, MessageKind.NOT_A_TYPE, {'node': node});
     } else {
       if (element.isClass()) {
         loadSupertype(element, node);
       } else {
-        compiler.reportMessage(
-          compiler.spanFromSpannable(node),
-          MessageKind.CLASS_NAME_EXPECTED.error([]),
-          Diagnostic.ERROR);
+        compiler.reportErrorCode(node, MessageKind.CLASS_NAME_EXPECTED);
       }
     }
   }
@@ -3185,19 +3203,20 @@
   void visitSend(Send node) {
     Identifier prefix = node.receiver.asIdentifier();
     if (prefix == null) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
       return;
     }
     Element element = context.lookup(prefix.source);
     if (element == null || !identical(element.kind, ElementKind.PREFIX)) {
-      error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+      error(node.receiver, MessageKind.NOT_A_PREFIX, {'node': node.receiver});
       return;
     }
     PrefixElement prefixElement = element;
     Identifier selector = node.selector.asIdentifier();
     var e = prefixElement.lookupLocalMember(selector.source);
     if (e == null || !e.impliesType()) {
-      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
+      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
+            {'typeName': node.selector});
       return;
     }
     loadSupertype(e, node);
@@ -3321,16 +3340,18 @@
     FieldParameterElement element;
     if (node.receiver.asIdentifier() == null ||
         !node.receiver.asIdentifier().isThis()) {
-      error(node, MessageKind.INVALID_PARAMETER, []);
-    } else if (!identical(enclosingElement.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
-      error(node, MessageKind.FIELD_PARAMETER_NOT_ALLOWED, []);
+      error(node, MessageKind.INVALID_PARAMETER);
+    } else if (!identical(enclosingElement.kind,
+                          ElementKind.GENERATIVE_CONSTRUCTOR)) {
+      error(node, MessageKind.FIELD_PARAMETER_NOT_ALLOWED);
     } else {
       SourceString name = getParameterName(node);
       Element fieldElement = currentClass.lookupLocalMember(name);
-      if (fieldElement == null || !identical(fieldElement.kind, ElementKind.FIELD)) {
-        error(node, MessageKind.NOT_A_FIELD, [name]);
+      if (fieldElement == null ||
+          !identical(fieldElement.kind, ElementKind.FIELD)) {
+        error(node, MessageKind.NOT_A_FIELD, {'fieldName': name});
       } else if (!fieldElement.isInstanceMember()) {
-        error(node, MessageKind.NOT_INSTANCE_FIELD, [name]);
+        error(node, MessageKind.NOT_INSTANCE_FIELD, {'fieldName': name});
       }
       Element variables = new VariableListElementX.node(currentDefinitions,
           ElementKind.VARIABLE_LIST, enclosingElement);
@@ -3390,9 +3411,7 @@
     int requiredParameterCount = 0;
     if (formalParameters == null) {
       if (!element.isGetter()) {
-        compiler.reportMessage(compiler.spanFromElement(element),
-                               MessageKind.MISSING_FORMALS.error([]),
-                               Diagnostic.ERROR);
+        compiler.reportErrorCode(element, MessageKind.MISSING_FORMALS);
       }
     } else {
       if (element.isGetter()) {
@@ -3402,9 +3421,8 @@
           if (compiler.rejectDeprecatedFeatures &&
               // TODO(ahe): Remove isPlatformLibrary check.
               !element.getLibrary().isPlatformLibrary) {
-            compiler.reportMessage(compiler.spanFromSpannable(formalParameters),
-                                   MessageKind.EXTRA_FORMALS.error([]),
-                                   Diagnostic.ERROR);
+            compiler.reportErrorCode(formalParameters,
+                                     MessageKind.EXTRA_FORMALS);
           } else {
             compiler.onDeprecatedFeature(formalParameters, 'getter parameters');
           }
@@ -3420,16 +3438,13 @@
                                visitor.optionalParameterCount != 0)) {
       // If there are no formal parameters, we already reported an error above.
       if (formalParameters != null) {
-        compiler.reportMessage(compiler.spanFromSpannable(formalParameters),
-                               MessageKind.ILLEGAL_SETTER_FORMALS.error([]),
-                               Diagnostic.ERROR);
+        compiler.reportErrorCode(formalParameters,
+                                 MessageKind.ILLEGAL_SETTER_FORMALS);
       }
     }
     if (element.isGetter() && (requiredParameterCount != 0
                                || visitor.optionalParameterCount != 0)) {
-      compiler.reportMessage(compiler.spanFromSpannable(formalParameters),
-                             MessageKind.EXTRA_FORMALS.error([]),
-                             Diagnostic.ERROR);
+      compiler.reportErrorCode(formalParameters, MessageKind.EXTRA_FORMALS);
     }
     return new FunctionSignatureX(parameters,
                                   visitor.optionalParameters,
@@ -3466,7 +3481,7 @@
 
   failOrReturnErroneousElement(Element enclosing, Node diagnosticNode,
                                SourceString targetName, MessageKind kind,
-                               List arguments) {
+                               Map arguments) {
     if (inConstContext) {
       error(diagnosticNode, kind, arguments);
     } else {
@@ -3502,7 +3517,7 @@
           diagnosticNode,
           new SourceString(fullConstructorName),
           MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          [fullConstructorName]);
+          {'constructorName': fullConstructorName});
     } else if (inConstContext && !result.modifiers.isConst()) {
       error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
     }
@@ -3530,7 +3545,8 @@
         // TODO(ahe): Remove this check and error message when we
         // don't have interfaces anymore.
         error(diagnosticNode,
-              MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
+              MessageKind.CANNOT_INSTANTIATE_INTERFACE,
+              {'interfaceName': cls.name});
       }
       // The unnamed constructor may not exist, so [e] may become unresolved.
       e = lookupConstructor(cls, diagnosticNode, const SourceString(''));
@@ -3562,8 +3578,9 @@
       ClassElement cls = e;
       cls.ensureResolved(compiler);
       if (cls.isInterface() && (cls.defaultClass == null)) {
-        error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
-              [cls.name]);
+        error(node.receiver,
+              MessageKind.CANNOT_INSTANTIATE_INTERFACE,
+              {'interfaceName': cls.name});
       }
       return lookupConstructor(cls, name, name.source);
     } else if (identical(e.kind, ElementKind.PREFIX)) {
@@ -3573,9 +3590,9 @@
         return failOrReturnErroneousElement(resolver.enclosingElement, name,
                                             name.source,
                                             MessageKind.CANNOT_RESOLVE,
-                                            [name]);
+                                            {'name': name});
       } else if (!identical(e.kind, ElementKind.CLASS)) {
-        error(node, MessageKind.NOT_A_TYPE, [name]);
+        error(node, MessageKind.NOT_A_TYPE, {'node': name});
       }
     } else {
       internalError(node.receiver, 'unexpected element $e');
@@ -3589,16 +3606,19 @@
     // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
     if (e == null) {
       return failOrReturnErroneousElement(resolver.enclosingElement, node, name,
-                                          MessageKind.CANNOT_RESOLVE, [name]);
+                                          MessageKind.CANNOT_RESOLVE,
+                                          {'name': name});
     } else if (e.isErroneous()) {
       return e;
     } else if (identical(e.kind, ElementKind.TYPEDEF)) {
-      error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]);
+      error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
+            {'typedefName': name});
     } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) {
-      error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]);
+      error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
+            {'typeVariableName': name});
     } else if (!identical(e.kind, ElementKind.CLASS)
         && !identical(e.kind, ElementKind.PREFIX)) {
-      error(node, MessageKind.NOT_A_TYPE, [name]);
+      error(node, MessageKind.NOT_A_TYPE, {'node': name});
     }
     return e;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index 2f6ce5d..130486c 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -7,6 +7,7 @@
 import 'dart:collection' show Queue, LinkedHashMap;
 
 import '../dart2jslib.dart' hide Diagnostic;
+import '../dart_types.dart';
 import '../../compiler.dart' show Diagnostic;
 import '../tree/tree.dart';
 import '../elements/elements.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index b74cc82..289c2c8 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -1919,12 +1919,6 @@
 
   FunctionExpression parseNode(DiagnosticListener listener) {
     if (cachedNode != null) return cachedNode;
-    if (patch == null) {
-      if (modifiers.isExternal()) {
-        listener.cancel("External method without an implementation",
-                        element: this);
-      }
-    }
     parseFunction(Parser p) {
       if (isMember() && modifiers.isFactory()) {
         p.parseFactoryMethod(beginToken);
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index ae56ccf..1c27852 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -29,7 +29,7 @@
   bool isWindows = (Platform.operatingSystem == 'windows');
   Uri cwd = getCurrentDirectory();
   Map<String, SourceFile> sourceFiles = <String, SourceFile>{};
-  int dartBytesRead = 0;
+  int dartCharactersRead = 0;
 
   Future<String> readStringFromUri(Uri resourceUri) {
     if (resourceUri.scheme != 'file') {
@@ -42,7 +42,7 @@
       throw 'Error: Cannot read "${relativize(cwd, resourceUri, isWindows)}" '
             '(${ex.osError}).';
     }
-    dartBytesRead += source.length;
+    dartCharactersRead += source.length;
     sourceFiles[resourceUri.toString()] =
       new SourceFile(relativize(cwd, resourceUri, isWindows), source);
     return new Future.immediate(source);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index 162fac5..ddf6bab 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -393,10 +393,27 @@
  */
 class SsaBailoutPropagator extends HBaseVisitor {
   final Compiler compiler;
+  /**
+   * A list to propagate bailout information to blocks that start a
+   * guarded or labeled list of statements. Currently, these blocks
+   * are:
+   *    - first block of a then branch,
+   *    - first block of an else branch,
+   *    - a loop header,
+   *    - labeled block.
+   */
   final List<HBasicBlock> blocks;
-  final List<HLabeledBlockInformation> labeledBlockInformations;
-  final Set<HInstruction> generateAtUseSite;
+
+  /**
+   * The current subgraph we are visiting.
+   */
   SubGraph subGraph;
+
+  /**
+   * The current block information we are visiting.
+   */
+  HBlockInformation currentBlockInformation;
+
   /**
    * Max number of arguments to the bailout (not counting the state).
    */
@@ -434,11 +451,8 @@
    * version.
    */
 
-  SsaBailoutPropagator(this.compiler,
-                       this.generateAtUseSite,
-                       this.variableNames)
+  SsaBailoutPropagator(this.compiler, this.variableNames)
       : blocks = <HBasicBlock>[],
-        labeledBlockInformations = <HLabeledBlockInformation>[],
         bailoutArity = 0,
         parameterNames = new Map<String, int>();
 
@@ -451,18 +465,63 @@
     }
   }
 
+  /**
+   * Returns true if we can visit the given [blockFlow]. False
+   * otherwise. Currently, try/catch and switch are not in bailout
+   * methods, so this method only deals with loops and labeled blocks.
+   * If [blockFlow] is a labeled block or a loop, we also visit the
+   * continuation of the block flow.
+   */
+  bool handleBlockFlow(HBlockFlow blockFlow) {
+    HBlockInformation body = blockFlow.body;
+
+    // We reach here again when starting to visit a subgraph. Just
+    // return to visiting the block.
+    if (currentBlockInformation == body) return false;
+
+    HBlockInformation oldInformation = currentBlockInformation;
+    if (body is HLabeledBlockInformation) {
+      currentBlockInformation = body;
+      HLabeledBlockInformation info = body;
+      visitStatements(info.body, newFlow: true);
+    } else if (body is HLoopBlockInformation) {
+      currentBlockInformation = body;
+      HLoopBlockInformation info = body;
+      if (info.initializer != null) {
+        visitExpression(info.initializer);
+      }
+      blocks.addLast(info.loopHeader);
+      if (!info.isDoWhile()) {
+        visitExpression(info.condition);
+      }
+      visitStatements(info.body, newFlow: false);
+      if (info.isDoWhile()) {
+        visitExpression(info.condition);
+      }
+      if (info.updates != null) {
+        visitExpression(info.updates);
+      }
+      blocks.removeLast();
+    } else {
+      assert(body is! HTryBlockInformation);
+      assert(body is! HSwitchBlockInformation);
+      // [HIfBlockInformation] is handled by visitIf.
+      return false;
+    }
+
+    currentBlockInformation = oldInformation;
+    if (blockFlow.continuation != null) {
+      visitBasicBlock(blockFlow.continuation);
+    }
+    return true;
+  }
+
   void visitBasicBlock(HBasicBlock block) {
     // Abort traversal if we are leaving the currently active sub-graph.
     if (!subGraph.contains(block)) return;
 
-    if (block.isLoopHeader()) {
-      blocks.addLast(block);
-    } else if (block.isLabeledBlock()
-               && (blocks.isEmpty || !identical(blocks.last, block))) {
-      HLabeledBlockInformation info = block.blockFlow.body;
-      visitStatements(info.body);
-      return;
-    }
+    HBlockFlow blockFlow = block.blockFlow;
+    if (blockFlow != null && handleBlockFlow(blockFlow)) return;
 
     HInstruction instruction = block.first;
     while (instruction != null) {
@@ -471,35 +530,34 @@
     }
   }
 
-  void visitStatements(HStatementInformation info) {
-    assert(info is HSubGraphBlockInformation);
-    HSubGraphBlockInformation graph = info;
-    visitSubGraph(graph.subGraph);
+  void visitExpression(HSubExpressionBlockInformation info) {
+    visitSubGraph(info.subExpression);
+  }
+
+  /**
+   * Visit the statements in [info]. If [newFlow] is true, we add the
+   * first block of [statements] to the list of [blocks].
+   */
+  void visitStatements(HSubGraphBlockInformation info, {bool newFlow}) {
+    SubGraph graph = info.subGraph;
+    if (newFlow) blocks.addLast(graph.start);
+    visitSubGraph(graph);
+    if (newFlow) blocks.removeLast();
   }
 
   void visitSubGraph(SubGraph graph) {
     SubGraph oldSubGraph = subGraph;
     subGraph = graph;
-    HBasicBlock start = graph.start;
-    blocks.addLast(start);
-    visitBasicBlock(start);
-    blocks.removeLast();
+    visitBasicBlock(graph.start);
     subGraph = oldSubGraph;
-
-    if (start.isLabeledBlock()) {
-      HBasicBlock continuation = start.blockFlow.continuation;
-      if (continuation != null) {
-        visitBasicBlock(continuation);
-      }
-    }
   }
 
   void visitIf(HIf instruction) {
     int preVisitedBlocks = 0;
     HIfBlockInformation info = instruction.blockInformation.body;
-    visitStatements(info.thenGraph);
+    visitStatements(info.thenGraph, newFlow: true);
     preVisitedBlocks++;
-    visitStatements(info.elseGraph);
+    visitStatements(info.elseGraph, newFlow: true);
     preVisitedBlocks++;
 
     HBasicBlock joinBlock = instruction.joinBlock;
@@ -532,24 +590,9 @@
   }
 
   void visitLoopBranch(HLoopBranch branch) {
-    HBasicBlock branchBlock = branch.block;
-    List<HBasicBlock> dominated = branchBlock.dominatedBlocks;
     // For a do-while loop, the body has already been visited.
     if (!branch.isDoWhile()) {
-      visitBasicBlock(dominated[0]);
-    }
-    blocks.removeLast();
-
-    // If the branch does not dominate the code after the loop, the
-    // dominator will visit it.
-    if (!identical(branchBlock.successors[1].dominator, branchBlock)) return;
-
-    visitBasicBlock(branchBlock.successors[1]);
-    // With labeled breaks we can have more dominated blocks.
-    if (dominated.length >= 3) {
-      for (int i = 2; i < dominated.length; i++) {
-        visitBasicBlock(dominated[i]);
-      }
+      visitBasicBlock(branch.block.dominatedBlocks[0]);
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 8150846..67085fd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -136,14 +136,19 @@
   /**
    * The values of locals that can be directly accessed (without redirections
    * to boxes or closure-fields).
+   *
+   * [directLocals] is iterated, so it is a [LinkedHashMap] to make the
+   * iteration order a function only of insertions and not a function of
+   * e.g. Element hash codes.  I'd prefer to use a SortedMap but some elements
+   * don't have source locations for [Elements.compareByPosition].
    */
-  Map<Element, HInstruction> directLocals;
+  LinkedHashMap<Element, HInstruction> directLocals;
   Map<Element, Element> redirectionMapping;
   SsaBuilder builder;
   ClosureClassMap closureData;
 
   LocalsHandler(this.builder)
-      : directLocals = new Map<Element, HInstruction>(),
+      : directLocals = new LinkedHashMap<Element, HInstruction>(),
         redirectionMapping = new Map<Element, Element>();
 
   get typesTask => builder.compiler.typesTask;
@@ -154,7 +159,8 @@
    * throughout the AST visit.
    */
   LocalsHandler.from(LocalsHandler other)
-      : directLocals = new Map<Element, HInstruction>.from(other.directLocals),
+      : directLocals =
+            new LinkedHashMap<Element, HInstruction>.from(other.directLocals),
         redirectionMapping = other.redirectionMapping,
         builder = other.builder,
         closureData = other.closureData;
@@ -524,10 +530,9 @@
   }
 
   void beginLoopHeader(Node node, HBasicBlock loopEntry) {
-    // Create a copy because we modify the map while iterating over
-    // it.
+    // Create a copy because we modify the map while iterating over it.
     Map<Element, HInstruction> saved =
-        new Map<Element, HInstruction>.from(directLocals);
+        new LinkedHashMap<Element, HInstruction>.from(directLocals);
 
     // Create phis for all elements in the definitions environment.
     saved.forEach((Element element, HInstruction instruction) {
@@ -590,7 +595,8 @@
     // block. Since variable declarations are scoped the declared
     // variable cannot be alive outside the block. Note: this is only
     // true for nodes where we do joins.
-    Map<Element, HInstruction> joinedLocals = new Map<Element, HInstruction>();
+    Map<Element, HInstruction> joinedLocals =
+        new LinkedHashMap<Element, HInstruction>();
     otherLocals.directLocals.forEach((element, instruction) {
       // We know 'this' cannot be modified.
       if (identical(element, closureData.thisElement)) {
@@ -622,7 +628,8 @@
                               HBasicBlock joinBlock) {
     assert(locals.length > 0);
     if (locals.length == 1) return locals[0];
-    Map<Element, HInstruction> joinedLocals = new Map<Element,HInstruction>();
+    Map<Element, HInstruction> joinedLocals =
+        new LinkedHashMap<Element,HInstruction>();
     HInstruction thisValue = null;
     directLocals.forEach((Element element, HInstruction instruction) {
       if (!identical(element, closureData.thisElement)) {
@@ -819,10 +826,9 @@
   // block is closed.
   HBasicBlock lastOpenedBlock;
 
-  List<Element> sourceElementStack;
+  final List<Element> sourceElementStack;
 
-  LibraryElement get currentLibrary => work.element.getLibrary();
-  Element get currentElement => work.element;
+  Element get currentElement => sourceElementStack.last.declaration;
   Compiler get compiler => builder.compiler;
   CodeEmitterTask get emitter => builder.emitter;
 
@@ -980,7 +986,8 @@
    */
   InliningState enterInlinedMethod(PartialFunctionElement function,
                                    Selector selector,
-                                   Link<Node> arguments) {
+                                   Link<Node> arguments,
+                                   Node currentNode) {
     assert(invariant(function, function.isImplementation));
 
     // Once we start to compile the arguments we must be sure that we don't
@@ -992,11 +999,36 @@
                                                   compiledArguments);
     assert(succeeded);
 
+    FunctionSignature signature = function.computeSignature(compiler);
+    int index = 0;
+    signature.orderedForEachParameter((Element parameter) {
+      HInstruction argument = compiledArguments[index++];
+      localsHandler.updateLocal(parameter, argument);
+      potentiallyCheckType(argument, parameter.computeType(compiler));
+    });
+
+    if (function.isConstructor()) {
+      ClassElement enclosing = function.getEnclosingClass();
+      if (compiler.world.needsRti(enclosing)) {
+        assert(currentNode is NewExpression);
+        InterfaceType type = elements.getType(currentNode);
+        Link<DartType> typeVariable = enclosing.typeVariables;
+        type.typeArguments.forEach((DartType argument) {
+          HInstruction instruction =
+              analyzeTypeArgument(argument, currentNode);
+          localsHandler.updateLocal(typeVariable.head.element, instruction);
+          typeVariable = typeVariable.tail;
+        });
+        while (!typeVariable.isEmpty) {
+          localsHandler.updateLocal(typeVariable.head.element,
+                                    graph.addConstantNull(constantSystem));
+          typeVariable = typeVariable.tail;
+        }
+      }
+    }
     InliningState state =
         new InliningState(function, returnElement, returnType, elements, stack);
-    inliningStack.add(state);
-    sourceElementStack.add(function);
-    stack = <HInstruction>[];
+
     // TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
     returnElement = new ElementX(const SourceString("result"),
                                  ElementKind.VARIABLE,
@@ -1005,22 +1037,15 @@
                               graph.addConstantNull(constantSystem));
     elements = compiler.enqueuer.resolution.getCachedElements(function);
     assert(elements != null);
-    FunctionSignature signature = function.computeSignature(compiler);
     returnType = signature.returnType;
-    int index = 0;
-    signature.orderedForEachParameter((Element parameter) {
-      HInstruction argument = compiledArguments[index++];
-      localsHandler.updateLocal(parameter, argument);
-      potentiallyCheckType(argument, parameter.computeType(compiler));
-    });
+    stack = <HInstruction>[];
+    inliningStack.add(state);
     return state;
   }
 
   void leaveInlinedMethod(InliningState state) {
     InliningState poppedState = inliningStack.removeLast();
     assert(state == poppedState);
-    FunctionElement poppedElement = sourceElementStack.removeLast();
-    assert(poppedElement == poppedState.function);
     elements = state.oldElements;
     stack.add(localsHandler.readLocal(returnElement));
     returnElement = state.oldReturnElement;
@@ -1031,11 +1056,13 @@
   }
 
   /**
-   * Documentation wanted -- johnniwinther
+   * Try to inline [element] within the currect context of the
+   * builder. The insertion point is the state of the builder.
    */
   bool tryInlineMethod(Element element,
                        Selector selector,
-                       Link<Node> arguments) {
+                       Link<Node> arguments,
+                       Node currentNode) {
     if (compiler.disableInlining) return false;
     // Ensure that [element] is an implementation element.
     element = element.implementation;
@@ -1045,11 +1072,14 @@
     // containing nodes.
     // [PartialFunctionElement]s are [FunctionElement]s that have [Node]s.
     if (element is !PartialFunctionElement) return false;
+    // TODO(ngeoffray): try to inline generative constructors. They
+    // don't have any body, which make it more difficult.
+    if (element.isGenerativeConstructor()) return false;
     if (inliningStack.length > MAX_INLINING_DEPTH) return false;
     // Don't inline recursive calls. We use the same elements for the inlined
     // functions and would thus clobber our local variables.
     // Use [:element.declaration:] since [work.element] is always a declaration.
-    if (work.element == element.declaration) return false;
+    if (currentElement == element.declaration) return false;
     for (int i = 0; i < inliningStack.length; i++) {
       if (inliningStack[i].function == element) return false;
     }
@@ -1068,8 +1098,11 @@
       return false;
     }
 
-    InliningState state = enterInlinedMethod(function, selector, arguments);
-    functionExpression.body.accept(this);
+    InliningState state = enterInlinedMethod(
+        function, selector, arguments, currentNode);
+    inlinedFrom(element, () {
+      functionExpression.body.accept(this);
+    });
     leaveInlinedMethod(state);
     return true;
   }
@@ -1143,9 +1176,15 @@
 
       ClosureClassMap oldClosureData = localsHandler.closureData;
       Node node = constructor.parseNode(compiler);
-      localsHandler.closureData =
+      ClosureClassMap newClosureData =
           compiler.closureToClassMapper.computeClosureToClassMapping(
               constructor, node, elements);
+      // The [:this:] element now refers to the one in the new closure
+      // data, that is the [:this:] of the super constructor. We
+      // update the element to refer to the current [:this:].
+      localsHandler.updateLocal(newClosureData.thisElement,
+                                localsHandler.readThis());
+      localsHandler.closureData = newClosureData;
 
       params.orderedForEachParameter((Element parameterElement) {
         if (elements.isParameterChecked(parameterElement)) {
@@ -1341,7 +1380,6 @@
       List bodyCallInputs = <HInstruction>[];
       bodyCallInputs.add(newObject);
       FunctionSignature functionSignature = body.computeSignature(compiler);
-      int arity = functionSignature.parameterCount;
       functionSignature.orderedForEachParameter((parameter) {
         if (!localsHandler.isBoxed(parameter)) {
           // The parameter will be a field in the box passed as the
@@ -1381,7 +1419,8 @@
       // these selectors. Maybe the resolver can do more of the work
       // for us here?
       LibraryElement library = body.getLibrary();
-      Selector selector = new Selector.call(name, library, arity);
+      Selector selector = new Selector.call(
+          name, library, bodyCallInputs.length - 1);
       HInvokeDynamic invoke =
           new HInvokeDynamicMethod(selector, bodyCallInputs);
       invoke.element = body;
@@ -1620,7 +1659,9 @@
     SourceFileLocation location = new SourceFileLocation(sourceFile, token);
     if (!location.isValid()) {
       throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
-          [token.charOffset, sourceFile.filename, sourceFile.text.length]);
+          {'offset': token.charOffset,
+           'fileName': sourceFile.filename,
+           'length': sourceFile.text.length});
     }
     return location;
 }
@@ -2040,7 +2081,7 @@
     endLoop(loopEntryBlock, conditionEndBlock, jumpHandler, localsHandler);
     if (!isAbortingBody || hasContinues) {
       loopEntryBlock.postProcessLoopHeader();
-      SubGraph bodyGraph = new SubGraph(bodyEntryBlock, bodyExitBlock);
+      SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock);
       HLoopBlockInformation loopBlockInfo =
           new HLoopBlockInformation(
               HLoopBlockInformation.DO_WHILE_LOOP,
@@ -2345,7 +2386,7 @@
       } else {
         if (element.isGetter()) {
           Selector selector = elements.getSelector(send);
-          if (tryInlineMethod(element, selector, const Link<Node>())) {
+          if (tryInlineMethod(element, selector, const Link<Node>(), send)) {
             return;
           }
         }
@@ -2749,7 +2790,7 @@
     Element element = elements[node];
     bool isClosureCall = false;
     if (element != null && compiler.world.hasNoOverridingMember(element)) {
-      if (tryInlineMethod(element, selector, node.arguments)) {
+      if (tryInlineMethod(element, selector, node.arguments, node)) {
         if (element.isGetter()) {
           // If the element is a getter, we are doing a closure call
           // on what this getter returns.
@@ -3008,7 +3049,7 @@
     Selector selector = elements.getSelector(node);
     SourceString name = selector.name;
 
-    ClassElement cls = work.element.getEnclosingClass();
+    ClassElement cls = currentElement.getEnclosingClass();
     Element element = cls.lookupSuperMember(Compiler.NO_SUCH_METHOD);
     if (element.enclosingElement.declaration != compiler.objectClass) {
       // Register the call as dynamic if [:noSuchMethod:] on the super class
@@ -3064,7 +3105,7 @@
 
   visitSend(Send node) {
     Element element = elements[node];
-    if (element != null && identical(element, work.element)) {
+    if (element != null && identical(element, currentElement)) {
       graph.isRecursiveMethod = true;
     }
     super.visitSend(node);
@@ -3125,7 +3166,7 @@
      * Helper to create an instruction that gets the value of a type variable.
      */
     void addTypeVariableReference(TypeVariableType type) {
-      Element member = work.element;
+      Element member = currentElement;
       if (member.enclosingElement.isClosure()) {
         ClosureClassElement closureClass = member.enclosingElement;
         member = closureClass.methodElement;
@@ -3248,11 +3289,17 @@
       generateAbstractClassInstantiationError(node, cls.name.slowToString());
       return;
     }
-    if (compiler.world.needsRti(constructor.enclosingElement)) {
-      if (!type.isRaw) {
-        type.typeArguments.forEach((DartType argument) {
-          inputs.add(analyzeTypeArgument(argument, node));
-        });
+    if (compiler.world.needsRti(cls)) {
+      Link<DartType> typeVariable = cls.typeVariables;
+      type.typeArguments.forEach((DartType argument) {
+        inputs.add(analyzeTypeArgument(argument, node));
+        typeVariable = typeVariable.tail;
+      });
+      // Also add null to non-provided type variables to call the
+      // constructor with the right number of arguments.
+      while (!typeVariable.isEmpty) {
+        inputs.add(graph.addConstantNull(constantSystem));
+        typeVariable = typeVariable.tail;
       }
     }
 
@@ -3292,7 +3339,7 @@
       bool isIdenticalFunction = element == compiler.identicalFunction;
 
       if (!isIdenticalFunction
-          && tryInlineMethod(element, selector, node.arguments)) {
+          && tryInlineMethod(element, selector, node.arguments, node)) {
         return;
       }
 
@@ -3319,7 +3366,7 @@
       // useful.
       HType returnType =
           builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange(
-              work.element, element);
+              currentElement, element);
       if (returnType != null) instruction.guaranteedType = returnType;
       pushWithPosition(instruction, node);
     } else {
@@ -3487,7 +3534,12 @@
       } else {
         // TODO(karlklose): move this type registration to the codegen.
         compiler.codegenWorld.instantiatedTypes.add(type);
-        visitNewSend(node.send, type);
+        Send send = node.send;
+        Element constructor = elements[send];
+        Selector selector = elements.getSelector(send);
+        if (!tryInlineMethod(constructor, selector, send.arguments, node)) {
+          visitNewSend(send, type);
+        }
       }
     }
   }
@@ -3849,7 +3901,7 @@
     void buildInitializer() {
       SourceString iteratorName = const SourceString("iterator");
       Selector selector =
-          new Selector.getter(iteratorName, work.element.getLibrary());
+          new Selector.getter(iteratorName, currentElement.getLibrary());
       Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector);
       visit(node.expression);
       HInstruction receiver = pop();
@@ -3870,14 +3922,15 @@
     }
     HInstruction buildCondition() {
       SourceString name = const SourceString('moveNext');
-      Selector selector = new Selector.call(name, work.element.getLibrary(), 0);
+      Selector selector = new Selector.call(
+          name, currentElement.getLibrary(), 0);
       bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
       push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator]));
       return popBoolified();
     }
     void buildBody() {
       SourceString name = const SourceString('current');
-      Selector call = new Selector.getter(name, work.element.getLibrary());
+      Selector call = new Selector.getter(name, currentElement.getLibrary());
       bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call);
       push(new HInvokeDynamicGetter(call, null, iterator, hasGetter));
 
@@ -4381,8 +4434,9 @@
       open(startCatchBlock);
       // TODO(kasperl): Bad smell. We shouldn't be constructing elements here.
       // Note that the name of this element is irrelevant.
-      Element element = new ElementX(
-          const SourceString('exception'), ElementKind.PARAMETER, work.element);
+      Element element = new ElementX(const SourceString('exception'),
+                                     ElementKind.PARAMETER,
+                                     currentElement);
       exception = new HLocalValue(element);
       add(exception);
       HInstruction oldRethrowableException = rethrowableException;
@@ -4678,8 +4732,10 @@
     if (seenReturn) tooDifficult = true;
   }
 
-  void visitReturn(Node node) {
-    if (seenReturn || identical(node.getBeginToken().stringValue, 'native')) {
+  void visitReturn(Return node) {
+    if (seenReturn
+        || identical(node.getBeginToken().stringValue, 'native')
+        || node.isRedirectingFactoryBody) {
       tooDifficult = true;
       return;
     }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 3f0a0b6..eeaad2a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -337,10 +337,6 @@
   beginGraph(HGraph graph);
   endGraph(HGraph graph);
 
-  beginLoop(HBasicBlock block);
-  endLoop(HBasicBlock block);
-  handleLoopCondition(HLoopBranch node);
-
   preLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
   startLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
   endLabeledBlock(HLabeledBlockInformation labeledBlockInfo);
@@ -959,11 +955,7 @@
         assignPhisOfSuccessors(avoidEdge);
         bool hasPhiUpdates = !updateBody.statements.isEmpty;
         currentContainer = body;
-        if (hasPhiUpdates || !isConditionExpression || info.updates != null) {
-          wrapLoopBodyForContinue(info);
-        } else {
-          visitBodyIgnoreLabels(info);
-        }
+        visitBodyIgnoreLabels(info);
         if (info.updates != null) {
           generateStatements(info.updates);
         }
@@ -1125,15 +1117,9 @@
     currentBlock = node;
     // If this node has block-structure based information attached,
     // try using that to traverse from here.
-    if (node.blockFlow != null &&
-        handleBlockFlow(node.blockFlow)) {
+    if (node.blockFlow != null && handleBlockFlow(node.blockFlow)) {
       return;
     }
-    // Flow based traversal.
-    if (node.isLoopHeader() &&
-        !identical(node.loopInformation.loopBlockInformation, currentBlockInformation)) {
-      beginLoop(node);
-    }
     iterateBasicBlock(node);
   }
 
@@ -1228,7 +1214,7 @@
     if (handler == null) return;
 
     // Map the instructions to strings.
-    Iterable<Copy> copies = handler.copies.mappedBy((Copy copy) {
+    Iterable<Copy> copies = handler.copies.map((Copy copy) {
       return new Copy(variableNames.getName(copy.source),
                       variableNames.getName(copy.destination));
     });
@@ -1363,6 +1349,18 @@
     visitBasicBlock(dominated[0]);
   }
 
+  visitLoopBranch(HLoopBranch node) {
+    assert(node.block == subGraph.end);
+    // We are generating code for a loop condition.
+    // If we are generating the subgraph as an expression, the
+    // condition will be generated as the expression.
+    // Otherwise, we don't generate the expression, and leave that
+    // to the code that called [visitSubGraph].
+    if (isGeneratingExpression) {
+      use(node.inputs[0]);
+    }
+  }
+
   /**
    * Checks if [map] contains an [ElementAction] for [element], and
    * if so calls that action and returns true.
@@ -1833,43 +1831,6 @@
     world.registerInstantiatedClass(type.element);
   }
 
-  visitLoopBranch(HLoopBranch node) {
-    if (subGraph != null && identical(node.block, subGraph.end)) {
-      // We are generating code for a loop condition.
-      // If doing this as part of a SubGraph traversal, the
-      // calling code will handle the control flow logic.
-
-      // If we are generating the subgraph as an expression, the
-      // condition will be generated as the expression.
-      // Otherwise, we don't generate the expression, and leave that
-      // to the code that called [visitSubGraph].
-      if (isGeneratingExpression) {
-        use(node.inputs[0]);
-      }
-      return;
-    }
-    HBasicBlock branchBlock = currentBlock;
-    handleLoopCondition(node);
-    List<HBasicBlock> dominated = currentBlock.dominatedBlocks;
-    if (!node.isDoWhile()) {
-      // For a do while loop, the body has already been visited.
-      visitBasicBlock(dominated[0]);
-    }
-    endLoop(node.block);
-
-    // If the branch does not dominate the code after the loop, the
-    // dominator will visit it.
-    if (!identical(branchBlock.successors[1].dominator, branchBlock)) return;
-
-    visitBasicBlock(branchBlock.successors[1]);
-    // With labeled breaks we can have more dominated blocks.
-    if (dominated.length >= 3) {
-      for (int i = 2; i < dominated.length; i++) {
-        visitBasicBlock(dominated[i]);
-      }
-    }
-  }
-
   visitNot(HNot node) {
     assert(node.inputs.length == 1);
     generateNot(node.inputs[0]);
@@ -2538,7 +2499,7 @@
         // of the control flow (controlled by the state argument passed
         // above).  We need to pass it to get later arguments in the right
         // position.
-        arguments.add(new js.LiteralNull());
+        arguments.add(new js.LiteralNumber('0'));
       }
       use(parameter);
       arguments.add(pop());
@@ -2655,33 +2616,6 @@
     // Do nothing. Bailout targets are only used in the non-optimized version.
   }
 
-  void beginLoop(HBasicBlock block) {
-    oldContainerStack.add(currentContainer);
-    currentContainer = new js.Block.empty();
-  }
-
-  void endLoop(HBasicBlock block) {
-    js.Statement body = currentContainer;
-    currentContainer = oldContainerStack.removeLast();
-    body = unwrapStatement(body);
-    js.While loop = new js.While(newLiteralBool(true), body);
-
-    HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader;
-    HLoopInformation info = header.loopInformation;
-    attachLocationRange(loop,
-                        info.loopBlockInformation.sourcePosition,
-                        info.loopBlockInformation.endSourcePosition);
-    pushStatement(wrapIntoLabels(loop, info.labels));
-  }
-
-  void handleLoopCondition(HLoopBranch node) {
-    use(node.inputs[0]);
-    js.Expression test = new js.Prefix('!', pop());
-    js.Statement then = new js.Break(null);
-    pushStatement(new js.If.noElse(test, then), node);
-  }
-
-
   void preLabeledBlock(HLabeledBlockInformation labeledBlockInfo) {
   }
 
@@ -2735,8 +2669,7 @@
       => new js.VariableUse(variableNames.stateName);
 
   HBasicBlock beginGraph(HGraph graph) {
-    propagator =
-        new SsaBailoutPropagator(compiler, generateAtUseSite, variableNames);
+    propagator = new SsaBailoutPropagator(compiler, variableNames);
     propagator.visitGraph(graph);
     // TODO(ngeoffray): We could avoid generating the state at the
     // call site for non-complex bailout methods.
@@ -2795,6 +2728,22 @@
 
   bool visitAndOrInfo(HAndOrBlockInformation info) => false;
 
+  visitLoopBranch(HLoopBranch node) {
+    if (node.computeLoopHeader().hasBailoutTargets()) {
+      // The graph visitor in [visitLoopInfo] does not handle the
+      // condition. We must instead manually emit it here.
+      handleLoopCondition(node);
+      // We must also visit the body from here.
+      // For a do while loop, the body has already been visited.
+      if (!node.isDoWhile()) {
+        visitBasicBlock(node.block.dominatedBlocks[0]);
+      }
+    } else {
+      super.visitLoopBranch(node);
+    }
+  }
+
+
   bool visitIfInfo(HIfBlockInformation info) {
     if (info.thenGraph.start.hasBailoutTargets()) return false;
     if (info.elseGraph.start.hasBailoutTargets()) return false;
@@ -2802,8 +2751,27 @@
   }
 
   bool visitLoopInfo(HLoopBlockInformation info) {
-    if (info.start.hasBailoutTargets()) return false;
-    if (info.loopHeader.hasBailoutTargets()) return false;
+    // Always emit with block flow traversal.
+    if (info.loopHeader.hasBailoutTargets()) {
+      // If there are any bailout targets in the loop, we cannot use
+      // the pretty [SsaCodeGenerator.visitLoopInfo] printer.
+      if (info.initializer != null) {
+        generateStatements(info.initializer);
+      }
+      beginLoop(info.loopHeader);
+      if (!info.isDoWhile()) {
+        generateStatements(info.condition);
+      }
+      generateStatements(info.body);
+      if (info.isDoWhile()) {
+        generateStatements(info.condition);
+      }
+      if (info.updates != null) {
+        generateStatements(info.updates);
+      }
+      endLoop(info.end);
+      return true;
+    }
     return super.visitLoopInfo(info);
   }
 
@@ -2843,14 +2811,14 @@
     // undefined for the trailing arguments.
     node.padding = new List<int>(node.inputs.length);
     int j = 0;
-    int pendingNulls = 0;
+    int pendingUnusedArguments = 0;
     for (int i = 0; i < newInputs.length; i++) {
       HInstruction input = newInputs[i];
       if (input == null) {
-        pendingNulls++;
+        pendingUnusedArguments++;
       } else {
-        node.padding[j] = pendingNulls;
-        pendingNulls = 0;
+        node.padding[j] = pendingUnusedArguments;
+        pendingUnusedArguments = 0;
         node.updateInput(j, input);
         j++;
       }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 99329fd..2876e06 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1857,6 +1857,23 @@
   bool isDoWhile() {
     return identical(kind, DO_WHILE_LOOP);
   }
+
+  HBasicBlock computeLoopHeader() {
+    HBasicBlock result;
+    if (isDoWhile()) {
+      // In case of a do/while, the successor is a block that avoids
+      // a critical edge and branchs to the loop header.
+      result = block.successors[0].successors[0];
+    } else {
+      // For other loops, the loop header might be up the dominator
+      // tree if the loop condition has control flow.
+      result = block;
+      while (!result.isLoopHeader()) result = result.dominator;
+    }
+
+    assert(result.isLoopHeader());
+    return result;
+  }
 }
 
 class HConstant extends HInstruction {
@@ -2589,7 +2606,10 @@
                         this.target,
                         this.labels,
                         this.sourcePosition,
-                        this.endSourcePosition);
+                        this.endSourcePosition) {
+    assert(
+        (kind == DO_WHILE_LOOP ? body.start : condition.start).isLoopHeader());
+  }
 
   HBasicBlock get start {
     if (initializer != null) return initializer.start;
@@ -2615,6 +2635,8 @@
     return node.accept(const LoopTypeVisitor());
   }
 
+  bool isDoWhile() => kind == DO_WHILE_LOOP;
+
   bool accept(HStatementInformationVisitor visitor) =>
     visitor.visitLoopInfo(this);
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index ed1f6cf..c51395f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -1529,6 +1529,7 @@
     HOneShotInterceptor interceptor = new HOneShotInterceptor(
         user.selector, inputs, node.interceptedClasses);
     interceptor.sourcePosition = user.sourcePosition;
+    interceptor.sourceElement = user.sourceElement;
 
     HBasicBlock block = user.block;
     block.addAfter(user, interceptor);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index f1e0c71..13de8b6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -9,6 +9,7 @@
 import '../closure.dart';
 import '../js/js.dart' as js;
 import '../dart2jslib.dart' hide Selector;
+import '../dart_types.dart';
 import '../source_file.dart';
 import '../source_map_builder.dart';
 import '../elements/elements.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
index 1f545d3..34f960d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
@@ -473,9 +473,9 @@
   String allocateWithHint(String originalName) {
     int i = 0;
     JavaScriptBackend backend = compiler.backend;
-    String name = backend.namer.safeName(originalName);
+    String name = backend.namer.safeVariableName(originalName);
     while (usedNames.contains(name)) {
-      name = backend.namer.safeName('$originalName${i++}');
+      name = backend.namer.safeVariableName('$originalName${i++}');
     }
     return name;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index c826241..ed5ac45 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -26,677 +26,6 @@
   }
 }
 
-class TypeKind {
-  final String id;
-
-  const TypeKind(String this.id);
-
-  static const TypeKind FUNCTION = const TypeKind('function');
-  static const TypeKind INTERFACE = const TypeKind('interface');
-  static const TypeKind STATEMENT = const TypeKind('statement');
-  static const TypeKind TYPEDEF = const TypeKind('typedef');
-  static const TypeKind TYPE_VARIABLE = const TypeKind('type variable');
-  static const TypeKind MALFORMED_TYPE = const TypeKind('malformed');
-  static const TypeKind VOID = const TypeKind('void');
-
-  String toString() => id;
-}
-
-abstract class DartType {
-  SourceString get name;
-
-  TypeKind get kind;
-
-  const DartType();
-
-  /**
-   * Returns the [Element] which declared this type.
-   *
-   * This can be [ClassElement] for classes, [TypedefElement] for typedefs,
-   * [TypeVariableElement] for type variables and [FunctionElement] for
-   * function types.
-   *
-   * Invariant: [element] must be a declaration element.
-   */
-  Element get element;
-
-  /**
-   * Performs the substitution [: [arguments[i]/parameters[i]]this :].
-   *
-   * The notation is known from this lambda calculus rule:
-   *
-   *     (lambda x.e0)e1 -> [e1/x]e0.
-   *
-   * See [TypeVariableType] for a motivation for this method.
-   *
-   * Invariant: There must be the same number of [arguments] and [parameters].
-   */
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters);
-
-  /**
-   * Returns the unaliased type of this type.
-   *
-   * The unaliased type of a typedef'd type is the unaliased type to which its
-   * name is bound. The unaliased version of any other type is the type itself.
-   *
-   * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the
-   * function type [: (B) -> A :] and the unaliased type of
-   * [: Func<int,String> :] is the function type [: (String) -> int :].
-   */
-  DartType unalias(Compiler compiler);
-
-  /**
-   * A type is malformed if it is itself a malformed type or contains a
-   * malformed type.
-   */
-  bool get isMalformed => false;
-
-  /**
-   * Calls [f] with each [MalformedType] within this type.
-   *
-   * If [f] returns [: false :], the traversal stops prematurely.
-   *
-   * [forEachMalformedType] returns [: false :] if the traversal was stopped
-   * prematurely.
-   */
-  bool forEachMalformedType(bool f(MalformedType type)) => true;
-
-  bool operator ==(other);
-
-  /**
-   * Is [: true :] if this type has no explict type arguments.
-   */
-  bool get isRaw => true;
-
-  DartType asRaw() => this;
-}
-
-/**
- * Represents a type variable, that is the type parameters of a class type.
- *
- * For example, in [: class Array<E> { ... } :], E is a type variable.
- *
- * Each class should have its own unique type variables, one for each type
- * parameter. A class with type parameters is said to be parameterized or
- * generic.
- *
- * Non-static members, constructors, and factories of generic
- * class/interface can refer to type variables of the current class
- * (not of supertypes).
- *
- * When using a generic type, also known as an application or
- * instantiation of the type, the actual type arguments should be
- * substituted for the type variables in the class declaration.
- *
- * For example, given a box, [: class Box<T> { T value; } :], the
- * type of the expression [: new Box<String>().value :] is
- * [: String :] because we must substitute [: String :] for the
- * the type variable [: T :].
- */
-class TypeVariableType extends DartType {
-  final TypeVariableElement element;
-
-  TypeVariableType(this.element);
-
-  TypeKind get kind => TypeKind.TYPE_VARIABLE;
-
-  SourceString get name => element.name;
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    Link<DartType> parameterLink = parameters;
-    Link<DartType> argumentLink = arguments;
-    while (!argumentLink.isEmpty && !parameterLink.isEmpty) {
-      TypeVariableType parameter = parameterLink.head;
-      DartType argument = argumentLink.head;
-      if (parameter == this) {
-        assert(argumentLink.tail.isEmpty == parameterLink.tail.isEmpty);
-        return argument;
-      }
-      parameterLink = parameterLink.tail;
-      argumentLink = argumentLink.tail;
-    }
-    assert(argumentLink.isEmpty && parameterLink.isEmpty);
-    // The type variable was not substituted.
-    return this;
-  }
-
-  DartType unalias(Compiler compiler) => this;
-
-  int get hashCode => 17 * element.hashCode;
-
-  bool operator ==(other) {
-    if (other is !TypeVariableType) return false;
-    return identical(other.element, element);
-  }
-
-  String toString() => name.slowToString();
-}
-
-/**
- * A statement type tracks whether a statement returns or may return.
- */
-class StatementType extends DartType {
-  final String stringName;
-
-  Element get element => null;
-
-  TypeKind get kind => TypeKind.STATEMENT;
-
-  SourceString get name => new SourceString(stringName);
-
-  const StatementType(this.stringName);
-
-  static const RETURNING = const StatementType('<returning>');
-  static const NOT_RETURNING = const StatementType('<not returning>');
-  static const MAYBE_RETURNING = const StatementType('<maybe returning>');
-
-  /** Combine the information about two control-flow edges that are joined. */
-  StatementType join(StatementType other) {
-    return (identical(this, other)) ? this : MAYBE_RETURNING;
-  }
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    // Statement types are not substitutable.
-    return this;
-  }
-
-  DartType unalias(Compiler compiler) => this;
-
-  int get hashCode => 17 * stringName.hashCode;
-
-  bool operator ==(other) {
-    if (other is !StatementType) return false;
-    return other.stringName == stringName;
-  }
-
-  String toString() => stringName;
-}
-
-class VoidType extends DartType {
-  const VoidType(this.element);
-
-  TypeKind get kind => TypeKind.VOID;
-
-  SourceString get name => element.name;
-
-  final Element element;
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    // Void cannot be substituted.
-    return this;
-  }
-
-  DartType unalias(Compiler compiler) => this;
-
-  int get hashCode => 1729;
-
-  bool operator ==(other) => other is VoidType;
-
-  String toString() => name.slowToString();
-}
-
-class MalformedType extends DartType {
-  final ErroneousElement element;
-
-  /**
-   * [declaredType] holds the type which the user wrote in code.
-   *
-   * For instance, for a resolved but malformed type like [: Map<String> :] the
-   * [declaredType] is [: Map<String> :] whereas for an unresolved type
-   */
-  final DartType userProvidedBadType;
-
-  /**
-   * Type arguments for the malformed typed, if these cannot fit in the
-   * [declaredType].
-   *
-   * This field is for instance used for [: dynamic<int> :] and [: T<int> :]
-   * where [: T :] is a type variable, in which case [declaredType] holds
-   * [: dynamic :] and [: T :], respectively, or for [: X<int> :] where [: X :]
-   * is not resolved or does not imply a type.
-   */
-  final Link<DartType> typeArguments;
-
-  MalformedType(this.element, this.userProvidedBadType,
-                [this.typeArguments = null]);
-
-  TypeKind get kind => TypeKind.MALFORMED_TYPE;
-
-  SourceString get name => element.name;
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    // Malformed types are not substitutable.
-    return this;
-  }
-
-  bool get isMalformed => true;
-
-  bool forEachMalformedType(bool f(MalformedType type)) => f(this);
-
-  DartType unalias(Compiler compiler) => this;
-
-  String toString() {
-    var sb = new StringBuffer();
-    if (typeArguments != null) {
-      if (userProvidedBadType != null) {
-        sb.add(userProvidedBadType.name.slowToString());
-      } else {
-        sb.add(element.name.slowToString());
-      }
-      if (!typeArguments.isEmpty) {
-        sb.add('<');
-        typeArguments.printOn(sb, ', ');
-        sb.add('>');
-      }
-    } else {
-      sb.add(userProvidedBadType.toString());
-    }
-    return sb.toString();
-  }
-}
-
-bool hasMalformed(Link<DartType> types) {
-  for (DartType typeArgument in types) {
-    if (typeArgument.isMalformed) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// TODO(johnniwinther): Add common supertype for InterfaceType and TypedefType.
-class InterfaceType extends DartType {
-  final ClassElement element;
-  final Link<DartType> typeArguments;
-  final bool isMalformed;
-
-  InterfaceType(this.element,
-                [Link<DartType> typeArguments = const Link<DartType>()])
-      : this.typeArguments = typeArguments,
-        this.isMalformed = hasMalformed(typeArguments) {
-    assert(invariant(element, element.isDeclaration));
-  }
-
-  TypeKind get kind => TypeKind.INTERFACE;
-
-  SourceString get name => element.name;
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic types.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    Link<DartType> newTypeArguments =
-        Types.substTypes(typeArguments, arguments, parameters);
-    if (!identical(typeArguments, newTypeArguments)) {
-      // Create a new type only if necessary.
-      return new InterfaceType(element, newTypeArguments);
-    }
-    return this;
-  }
-
-  bool forEachMalformedType(bool f(MalformedType type)) {
-    for (DartType typeArgument in typeArguments) {
-      if (!typeArgument.forEachMalformedType(f)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Returns the type as an instance of class [other], if possible, null
-   * otherwise.
-   */
-  DartType asInstanceOf(ClassElement other) {
-    if (element == other) return this;
-    for (InterfaceType supertype in element.allSupertypes) {
-      ClassElement superclass = supertype.element;
-      if (superclass == other) {
-        Link<DartType> arguments = Types.substTypes(supertype.typeArguments,
-                                                    typeArguments,
-                                                    element.typeVariables);
-        return new InterfaceType(superclass, arguments);
-      }
-    }
-    return null;
-  }
-
-  DartType unalias(Compiler compiler) => this;
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.add(name.slowToString());
-    if (!isRaw) {
-      sb.add('<');
-      typeArguments.printOn(sb, ', ');
-      sb.add('>');
-    }
-    return sb.toString();
-  }
-
-  int get hashCode {
-    int hash = element.hashCode;
-    for (Link<DartType> arguments = this.typeArguments;
-         !arguments.isEmpty;
-         arguments = arguments.tail) {
-      int argumentHash = arguments.head != null ? arguments.head.hashCode : 0;
-      hash = 17 * hash + 3 * argumentHash;
-    }
-    return hash;
-  }
-
-  bool operator ==(other) {
-    if (other is !InterfaceType) return false;
-    if (!identical(element, other.element)) return false;
-    return typeArguments == other.typeArguments;
-  }
-
-  bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
-
-  InterfaceType asRaw() => element.rawType;
-}
-
-class FunctionType extends DartType {
-  final Element element;
-  DartType returnType;
-  Link<DartType> parameterTypes;
-  final bool isMalformed;
-
-  FunctionType(DartType returnType, Link<DartType> parameterTypes,
-               Element this.element)
-      : this.returnType = returnType,
-        this.parameterTypes = parameterTypes,
-        this.isMalformed = returnType != null && returnType.isMalformed ||
-            hasMalformed(parameterTypes) {
-    assert(element == null || invariant(element, element.isDeclaration));
-  }
-
-  TypeKind get kind => TypeKind.FUNCTION;
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    var newReturnType = returnType.subst(arguments, parameters);
-    bool changed = !identical(newReturnType, returnType);
-    var newParameterTypes = Types.substTypes(parameterTypes, arguments,
-                                             parameters);
-    if (!changed && !identical(parameterTypes, newParameterTypes)) {
-      changed = true;
-    }
-    if (changed) {
-      // Create a new type only if necessary.
-      return new FunctionType(newReturnType, newParameterTypes, element);
-    }
-    return this;
-  }
-
-  bool forEachMalformedType(bool f(MalformedType type)) {
-    if (!returnType.forEachMalformedType(f)) {
-      return false;
-    }
-    for (DartType parameterType in parameterTypes) {
-      if (!parameterType.forEachMalformedType(f)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  DartType unalias(Compiler compiler) => this;
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    bool first = true;
-    sb.add('(');
-    parameterTypes.printOn(sb, ', ');
-    sb.add(') -> ${returnType}');
-    return sb.toString();
-  }
-
-  SourceString get name => const SourceString('Function');
-
-  int computeArity() {
-    int arity = 0;
-    parameterTypes.forEach((_) { arity++; });
-    return arity;
-  }
-
-  void initializeFrom(FunctionType other) {
-    assert(returnType == null);
-    assert(parameterTypes == null);
-    returnType = other.returnType;
-    parameterTypes = other.parameterTypes;
-  }
-
-  int get hashCode {
-    int hash = 17 * element.hashCode + 3 * returnType.hashCode;
-    for (Link<DartType> parameters = parameterTypes;
-         !parameters.isEmpty;
-        parameters = parameters.tail) {
-      hash = 17 * hash + 3 * parameters.head.hashCode;
-    }
-    return hash;
-  }
-
-  bool operator ==(other) {
-    if (other is !FunctionType) return false;
-    return returnType == other.returnType
-           && parameterTypes == other.parameterTypes;
-  }
-}
-
-class TypedefType extends DartType {
-  final TypedefElement element;
-  final Link<DartType> typeArguments;
-  final bool isMalformed;
-
-  TypedefType(this.element,
-              [Link<DartType> typeArguments = const Link<DartType>()])
-      : this.typeArguments = typeArguments,
-        this.isMalformed = hasMalformed(typeArguments);
-
-  TypeKind get kind => TypeKind.TYPEDEF;
-
-  SourceString get name => element.name;
-
-  DartType subst(Link<DartType> arguments, Link<DartType> parameters) {
-    if (typeArguments.isEmpty) {
-      // Return fast on non-generic typedefs.
-      return this;
-    }
-    if (parameters.isEmpty) {
-      assert(arguments.isEmpty);
-      // Return fast on empty substitutions.
-      return this;
-    }
-    Link<DartType> newTypeArguments = Types.substTypes(typeArguments, arguments,
-                                                       parameters);
-    if (!identical(typeArguments, newTypeArguments)) {
-      // Create a new type only if necessary.
-      return new TypedefType(element, newTypeArguments);
-    }
-    return this;
-  }
-
-  bool forEachMalformedType(bool f(MalformedType type)) {
-    for (DartType typeArgument in typeArguments) {
-      if (!typeArgument.forEachMalformedType(f)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  DartType unalias(Compiler compiler) {
-    // TODO(ahe): This should be [ensureResolved].
-    compiler.resolveTypedef(element);
-    // TODO(johnniwinther): Perform substitution on the unaliased type.
-    return element.alias.unalias(compiler);
-  }
-
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    sb.add(name.slowToString());
-    if (!isRaw) {
-      sb.add('<');
-      typeArguments.printOn(sb, ', ');
-      sb.add('>');
-    }
-    return sb.toString();
-  }
-
-  int get hashCode => 17 * element.hashCode;
-
-  bool operator ==(other) {
-    if (other is !TypedefType) return false;
-    if (!identical(element, other.element)) return false;
-    return typeArguments == other.typeArguments;
-  }
-
-  bool get isRaw => typeArguments.isEmpty || identical(this, element.rawType);
-
-  TypedefType asRaw() => element.rawType;
-}
-
-/**
- * Special type to hold the [dynamic] type. Used for correctly returning
- * 'dynamic' on [toString].
- */
-class DynamicType extends InterfaceType {
-  DynamicType(ClassElement element) : super(element);
-
-  SourceString get name => const SourceString('dynamic');
-}
-
-class Types {
-  final Compiler compiler;
-  // TODO(karlklose): should we have a class Void?
-  final VoidType voidType;
-  final DynamicType dynamicType;
-
-  factory Types(Compiler compiler, ClassElement dynamicElement) {
-    LibraryElement library = new LibraryElementX(new Script(null, null));
-    VoidType voidType = new VoidType(new VoidElementX(library));
-    DynamicType dynamicType = new DynamicType(dynamicElement);
-    dynamicElement.rawType = dynamicElement.thisType = dynamicType;
-    return new Types.internal(compiler, voidType, dynamicType);
-  }
-
-  Types.internal(this.compiler, this.voidType, this.dynamicType);
-
-  /** Returns true if t is a subtype of s */
-  bool isSubtype(DartType t, DartType s) {
-    if (identical(t, s) ||
-        identical(t, dynamicType) ||
-        identical(s, dynamicType) ||
-        t.isMalformed ||
-        s.isMalformed ||
-        identical(s.element, compiler.objectClass) ||
-        identical(t.element, compiler.nullClass)) {
-      return true;
-    }
-    t = t.unalias(compiler);
-    s = s.unalias(compiler);
-
-    if (t is VoidType) {
-      return false;
-    } else if (t is InterfaceType) {
-      if (s is !InterfaceType) return false;
-      ClassElement tc = t.element;
-      if (identical(tc, s.element)) return true;
-      for (Link<DartType> supertypes = tc.allSupertypes;
-           supertypes != null && !supertypes.isEmpty;
-           supertypes = supertypes.tail) {
-        DartType supertype = supertypes.head;
-        if (identical(supertype.element, s.element)) return true;
-      }
-      return false;
-    } else if (t is FunctionType) {
-      if (identical(s.element, compiler.functionClass)) return true;
-      if (s is !FunctionType) return false;
-      FunctionType tf = t;
-      FunctionType sf = s;
-      Link<DartType> tps = tf.parameterTypes;
-      Link<DartType> sps = sf.parameterTypes;
-      while (!tps.isEmpty && !sps.isEmpty) {
-        if (!isAssignable(tps.head, sps.head)) return false;
-        tps = tps.tail;
-        sps = sps.tail;
-      }
-      if (!tps.isEmpty || !sps.isEmpty) return false;
-      if (!isAssignable(sf.returnType, tf.returnType)) return false;
-      return true;
-    } else if (t is TypeVariableType) {
-      if (s is !TypeVariableType) return false;
-      return (identical(t.element, s.element));
-    } else {
-      throw 'internal error: unknown type kind';
-    }
-  }
-
-  bool isAssignable(DartType r, DartType s) {
-    return isSubtype(r, s) || isSubtype(s, r);
-  }
-
-
-  /**
-   * Helper method for performing substitution of a linked list of types.
-   *
-   * If no types are changed by the substitution, the [types] is returned
-   * instead of a newly created linked list.
-   */
-  static Link<DartType> substTypes(Link<DartType> types,
-                                   Link<DartType> arguments,
-                                   Link<DartType> parameters) {
-    bool changed = false;
-    var builder = new LinkBuilder<DartType>();
-    Link<DartType> typeLink = types;
-    while (!typeLink.isEmpty) {
-      var argument = typeLink.head.subst(arguments, parameters);
-      if (!changed && !identical(argument, typeLink.head)) {
-        changed = true;
-      }
-      builder.addLast(argument);
-      typeLink = typeLink.tail;
-    }
-    if (changed) {
-      // Create a new link only if necessary.
-      return builder.toLink();
-    }
-    return types;
-  }
-
-  /**
-   * Combine error messages in a malformed type to a single message string.
-   */
-  static String fetchReasonsFromMalformedType(DartType type) {
-    // TODO(johnniwinther): Figure out how to produce good error message in face
-    // of multiple errors, and how to ensure non-localized error messages.
-    var reasons = new List<String>();
-    type.forEachMalformedType((MalformedType malformedType) {
-      ErroneousElement error = malformedType.element;
-      Message message = error.messageKind.message(error.messageArguments);
-      reasons.add(message.toString());
-      return true;
-    });
-    return Strings.join(reasons, ', ');
-  }
-}
-
 class CancelTypeCheckException {
   final Node node;
   final String reason;
@@ -739,7 +68,7 @@
     throw new CancelTypeCheckException(node, message);
   }
 
-  reportTypeWarning(Node node, MessageKind kind, [List arguments = const []]) {
+  reportTypeWarning(Node node, MessageKind kind, [Map arguments = const {}]) {
     compiler.reportWarning(node, new TypeWarning(kind, arguments));
   }
 
@@ -784,7 +113,8 @@
    */
   checkAssignable(Node node, DartType s, DartType t) {
     if (!types.isAssignable(s, t)) {
-      reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE, [s, t]);
+      reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE,
+                        {'fromType': s, 'toType': t});
     }
   }
 
@@ -924,7 +254,7 @@
       return computeType(member);
     }
     reportTypeWarning(node, MessageKind.METHOD_NOT_FOUND,
-                      [classElement.name, name]);
+                      {'className': classElement.name, 'methodName': name});
     return types.dynamicType;
   }
 
@@ -948,7 +278,7 @@
         reportTypeWarning(arguments.head, MessageKind.ADDITIONAL_ARGUMENT);
       } else if (!parameterTypes.isEmpty) {
         reportTypeWarning(send, MessageKind.MISSING_ARGUMENT,
-                          [parameterTypes.head]);
+                          {'argumentType': parameterTypes.head});
       }
     }
   }
@@ -1156,8 +486,7 @@
       final expressionType = analyze(expression);
       if (isVoidFunction
           && !types.isAssignable(expressionType, types.voidType)) {
-        reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID,
-                          [expressionType]);
+        reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
       } else {
         checkAssignable(expression, expectedReturnType, expressionType);
       }
@@ -1168,7 +497,8 @@
     // - f is not a generative constructor.
     // - The return type of f may not be assigned to void.
     } else if (!types.isAssignable(expectedReturnType, types.voidType)) {
-      reportTypeWarning(node, MessageKind.RETURN_NOTHING, [expectedReturnType]);
+      reportTypeWarning(node, MessageKind.RETURN_NOTHING,
+                        {'returnType': expectedReturnType});
     }
     return StatementType.RETURNING;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index ee7845c..6c05203 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -970,7 +970,11 @@
                                          compiler.listClass.getLibrary()));
   }
 
-  void analyzeMain(Element element) {
+  /**
+   * Performs concrete type inference of the code reachable from [element].
+   * Returns [:true:] if and only if analysis succeeded.
+   */
+  bool analyzeMain(Element element) {
     initialize();
     cache[element] = new Map<ConcreteTypesEnvironment, ConcreteType>();
     populateCacheWithBuiltinRules();
@@ -985,10 +989,12 @@
         template[item.environment] = concreteType;
         invalidateCallers(item.method);
       }
+      return true;
     } on CancelTypeInferenceException catch(e) {
       if (LOG_FAILURES) {
-        compiler.log("'${e.node.toDebugString()}': ${e.reason}");
+        compiler.log(e.reason);
       }
+      return false;
     }
   }
 
@@ -1498,6 +1504,11 @@
   }
 
   ConcreteType visitOperatorSend(Send node) {
+    SourceString name =
+        canonicalizeMethodName(node.selector.asIdentifier().source);
+    if (name == const SourceString('is')) {
+      return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
+    }
     return visitDynamicSend(node);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index a2d7edfc..fdce427 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -22,7 +22,7 @@
   final String name = 'Type inference';
   final Set<Element> untypedElements;
   final Map<Element, Link<Element>> typedSends;
-  final ConcreteTypesInferrer concreteTypesInferrer;
+  ConcreteTypesInferrer concreteTypesInferrer;
 
   TypesTask(Compiler compiler)
     : untypedElements = new Set<Element>(),
@@ -47,7 +47,13 @@
   void onResolutionComplete(Element mainElement) {
     measure(() {
       if (concreteTypesInferrer != null) {
-        concreteTypesInferrer.analyzeMain(mainElement);
+        bool success = concreteTypesInferrer.analyzeMain(mainElement);
+        if (!success) {
+          // If the concrete type inference bailed out, we pretend it didn't
+          // happen. In the future we might want to record that it failed but
+          // use the partial results as hints.
+          concreteTypesInferrer = null;
+        }
       }
     });
   }
@@ -219,7 +225,7 @@
   }
 
   void interest(Node node, String note) {
-    var message = MessageKind.GENERIC.message([note]);
+    var message = MessageKind.GENERIC.message({'text': note});
     task.compiler.reportWarning(node, message);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 3619f47..34954ec 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -7,6 +7,7 @@
 import '../closure.dart';
 import '../elements/elements.dart';
 import '../dart2jslib.dart';
+import '../dart_types.dart';
 import '../tree/tree.dart';
 import '../util/util.dart';
 import '../js/js.dart' as js;
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index a78f395..9cc81cc 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -66,6 +66,8 @@
   get length {
     throw new UnsupportedError('get:length');
   }
+
+  int slowLength() => 0;
 }
 
 abstract class LinkBuilder<T> {
diff --git a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
index 90b863c..d00ec86 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
@@ -107,6 +107,8 @@
     }
     return myElements.isEmpty && other.isEmpty;
   }
+
+  int slowLength() => 1 + tail.slowLength();
 }
 
 class LinkBuilderImplementation<T> implements LinkBuilder<T> {
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 70c1eaf..8a07687 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -16,6 +16,17 @@
 // TODO(ahe): How about "Bolt"?
 abstract class Spannable {}
 
+class _SpannableSentinel implements Spannable {
+  final String name;
+
+  const _SpannableSentinel(this.name);
+
+  String toString() => name;
+}
+
+const Spannable CURRENT_ELEMENT_SPANNABLE =
+    const _SpannableSentinel("Current element");
+
 class SpannableAssertionFailure {
   final Spannable node;
   final String message;
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 3d9c1da..343ad14 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -8,10 +8,10 @@
   final String template;
   const MessageKind(this.template);
 
-  static const GENERIC = const MessageKind('#{1}');
+  static const GENERIC = const MessageKind('#{text}');
 
   static const NOT_ASSIGNABLE = const MessageKind(
-      '#{2} is not assignable to #{1}');
+      '#{fromType} is not assignable to #{toType}');
   static const VOID_EXPRESSION = const MessageKind(
       'expression does not yield a value');
   static const VOID_VARIABLE = const MessageKind(
@@ -19,17 +19,17 @@
   static const RETURN_VALUE_IN_VOID = const MessageKind(
       'cannot return value from void function');
   static const RETURN_NOTHING = const MessageKind(
-      'value of type #{1} expected');
+      'value of type #{returnType} expected');
   static const MISSING_ARGUMENT = const MessageKind(
-      'missing argument of type #{1}');
+      'missing argument of type #{argumentType}');
   static const ADDITIONAL_ARGUMENT = const MessageKind(
       'additional argument');
   static const METHOD_NOT_FOUND = const MessageKind(
-      'no method named #{2} in class #{1}');
+      'no method named #{methodName} in class #{className}');
   static const MEMBER_NOT_STATIC = const MessageKind(
-      '#{1}.#{2} is not static');
+      '#{className}.#{memberName} is not static');
   static const NO_INSTANCE_AVAILABLE = const MessageKind(
-      '#{1} is only available in instance methods');
+      '#{name} is only available in instance methods');
 
   static const UNREACHABLE_CODE = const MessageKind(
       'unreachable code');
@@ -39,43 +39,43 @@
       'not all paths lead to a return or throw statement');
 
   static const CANNOT_RESOLVE = const MessageKind(
-      'cannot resolve #{1}');
+      'cannot resolve #{name}');
   static const CANNOT_RESOLVE_CONSTRUCTOR = const MessageKind(
-      'cannot resolve constructor #{1}');
+      'cannot resolve constructor #{constructorName}');
   static const CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
-      'cannot resolve constructor #{1} for implicit super call');
+      'cannot resolve constructor #{constructorName} for implicit super call');
   static const CANNOT_RESOLVE_TYPE = const MessageKind(
-      'cannot resolve type #{1}');
+      'cannot resolve type #{typeName}');
   static const DUPLICATE_DEFINITION = const MessageKind(
-      'duplicate definition of #{1}');
+      'duplicate definition of #{name}');
   static const DUPLICATE_IMPORT = const MessageKind(
-      'duplicate import of #{1}');
+      'duplicate import of #{name}');
   static const DUPLICATE_EXPORT = const MessageKind(
-      'duplicate export of #{1}');
+      'duplicate export of #{name}');
   static const NOT_A_TYPE = const MessageKind(
-      '#{1} is not a type');
+      '#{node} is not a type');
   static const NOT_A_PREFIX = const MessageKind(
-      '#{1} is not a prefix');
+      '#{node} is not a prefix');
   static const NO_SUPER_IN_OBJECT = const MessageKind(
       "'Object' does not have a superclass");
   static const CANNOT_FIND_CONSTRUCTOR = const MessageKind(
-      'cannot find constructor #{1}');
+      'cannot find constructor #{constructorName}');
   static const CANNOT_FIND_CONSTRUCTOR2 = const MessageKind(
-      'cannot find constructor #{1} in #{2}');
+      'cannot find constructor #{constructorName} in #{className}');
   static const CYCLIC_CLASS_HIERARCHY = const MessageKind(
-      '#{1} creates a cycle in the class hierarchy');
+      '#{className} creates a cycle in the class hierarchy');
   static const INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
       'field initializer expected');
   static const NO_SUPER_IN_STATIC = const MessageKind(
       "'super' is only available in instance methods");
   static const DUPLICATE_INITIALIZER = const MessageKind(
-      'field #{1} is initialized more than once');
+      'field #{fieldName} is initialized more than once');
   static const ALREADY_INITIALIZED = const MessageKind(
-      '#{1} was already initialized here');
+      '#{fieldName} was already initialized here');
   static const INIT_STATIC_FIELD = const MessageKind(
-      'cannot initialize static field #{1}');
+      'cannot initialize static field #{fieldName}');
   static const NOT_A_FIELD = const MessageKind(
-      '#{1} is not a field');
+      '#{fieldName} is not a field');
   static const CONSTRUCTOR_CALL_EXPECTED = const MessageKind(
       "only call to 'this' or 'super' constructor allowed");
   static const INVALID_FOR_IN = const MessageKind(
@@ -95,19 +95,17 @@
   static const DUPLICATE_SUPER_INITIALIZER = const MessageKind(
       'cannot have more than one super initializer');
   static const INVALID_ARGUMENTS = const MessageKind(
-      "arguments do not match the expected parameters of #{1}");
+      "arguments do not match the expected parameters of #{methodName}");
   static const NO_MATCHING_CONSTRUCTOR = const MessageKind(
       "super call arguments and constructor parameters don't match");
   static const NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
       "implicit super call arguments and constructor parameters don't match");
-  static const NO_CONSTRUCTOR = const MessageKind(
-      '#{1} is a #{2}, not a constructor');
   static const FIELD_PARAMETER_NOT_ALLOWED = const MessageKind(
       'a field parameter is only allowed in generative constructors');
   static const INVALID_PARAMETER = const MessageKind(
       "cannot resolve parameter");
   static const NOT_INSTANCE_FIELD = const MessageKind(
-      '#{1} is not an instance field');
+      '#{fieldName} is not an instance field');
   static const NO_CATCH_NOR_FINALLY = const MessageKind(
       "expected 'catch' or 'finally'");
   static const EMPTY_CATCH_DECLARATION = const MessageKind(
@@ -124,27 +122,30 @@
       'cannot use re-throw outside of catch block (expression expected after '
       '"throw")');
   static const UNBOUND_LABEL = const MessageKind(
-      'cannot resolve label #{1}');
+      'cannot resolve label #{labelName}');
   static const NO_BREAK_TARGET = const MessageKind(
       'break statement not inside switch or loop');
   static const NO_CONTINUE_TARGET = const MessageKind(
       'continue statement not inside loop');
   static const EXISTING_LABEL = const MessageKind(
-      'original declaration of duplicate label #{1}');
+      'original declaration of duplicate label #{labelName}');
   static const DUPLICATE_LABEL = const MessageKind(
-      'duplicate declaration of label #{1}');
+      'duplicate declaration of label #{labelName}');
   static const UNUSED_LABEL = const MessageKind(
-      'unused label #{1}');
+      'unused label #{labelName}');
   static const INVALID_CONTINUE = const MessageKind(
       'target of continue is not a loop or switch case');
+  static const INVALID_BREAK = const MessageKind(
+      'target of break is not a statement');
+
   static const TYPE_VARIABLE_AS_CONSTRUCTOR = const MessageKind(
       'cannot use type variable as constructor');
   static const DUPLICATE_TYPE_VARIABLE_NAME = const MessageKind(
-      'type variable #{1} already declared');
+      'type variable #{typeVariableName} already declared');
   static const TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const MessageKind(
-      'cannot refer to type variable #{1} within a static member');
-  static const INVALID_BREAK = const MessageKind(
-      'target of break is not a statement');
+      'cannot refer to type variable #{typeVariableName} '
+      'within a static member');
+
   static const INVALID_USE_OF_SUPER = const MessageKind(
       'super not allowed here');
   static const INVALID_CASE_DEFAULT = const MessageKind(
@@ -171,22 +172,22 @@
       'map-literal key not a string literal');
 
   static const NO_SUCH_LIBRARY_MEMBER = const MessageKind(
-      '#{1} has no member named #{2}');
+      '#{libraryName} has no member named #{memberName}');
 
   static const CANNOT_INSTANTIATE_INTERFACE = const MessageKind(
-      "cannot instantiate interface '#{1}'");
+      "cannot instantiate interface '#{interfaceName}'");
 
   static const CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
-      "cannot instantiate typedef '#{1}'");
+      "cannot instantiate typedef '#{typedefName}'");
 
   static const CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
-      "cannot instantiate type variable '#{1}'");
+      "cannot instantiate type variable '#{typeVariableName}'");
 
   static const NO_DEFAULT_CLASS = const MessageKind(
-      "no default class on enclosing interface '#{1}'");
+      "no default class on enclosing interface '#{interfaceName}'");
 
   static const CYCLIC_TYPE_VARIABLE = const MessageKind(
-      "cyclic reference to type variable #{1}");
+      "cyclic reference to type variable #{typeVariableName}");
 
   static const CLASS_NAME_EXPECTED = const MessageKind(
       "class name expected");
@@ -195,19 +196,20 @@
       "interface type expected");
 
   static const CANNOT_EXTEND = const MessageKind(
-      "#{1} cannot be extended");
+      "#{type} cannot be extended");
 
   static const CANNOT_IMPLEMENT = const MessageKind(
-      "#{1} cannot be implemented");
+      "#{type} cannot be implemented");
 
   static const DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
-      "Error: #{1} can not be both extended and implemented.");
+      "Error: #{type} can not be both extended and implemented.");
 
   static const DUPLICATE_IMPLEMENTS = const MessageKind(
-      "Error: #{1} must not occur more than once in the implements clause.");
+      "Error: #{type} must not occur more than once "
+      "in the implements clause.");
 
   static const ILLEGAL_SUPER_SEND = const MessageKind(
-      "#{1} cannot be called on super");
+      "#{name} cannot be called on super");
 
   static const ADDITIONAL_TYPE_ARGUMENT = const MessageKind(
       "additional type argument");
@@ -218,41 +220,42 @@
   // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or MISSING_TYPE_ARGUMENT
   // instead.
   static const TYPE_ARGUMENT_COUNT_MISMATCH = const MessageKind(
-      "incorrect number of type arguments on #{1}");
+      "incorrect number of type arguments on #{type}");
 
   static const MISSING_ARGUMENTS_TO_ASSERT = const MessageKind(
       "missing arguments to assert");
 
   static const GETTER_MISMATCH = const MessageKind(
-      "Error: setter disagrees on: #{1}.");
+      "Error: setter disagrees on: #{modifiers}.");
 
   static const SETTER_MISMATCH = const MessageKind(
-      "Error: getter disagrees on: #{1}.");
+      "Error: getter disagrees on: #{modifiers}.");
 
   static const ILLEGAL_SETTER_FORMALS = const MessageKind(
       "Error: a setter must have exactly one argument.");
 
   static const NO_STATIC_OVERRIDE = const MessageKind(
-      "Error: static member cannot override instance member '#{1}' of '#{2}'.");
+      "Error: static member cannot override instance member '#{memberName}' of "
+      "'#{className}'.");
 
   static const NO_STATIC_OVERRIDE_CONT = const MessageKind(
       "Info: this is the instance member that cannot be overridden "
       "by a static member.");
 
   static const CANNOT_OVERRIDE_FIELD_WITH_METHOD = const MessageKind(
-      "Error: method cannot override field '#{1}' of '#{2}'.");
+      "Error: method cannot override field '#{memberName}' of '#{className}'.");
 
   static const CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT = const MessageKind(
       "Info: this is the field that cannot be overridden by a method.");
 
   static const CANNOT_OVERRIDE_METHOD_WITH_FIELD = const MessageKind(
-      "Error: field cannot override method '#{1}' of '#{2}'.");
+      "Error: field cannot override method '#{memberName}' of '#{className}'.");
 
   static const CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT = const MessageKind(
       "Info: this is the method that cannot be overridden by a field.");
 
   static const BAD_ARITY_OVERRIDE = const MessageKind(
-      "Error: cannot override method '#{1}' in '#{2}'; "
+      "Error: cannot override method '#{memberName}' in '#{className}'; "
       "the parameters do not match.");
 
   static const BAD_ARITY_OVERRIDE_CONT = const MessageKind(
@@ -265,33 +268,33 @@
       "Error: Formal parameters are not allowed here.");
 
   static const UNARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator #{1} must have no parameters.");
+      "Error: Operator #{operatorName} must have no parameters.");
 
   static const MINUS_OPERATOR_BAD_ARITY = const MessageKind(
       "Error: Operator - must have 0 or 1 parameters.");
 
   static const BINARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator #{1} must have exactly 1 parameter.");
+      "Error: Operator #{operatorName} must have exactly 1 parameter.");
 
   static const TERNARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator #{1} must have exactly 2 parameters.");
+      "Error: Operator #{operatorName} must have exactly 2 parameters.");
 
   static const OPERATOR_OPTIONAL_PARAMETERS = const MessageKind(
-      "Error: Operator #{1} cannot have optional parameters.");
+      "Error: Operator #{operatorName} cannot have optional parameters.");
 
   static const OPERATOR_NAMED_PARAMETERS = const MessageKind(
-      "Error: Operator #{1} cannot have named parameters.");
+      "Error: Operator #{operatorName} cannot have named parameters.");
 
   // TODO(ahe): This message is hard to localize.  This is acceptable,
   // as it will be removed when we ship Dart version 1.0.
   static const DEPRECATED_FEATURE_WARNING = const MessageKind(
-      "Warning: deprecated language feature, #{1}, "
+      "Warning: deprecated language feature, #{featureName}, "
       "will be removed in a future Dart milestone.");
 
   // TODO(ahe): This message is hard to localize.  This is acceptable,
   // as it will be removed when we ship Dart version 1.0.
   static const DEPRECATED_FEATURE_ERROR = const MessageKind(
-      "Error: #{1} are not legal "
+      "Error: #{featureName} are not legal "
       "due to option --reject-deprecated-language-features.");
 
   static const CONSTRUCTOR_WITH_RETURN_TYPE = const MessageKind(
@@ -301,10 +304,10 @@
       "Error: cannot have final modifier on method.");
 
   static const ILLEGAL_CONSTRUCTOR_MODIFIERS = const MessageKind(
-      "Error: illegal constructor modifiers: #{1}.");
+      "Error: illegal constructor modifiers: #{modifiers}.");
 
   static const ILLEGAL_MIXIN_APPLICATION_MODIFIERS = const MessageKind(
-      "Error: illegal mixin application modifiers: #{1}.");
+      "Error: illegal mixin application modifiers: #{modifiers}.");
 
   static const ILLEGAL_MIXIN_SUPERCLASS = const MessageKind(
       "Error: class used as mixin must have Object as superclass.");
@@ -313,10 +316,11 @@
       "Error: class used as mixin cannot have non-factory constructor.");
 
   static const ILLEGAL_MIXIN_CYCLE = const MessageKind(
-      "Error: class used as mixin introduces mixin cycle: #{1} <-> #{2}.");
+      "Error: class used as mixin introduces mixin cycle: "
+      "#{mixinName1} <-> #{mixinName2}.");
 
   static const ILLEGAL_MIXIN_WITH_SUPER = const MessageKind(
-      "Error: cannot use class #{1} as a mixin because it uses super.");
+      "Error: cannot use class #{className} as a mixin because it uses super.");
 
   static const ILLEGAL_MIXIN_SUPER_USE = const MessageKind(
       "Use of super in class used as mixin.");
@@ -337,7 +341,7 @@
       'Error: part header must come before top-level definitions.');
 
   static const LIBRARY_NAME_MISMATCH = const MessageKind(
-      'Warning: expected part of library name "#{1}".');
+      'Warning: expected part of library name "#{libraryName}".');
 
   static const MISSING_PART_OF_TAG = const MessageKind(
       'Note: This file has no part-of tag, but it is being used as a part.');
@@ -349,43 +353,47 @@
       'Error: directive not allowed here.');
 
   static const DUPLICATED_LIBRARY_NAME = const MessageKind(
-      'Warning: duplicated library name "#{1}".');
+      'Warning: duplicated library name "#{libraryName}".');
 
   static const INVALID_SOURCE_FILE_LOCATION = const MessageKind('''
-Invalid offset (#{1}) in source map.
-File: #{2}
-Length: #{3}''');
+Invalid offset (#{offset}) in source map.
+File: #{fileName}
+Length: #{length}''');
 
   static const PATCH_RETURN_TYPE_MISMATCH = const MessageKind(
-      "Patch return type '#{3}' doesn't match '#{2}' on origin method '#{1}'.");
+      "Patch return type '#{patchReturnType}' doesn't match "
+      "'#{originReturnType}' on origin method '#{methodName}'.");
 
   static const PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH = const MessageKind(
-      "Required parameter count of patch method (#{3}) doesn't match parameter "
-      "count on origin method '#{1}' (#{2}).");
+      "Required parameter count of patch method (#{patchParameterCount}) "
+      "doesn't match parameter count on origin method '#{methodName}' "
+      "(#{originParameterCount}).");
 
   static const PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH = const MessageKind(
-      "Optional parameter count of patch method (#{3}) doesn't match parameter "
-      "count on origin method '#{1}' (#{2}).");
+      "Optional parameter count of patch method (#{patchParameterCount}) "
+      "doesn't match parameter count on origin method '#{methodName}' "
+      "(#{originParameterCount}).");
 
   static const PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH = const MessageKind(
-      "Optional parameters of origin and patch method '#{1}' must "
+      "Optional parameters of origin and patch method '#{methodName}' must "
       "both be either named or positional.");
 
   static const PATCH_PARAMETER_MISMATCH = const MessageKind(
-      "Patch method parameter '#{3}' doesn't match '#{2}' on origin method "
-      "#{1}.");
+      "Patch method parameter '#{patchParameter}' doesn't match "
+      "'#{originParameter}' on origin method #{methodName}.");
+
+  static const EXTERNAL_WITHOUT_IMPLEMENTATION = const MessageKind(
+      "External method without an implementation.");
 
   static const TOP_LEVEL_VARIABLE_DECLARED_STATIC = const MessageKind(
       "Top-level variable cannot be declared static.");
 
   static const WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT = const MessageKind(
-      "Wrong number of arguments to assert. Should be 1, but given #{1}.");
+      "Wrong number of arguments to assert. Should be 1, but given "
+      "#{argumentCount}.");
 
   static const ASSERT_IS_GIVEN_NAMED_ARGUMENTS = const MessageKind(
-      "assert takes no named arguments, but given #{1}.");
-
-  static const MALFORMED_TYPE_REFERENCE = const MessageKind(
-      "Malformed type reference encountered in #{1}.");
+      "assert takes no named arguments, but given #{argumentCount}.");
 
   static const FACTORY_REDIRECTION_IN_NON_FACTORY = const MessageKind(
       "Error: Factory redirection only allowed in factories.");
@@ -410,7 +418,7 @@
 
 * the name and version of your operating system,
 
-* the Dart SDK build number (#{1}), and
+* the Dart SDK build number (#{buildId}), and
 
 * the entire message you see here (including the full stack trace
   below as well as the source location above).
@@ -418,34 +426,43 @@
 
   toString() => template;
 
-  Message message([List arguments = const []]) {
+  Message message([Map arguments = const {}]) {
     return new Message(this, arguments);
   }
 
-  CompilationError error([List arguments = const []]) {
+  CompilationError error([Map arguments = const {}]) {
     return new CompilationError(this, arguments);
   }
 }
 
 class Message {
   final kind;
-  final List arguments;
+  final Map arguments;
   String message;
 
-  Message(this.kind, this.arguments);
+  Message(this.kind, this.arguments) {
+    assert(() { computeMessage(); return true; });
+  }
 
-  String toString() {
+  String computeMessage() {
     if (message == null) {
       message = kind.template;
-      int position = 1;
-      for (var argument in arguments) {
-        String string = slowToString(argument);
-        message = message.replaceAll('#{${position++}}', string);
-      }
+      arguments.forEach((key, value) {
+        String string = slowToString(value);
+        message = message.replaceAll('#{${key}}', string);
+      });
+      assert(invariant(
+          CURRENT_ELEMENT_SPANNABLE,
+          !message.contains(new RegExp(r"#\{.+\}")),
+          message: 'Missing arguments in error message: "$message"'));
     }
     return message;
   }
 
+  String toString() {
+    return computeMessage();
+  }
+
   bool operator==(other) {
     if (other is !Message) return false;
     return (kind == other.kind) && (toString() == other.toString());
@@ -462,32 +479,32 @@
 
 class Diagnostic {
   final Message message;
-  Diagnostic(MessageKind kind, List arguments)
-    : message = new Message(kind, arguments);
+  Diagnostic(MessageKind kind, [Map arguments = const {}])
+      : message = new Message(kind, arguments);
   String toString() => message.toString();
 }
 
 class TypeWarning extends Diagnostic {
-  TypeWarning(MessageKind kind, List arguments)
+  TypeWarning(MessageKind kind, [Map arguments = const {}])
     : super(kind, arguments);
 }
 
 class ResolutionError extends Diagnostic {
-  ResolutionError(MessageKind kind, List arguments)
-    : super(kind, arguments);
+  ResolutionError(MessageKind kind, [Map arguments = const {}])
+      : super(kind, arguments);
 }
 
 class ResolutionWarning extends Diagnostic {
-  ResolutionWarning(MessageKind kind, List arguments)
+  ResolutionWarning(MessageKind kind, [Map arguments = const {}])
     : super(kind, arguments);
 }
 
 class CompileTimeConstantError extends Diagnostic {
-  CompileTimeConstantError(MessageKind kind, List arguments)
+  CompileTimeConstantError(MessageKind kind, [Map arguments = const {}])
     : super(kind, arguments);
 }
 
 class CompilationError extends Diagnostic {
-  CompilationError(MessageKind kind, List arguments)
+  CompilationError(MessageKind kind, [Map arguments = const {}])
     : super(kind, arguments);
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 6576701..2520489 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -357,7 +357,7 @@
     }
 
     startFile("apidoc.json");
-    var libraries = _sortedLibraries.mappedBy(
+    var libraries = _sortedLibraries.map(
         (lib) => new LibraryElement(lib.qualifiedName, lib))
         .toList();
     write(json_serializer.serialize(libraries));
@@ -1700,7 +1700,7 @@
     final typeArgs = type.typeArguments;
     if (typeArgs.length > 0) {
       final args =
-          Strings.join(typeArgs.mappedBy((arg) => typeName(arg)), ', ');
+          Strings.join(typeArgs.map((arg) => typeName(arg)), ', ');
       return '${type.originalDeclaration.simpleName}&lt;$args&gt;';
     }
 
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
index 021b7f7..194bc5f 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-live-nav.dart
@@ -11,13 +11,10 @@
 // TODO(rnystrom): Use "package:" URL (#4968).
 import '../../classify.dart';
 import '../../markdown.dart' as md;
-part '../dartdoc/nav.dart';
-
-// TODO(rnystrom): Use "package:" URL (#4968).
-part 'dropdown.dart';
-part 'search.dart';
-part '../dartdoc/nav.dart';
-part 'client-shared.dart';
+import '../dartdoc/nav.dart';
+import 'dropdown.dart';
+import 'search.dart';
+import 'client-shared.dart';
 
 main() {
   setup();
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart
index 82a71c7..7348f2e 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-shared.dart
@@ -2,7 +2,13 @@
 // for 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 client;
+library client_shared;
+
+import 'dart:html';
+import 'dropdown.dart';
+import '../../classify.dart';
+import '../dartdoc/nav.dart';
+
 
 // Code shared between the different client-side libraries.
 
@@ -49,7 +55,7 @@
         } else {
           // Syntax highlight.
           if (!pre.classes.contains('formatted')) {
-            pre.innerHTML = classifySource(pre.text);
+            pre.innerHtml = classifySource(pre.text);
             pre.classes.add('formatted');
           };
           pre.classes.add('expanded');
@@ -70,10 +76,10 @@
     String display = showInherited.dataAttributes['show-inherited'];
     if (display == 'block') {
       display = 'none';
-      showInherited.innerHTML = 'Show inherited';
+      showInherited.innerHtml = 'Show inherited';
     } else {
       display = 'block';
-      showInherited.innerHTML = 'Hide inherited';
+      showInherited.innerHtml = 'Hide inherited';
     }
     showInherited.dataAttributes['show-inherited'] = display;
     for (var elem in document.queryAll('.inherited')) {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart b/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart
index a411064..d76b21e 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/client-static.dart
@@ -7,15 +7,9 @@
 
 import 'dart:html';
 import 'dart:json';
-import '../../../../compiler/implementation/source_file.dart';
-// TODO(rnystrom): Use "package:" URL (#4968).
-import '../../classify.dart';
-import '../dartdoc/nav.dart';
+import 'dropdown.dart';
+import 'client-shared.dart';
 
-// TODO(rnystrom): Use "package:" URL (#4968).
-part 'dropdown.dart';
-part 'search.dart';
-part 'client-shared.dart';
 part '../../../tmp/nav.dart';
 
 main() {
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
index ca0ff81..05798b3 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/dropdown.dart
@@ -2,7 +2,12 @@
 // for 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 client;
+library dropdown;
+
+import 'dart:html';
+import 'search.dart';
+import 'client-shared.dart';
+import '../dartdoc/nav.dart';
 
 List libraryList;
 InputElement searchInput;
@@ -59,7 +64,7 @@
 
   if (results.isEmpty) {
     var row = table.insertRow(0);
-    row.innerHTML = "<tr><td>No matches found for '$text'.</td></tr>";
+    row.innerHtml = "<tr><td>No matches found for '$text'.</td></tr>";
   } else {
     results.sort(resultComparator);
 
@@ -72,11 +77,11 @@
     }
     if (results.length >= 10) {
       var row = table.insertRow(table.rows.length);
-      row.innerHTML = '<tr><td>+ ${results.length-10} more.</td></tr>';
+      row.innerHtml = '<tr><td>+ ${results.length-10} more.</td></tr>';
       results = results.getRange(0, 10);
     }
   }
-  dropdown.elements = elements;
+  dropdown.children = elements;
   updateResults(text, results);
   showDropDown();
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
index 111d333..22f4880 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/client/search.dart
@@ -2,7 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of client;
+library search;
+
+import 'dart:html';
+import 'dropdown.dart';
+import '../dartdoc/nav.dart';
 
 /**
  * [SearchText] represent the search field text. The text is viewed in three
diff --git a/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart b/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart
index afab003..017633f 100644
--- a/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/dartdoc_search_test.dart
@@ -5,8 +5,8 @@
 library dartdoc_search_test;

 

 // TODO(rnystrom): Use "package:" URL (#4968).

-part '../lib/src/dartdoc/nav.dart';

-part '../lib/src/client/search.dart';

+import '../lib/src/dartdoc/nav.dart';

+import '../lib/src/client/search.dart';

 

 const String URL = 'dummy-url';

 

diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 9e0fefd..80716fb 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -7,7 +7,6 @@
 part 'async_error.dart';
 part 'future.dart';
 part 'future_impl.dart';
-part 'merge_stream.dart';
 part 'stream.dart';
 part 'stream_controller.dart';
 part 'stream_impl.dart';
diff --git a/sdk/lib/async/async_sources.gypi b/sdk/lib/async/async_sources.gypi
index 74daf49..fe95d17 100644
--- a/sdk/lib/async/async_sources.gypi
+++ b/sdk/lib/async/async_sources.gypi
@@ -8,7 +8,6 @@
     'async_error.dart',
     'future.dart',
     'future_impl.dart',
-    'merge_stream.dart',
     'stream.dart',
     'stream_controller.dart',
     'stream_impl.dart',
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 0c4daa0..0d32aae 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -85,16 +85,50 @@
 // TODO(floitsch): document chaining.
 abstract class Future<T> {
   /**
+   * Creates a future containing the result of calling [function].
+   *
+   * The result of computing [:function():] is either a returned value or
+   * a throw.
+   *
+   * If a value is returned, it becomes the result of the created future.
+   *
+   * If calling [function] throws, the created [Future] will be completed
+   * with an async error containing the thrown value and a captured
+   * stacktrace.
+   *
+   * However, if the result of calling [function] is already an asynchronous
+   * result, we treat it specially.
+   *
+   * If the returned value is itself a [Future], completion of
+   * the created future will wait until the returned future completes,
+   * and will then complete with the same result.
+   *
+   * If a thrown value is an [AsyncError], it is used directly as the result
+   * of the created future.
+   */
+  factory Future.of(function()) {
+    try {
+      var result = function();
+      return new _FutureImpl<T>().._setOrChainValue(result);
+    } catch (error, stackTrace) {
+      return new _FutureImpl<T>.immediateError(error, stackTrace);
+    }
+  }
+
+  /**
    * A future whose value is available in the next event-loop iteration.
    *
-   * See [Completer]s, for futures with values that are computed asynchronously.
+   * If [value] is not a [Future], using this constructor is equivalent
+   * to [:new Future.of(() => value):].
+   *
+   * See [Completer] to create a Future and complete it later.
    */
   factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value);
 
   /**
    * A future that completes with an error in the next event-loop iteration.
    *
-   * See [Completer]s, for futures with values that are computed asynchronously.
+   * See [Completer] to create a Future and complete it later.
    */
   factory Future.immediateError(var error, [Object stackTrace]) {
     return new _FutureImpl<T>.immediateError(error, stackTrace);
@@ -113,7 +147,8 @@
    * See [Completer]s, for futures with values that are computed asynchronously.
    */
   factory Future.delayed(int milliseconds, T value()) {
-    _FutureImpl<T> future = new _ThenFuture<dynamic, T>((_) => value());
+    _ThenFuture<dynamic, T> future =
+        new _ThenFuture<dynamic, T>((_) => value());
     new Timer(milliseconds, (_) => future._sendValue(null));
     return future;
   }
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index e91da2b..53ba3f3 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -304,31 +304,8 @@
     }
   }
 
-  _FutureListener _asListener() => new _FutureListener.wrap(this);
-}
-
-/**
- * Transforming future base class.
- *
- * A transforming future is itself a future and a future listener.
- * Subclasses override [_sendValue]/[_sendError] to intercept
- * the results of a previous future.
- */
-abstract class _TransformFuture<S, T> extends _FutureImpl<T>
-                                      implements _FutureListener<S> {
-  // _FutureListener implementation.
-  _FutureListener _nextListener;
-
-  void _sendValue(S value);
-
-  void _sendError(AsyncError error);
-
-  void _subscribeTo(_FutureImpl future) {
-    future._addListener(this);
-  }
-
   /**
-   * Helper function to hand the result of transforming an incoming event.
+   * Helper function to handle the result of transforming an incoming event.
    *
    * If the result is itself a [Future], this future is linked to that
    * future's output. If not, this future is completed with the result.
@@ -351,6 +328,29 @@
       _setValue(result);
     }
   }
+
+  _FutureListener _asListener() => new _FutureListener.wrap(this);
+}
+
+/**
+ * Transforming future base class.
+ *
+ * A transforming future is itself a future and a future listener.
+ * Subclasses override [_sendValue]/[_sendError] to intercept
+ * the results of a previous future.
+ */
+abstract class _TransformFuture<S, T> extends _FutureImpl<T>
+                                      implements _FutureListener<S> {
+  // _FutureListener implementation.
+  _FutureListener _nextListener;
+
+  void _sendValue(S value);
+
+  void _sendError(AsyncError error);
+
+  void _subscribeTo(_FutureImpl future) {
+    future._addListener(this);
+  }
 }
 
 /** The onValue and onError handlers return either a value or a future */
diff --git a/sdk/lib/async/merge_stream.dart b/sdk/lib/async/merge_stream.dart
deleted file mode 100644
index 424b69c..0000000
--- a/sdk/lib/async/merge_stream.dart
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart.async;
-
-class _SupercedeEntry<T> {
-  final SupercedeStream stream;
-  Stream<T> source;
-  StreamSubscription subscription = null;
-  _SupercedeEntry next;
-
-  _SupercedeEntry(this.stream, this.source, this.next);
-
-  // Whether the source stream is complete.
-  bool get isDone => source == null;
-
-  void onData(T data) {
-    // Stop all lower-priority sources.
-    stream._setData(this, data);
-  }
-
-  void onError(AsyncError error) {
-    stream._signalError(error);
-  }
-
-  void onDone() {
-    subscription = null;
-    source = null;
-    stream._setDone(this);
-  }
-
-  void start() {
-    assert(subscription == null);
-    if (!isDone) {
-      subscription =
-          source.listen(onData, onError: onError, onDone: onDone);
-    }
-  }
-
-  void stop() {
-    if (!isDone) {
-      subscription.cancel();
-      subscription = null;
-    }
-  }
-
-  void pause() {
-    if (!isDone) subscription.pause();
-  }
-
-  void resume() {
-    if (!isDone) subscription.resume();
-  }
-}
-
-/**
- * [Stream] that forwards data from its active source with greatest priority.
- *
- * The [SupercedeStream] gets data from some source [Stream]s which
- * are ordered in order of increasing priority.
- * When a higher priority stream provides data, all lower priority streams
- * are dropped.
- *
- * Errors from all (undropped) streams are forwarded.
- */
-class SupercedeStream<T> extends _MultiStreamImpl<T> {
-  _SupercedeEntry _entries = null;
-
-  /**
-   * Create [SupercedeStream] from the given [sources].
-   *
-   * The [sources] are iterated in order of increasing priority.
-   */
-  SupercedeStream(Iterable<Stream<T>> sources) {
-    // Set up linked list of sources in decreasing priority order.
-    // The order allows us to drop all lower priority streams when a higher
-    // priority stream provides a value.
-    for (Stream<T> stream in sources) {
-      _entries = new _SupercedeEntry(this, stream, _entries);
-    }
-  }
-
-  void _onSubscriptionStateChange() {
-    if (_hasSubscribers) {
-      for (_SupercedeEntry entry = _entries;
-           entry != null;
-           entry = entry.next) {
-        entry.start();
-      }
-    } else {
-      for (_SupercedeEntry entry = _entries;
-           entry != null;
-           entry = entry.next) {
-        entry.stop();
-      }
-    }
-  }
-
-  void _onPauseStateChange() {
-    if (_isPaused) {
-      for (_SupercedeEntry entry = _entries;
-           entry != null;
-           entry = entry.next) {
-        entry.pause();
-      }
-    } else {
-      for (_SupercedeEntry entry = _entries;
-           entry != null;
-           entry = entry.next) {
-        entry.resume();
-      }
-    }
-  }
-
-  void _setData(_SupercedeEntry entry, T data) {
-    while (entry.next != null)  {
-      _SupercedeEntry nextEntry = entry.next;
-      entry.next = null;
-      nextEntry.stop();
-      entry = nextEntry;
-    }
-    _add(data);
-  }
-
-  void _setDone(_SupercedeEntry entry) {
-    if (identical(_entries, entry)) {
-      // Remove the leading completed streams. These are streams
-      // the completed without ever providing data.
-      while (_entries.isDone) {
-        _entries = _entries.next;
-        if (_entries == null) {
-          _close();
-          return;
-        }
-      }
-    }
-    // Otherwise we leave the completed entry in the list and
-    // remove it when a higher priority stream provides data or
-    // all higher priority streams have completed.
-  }
-}
-
-/**
- * Helper class for [CyclicScheduleStream].
- *
- * Used to maintain a list of source streams which are activated in cyclic
- * order.
- *
- * The stream is either unsubscribed, paused or active. Only one stream
- * will be active at a time. A source is not subscribed until it's first
- * activated.
- *
- * If the source completes, the entry is removed from [stream].
- */
-class _CycleEntry<T> {
-  final CyclicScheduleStream stream;
-  /** A single source stream for the [CyclicScheduleStream]. */
-  Stream source;
-  /** The active subscription, if any. */
-  StreamSubscription subscription = null;
-  /** Next entry in a linked list of entries. */
-  _CycleEntry next;
-
-  _CycleEntry(this.stream, this.source);
-
-  void cancel() {
-    // This method may be called event if this entry has never been activated.
-    if (subscription != null) {
-      subscription.cancel();
-      subscription = null;
-    }
-  }
-
-  void pause() {
-    ensureSubscribed();
-    if (!subscription.isPaused) {
-      subscription.pause();
-    }
-  }
-
-  void activate() {
-    ensureSubscribed();
-    if (subscription.isPaused) {
-      subscription.resume();
-    }
-  }
-
-  void ensureSubscribed() {
-    if (subscription == null) {
-      subscription =
-          source.listen(stream._onData,
-                        onError: stream._signalError,
-                        onDone: stream._onDone);
-    }
-  }
-}
-
-/**
- * [Stream] that schedules events from multiple sources in cyclic order.
- *
- * The source streams are activated and paused so that only one data event
- * is generated at a time, and those data events are output on this stream.
- *
- * Error events from the currently active stream are forwarded without
- * changing the schedule. When a source stream ends, it is removed from
- * the schedule.
- */
-class CyclicScheduleStream<T> extends _MultiStreamImpl<T> {
-  _CycleEntry _currentEntry = null;
-  _CycleEntry _lastEntry = null;
-
-  /**
-   * Create a [Stream] that provides data from [sources] one event at a time.
-   *
-   * The data are provided as one event from each stream in the order they are
-   * given by the [Iterable], and then cycling as long as there are data.
-   */
-  CyclicScheduleStream(Iterable<Stream<T>> sources) {
-    _CycleEntry entry = null;
-    for (Stream<T> source in sources) {
-      _CycleEntry newEntry = new _CycleEntry(this, source);
-      if (_lastEntry == null) {
-        _currentEntry = _lastEntry = newEntry;
-      } else {
-        _lastEntry = _lastEntry.next = newEntry;
-      }
-    }
-    if (_currentEntry == null) {
-      _close();
-    }
-  }
-
-  void _onSubscriptionStateChange() {
-    if (_hasSubscribers) {
-      _currentEntry.activate();
-      for (_CycleEntry entry = _currentEntry.next;
-           entry != null;
-           entry = entry.next) {
-        entry.pause();
-      }
-      return;
-    }
-    for (_CycleEntry entry = _currentEntry; entry != null; entry = entry.next) {
-      entry.cancel();
-    }
-  }
-
-  void _onPauseStateChange() {
-    if (_isPaused) {
-      _currentEntry.pause();
-    } else {
-      _currentEntry.activate();
-    }
-  }
-
-  void _onData(T data) {
-    if (_currentEntry.next != null) {
-      _currentEntry.pause();
-      _add(data);
-      // Move the current entry to the end of the list.
-      _lastEntry = _lastEntry.next = _currentEntry;
-      _currentEntry = _currentEntry.next;
-      _lastEntry.next = null;
-      _currentEntry.activate();
-    } else {
-      // No pausing with only one entry left.
-      _add(data);
-    }
-  }
-
-  void _onDone() {
-    if (_currentEntry.next == null) {
-      _close();
-      _currentEntry = _lastEntry = null;
-    } else {
-      // Remove the current entry from the list now that it's complete.
-      _currentEntry = _currentEntry.next;
-      _currentEntry.activate();
-    }
-  }
-}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index ed4ab1a..afdeaf3 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -40,12 +40,11 @@
  * A broadcast stream allows any number of listeners, and it fires
  * its events when they are ready, whether there are listeners or not.
  *
- * Braodcast streams are used for independent events/observers.
+ * Broadcast streams are used for independent events/observers.
  *
- * The default implementation of [isBroadcast] and
- * [asBroadcastStream] are assuming this is a single-subscription stream
- * and a broadcast stream inheriting from [Stream] must override these
- * to return [:true:] and [:this:] respectively.
+ * The default implementation of [isBroadcast] returns false.
+ * A broadcast stream inheriting from [Stream] must override [isBroadcast]
+ * to return [:true:].
  */
 abstract class Stream<T> {
   Stream();
@@ -93,37 +92,11 @@
    * If this stream is already a broadcast stream, it is returned unmodified.
    */
   Stream<T> asBroadcastStream() {
+    if (isBroadcast) return this;
     return new _SingleStreamMultiplexer<T>(this);
   }
 
   /**
-   * Stream that outputs events from the [sources] in cyclic order.
-   *
-   * The merged streams are paused and resumed in order to ensure the proper
-   * order of output events.
-   */
-  factory Stream.cyclic(Iterable<Stream> sources) {
-    return new CyclicScheduleStream<T>(sources);
-  }
-
- /**
-   * Create a stream that forwards data from the highest priority active source.
-   *
-   * Sources are provided in order of increasing priority, and only data from
-   * the highest priority source stream that has provided data are output
-   * on the created stream.
-   *
-   * Errors from the most recent active stream, and any higher priority stream,
-   * are forwarded to the created stream.
-   *
-   * If a higher priority source stream completes without providing data,
-   * it will have no effect on lower priority streams.
-   */
-  factory Stream.superceding(Iterable<Stream<T>> sources) {
-    return new SupercedeStream<T>(sources);
-  }
-
-  /**
    * Add a subscription to this stream.
    *
    * On each data event from this stream, the subscribers [onData] handler
@@ -149,18 +122,25 @@
    * but it only sends the data events that satisfy the [test].
    */
   Stream<T> where(bool test(T event)) {
-    return new WhereStream<T>(this, test);
+    return new _WhereStream<T>(this, test);
   }
 
   /**
    * Create a new stream that converts each element of this stream
    * to a new value using the [convert] function.
    */
-  Stream mappedBy(convert(T event)) {
-    return new MapStream<T, dynamic>(this, convert);
+  Stream map(convert(T event)) {
+    return new _MapStream<T, dynamic>(this, convert);
   }
 
   /**
+   * Deprecated alias for [map].
+   *
+   * @deprecated
+   */
+  Stream mappedBy(f(T element)) => map(f);
+
+  /**
    * Create a wrapper Stream that intercepts some errors from this stream.
    *
    * If this stream sends an error that matches [test], then it is intercepted
@@ -172,10 +152,13 @@
    * If the error is intercepted, the [handle] function can decide what to do
    * with it. It can throw if it wants to raise a new (or the same) error,
    * or simply return to make the stream forget the error.
+   *
+   * If you need to transform an error into a data event, use the more generic
+   * [Stream.transformEvent] to handle the event by writing a data event to
+   * the output sink
    */
-   // TODO(lrn): Say what to do if you want to convert the error to a value.
   Stream<T> handleError(void handle(AsyncError error), { bool test(error) }) {
-    return new HandleErrorStream<T>(this, handle, test);
+    return new _HandleErrorStream<T>(this, handle, test);
   }
 
   /**
@@ -187,13 +170,13 @@
    * in order.
    */
   Stream expand(Iterable convert(T value)) {
-    return new ExpandStream<T, dynamic>(this, convert);
+    return new _ExpandStream<T, dynamic>(this, convert);
   }
 
   /**
    * Bind this stream as the input of the provided [StreamConsumer].
    */
-  Future pipe(StreamConsumer<dynamic, T> streamConsumer) {
+  Future pipe(StreamConsumer<T, dynamic> streamConsumer) {
     return streamConsumer.consume(this);
   }
 
@@ -206,14 +189,15 @@
     return streamTransformer.bind(this);
   }
 
-
   /** Reduces a sequence of values by repeatedly applying [combine]. */
   Future reduce(var initialValue, combine(var previous, T element)) {
     _FutureImpl result = new _FutureImpl();
     var value = initialValue;
     StreamSubscription subscription;
     subscription = this.listen(
-      (T element) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ element) {
         _runUserCode(
           () => combine(value, element),
           (result) { value = result; },
@@ -257,13 +241,15 @@
     _FutureImpl<bool> future = new _FutureImpl<bool>();
     StreamSubscription subscription;
     subscription = this.listen(
-        (T element) {
+        // TODO(ahe): Restore type when feature is implemented in dart2js
+        // checked mode. http://dartbug.com/7733
+        (/*T*/ element) {
           _runUserCode(
-            () => match(element),
+            () => (element == match),
             (bool isMatch) {
               if (isMatch) {
                 subscription.cancel();
-                future._setValue(element);
+                future._setValue(true);
               }
             },
             _cancelAndError(subscription, future)
@@ -287,7 +273,9 @@
     _FutureImpl<bool> future = new _FutureImpl<bool>();
     StreamSubscription subscription;
     subscription = this.listen(
-        (T element) {
+        // TODO(ahe): Restore type when feature is implemented in dart2js
+        // checked mode. http://dartbug.com/7733
+        (/*T*/ element) {
           _runUserCode(
             () => test(element),
             (bool isMatch) {
@@ -317,7 +305,9 @@
     _FutureImpl<bool> future = new _FutureImpl<bool>();
     StreamSubscription subscription;
     subscription = this.listen(
-        (T element) {
+        // TODO(ahe): Restore type when feature is implemented in dart2js
+        // checked mode. http://dartbug.com/7733
+        (/*T*/ element) {
           _runUserCode(
             () => test(element),
             (bool isMatch) {
@@ -363,12 +353,17 @@
    * If [compare] is omitted, it defaults to [Comparable.compare].
    */
   Future<T> min([int compare(T a, T b)]) {
-    if (compare == null) compare = Comparable.compare;
+    if (compare == null) {
+      var defaultCompare = Comparable.compare;
+      compare = defaultCompare;
+    }
     _FutureImpl<T> future = new _FutureImpl<T>();
     StreamSubscription subscription;
     T min = null;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         min = value;
         subscription.onData((T value) {
           _runUserCode(
@@ -402,12 +397,17 @@
    * If [compare] is omitted, it defaults to [Comparable.compare].
    */
   Future<T> max([int compare(T a, T b)]) {
-    if (compare == null) compare = Comparable.compare;
+    if (compare == null)  {
+      var defaultCompare = Comparable.compare;
+      compare = defaultCompare;
+    }
     _FutureImpl<T> future = new _FutureImpl<T>();
     StreamSubscription subscription;
     T max = null;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         max = value;
         subscription.onData((T value) {
           _runUserCode(
@@ -452,7 +452,9 @@
     List<T> result = <T>[];
     _FutureImpl<List<T>> future = new _FutureImpl<List<T>>();
     this.listen(
-      (T data) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ data) {
         result.add(data);
       },
       onError: future._setError,
@@ -468,7 +470,9 @@
     Set<T> result = new Set<T>();
     _FutureImpl<Set<T>> future = new _FutureImpl<Set<T>>();
     this.listen(
-      (T data) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ data) {
         result.add(data);
       },
       onError: future._setError,
@@ -489,7 +493,7 @@
    * so will the returned stream.
    */
   Stream<T> take(int count) {
-    return new TakeStream(this, count);
+    return new _TakeStream(this, count);
   }
 
   /**
@@ -501,14 +505,14 @@
    * a value that [test] doesn't accept.
    */
   Stream<T> takeWhile(bool test(T value)) {
-    return new TakeWhileStream(this, test);
+    return new _TakeWhileStream(this, test);
   }
 
   /**
    * Skips the first [count] data events from this stream.
    */
   Stream<T> skip(int count) {
-    return new SkipStream(this, count);
+    return new _SkipStream(this, count);
   }
 
   /**
@@ -520,7 +524,7 @@
    * event data, the returned stream will have the same events as this stream.
    */
   Stream<T> skipWhile(bool test(T value)) {
-    return new SkipWhileStream(this, test);
+    return new _SkipWhileStream(this, test);
   }
 
   /**
@@ -533,7 +537,7 @@
    * omitted, the '==' operator on the last provided data element is used.
    */
   Stream<T> distinct([bool equals(T previous, T next)]) {
-    return new DistinctStream(this, equals);
+    return new _DistinctStream(this, equals);
   }
 
   /**
@@ -546,7 +550,9 @@
     _FutureImpl<T> future = new _FutureImpl<T>();
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         future._setValue(value);
         subscription.cancel();
         return;
@@ -570,7 +576,9 @@
     bool foundResult = false;
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         foundResult = true;
         result = value;
       },
@@ -597,7 +605,9 @@
     bool foundResult = false;
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         if (foundResult) {
           // This is the second element we get.
           Error error = new StateError("More than one element");
@@ -638,7 +648,9 @@
     _FutureImpl<T> future = new _FutureImpl<T>();
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         _runUserCode(
           () => test(value),
           (bool isMatch) {
@@ -676,7 +688,9 @@
     bool foundResult = false;
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         _runUserCode(
           () => true == test(value),
           (bool isMatch) {
@@ -717,7 +731,9 @@
     bool foundResult = false;
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         _runUserCode(
           () => true == test(value),
           (bool isMatch) {
@@ -761,7 +777,9 @@
     _FutureImpl<T> future = new _FutureImpl<T>();
     StreamSubscription subscription;
     subscription = this.listen(
-      (T value) {
+      // TODO(ahe): Restore type when feature is implemented in dart2js
+      // checked mode. http://dartbug.com/7733
+      (/*T*/ value) {
         if (index == 0) {
           future._setValue(value);
           subscription.cancel();
@@ -880,6 +898,7 @@
   Future<T> consume(Stream<S> stream);
 }
 
+
 /**
  * The target of a [Stream.transform] call.
  *
@@ -890,17 +909,212 @@
   /**
    * Create a [StreamTransformer] that delegates events to the given functions.
    *
-   * If a parameter is omitted, a default handler is used that forwards the
-   * event directly to the sink.
+   * This is actually a [StreamEventTransformer] where the event handling is
+   * performed by the function arguments.
+   * If an argument is omitted, it acts as the corresponding default method from
+   * [StreamEventTransformer].
    *
-   * Pauses on the returned stream are forwarded to the input stream as well.
+   * Example use:
+   *
+   *     stringStream.transform(new StreamTransformer<String, String>(
+   *         handleData: (Strung value, StreamSink<String> sink) {
+   *           sink.add(value);
+   *           sink.add(value);  // Duplicate the incoming events.
+   *         }));
+   *
    */
-  factory StreamTransformer.from({
-      void onData(S data, StreamSink<T> sink),
-      void onError(AsyncError error, StreamSink<T> sink),
-      void onDone(StreamSink<T> sink)}) {
-    return new _StreamTransformerImpl<S, T>(onData, onError, onDone);
+  factory StreamTransformer({
+      void handleData(S data, StreamSink<T> sink),
+      void handleError(AsyncError error, StreamSink<T> sink),
+      void handleDone(StreamSink<T> sink)}) {
+    return new _StreamTransformerImpl<S, T>(handleData,
+                                            handleError,
+                                            handleDone);
   }
 
   Stream<T> bind(Stream<S> stream);
 }
+
+
+/**
+ * Base class for transformers that modifies stream events.
+ *
+ * A [StreamEventTransformer] transforms incoming Stream
+ * events of one kind into outgoing events of (possibly) another kind.
+ *
+ * Subscribing on the stream returned by [bind] is the same as subscribing on
+ * the source stream, except that events are passed through the [transformer]
+ * before being emitted. The transformer may generate any number and
+ * types of events for each incoming event. Pauses on the returned
+ * subscription are forwarded to this stream.
+ *
+ * An example that duplicates all data events:
+ *
+ *     class DoubleTransformer<T> extends StreamEventTransformerBase<T, T> {
+ *       void handleData(T data, StreamSink<T> sink) {
+ *         sink.add(value);
+ *         sink.add(value);
+ *       }
+ *     }
+ *     someTypeStream.transform(new DoubleTransformer<Type>());
+ *
+ * The default implementations of the "handle" methods forward
+ * the events unmodified. If using the default [handleData] the generic type [T]
+ * needs to be assignable to [S].
+ */
+abstract class StreamEventTransformer<S, T> implements StreamTransformer<S, T> {
+  const StreamEventTransformer();
+
+  Stream<T> bind(Stream<S> source) {
+    return new EventTransformStream<S, T>(source, this);
+  }
+
+  /**
+   * Act on incoming data event.
+   *
+   * The method may generate any number of events on the sink, but should
+   * not throw.
+   */
+  void handleData(S event, StreamSink<T> sink) {
+    var data = event;
+    sink.add(data);
+  }
+
+  /**
+   * Act on incoming error event.
+   *
+   * The method may generate any number of events on the sink, but should
+   * not throw.
+   */
+  void handleError(AsyncError error, StreamSink<T> sink) {
+    sink.signalError(error);
+  }
+
+  /**
+   * Act on incoming done event.
+   *
+   * The method may generate any number of events on the sink, but should
+   * not throw.
+   */
+  void handleDone(StreamSink<T> sink){
+    sink.close();
+  }
+}
+
+
+/**
+ * Stream that transforms another stream by intercepting and replacing events.
+ *
+ * This [Stream] is a transformation of a source stream. Listening on this
+ * stream is the same as listening on the source stream, except that events
+ * are intercepted and modified by a [StreamEventTransformer] before becoming
+ * events on this stream.
+ */
+class EventTransformStream<S, T> extends Stream<T> {
+  final Stream<S> _source;
+  final StreamEventTransformer _transformer;
+  EventTransformStream(Stream<S> source,
+                       StreamEventTransformer<S, T> transformer)
+      : _source = source, _transformer = transformer;
+
+  StreamSubscription<T> listen(void onData(T data),
+                               { void onError(AsyncError error),
+                                 void onDone(),
+                                 bool unsubscribeOnError }) {
+    return new _EventTransformStreamSubscription(_source, _transformer,
+                                                 onData, onError, onDone,
+                                                 unsubscribeOnError);
+  }
+}
+
+class _EventTransformStreamSubscription<S, T>
+    extends _BaseStreamSubscription<T>
+    implements _StreamOutputSink<T> {
+  /** The transformer used to transform events. */
+  final StreamEventTransformer<S, T> _transformer;
+  /** Whether to unsubscribe when emitting an error. */
+  final bool _unsubscribeOnError;
+  /** Source of incoming events. */
+  StreamSubscription<S> _subscription;
+  /** Cached StreamSink wrapper for this class. */
+  StreamSink<T> _sink;
+
+  _EventTransformStreamSubscription(Stream<S> source,
+                                    this._transformer,
+                                    void onData(T data),
+                                    void onError(AsyncError error),
+                                    void onDone(),
+                                    this._unsubscribeOnError)
+      : super(onData, onError, onDone) {
+    _sink = new _StreamOutputSinkWrapper<T>(this);
+    _subscription = source.listen(_handleData,
+                                  onError: _handleError,
+                                  onDone: _handleDone);
+  }
+
+  void pause([Future pauseSignal]) {
+    if (_subscription != null) _subscription.pause(pauseSignal);
+  }
+
+  void resume() {
+    if (_subscription != null) _subscription.resume();
+  }
+
+  void cancel() {
+    if (_subscription != null) {
+      _subscription.cancel();
+      _subscription = null;
+    }
+  }
+
+  void _handleData(S data) {
+    try {
+      _transformer.handleData(data, _sink);
+    } catch (e, s) {
+      _sendError(_asyncError(e, s));
+    }
+  }
+
+  void _handleError(AsyncError error) {
+    try {
+      _transformer.handleError(error, _sink);
+    } catch (e, s) {
+      _sendError(_asyncError(e, s, error));
+    }
+  }
+
+  void _handleDone() {
+    try {
+      _transformer.handleDone(_sink);
+    } catch (e, s) {
+      _sendError(_asyncError(e, s));
+    }
+  }
+
+  // StreamOutputSink interface.
+  void _sendData(T data) {
+    _onData(data);
+  }
+
+  void _sendError(AsyncError error) {
+    _onError(error);
+    if (_unsubscribeOnError) {
+      cancel();
+    }
+  }
+
+  void _sendDone() {
+    // It's ok to cancel even if we have been unsubscribed already.
+    cancel();
+    _onDone();
+  }
+}
+
+class _StreamOutputSinkWrapper<T> implements StreamSink<T> {
+  _StreamOutputSink _sink;
+  _StreamOutputSinkWrapper(this._sink);
+
+  void add(T data) => _sink._sendData(data);
+  void signalError(AsyncError error) => _sink._sendError(error);
+  void close() => _sink._sendDone();
+}
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 28c41b0..caa6318 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -62,10 +62,10 @@
   // ------------------------------------------------------------------
   // Stream interface.
 
-  StreamSubscription listen(void onData(T data),
-                            { void onError(AsyncError error),
-                              void onDone(),
-                              bool unsubscribeOnError }) {
+  StreamSubscription<T> listen(void onData(T data),
+                               { void onError(AsyncError error),
+                                 void onDone(),
+                                 bool unsubscribeOnError }) {
     if (_isComplete) {
       return new _DoneSubscription(onDone);
     }
@@ -73,7 +73,7 @@
     if (onError == null) onError = _nullErrorHandler;
     if (onDone == null) onDone = _nullDoneHandler;
     unsubscribeOnError = identical(true, unsubscribeOnError);
-    _StreamListener subscription =
+    _StreamSubscriptionImpl subscription =
         _createSubscription(onData, onError, onDone, unsubscribeOnError);
     _addListener(subscription);
     return subscription;
@@ -1092,8 +1092,10 @@
   bool get _isComplete => _timer == null && _pauseCount == 0;
 
   void onData(void handleAction(T value)) {}
-  void onError(void handleError(StateError error)) {}
-  void onDone(void handleDone(T value)) {
+
+  void onError(void handleError(AsyncError error)) {}
+
+  void onDone(void handleDone()) {
     _handler = handleDone;
   }
 
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index 1945bb2..8867ee0 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -53,20 +53,23 @@
 
   bool get isBroadcast => _source.isBroadcast;
 
-  bool asBroadcastStream() => _source.asBroadcastStream;
-
-  StreamSubscription listen(void onData(T value),
-                            { void onError(AsyncError error),
-                              void onDone(),
-                              bool unsubscribeOnError }) {
+  StreamSubscription<T> listen(void onData(T value),
+                              { void onError(AsyncError error),
+                                void onDone(),
+                                bool unsubscribeOnError }) {
     if (onData == null) onData = _nullDataHandler;
     if (onError == null) onError = _nullErrorHandler;
     if (onDone == null) onDone = _nullDoneHandler;
     unsubscribeOnError = identical(true, unsubscribeOnError);
-    StreamSubscription subscription =
-        new _ForwardingStreamSubscription<S, T>(
-            this, onData, onError, onDone, unsubscribeOnError);
-    return subscription;
+    return _createSubscription(onData, onError, onDone, unsubscribeOnError);
+  }
+
+  StreamSubscription<T> _createSubscription(void onData(T value),
+                                            void onError(AsyncError error),
+                                            void onDone(),
+                                            bool unsubscribeOnError) {
+    return new _ForwardingStreamSubscription<S, T>(
+        this, onData, onError, onDone, unsubscribeOnError);
   }
 
   // Override the following methods in subclasses to change the behavior.
@@ -86,33 +89,26 @@
 }
 
 /**
- * Abstract superclass for subscriptions that forward to other subscriptions.
+ * Common behavior of [StreamSubscription] classes.
+ *
+ * Stores and allows updating of the event handlers of a [StreamSubscription].
  */
-class _ForwardingStreamSubscription<S, T>
-    implements StreamSubscription<T>, _StreamOutputSink<T> {
-  final _ForwardingStream<S, T> _stream;
+abstract class _BaseStreamSubscription<T> implements StreamSubscription<T> {
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
   var /* _DataHandler<T> */ _onData;
   _ErrorHandler _onError;
   _DoneHandler _onDone;
 
-  StreamSubscription<S> _subscription;
-
-  _ForwardingStreamSubscription(this._stream,
-                                this._onData,
-                                this._onError,
-                                this._onDone,
-                                bool unsubscribeOnError) {
-    _subscription =
-        _stream._source.listen(_handleData,
-                               onError: _handleError,
-                               onDone: _handleDone,
-                               unsubscribeOnError: unsubscribeOnError);
+  _BaseStreamSubscription(this._onData,
+                          this._onError,
+                          this._onDone) {
+    if (_onData == null) _onData = _nullDataHandler;
+    if (_onError == null) _onError = _nullErrorHandler;
+    if (_onDone == null) _onDone = _nullDoneHandler;
   }
 
   // StreamSubscription interface.
-
   void onData(void handleData(T event)) {
     if (handleData == null) handleData = _nullDataHandler;
     _onData = handleData;
@@ -128,6 +124,39 @@
     _onDone = handleDone;
   }
 
+  void pause([Future resumeSignal]);
+
+  void resume();
+
+  void cancel();
+}
+
+
+/**
+ * Abstract superclass for subscriptions that forward to other subscriptions.
+ */
+class _ForwardingStreamSubscription<S, T>
+    extends _BaseStreamSubscription<T> implements _StreamOutputSink<T> {
+  final _ForwardingStream<S, T> _stream;
+  final bool _unsubscribeOnError;
+
+  StreamSubscription<S> _subscription;
+
+  _ForwardingStreamSubscription(this._stream,
+                                void onData(T data),
+                                void onError(AsyncError error),
+                                void onDone(),
+                                this._unsubscribeOnError)
+      : super(onData, onError, onDone) {
+    // Don't unsubscribe on incoming error, only if we send an error forwards.
+    _subscription =
+        _stream._source.listen(_handleData,
+                               onError: _handleError,
+                               onDone: _handleDone);
+  }
+
+  // StreamSubscription interface.
+
   void pause([Future resumeSignal]) {
     if (_subscription == null) {
       throw new StateError("Subscription has been unsubscribed");
@@ -158,6 +187,10 @@
 
   void _sendError(AsyncError error) {
     _onError(error);
+    if (_unsubscribeOnError) {
+      _subscription.cancel();
+      _subscription = null;
+    }
   }
 
   void _sendDone() {
@@ -171,7 +204,9 @@
 
   // Methods used as listener on source subscription.
 
-  void _handleData(S data) {
+  // TODO(ahe): Restore type when feature is implemented in dart2js
+  // checked mode. http://dartbug.com/7733
+  void _handleData(/*S*/ data) {
     _stream._handleData(data, this);
   }
 
@@ -190,10 +225,10 @@
 
 typedef bool _Predicate<T>(T value);
 
-class WhereStream<T> extends _ForwardingStream<T, T> {
+class _WhereStream<T> extends _ForwardingStream<T, T> {
   final _Predicate<T> _test;
 
-  WhereStream(Stream<T> source, bool test(T value))
+  _WhereStream(Stream<T> source, bool test(T value))
       : _test = test, super(source);
 
   void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -216,10 +251,10 @@
 /**
  * A stream pipe that converts data events before passing them on.
  */
-class MapStream<S, T> extends _ForwardingStream<S, T> {
+class _MapStream<S, T> extends _ForwardingStream<S, T> {
   final _Transformation _transform;
 
-  MapStream(Stream<S> source, T transform(S event))
+  _MapStream(Stream<S> source, T transform(S event))
       : this._transform = transform, super(source);
 
   void _handleData(S inputEvent, _StreamOutputSink<T> sink) {
@@ -237,10 +272,10 @@
 /**
  * A stream pipe that converts data events before passing them on.
  */
-class ExpandStream<S, T> extends _ForwardingStream<S, T> {
+class _ExpandStream<S, T> extends _ForwardingStream<S, T> {
   final _Transformation<S, Iterable<T>> _expand;
 
-  ExpandStream(Stream<S> source, Iterable<T> expand(S event))
+  _ExpandStream(Stream<S> source, Iterable<T> expand(S event))
       : this._expand = expand, super(source);
 
   void _handleData(S inputEvent, _StreamOutputSink<T> sink) {
@@ -264,11 +299,11 @@
  * A stream pipe that converts or disposes error events
  * before passing them on.
  */
-class HandleErrorStream<T> extends _ForwardingStream<T, T> {
+class _HandleErrorStream<T> extends _ForwardingStream<T, T> {
   final _ErrorTransformation _transform;
   final _ErrorTest _test;
 
-  HandleErrorStream(Stream<T> source,
+  _HandleErrorStream(Stream<T> source,
                     void transform(AsyncError event),
                     bool test(error))
       : this._transform = transform, this._test = test, super(source);
@@ -297,10 +332,10 @@
 }
 
 
-class TakeStream<T> extends _ForwardingStream<T, T> {
+class _TakeStream<T> extends _ForwardingStream<T, T> {
   int _remaining;
 
-  TakeStream(Stream<T> source, int count)
+  _TakeStream(Stream<T> source, int count)
       : this._remaining = count, super(source) {
     // This test is done early to avoid handling an async error
     // in the _handleData method.
@@ -321,10 +356,10 @@
 }
 
 
-class TakeWhileStream<T> extends _ForwardingStream<T, T> {
+class _TakeWhileStream<T> extends _ForwardingStream<T, T> {
   final _Predicate<T> _test;
 
-  TakeWhileStream(Stream<T> source, bool test(T value))
+  _TakeWhileStream(Stream<T> source, bool test(T value))
       : this._test = test, super(source);
 
   void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -345,10 +380,10 @@
   }
 }
 
-class SkipStream<T> extends _ForwardingStream<T, T> {
+class _SkipStream<T> extends _ForwardingStream<T, T> {
   int _remaining;
 
-  SkipStream(Stream<T> source, int count)
+  _SkipStream(Stream<T> source, int count)
       : this._remaining = count, super(source) {
     // This test is done early to avoid handling an async error
     // in the _handleData method.
@@ -364,11 +399,11 @@
   }
 }
 
-class SkipWhileStream<T> extends _ForwardingStream<T, T> {
+class _SkipWhileStream<T> extends _ForwardingStream<T, T> {
   final _Predicate<T> _test;
   bool _hasFailed = false;
 
-  SkipWhileStream(Stream<T> source, bool test(T value))
+  _SkipWhileStream(Stream<T> source, bool test(T value))
       : this._test = test, super(source);
 
   void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -393,13 +428,13 @@
 
 typedef bool _Equality<T>(T a, T b);
 
-class DistinctStream<T> extends _ForwardingStream<T, T> {
+class _DistinctStream<T> extends _ForwardingStream<T, T> {
   static var _SENTINEL = new Object();
 
   _Equality<T> _equals;
   var _previous = _SENTINEL;
 
-  DistinctStream(Stream<T> source, bool equals(T a, T b))
+  _DistinctStream(Stream<T> source, bool equals(T a, T b))
       : _equals = equals, super(source);
 
   void _handleData(T inputEvent, _StreamOutputSink<T> sink) {
@@ -426,79 +461,28 @@
   }
 }
 
+// Stream transformations and event transformations.
 
 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink);
 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink);
 typedef void _TransformDoneHandler<T>(StreamSink<T> sink);
 
-/**
- * A stream transformer that intercepts all events and can generate any event as
- * output.
- *
- * Each incoming event on the source stream is passed to the corresponding
- * provided event handler, along with a [StreamSink] linked to the output
- * Stream.
- * The handler can then decide exactly which events to send to the output.
- */
-class _StreamTransformerImpl<S, T> implements StreamTransformer<S, T> {
-  final _TransformDataHandler<S, T> _onData;
-  final _TransformErrorHandler<T> _onError;
-  final _TransformDoneHandler<T> _onDone;
-  StreamSink<T> _sink;
-
-  _StreamTransformerImpl(void onData(S data, StreamSink<T> sink),
-                         void onError(AsyncError data, StreamSink<T> sink),
-                         void onDone(StreamSink<T> sink))
-      : this._onData = (onData == null ? _defaultHandleData : onData),
-        this._onError = (onError == null ? _defaultHandleError : onError),
-        this._onDone = (onDone == null ? _defaultHandleDone : onDone);
-
-  Stream<T> bind(Stream<S> source) {
-    Stream<T> stream = new _SingleStreamImpl<T>();
-    // Cache a Sink object to avoid creating a new one for each event.
-    _sink = new _StreamImplSink(stream);
-    source.listen(_handleData, onError: _handleError, onDone: _handleDone);
-    return stream;
-  }
-
-  void _handleData(S data) {
-    try {
-      _onData(data, _sink);
-    } catch (e, s) {
-      _stream._signalError(_asyncError(e, s));
-    }
-  }
-
-  void _handleError(AsyncError error) {
-    try {
-      _onError(error, _sink);
-    } catch (e, s) {
-      _stream._signalError(_asyncError(e, s, error));
-    }
-  }
-
-  void _handleDone() {
-    try {
-      _onDone(_sink);
-    } catch (e, s) {
-      _stream._signalError(_asyncError(e, s));
-    }
-  }
-
-  /** Default data handler forwards all data. */
-  static void _defaultHandleData(var data, StreamSink sink) {
-    sink.add(data);
-  }
-  /** Default error handler forwards all errors. */
-  static void _defaultHandleError(AsyncError error, StreamSink sink) {
-    sink.signalError(error);
-  }
-  /** Default done handler forwards done. */
-  static void _defaultHandleDone(StreamSink sink) {
-    sink.close();
-  }
+/** Default data handler forwards all data. */
+void _defaultHandleData(var data, StreamSink sink) {
+  sink.add(data);
 }
 
+/** Default error handler forwards all errors. */
+void _defaultHandleError(AsyncError error, StreamSink sink) {
+  sink.signalError(error);
+}
+
+/** Default done handler forwards done. */
+void _defaultHandleDone(StreamSink sink) {
+  sink.close();
+}
+
+
 /** Creates a [StreamSink] from a [_StreamImpl]'s input methods. */
 class _StreamImplSink<T> implements StreamSink<T> {
   _StreamImpl<T> _target;
@@ -508,4 +492,43 @@
   void close() { _target._close(); }
 }
 
+/**
+ * A [StreamTransformer] that modifies stream events.
+ *
+ * This class is used by [StreamTransformer]'s factory constructor.
+ * It is actually an [StreamEventTransformer] where the functions used to
+ * modify the events are passed as constructor arguments.
+ *
+ * If an argument is omitted, it acts as the default method from
+ * [StreamEventTransformer].
+ */
+class _StreamTransformerImpl<S, T> extends StreamEventTransformer<S, T> {
+  // TODO(ahe): Restore type when feature is implemented in dart2js
+  // checked mode. http://dartbug.com/7733
+  final Function /*_TransformDataHandler<S, T>*/ _handleData;
+  final _TransformErrorHandler<T> _handleError;
+  final _TransformDoneHandler<T> _handleDone;
+
+  _StreamTransformerImpl(void handleData(S data, StreamSink<T> sink),
+                         void handleError(AsyncError data, StreamSink<T> sink),
+                         void handleDone(StreamSink<T> sink))
+      : this._handleData  = (handleData == null  ? _defaultHandleData
+                                                 : handleData),
+        this._handleError = (handleError == null ? _defaultHandleError
+                                                 : handleError),
+        this._handleDone  = (handleDone == null  ? _defaultHandleDone
+                                                 : handleDone);
+
+  void handleData(S data, StreamSink<T> sink) {
+    _handleData(data, sink);
+  }
+
+  void handleError(AsyncError error, StreamSink<T> sink) {
+    _handleError(error, sink);
+  }
+
+  void handleDone(StreamSink<T> sink) {
+    _handleDone(sink);
+  }
+}
 
diff --git a/sdk/lib/chrome/dart2js/chrome_dart2js.dart b/sdk/lib/chrome/dart2js/chrome_dart2js.dart
index bba2925..7c982f4 100644
--- a/sdk/lib/chrome/dart2js/chrome_dart2js.dart
+++ b/sdk/lib/chrome/dart2js/chrome_dart2js.dart
@@ -1,6 +1,8 @@
 library chrome;
 
 import 'dart:_foreign_helper' show JS;
+import 'dart:html_common';
+import 'dart:html';
 // 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.
@@ -10,39 +12,975 @@
 
 
 
+
+// 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 set of utilities for use with the Chrome Extension APIs.
+ *
+ * Allows for easy access to required JS objects.
+ */
+
+/**
+ * A dart object, that is convertible to JS. Used for creating objects in dart,
+ * then passing them to JS.
+ *
+ * Objects that are passable to JS need to implement this interface.
+ */
+abstract class ChromeObject {
+  /*
+   * Default Constructor
+   *
+   * Called by child objects during their regular construction.
+   */
+  ChromeObject() : _jsObject = JS('var', '{}');
+
+  /*
+   * Internal proxy constructor
+   *
+   * Creates a new Dart object using this existing proxy.
+   */
+  ChromeObject._proxy(this._jsObject);
+
+  /*
+   * JS Object Representation
+   */
+  Object _jsObject;
+}
+
+/**
+ * Useful functions for converting arguments.
+ */
+
+/**
+ * Converts the given map-type argument to js-friendly format, recursively.
+ * Returns the new Map object.
+ */
+Object _convertMapArgument(Map argument) {
+  Map m = new Map();
+  for (Object key in argument.keys)
+    m[key] = convertArgument(argument[key]);
+  return convertDartToNative_Dictionary(m);
+}
+
+/**
+ * Converts the given list-type argument to js-friendly format, recursively.
+ * Returns the new List object.
+ */
+List _convertListArgument(List argument) {
+  List l = new List();
+  for (var i = 0; i < argument.length; i ++)
+    l.add(convertArgument(argument[i]));
+  return l;
+}
+
+/**
+ * Converts the given argument Object to js-friendly format, recursively.
+ *
+ * Flattens out all Chrome objects into their corresponding ._toMap()
+ * definitions, then converts them to JS objects.
+ *
+ * Returns the new argument.
+ *
+ * Cannot be used for functions.
+ */
+Object convertArgument(var argument) {
+  if (argument == null)
+    return argument;
+
+  if (argument is num || argument is String || argument is bool)
+    return argument;
+
+  if (argument is ChromeObject)
+    return argument._jsObject;
+
+  if (argument is List)
+    return _convertListArgument(argument);
+
+  if (argument is Map)
+    return _convertMapArgument(argument);
+
+  if (argument is Function)
+    throw new Exception("Cannot serialize Function argument ${argument}.");
+
+  // TODO(sashab): Try and detect whether the argument is already serialized.
+  return argument;
+}
+
+/// Description of a declarative rule for handling events.
+class Rule extends ChromeObject {
+  /*
+   * Public (Dart) constructor
+   */
+  Rule({String id, List conditions, List actions, int priority}) {
+    this.id = id;
+    this.conditions = conditions;
+    this.actions = actions;
+    this.priority = priority;
+  }
+
+  /*
+   * Private (JS) constructor
+   */
+  Rule._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  // TODO(sashab): Wrap these generic Lists somehow.
+  List get conditions => JS('List', '#.conditions', this._jsObject);
+
+  void set conditions(List conditions) {
+    JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions));
+  }
+
+  // TODO(sashab): Wrap these generic Lists somehow.
+  List get actions => JS('List', '#.actions', this._jsObject);
+
+  void set actions(List actions) {
+    JS('void', '#.actions = #', this._jsObject, convertArgument(actions));
+  }
+
+  int get priority => JS('int', '#.priority', this._jsObject);
+
+  void set priority(int priority) {
+    JS('void', '#.priority = #', this._jsObject, priority);
+  }
+
+}
+
+/**
+ * The Event class.
+ *
+ * Chrome Event classes extend this interface.
+ *
+ * e.g.
+ *
+ *  // chrome.app.runtime.onLaunched
+ *  class Event_ChromeAppRuntimeOnLaunched extends Event {
+ *    // constructor, passing the arity of the callback
+ *    Event_ChromeAppRuntimeOnLaunched(jsObject) :
+ *     super._(jsObject, 1);
+ *
+ *    // methods, strengthening the Function parameter specificity
+ *    void addListener(void callback(LaunchData launchData))
+ *        => super.addListener(callback);
+ *    void removeListener(void callback(LaunchData launchData))
+ *        => super.removeListener(callback);
+ *    bool hasListener(void callback(LaunchData launchData))
+ *        => super.hasListener(callback);
+ *  }
+ *
+ */
+class Event {
+  /*
+   * JS Object Representation
+   */
+  Object _jsObject;
+
+  /*
+   * Number of arguments the callback takes.
+   */
+  int _callbackArity;
+
+  /*
+   * Private constructor
+   */
+  Event._(this._jsObject, this._callbackArity);
+
+  /*
+   * Methods
+   */
+
+  /// Registers an event listener <em>callback</em> to an event.
+  void addListener(Function callback) =>
+      JS('void',
+         '#.addListener(#)',
+         this._jsObject,
+         convertDartClosureToJS(callback, this._callbackArity)
+      );
+
+  /// Deregisters an event listener <em>callback</em> from an event.
+  void removeListener(Function callback) =>
+      JS('void',
+         '#.removeListener(#)',
+         this._jsObject,
+         convertDartClosureToJS(callback, this._callbackArity)
+      );
+
+  /// Returns True if <em>callback</em> is registered to the event.
+  bool hasListener(Function callback) =>
+      JS('bool',
+         '#.hasListener(#)',
+         this._jsObject,
+         convertDartClosureToJS(callback, this._callbackArity)
+      );
+
+  /// Returns true if any event listeners are registered to the event.
+  bool hasListeners() =>
+      JS('bool',
+         '#.hasListeners()',
+         this._jsObject
+      );
+
+  /// Registers rules to handle events.
+  ///
+  /// [eventName] is the name of the event this function affects and [rules] are
+  /// the rules to be registered. These do not replace previously registered
+  /// rules. [callback] is called with registered rules.
+  ///
+  void addRules(String eventName, List<Rule> rules,
+                [void callback(List<Rule> rules)]) {
+    // proxy the callback
+    void __proxy_callback(List rules) {
+      if (?callback) {
+        List<Rule> __proxy_rules = new List<Rule>();
+
+        for (Object o in rules)
+          __proxy_rules.add(new Rule._proxy(o));
+
+        callback(__proxy_rules);
+      }
+    }
+
+    JS('void',
+       '#.addRules(#, #, #)',
+       this._jsObject,
+       convertArgument(eventName),
+       convertArgument(rules),
+       convertDartClosureToJS(__proxy_callback, 1)
+    );
+  }
+
+  /// Returns currently registered rules.
+  ///
+  /// [eventName] is the name of the event this function affects and, if an array
+  /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+  /// this array are returned. [callback] is called with registered rules.
+  ///
+  void getRules(String eventName, [List<String> ruleIdentifiers,
+                                   void callback(List<Rule> rules)]) {
+    // proxy the callback
+    void __proxy_callback(List rules) {
+      if (?callback) {
+        List<Rule> __proxy_rules = new List<Rule>();
+
+        for (Object o in rules)
+          __proxy_rules.add(new Rule._proxy(o));
+
+        callback(__proxy_rules);
+      }
+    }
+
+    JS('void',
+       '#.getRules(#, #, #)',
+       this._jsObject,
+       convertArgument(eventName),
+       convertArgument(ruleIdentifiers),
+       convertDartClosureToJS(__proxy_callback, 1)
+    );
+  }
+
+  /// Unregisters currently registered rules.
+  ///
+  /// [eventName] is the name of the event this function affects and, if an array
+  /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+  /// this array are unregistered. [callback] is called when the rules are
+  /// unregistered.
+  ///
+  void removeRules(String eventName, [List<String> ruleIdentifiers,
+                                      void callback()]) =>
+      JS('void',
+         '#.removeRules(#, #, #)',
+         this._jsObject,
+         convertArgument(eventName),
+         convertArgument(ruleIdentifiers),
+         convertDartClosureToJS(callback, 0)
+      );
+}
+
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 
-// This is an example of exposing chrome APIs in Dart and will be replaced with
-// the proper implementation in the future.
+// chrome.app
+class API_ChromeApp {
+  /*
+   * JS Variable
+   */
+  Object _jsObject;
 
-class AppModule {
-  AppModule._();
+  /*
+   * Members
+   */
+  API_ChromeAppWindow window;
+  API_ChromeAppRuntime runtime;
 
-  WindowModule get window => new WindowModule._();
-}
+  /*
+   * Constructor
+   */
+  API_ChromeApp(this._jsObject) {
+    var window_object = JS('', '#.window', this._jsObject);
+    if (window_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    window = new API_ChromeAppWindow(window_object);
 
-class WindowModule {
-  WindowModule._();
-
-  void create(String url) {
-    var chrome = JS('', 'chrome');
-
-    if (chrome == null) {
-      throw new UnsupportedError('Not supported by current browser');
-    }
-    var app = JS('', '#.app', chrome);
-    if (app == null) {
-      throw new UnsupportedError('Not supported by current browser');
-    }
-    var window = JS('', '#.window', app);
-    if (app == null) {
-      throw new UnsupportedError('Not supported by current browser');
-    }
-    JS('void', '#.create(#)', window, url);
+    var runtime_object = JS('', '#.runtime', this._jsObject);
+    if (runtime_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    runtime = new API_ChromeAppRuntime(runtime_object);
   }
 }
 
-final app = new AppModule._();
+// chrome
+class API_Chrome {
+  /*
+   * JS Variable
+   */
+  Object _jsObject;
+
+  /*
+   * Members
+   */
+  API_ChromeApp app;
+
+  /*
+   * Constructor
+   */
+  API_Chrome() {
+    this._jsObject = JS("Object", "chrome");
+    if (this._jsObject == null)
+      throw new UnsupportedError('Not supported by current browser.');
+
+    var app_object = JS('', '#.app', this._jsObject);
+    if (app_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    app = new API_ChromeApp(app_object);
+  }
+}
+
+// The final chrome objects
+final API_Chrome chrome = new API_Chrome();
+// 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.
+
+// from app_runtime.idl
+
+/**
+ * Types
+ */
+
+/// A WebIntents intent object. Deprecated.
+class Intent extends ChromeObject {
+  /*
+   * Public (Dart) constructor
+   */
+  Intent({String action, String type, var data}) {
+    this.action = action;
+    this.type = type;
+    this.data = data;
+  }
+
+  /*
+   * Private (JS) constructor
+   */
+  Intent._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+
+  /// The WebIntent being invoked.
+  String get action => JS('String', '#.action', this._jsObject);
+
+  void set action(String action) {
+    JS('void', '#.action = #', this._jsObject, action);
+  }
+
+  /// The MIME type of the data.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+
+  /// Data associated with the intent.
+  // TODO(sashab): What is the best way to serialize/return generic JS objects?
+  Object get data => JS('Object', '#.data', this._jsObject);
+
+  void set data(Object data) {
+    JS('void', '#.data = #', this._jsObject, convertArgument(data));
+  }
+
+  /*
+   * TODO(sashab): What is a NullCallback() type?
+   * Add postResult and postFailure once understanding what this type is, and
+   * once there is a way to pass functions back from JS.
+   */
+}
+
+class LaunchItem extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  LaunchItem({FileEntry entry, String type}) {
+    this.entry = entry;
+    this.type = type;
+  }
+
+  /*
+   * Private constructor
+   */
+  LaunchItem._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+
+  /// FileEntry for the file.
+  FileEntry get entry => JS('FileEntry', '#.entry', this._jsObject);
+
+  void set entry(FileEntry entry) {
+    JS('void', '#.entry = #', this._jsObject, entry);
+  }
+
+  /// The MIME type of the file.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+}
+
+/// Optional data for the launch.
+class LaunchData extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  LaunchData({Intent intent, String id, List<LaunchItem> items}) {
+    this.intent = intent;
+    this.id = id;
+    this.items = items;
+  }
+
+  /*
+   * Private constructor
+   */
+  LaunchData._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  Intent get intent => new Intent._proxy(JS('', '#.intent', this._jsObject));
+
+  void set intent(Intent intent) {
+    JS('void', '#.intent = #', this._jsObject, convertArgument(intent));
+  }
+
+  /// The id of the file handler that the app is being invoked with.
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  List<LaunchItem> get items() {
+    List<LaunchItem> items_final = new List<LaunchItem>();
+    for (var o in JS('List', '#.items', this._jsObject)) {
+      items_final.add(new LaunchItem._proxy(o));
+    }
+    return items_final;
+  }
+
+  void set items(List<LaunchItem> items) {
+    JS('void', '#.items = #', this._jsObject, convertArgument(items));
+  }
+}
+
+class IntentResponse extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  IntentResponse({int intentId, bool success, Object data}) {
+    this.intentId = intentId;
+    this.success = success;
+    this.data = data;
+  }
+
+  /*
+   * Private constructor
+   */
+  IntentResponse._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+
+  /// Identifies the intent.
+  int get intentId => JS('int', '#.intentId', this._jsObject);
+
+  void set intentId(int intentId) {
+    JS('void', '#.intentId = #', this._jsObject, intentId);
+  }
+
+  /// Was this intent successful? (i.e., postSuccess vs postFailure).
+  bool get success => JS('bool', '#.success', this._jsObject);
+
+  void set success(bool success) {
+    JS('void', '#.success = #', this._jsObject, success);
+  }
+
+  /// Data associated with the intent response.
+  // TODO(sashab): What's the best way to serialize/return generic JS objects?
+  Object get data => JS('Object', '#.data', this._jsObject);
+
+  void set data(Object data) {
+    JS('void', '#.data = #', this._jsObject, convertArgument(data));
+  }
+}
+
+/**
+ * Events
+ */
+
+/// Fired at Chrome startup to apps that were running when Chrome last shut
+/// down.
+class Event_ChromeAppRuntimeOnRestarted extends Event {
+  /*
+   * Override callback type definitions
+   */
+  void addListener(void callback())
+      => super.addListener(callback);
+  void removeListener(void callback())
+      => super.removeListener(callback);
+  bool hasListener(void callback())
+      => super.hasListener(callback);
+
+  /*
+   * Constructor
+   */
+  Event_ChromeAppRuntimeOnRestarted(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when an app is launched from the launcher or in response to a web
+/// intent.
+class Event_ChromeAppRuntimeOnLaunched extends Event {
+  /*
+   * Override callback type definitions
+   */
+  void addListener(void callback(LaunchData launchData))
+      => super.addListener(callback);
+  void removeListener(void callback(LaunchData launchData))
+      => super.removeListener(callback);
+  bool hasListener(void callback(LaunchData launchData))
+      => super.hasListener(callback);
+
+  /*
+   * Constructor
+   */
+  Event_ChromeAppRuntimeOnLaunched(jsObject) : super._(jsObject, 1);
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppRuntime {
+  /*
+   * API connection
+   */
+  Object _jsObject;
+
+  /*
+   * Events
+   */
+  Event_ChromeAppRuntimeOnRestarted onRestarted;
+  Event_ChromeAppRuntimeOnLaunched onLaunched;
+
+  /*
+   * Functions
+   */
+  void postIntentResponse(IntentResponse intentResponse) =>
+    JS('void', '#.postIntentResponse(#)', this._jsObject,
+        convertArgument(intentResponse));
+
+  /*
+   * Constructor
+   */
+  API_ChromeAppRuntime(this._jsObject) {
+    onRestarted = new Event_ChromeAppRuntimeOnRestarted(JS('Object',
+                                                           '#.onRestarted',
+                                                           this._jsObject));
+    onLaunched = new Event_ChromeAppRuntimeOnLaunched(JS('Object',
+                                                         '#.onLaunched',
+                                                         this._jsObject));
+  }
+}
+
+// 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.
+
+// from app.window.idl
+
+/**
+ * Types
+ */
+class CreateWindowOptions extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  CreateWindowOptions({String id, int defaultWidth, int defaultHeight,
+      int defaultLeft, int defaultTop, int width, int height, int left, int top,
+      int minWidth, int minHeight, int maxWidth, int maxHeight, String type,
+      String frame, Bounds bounds, bool hidden}) {
+    this.id = id;
+    this.defaultWidth = defaultWidth;
+    this.defaultHeight = defaultHeight;
+    this.defaultLeft = defaultLeft;
+    this.defaultTop = defaultTop;
+    this.width = width;
+    this.height = height;
+    this.left = left;
+    this.top = top;
+    this.minWidth = minWidth;
+    this.minHeight = minHeight;
+    this.maxWidth = maxWidth;
+    this.maxHeight = maxHeight;
+    this.type = type;
+    this.frame = frame;
+    this.bounds = bounds;
+    this.hidden = hidden;
+  }
+
+  /*
+   * Private constructor
+   */
+  CreateWindowOptions._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// Id to identify the window. This will be used to remember the size
+  /// and position of the window and restore that geometry when a window
+  /// with the same id (and no explicit size or position) is later opened.
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  /// Default width of the window. (Deprecated; regular bounds act like this
+  /// now.)
+  int get defaultWidth => JS('int', '#.defaultWidth', this._jsObject);
+
+  void set defaultWidth(int defaultWidth) {
+    JS('void', '#.defaultWidth = #', this._jsObject, defaultWidth);
+  }
+
+  /// Default height of the window. (Deprecated; regular bounds act like this
+  /// now.)
+  int get defaultHeight => JS('int', '#.defaultHeight', this._jsObject);
+
+  void set defaultHeight(int defaultHeight) {
+    JS('void', '#.defaultHeight = #', this._jsObject, defaultHeight);
+  }
+
+  /// Default X coordinate of the window. (Deprecated; regular bounds act like
+  /// this now.)
+  int get defaultLeft => JS('int', '#.defaultLeft', this._jsObject);
+
+  void set defaultLeft(int defaultLeft) {
+    JS('void', '#.defaultLeft = #', this._jsObject, defaultLeft);
+  }
+
+  /// Default Y coordinate of the window. (Deprecated; regular bounds act like
+  /// this now.)
+  int get defaultTop => JS('int', '#.defaultTop', this._jsObject);
+
+  void set defaultTop(int defaultTop) {
+    JS('void', '#.defaultTop = #', this._jsObject, defaultTop);
+  }
+
+  /// Width of the window. (Deprecated; use 'bounds'.)
+  int get width => JS('int', '#.width', this._jsObject);
+
+  void set width(int width) {
+    JS('void', '#.width = #', this._jsObject, width);
+  }
+
+  /// Height of the window. (Deprecated; use 'bounds'.)
+  int get height => JS('int', '#.height', this._jsObject);
+
+  void set height(int height) {
+    JS('void', '#.height = #', this._jsObject, height);
+  }
+
+  /// X coordinate of the window. (Deprecated; use 'bounds'.)
+  int get left => JS('int', '#.left', this._jsObject);
+
+  void set left(int left) {
+    JS('void', '#.left = #', this._jsObject, left);
+  }
+
+  /// Y coordinate of the window. (Deprecated; use 'bounds'.)
+  int get top => JS('int', '#.top', this._jsObject);
+
+  void set top(int top) {
+    JS('void', '#.top = #', this._jsObject, top);
+  }
+
+  /// Minimium width of the window.
+  int get minWidth => JS('int', '#.minWidth', this._jsObject);
+
+  void set minWidth(int minWidth) {
+    JS('void', '#.minWidth = #', this._jsObject, minWidth);
+  }
+
+  /// Minimum height of the window.
+  int get minHeight => JS('int', '#.minHeight', this._jsObject);
+
+  void set minHeight(int minHeight) {
+    JS('void', '#.minHeight = #', this._jsObject, minHeight);
+  }
+
+  /// Maximum width of the window.
+  int get maxWidth => JS('int', '#.maxWidth', this._jsObject);
+
+  void set maxWidth(int maxWidth) {
+    JS('void', '#.maxWidth = #', this._jsObject, maxWidth);
+  }
+
+  /// Maximum height of the window.
+  int get maxHeight => JS('int', '#.maxHeight', this._jsObject);
+
+  void set maxHeight(int maxHeight) {
+    JS('void', '#.maxHeight = #', this._jsObject, maxHeight);
+  }
+
+  /// Window type: 'shell' (the default) is the only currently supported value.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+
+  /// Frame type: 'none' or 'chrome' (defaults to 'chrome').
+  String get frame => JS('String', '#.frame', this._jsObject);
+
+  void set frame(String frame) {
+    JS('void', '#.frame = #', this._jsObject, frame);
+  }
+
+  /// Size of the content in the window (excluding the titlebar). If specified
+  /// in addition to any of the left/top/width/height parameters, this field
+  /// takes precedence. If a frameBounds is specified, the frameBounds take
+  /// precedence.
+  Bounds get bounds =>
+      new Bounds._proxy(JS('Bounds', '#.bounds', this._jsObject));
+
+  void set bounds(Bounds bounds) {
+    JS('void', '#.bounds = #', this._jsObject, convertArgument(bounds));
+  }
+
+  /// If true, the window will be created in a hidden state. Call show() on
+  /// the window to show it once it has been created. Defaults to false.
+  bool get hidden => JS('bool', '#.hidden', this._jsObject);
+
+  void set hidden(bool hidden) {
+    JS('void', '#.hidden = #', this._jsObject, hidden);
+  }
+}
+
+class Bounds extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  Bounds({int left, int top, int width, int height}) {
+    this.left = left;
+    this.top = top;
+    this.width = width;
+    this.height = height;
+  }
+
+  /*
+   * Private constructor
+   */
+  Bounds._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  int get left => JS('int', '#.left', this._jsObject);
+
+  void set left(int left) {
+    JS('void', '#.left = #', this._jsObject, left);
+  }
+
+  int get top => JS('int', '#.top', this._jsObject);
+
+  void set top(int top) {
+    JS('void', '#.top = #', this._jsObject, top);
+  }
+
+  int get width => JS('int', '#.width', this._jsObject);
+
+  void set width(int width) {
+    JS('void', '#.width = #', this._jsObject, width);
+  }
+
+  int get height => JS('int', '#.height', this._jsObject);
+
+  void set height(int height) {
+    JS('void', '#.height = #', this._jsObject, height);
+  }
+}
+
+class AppWindow extends ChromeObject {
+  /*
+   * Public constructor
+   * TODO(sashab): Does it make sense to be able to create a new AppWindow this
+   * way?
+   */
+  //AppWindow();
+
+  /*
+   * Private constructor
+   */
+  AppWindow._proxy(jsObject) : super._proxy(jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// The JavaScript 'window' object for the created child.
+  // TODO(sashab, sra): Detect whether this is the current window, or an
+  // external one, and return an appropriately-typed object
+  WindowBase get contentWindow =>
+      JS("Window", "#.contentWindow", this._jsObject);
+
+  /*
+   * Functions
+   */
+
+  /// Focus the window.
+  void focus() => JS("void", "#.focus()", this._jsObject);
+
+  /// Minimize the window.
+  void minimize() => JS("void", "#.minimize()", this._jsObject);
+
+  /// Is the window minimized?
+  bool isMinimized() => JS("bool", "#.isMinimized()", this._jsObject);
+
+  /// Maximize the window.
+  void maximize() => JS("void", "#.maximize()", this._jsObject);
+
+  /// Is the window maximized?
+  bool isMaximized() => JS("bool", "c#.isMaximized()", this._jsObject);
+
+  /// Restore the window.
+  void restore() => JS("void", "#.restore()", this._jsObject);
+
+  /// Move the window to the position (|left|, |top|).
+  void moveTo(int left, int top) =>
+      JS("void", "#.moveTo(#, #)", this._jsObject, left, top);
+
+  /// Resize the window to |width|x|height| pixels in size.
+  void resizeTo(int width, int height) =>
+      JS("void", "#.resizeTo(#, #)", this._jsObject, width, height);
+
+  /// Draw attention to the window.
+  void drawAttention() => JS("void", "#.drawAttention()", this._jsObject);
+
+  /// Clear attention to the window.
+  void clearAttention() => JS("void", "#.clearAttention()", this._jsObject);
+
+  /// Close the window.
+  void close() => JS("void", "#.close()", this._jsObject);
+
+  /// Show the window. Does nothing if the window is already visible.
+  void show() => JS("void", "#.show()", this._jsObject);
+
+  /// Hide the window. Does nothing if the window is already hidden.
+  void hide() => JS("void", "#.hide()", this._jsObject);
+
+  /// Set the window's bounds.
+  void setBounds(Bounds bounds) =>
+      JS("void", "#.setBounds(#)", this._jsObject, convertArgument(bounds));
+
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppWindow {
+  /**
+   * JS object
+   */
+  Object _jsObject;
+
+  /**
+   * Constructor
+   */
+  API_ChromeAppWindow(this._jsObject);
+
+  /**
+   * Functions
+   */
+
+  /// Returns an <a href="#type-AppWindow">AppWindow</a> object for the
+  /// current script context (ie JavaScript 'window' object). This can also be
+  /// called on a handle to a script context for another page, for example:
+  /// otherWindow.chrome.app.window.current().
+  AppWindow current() =>
+      new AppWindow._proxy(JS("Object", "#.current()", this._jsObject));
+
+  /// The size and position of a window can be specified in a number of
+  /// different ways. The most simple option is not specifying anything at
+  /// all, in which case a default size and platform dependent position will
+  /// be used.
+  ///
+  /// Another option is to use the top/left and width/height properties,
+  /// which will always put the window at the specified coordinates with the
+  /// specified size.
+  ///
+  /// Yet another option is to give the window a (unique) id. This id is then
+  /// used to remember the size and position of the window whenever it is
+  /// moved or resized. This size and position is then used instead of the
+  /// specified bounds on subsequent opening of a window with the same id. If
+  /// you need to open a window with an id at a location other than the
+  /// remembered default, you can create it hidden, move it to the desired
+  /// location, then show it.
+  ///
+  /// You can also combine these various options, explicitly specifying for
+  /// example the size while having the position be remembered or other
+  /// combinations like that. Size and position are dealt with seperately,
+  /// but individual coordinates are not. So if you specify a top (or left)
+  /// coordinate, you should also specify a left (or top) coordinate, and
+  /// similar for size.
+  ///
+  /// If you specify both a regular and a default value for the same option
+  /// the regular value is the only one that takes effect.
+  void create(String url, [CreateWindowOptions options,
+                           void callback(AppWindow created_window)]) {
+    void __proxy_callback(Object created_window) {
+      if (?callback)
+        callback(new AppWindow._proxy(created_window));
+    }
+
+    JS("void", "#.create(#, #, #)",
+       this._jsObject,
+       url,
+       convertArgument(options),
+       convertDartClosureToJS(__proxy_callback, 1)
+    );
+  }
+}
\ No newline at end of file
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 5d4b81c..d63b8be 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -13,5 +13,4 @@
 part 'maps.dart';
 part 'queue.dart';
 part 'set.dart';
-part 'sort.dart';
 part 'splay_tree.dart';
diff --git a/sdk/lib/collection/collection_sources.gypi b/sdk/lib/collection/collection_sources.gypi
index 3f1c117..b262c10 100644
--- a/sdk/lib/collection/collection_sources.gypi
+++ b/sdk/lib/collection/collection_sources.gypi
@@ -12,7 +12,6 @@
     'maps.dart',
     'queue.dart',
     'set.dart',
-    'sort.dart',
     'splay_tree.dart',
   ],
 }
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index a8e89cc..0c45e21 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -313,12 +313,18 @@
     return new WhereIterable(iterable, f);
   }
 
+  static Iterable map(Iterable iterable, f(var element)) {
+    return new MappedIterable(iterable, f);
+  }
+
   static List mappedByList(List list, f(var element)) {
+    // This is currently a List as well as an Iterable.
     return new MappedList(list, f);
   }
 
-  static List takeList(List list, int n) {
+  static Iterable takeList(List list, int n) {
     // The generic type is currently lost. It will be fixed with mixins.
+    // This is currently a List as well as an Iterable.
     return new ListView(list, 0, n);
   }
 
@@ -327,8 +333,9 @@
     return new TakeWhileIterable(iterable, test);
   }
 
-  static List skipList(List list, int n) {
+  static Iterable skipList(List list, int n) {
     // The generic type is currently lost. It will be fixed with mixins.
+    // This is currently a List as well as an Iterable.
     return new ListView(list, n, null);
   }
 
@@ -337,9 +344,13 @@
     return new SkipWhileIterable(iterable, test);
   }
 
+  static List reversedList(List l) {
+    return new ReversedListView(l, 0, null);
+  }
+
   static void sortList(List l, int compare(a, b)) {
     if (compare == null) compare = Comparable.compare;
-    _Sort.sort(l, compare);
+    Sort.sort(l, compare);
   }
 }
 
@@ -439,7 +450,7 @@
       => IterableMixinWorkaround.mappedByList(list, f);
 
   /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  static List takeList(List list, int n)
+  static Iterable takeList(List list, int n)
       => IterableMixinWorkaround.takeList(list, n);
 
   /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
@@ -447,110 +458,13 @@
       => IterableMixinWorkaround.takeWhile(iterable, test);
 
   /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
-  static List skipList(List list, int n)
+  static Iterable skipList(List list, int n)
       => IterableMixinWorkaround.skipList(list, n);
 
   /** Deprecated. Use the same method in [IterableMixinWorkaround] instead.*/
   static Iterable skipWhile(Iterable iterable, bool test(var value))
       => IterableMixinWorkaround.skipWhile(iterable, test);
 
-  // TODO(jjb): visiting list should be an identityHashSet when it exists
-
-  /**
-   * Returns a string representing the specified collection. If the
-   * collection is a [List], the returned string looks like this:
-   * [:'[element0, element1, ... elementN]':]. The value returned by its
-   * [toString] method is used to represent each element. If the specified
-   * collection is not a list, the returned string looks like this:
-   * [:{element0, element1, ... elementN}:]. In other words, the strings
-   * returned for lists are surrounded by square brackets, while the strings
-   * returned for other collections are surrounded by curly braces.
-   *
-   * If the specified collection contains a reference to itself, either
-   * directly or indirectly through other collections or maps, the contained
-   * reference is rendered as [:'[...]':] if it is a list, or [:'{...}':] if
-   * it is not. This prevents the infinite regress that would otherwise occur.
-   * So, for example, calling this method on a list whose sole element is a
-   * reference to itself would return [:'[[...]]':].
-   *
-   * A typical implementation of a collection's [toString] method will
-   * simply return the results of this method applied to the collection.
-   */
-  static String collectionToString(Collection c) {
-    var result = new StringBuffer();
-    _emitCollection(c, result, new List());
-    return result.toString();
-  }
-
-  /**
-   * Appends a string representing the specified collection to the specified
-   * string buffer. The string is formatted as per [collectionToString].
-   * The [:visiting:] list contains references to all of the enclosing
-   * collections and maps (which are currently in the process of being
-   * emitted into [:result:]). The [:visiting:] parameter allows this method to
-   * generate a [:'[...]':] or [:'{...}':] where required. In other words,
-   * it allows this method and [_emitMap] to identify recursive collections
-   * and maps.
-   */
-  static void _emitCollection(Collection c,
-                              StringBuffer result,
-                              List visiting) {
-    visiting.add(c);
-    bool isList = c is List;
-    result.add(isList ? '[' : '{');
-
-    bool first = true;
-    for (var e in c) {
-      if (!first) {
-        result.add(', ');
-      }
-      first = false;
-      _emitObject(e, result, visiting);
-    }
-
-    result.add(isList ? ']' : '}');
-    visiting.removeLast();
-  }
-
-  /**
-   * Appends a string representing the specified object to the specified
-   * string buffer. If the object is a [Collection] or [Map], it is formatted
-   * as per [collectionToString] or [mapToString]; otherwise, it is formatted
-   * by invoking its own [toString] method.
-   *
-   * The [:visiting:] list contains references to all of the enclosing
-   * collections and maps (which are currently in the process of being
-   * emitted into [:result:]). The [:visiting:] parameter allows this method
-   * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
-   * it allows this method and [_emitCollection] to identify recursive maps
-   * and collections.
-   */
-  static void _emitObject(Object o, StringBuffer result, List visiting) {
-    if (o is Collection) {
-      if (_containsRef(visiting, o)) {
-        result.add(o is List ? '[...]' : '{...}');
-      } else {
-        _emitCollection(o, result, visiting);
-      }
-    } else if (o is Map) {
-      if (_containsRef(visiting, o)) {
-        result.add('{...}');
-      } else {
-        Maps._emitMap(o, result, visiting);
-      }
-    } else { // o is neither a collection nor a map
-      result.add(o);
-    }
-  }
-
-  /**
-   * Returns true if the specified collection contains the specified object
-   * reference.
-   */
-  static _containsRef(Collection c, Object ref) {
-    for (var e in c) {
-      if (identical(e, ref)) return true;
-    }
-    return false;
-  }
+  static String collectionToString(Collection c)
+      => ToString.collectionToString(c);
 }
diff --git a/sdk/lib/collection/maps.dart b/sdk/lib/collection/maps.dart
index 62c760f..b4eef3f 100644
--- a/sdk/lib/collection/maps.dart
+++ b/sdk/lib/collection/maps.dart
@@ -51,7 +51,7 @@
   }
 
   static Iterable getValues(Map map) {
-    return map.keys.mappedBy((key) => map[key]);
+    return map.keys.map((key) => map[key]);
   }
 
   static int length(Map map) => map.keys.length;
@@ -74,38 +74,5 @@
    * A typical implementation of a map's [toString] method will
    * simply return the results of this method applied to the collection.
    */
-  static String mapToString(Map m) {
-    var result = new StringBuffer();
-    _emitMap(m, result, new List());
-    return result.toString();
-  }
-
-  /**
-   * Appends a string representing the specified map to the specified
-   * string buffer. The string is formatted as per [mapToString].
-   * The [:visiting:] list contains references to all of the enclosing
-   * collections and maps (which are currently in the process of being
-   * emitted into [:result:]). The [:visiting:] parameter allows this method
-   * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
-   * it allows this method and [_emitCollection] to identify recursive maps
-   * and collections.
-   */
-  static void _emitMap(Map m, StringBuffer result, List visiting) {
-    visiting.add(m);
-    result.add('{');
-
-    bool first = true;
-    m.forEach((k, v) {
-      if (!first) {
-        result.add(', ');
-      }
-      first = false;
-      Collections._emitObject(k, result, visiting);
-      result.add(': ');
-      Collections._emitObject(v, result, visiting);
-    });
-
-    result.add('}');
-    visiting.removeLast();
-  }
+  static String mapToString(Map m) => ToString.mapToString(m);
 }
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index f5dea8b..87c6fb7 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -160,7 +160,7 @@
  * WARNING: This class is temporary located in dart:core. It'll be removed
  * at some point in the near future.
  */
-class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
+class DoubleLinkedQueue<E> extends Collection<E> implements Queue<E> {
   _DoubleLinkedQueueEntrySentinel<E> _sentinel;
 
   DoubleLinkedQueue() {
diff --git a/sdk/lib/collection_dev/collection_dev.dart b/sdk/lib/collection_dev/collection_dev.dart
index 20eaac9..12e8e62 100644
--- a/sdk/lib/collection_dev/collection_dev.dart
+++ b/sdk/lib/collection_dev/collection_dev.dart
@@ -6,3 +6,5 @@
 
 part 'iterable.dart';
 part 'list.dart';
+part 'sort.dart';
+part 'to_string.dart';
diff --git a/sdk/lib/collection_dev/collection_dev_sources.gypi b/sdk/lib/collection_dev/collection_dev_sources.gypi
index 4bee7d2..819f237 100644
--- a/sdk/lib/collection_dev/collection_dev_sources.gypi
+++ b/sdk/lib/collection_dev/collection_dev_sources.gypi
@@ -7,5 +7,7 @@
   'sources': [
     'iterable.dart',
     'list.dart',
+    'sort.dart',
+    'to_string.dart',
   ],
 }
diff --git a/sdk/lib/collection_dev/list.dart b/sdk/lib/collection_dev/list.dart
index 10facd6..09d6deb 100644
--- a/sdk/lib/collection_dev/list.dart
+++ b/sdk/lib/collection_dev/list.dart
@@ -93,6 +93,10 @@
     return result;
   }
 
+  Iterable map(f(E element)) {
+    return new MappedIterable(this, f);
+  }
+
   List mappedBy(f(E element)) {
     return new MappedList(this, f);
   }
@@ -105,7 +109,11 @@
     return new ListView(this, n, null);
   }
 
-  String toString() => Collections.collectionToString(this);
+  String toString() => ToString.collectionToString(this);
+
+  List<E> get reversed {
+    return new ReversedListView(this, 0, null);
+  }
 }
 
 /**
@@ -114,10 +122,8 @@
 abstract class FixedLengthListBase<E> extends ListBase<E> {
   void operator[]=(int index, E value);
 
-  List<E> get reversed => new ReversedListView<E>(this, 0, null);
-
   void sort([Comparator<E> compare]) {
-    coreSort(this, compare);
+    Sort.sort(this, compare);
   }
 
   void setRange(int start, int length, List<E> from, [int startFrom]) {
@@ -531,7 +537,7 @@
 
   bool moveNext() {
     if (_list.length != _originalLength) {
-      throw new ConcurrentModificationError(list);
+      throw new ConcurrentModificationError(_list);
     }
     if (_index <= _start) return false;
     _index -= 1;
diff --git a/sdk/lib/collection/sort.dart b/sdk/lib/collection_dev/sort.dart
similarity index 99%
rename from sdk/lib/collection/sort.dart
rename to sdk/lib/collection_dev/sort.dart
index a5805cd..9b89e63 100644
--- a/sdk/lib/collection/sort.dart
+++ b/sdk/lib/collection_dev/sort.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.collection;
+part of dart.collection.dev;
 
 /**
  * Dual-Pivot Quicksort algorithm.
@@ -12,7 +12,7 @@
  *
  * Some improvements have been copied from Android's implementation.
  */
-class _Sort {
+class Sort {
   // When a list has less then [:_INSERTION_SORT_THRESHOLD:] elements it will
   // be sorted by an insertion sort.
   static const int _INSERTION_SORT_THRESHOLD = 32;
diff --git a/sdk/lib/collection_dev/to_string.dart b/sdk/lib/collection_dev/to_string.dart
new file mode 100644
index 0000000..c55ccac
--- /dev/null
+++ b/sdk/lib/collection_dev/to_string.dart
@@ -0,0 +1,161 @@
+// 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.collection.dev;
+
+/**
+ * Temporary move `toString` methods into this class.
+ */
+class ToString {
+  // TODO(jjb): visiting list should be an identityHashSet when it exists
+
+  /**
+   * Returns a string representing the specified collection. If the
+   * collection is a [List], the returned string looks like this:
+   * [:'[element0, element1, ... elementN]':]. The value returned by its
+   * [toString] method is used to represent each element. If the specified
+   * collection is not a list, the returned string looks like this:
+   * [:{element0, element1, ... elementN}:]. In other words, the strings
+   * returned for lists are surrounded by square brackets, while the strings
+   * returned for other collections are surrounded by curly braces.
+   *
+   * If the specified collection contains a reference to itself, either
+   * directly or indirectly through other collections or maps, the contained
+   * reference is rendered as [:'[...]':] if it is a list, or [:'{...}':] if
+   * it is not. This prevents the infinite regress that would otherwise occur.
+   * So, for example, calling this method on a list whose sole element is a
+   * reference to itself would return [:'[[...]]':].
+   *
+   * A typical implementation of a collection's [toString] method will
+   * simply return the results of this method applied to the collection.
+   */
+  static String collectionToString(Collection c) {
+    var result = new StringBuffer();
+    _emitCollection(c, result, new List());
+    return result.toString();
+  }
+
+  /**
+   * Appends a string representing the specified collection to the specified
+   * string buffer. The string is formatted as per [collectionToString].
+   * The [:visiting:] list contains references to all of the enclosing
+   * collections and maps (which are currently in the process of being
+   * emitted into [:result:]). The [:visiting:] parameter allows this method to
+   * generate a [:'[...]':] or [:'{...}':] where required. In other words,
+   * it allows this method and [_emitMap] to identify recursive collections
+   * and maps.
+   */
+  static void _emitCollection(Collection c,
+                              StringBuffer result,
+                              List visiting) {
+    visiting.add(c);
+    bool isList = c is List;
+    result.add(isList ? '[' : '{');
+
+    bool first = true;
+    for (var e in c) {
+      if (!first) {
+        result.add(', ');
+      }
+      first = false;
+      _emitObject(e, result, visiting);
+    }
+
+    result.add(isList ? ']' : '}');
+    visiting.removeLast();
+  }
+
+  /**
+   * Appends a string representing the specified object to the specified
+   * string buffer. If the object is a [Collection] or [Map], it is formatted
+   * as per [collectionToString] or [mapToString]; otherwise, it is formatted
+   * by invoking its own [toString] method.
+   *
+   * The [:visiting:] list contains references to all of the enclosing
+   * collections and maps (which are currently in the process of being
+   * emitted into [:result:]). The [:visiting:] parameter allows this method
+   * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
+   * it allows this method and [_emitCollection] to identify recursive maps
+   * and collections.
+   */
+  static void _emitObject(Object o, StringBuffer result, List visiting) {
+    if (o is Collection) {
+      if (_containsRef(visiting, o)) {
+        result.add(o is List ? '[...]' : '{...}');
+      } else {
+        _emitCollection(o, result, visiting);
+      }
+    } else if (o is Map) {
+      if (_containsRef(visiting, o)) {
+        result.add('{...}');
+      } else {
+        _emitMap(o, result, visiting);
+      }
+    } else { // o is neither a collection nor a map
+      result.add(o);
+    }
+  }
+
+  /**
+   * Returns true if the specified collection contains the specified object
+   * reference.
+   */
+  static _containsRef(Collection c, Object ref) {
+    for (var e in c) {
+      if (identical(e, ref)) return true;
+    }
+    return false;
+  }
+
+  /**
+   * Returns a string representing the specified map. The returned string
+   * looks like this: [:'{key0: value0, key1: value1, ... keyN: valueN}':].
+   * The value returned by its [toString] method is used to represent each
+   * key or value.
+   *
+   * If the map collection contains a reference to itself, either
+   * directly as a key or value, or indirectly through other collections
+   * or maps, the contained reference is rendered as [:'{...}':]. This
+   * prevents the infinite regress that would otherwise occur. So, for example,
+   * calling this method on a map whose sole entry maps the string key 'me'
+   * to a reference to the map would return [:'{me: {...}}':].
+   *
+   * A typical implementation of a map's [toString] method will
+   * simply return the results of this method applied to the collection.
+   */
+  static String mapToString(Map m) {
+    var result = new StringBuffer();
+    _emitMap(m, result, new List());
+    return result.toString();
+  }
+
+  /**
+   * Appends a string representing the specified map to the specified
+   * string buffer. The string is formatted as per [mapToString].
+   * The [:visiting:] list contains references to all of the enclosing
+   * collections and maps (which are currently in the process of being
+   * emitted into [:result:]). The [:visiting:] parameter allows this method
+   * to generate a [:'[...]':] or [:'{...}':] where required. In other words,
+   * it allows this method and [_emitCollection] to identify recursive maps
+   * and collections.
+   */
+  static void _emitMap(Map m, StringBuffer result, List visiting) {
+    visiting.add(m);
+    result.add('{');
+
+    bool first = true;
+    m.forEach((k, v) {
+      if (!first) {
+        result.add(', ');
+      }
+      first = false;
+      _emitObject(k, result, visiting);
+      result.add(': ');
+      _emitObject(v, result, visiting);
+    });
+
+    result.add('}');
+    visiting.removeLast();
+  }
+}
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 92321f6..fadf0cc 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -99,7 +99,7 @@
 }
 
 /**
- * Date is the public interface to a point in time.
+ * A DateTime object represents a point in time.
  *
  * It can represent time values that are at a distance of at most
  * 8,640,000,000,000,000ms (100,000,000 days) from epoch (1970-01-01 UTC). In
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index e13f2fe..160e773 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -27,7 +27,7 @@
    * with that index to create the next value.
    *
    * As an [Iterable], [:new Iterable.generate(n, generator)):] is equivalent to
-   * [:const [0, ..., n - 1].mappedBy(generator):]
+   * [:const [0, ..., n - 1].map(generator):]
    */
   factory Iterable.generate(int count, E generator(int index)) {
     return new _GeneratorIterable<E>(count, generator);
@@ -48,7 +48,14 @@
    * multiple times over the the returned [Iterable] will invoke the supplied
    * function [f] multiple times on the same element.
    */
-  Iterable mappedBy(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+  Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+
+  /**
+   * Deprecated alias for [map].
+   *
+   * @deprecated
+   */
+  Iterable mappedBy(f(E element)) => map(f);
 
   /**
     * Returns a lazy [Iterable] with all elements that satisfy the
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index b98743c..10ba3e0 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -23,14 +23,6 @@
   external factory List.fixedLength(int length, {E fill: null});
 
   /**
-   * Creates an list of the given [length] where each entry is
-   * filled with [fill].
-   *
-   * The length of the returned list is not fixed.
-   */
-  external factory List.filled(int length, E fill);
-
-  /**
    * Creates an list with the elements of [other]. The order in
    * the list will be the order provided by the iterator of [other].
    *
@@ -198,36 +190,4 @@
    * [start] is greater than the length of the list.
    */
   void insertRange(int start, int length, [E fill]);
-
-  /**
-   * Returns a lazy unmodifiable [List] where each element [:e:] of [:this:] is
-   * replaced by the result of [:f(e):].
-   *
-   * This method returns a view of the mapped elements. As long as the
-   * returned [List] is not indexed or iterated over, the supplied function [f]
-   * will not be invoked. The transformed elements will not be cached. Accessing
-   * elements multiple times will invoke the supplied function [f] multiple
-   * times.
-   */
-  List mappedBy(f(E element));
-
-  /**
-   * Returns an unmodifiable [List] that hides the first [n] elements.
-   *
-   * The returned list is a view backed by [:this:].
-   *
-   * While [:this:] has fewer than [n] elements, then the resulting [List]
-   * will be empty.
-   */
-  List<E> skip(int n);
-
-  /**
-   * Returns an unmodifiable [List] with at most [n] elements.
-   *
-   * The returned list is a view backed by this.
-   *
-   * The returned [List] may contain fewer than [n] elements, while [:this:]
-   * contains fewer than [n] elements.
-   */
-  List<E> take(int n);
 }
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 7f2dcbd..27eb67f 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -80,6 +80,11 @@
 
   /**
    * Creates a new string by concatenating this string with [other].
+   *
+   * A sequence of strings can be concatenated by using [Iterable.join]:
+   *
+   *     var strings = ['foo', 'bar', 'geez'];
+   *     var concatenated = strings.join();
    */
   String concat(String other);
 
diff --git a/sdk/lib/core/strings.dart b/sdk/lib/core/strings.dart
index dcdcafc..412e23f 100644
--- a/sdk/lib/core/strings.dart
+++ b/sdk/lib/core/strings.dart
@@ -7,11 +7,15 @@
 abstract class Strings {
   /**
    * Joins all the given strings to create a new string.
+   *
+   * *Deprecated* Use `strings.join(separator)` instead.
    */
   external static String join(Iterable<String> strings, String separator);
 
   /**
    * Concatenates all the given strings to create a new string.
+   *
+   * *Deprecated* Use `strings.join()` instead.
    */
   external static String concatAll(Iterable<String> strings);
 }
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index e1340e2..d540e7b 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -1,8 +1,7 @@
-library html;
+library dart.dom.html;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -109,6 +108,7 @@
 @DomName('HTMLAnchorElement')
 class AnchorElement extends Element native "*HTMLAnchorElement" {
 
+  @DomName('HTMLAnchorElement.HTMLAnchorElement')
   @DocsEditable
   factory AnchorElement({String href}) {
     var e = document.$dom_createElement("a");
@@ -370,6 +370,7 @@
 @DomName('HTMLAreaElement')
 class AreaElement extends Element native "*HTMLAreaElement" {
 
+  @DomName('HTMLAreaElement.HTMLAreaElement')
   @DocsEditable
   factory AreaElement() => document.$dom_createElement("area");
 
@@ -437,9 +438,12 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ArrayBuffer native "*ArrayBuffer" {
 
+  @DomName('ArrayBuffer.ArrayBuffer')
   @DocsEditable
-  factory ArrayBuffer(int length) => ArrayBuffer._create(length);
-  static ArrayBuffer _create(int length) => JS('ArrayBuffer', 'new ArrayBuffer(#)', length);
+  factory ArrayBuffer(int length) {
+    return ArrayBuffer._create_1(length);
+  }
+  static ArrayBuffer _create_1(length) => JS('ArrayBuffer', 'new ArrayBuffer(#)', length);
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => JS('bool', 'typeof window.ArrayBuffer != "undefined"');
@@ -520,19 +524,16 @@
 @DomName('HTMLAudioElement')
 class AudioElement extends MediaElement native "*HTMLAudioElement" {
 
+  @DomName('HTMLAudioElement.HTMLAudioElement')
   @DocsEditable
   factory AudioElement([String src]) {
-    if (!?src) {
-      return AudioElement._create();
+    if (?src) {
+      return AudioElement._create_1(src);
     }
-    return AudioElement._create(src);
+    return AudioElement._create_2();
   }
-  static AudioElement _create([String src]) {
-    if (!?src) {
-      return JS('AudioElement', 'new Audio()');
-    }
-    return JS('AudioElement', 'new Audio(#)', src);
-  }
+  static AudioElement _create_1(src) => JS('AudioElement', 'new Audio(#)', src);
+  static AudioElement _create_2() => JS('AudioElement', 'new Audio()');
 }
 // 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
@@ -543,6 +544,7 @@
 @DomName('HTMLBRElement')
 class BRElement extends Element native "*HTMLBRElement" {
 
+  @DomName('HTMLBRElement.HTMLBRElement')
   @DocsEditable
   factory BRElement() => document.$dom_createElement("br");
 }
@@ -568,6 +570,7 @@
 @DomName('HTMLBaseElement')
 class BaseElement extends Element native "*HTMLBaseElement" {
 
+  @DomName('HTMLBaseElement.HTMLBaseElement')
   @DocsEditable
   factory BaseElement() => document.$dom_createElement("base");
 
@@ -696,17 +699,6 @@
 @DomName('Blob')
 class Blob native "*Blob" {
 
-  @DocsEditable
-  factory Blob(List blobParts, [String type, String endings]) {
-    if (!?type) {
-      return Blob._create(blobParts);
-    }
-    if (!?endings) {
-      return Blob._create(blobParts, type);
-    }
-    return Blob._create(blobParts, type, endings);
-  }
-
   @DomName('Blob.size')
   @DocsEditable
   final int size;
@@ -719,7 +711,7 @@
   @DocsEditable
   Blob slice([int start, int end, String contentType]) native;
 
-  static Blob _create([List blobParts = null, String type, String endings]) {
+  factory Blob(List blobParts, [String type, String endings]) {
     // TODO: validate that blobParts is a JS Array and convert if not.
     // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
     // array to ArrayBuffer if it is a total view.
@@ -800,6 +792,7 @@
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
+  @DomName('HTMLBodyElement.HTMLBodyElement')
   @DocsEditable
   factory BodyElement() => document.$dom_createElement("body");
 
@@ -916,6 +909,7 @@
 @DomName('HTMLButtonElement')
 class ButtonElement extends Element native "*HTMLButtonElement" {
 
+  @DomName('HTMLButtonElement.HTMLButtonElement')
   @DocsEditable
   factory ButtonElement() => document.$dom_createElement("button");
 
@@ -1006,6 +1000,7 @@
 @DomName('HTMLCanvasElement')
 class CanvasElement extends Element native "*HTMLCanvasElement" {
 
+  @DomName('HTMLCanvasElement.HTMLCanvasElement')
   @DocsEditable
   factory CanvasElement({int width, int height}) {
     var e = document.$dom_createElement("canvas");
@@ -1014,22 +1009,99 @@
     return e;
   }
 
+  /// The height of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.height')
   @DocsEditable
   int height;
 
+  /// The width of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.width')
   @DocsEditable
   int width;
 
+  CanvasRenderingContext getContext(String contextId, [Map attrs]) {
+    if (?attrs) {
+      var attrs_1 = convertDartToNative_Dictionary(attrs);
+      return _getContext_1(contextId, attrs_1);
+    }
+    return _getContext_2(contextId);
+  }
+  @JSName('getContext')
+  @DomName('HTMLCanvasElement.getContext')
+  @DocsEditable
+  CanvasRenderingContext _getContext_1(contextId, attrs) native;
+  @JSName('getContext')
+  @DomName('HTMLCanvasElement.getContext')
+  @DocsEditable
+  CanvasRenderingContext _getContext_2(contextId) native;
+
   @JSName('toDataURL')
+  /**
+   * Returns a data URI containing a representation of the image in the
+   * format specified by type (defaults to 'image/png').
+   *
+   * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+   *
+   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]
+   * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default
+   * value is used. Note: the default value varies by browser.
+   *
+   * If the height or width of this canvas element is 0, then 'data:' is returned,
+   * representing no data.
+   *
+   * If the type requested is not 'image/png', and the returned value is
+   * 'data:image/png', then the requested type is not supported.
+   *
+   * Example usage:
+   *
+   *     CanvasElement canvas = new CanvasElement();
+   *     var ctx = canvas.context2d
+   *     ..fillStyle = "rgb(200,0,0)"
+   *     ..fillRect(10, 10, 55, 50);
+   *     var dataUrl = canvas.toDataURL("image/jpeg", 0.95);
+   *     // The Data Uri would look similar to
+   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+   *     //Create a new image element from the data URI.
+   *     var img = new ImageElement();
+   *     img.src = dataUrl;
+   *     document.body.children.add(img);
+   *
+   * See also:
+   *
+   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+   *
+   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+   *
+   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+   */
   @DomName('HTMLCanvasElement.toDataURL')
   @DocsEditable
   String toDataUrl(String type, [num quality]) native;
 
-
-  CanvasRenderingContext getContext(String contextId) native;
   CanvasRenderingContext2D get context2d => getContext('2d');
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @Experimental
+  WebGLRenderingContext getContext3d({alpha: true, depth: true, stencil: false,
+    antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {
+
+    var options = {
+      'alpha': alpha,
+      'depth': depth,
+      'stencil': stencil,
+      'antialias': antialias,
+      'premultipliedAlpha': premultipliedAlpha,
+      'preserveDrawingBuffer': preserveDrawingBuffer,
+    };
+    var context = getContext('webgl', options);
+    if (context == null) {
+      context = getContext('experimental-webgl', options);
+    }
+    return context;
+  }
 }
 // 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
@@ -1037,9 +1109,47 @@
 
 
 @DocsEditable
+/**
+ * An opaque canvas object representing a gradient.
+ *
+ * Created by calling [createLinearGradient] or [createRadialGradient] on a
+ * [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ *     var canvas = new CanvasElement(width: 600, height: 600);
+ *     var ctx = canvas.context2d;
+ *     ctx.clearRect(0, 0, 600, 600);
+ *     ctx.save();
+ *     // Create radial gradient.
+ *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
+ *     gradient.addColorStop(0, '#000');
+ *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
+ *     // Assign gradients to fill.
+ *     ctx.fillStyle = gradient;
+ *     // Draw a rectangle with a gradient fill.
+ *     ctx.fillRect(0, 0, 600, 600);
+ *     ctx.save();
+ *     document.body.children.add(canvas);
+ *
+ * See also:
+ *
+ * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
+ * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
+ */
 @DomName('CanvasGradient')
 class CanvasGradient native "*CanvasGradient" {
 
+  /**
+   * Adds a color stop to this gradient at the offset.
+   *
+   * The [offset] can range between 0.0 and 1.0.
+   *
+   * See also:
+   *
+   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
+   */
   @DomName('CanvasGradient.addColorStop')
   @DocsEditable
   void addColorStop(num offset, String color) native;
@@ -1050,6 +1160,33 @@
 
 
 @DocsEditable
+/**
+ * An opaque object representing a pattern of image, canvas, or video.
+ *
+ * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ *     var canvas = new CanvasElement(width: 600, height: 600);
+ *     var ctx = canvas.context2d;
+ *     var img = new ImageElement();
+ *     // Image src needs to be loaded before pattern is applied.
+ *     img.onLoad.listen((event) {
+ *       // When the image is loaded, create a pattern
+ *       // from the ImageElement.
+ *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
+ *       ctx.rect(0, 0, canvas.width, canvas.height);
+ *       ctx.fillStyle = pattern;
+ *       ctx.fill();
+ *     });
+ *     img.src = "images/foo.jpg";
+ *     document.body.children.add(canvas);
+ *
+ * See also:
+ * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
+ * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
+ */
 @DomName('CanvasPattern')
 class CanvasPattern native "*CanvasPattern" {
 }
@@ -1059,9 +1196,16 @@
 
 
 @DocsEditable
+/**
+ * A rendering context for a canvas element.
+ *
+ * This context is extended by [CanvasRenderingContext2D] and
+ * [WebGLRenderingContext].
+ */
 @DomName('CanvasRenderingContext')
 class CanvasRenderingContext native "*CanvasRenderingContext" {
 
+  /// Reference to the canvas element to which this context belongs.
   @DomName('CanvasRenderingContext.canvas')
   @DocsEditable
   final CanvasElement canvas;
@@ -1180,7 +1324,7 @@
 
   @DomName('CanvasRenderingContext2D.clip')
   @DocsEditable
-  void clip() native;
+  void clip([String winding]) native;
 
   @DomName('CanvasRenderingContext2D.closePath')
   @DocsEditable
@@ -1225,7 +1369,7 @@
 
   @DomName('CanvasRenderingContext2D.fill')
   @DocsEditable
-  void fill() native;
+  void fill([String winding]) native;
 
   @DomName('CanvasRenderingContext2D.fillRect')
   @DocsEditable
@@ -1250,7 +1394,7 @@
 
   @DomName('CanvasRenderingContext2D.isPointInPath')
   @DocsEditable
-  bool isPointInPath(num x, num y) native;
+  bool isPointInPath(num x, num y, [String winding]) native;
 
   @DomName('CanvasRenderingContext2D.lineTo')
   @DocsEditable
@@ -1482,53 +1626,6 @@
 
 
 @DocsEditable
-@DomName('Clipboard')
-class Clipboard native "*Clipboard" {
-
-  @DomName('Clipboard.dropEffect')
-  @DocsEditable
-  String dropEffect;
-
-  @DomName('Clipboard.effectAllowed')
-  @DocsEditable
-  String effectAllowed;
-
-  @DomName('Clipboard.files')
-  @DocsEditable
-  @Returns('FileList')
-  @Creates('FileList')
-  final List<File> files;
-
-  @DomName('Clipboard.items')
-  @DocsEditable
-  final DataTransferItemList items;
-
-  @DomName('Clipboard.types')
-  @DocsEditable
-  final List types;
-
-  @DomName('Clipboard.clearData')
-  @DocsEditable
-  void clearData([String type]) native;
-
-  @DomName('Clipboard.getData')
-  @DocsEditable
-  String getData(String type) native;
-
-  @DomName('Clipboard.setData')
-  @DocsEditable
-  bool setData(String type, String data) native;
-
-  @DomName('Clipboard.setDragImage')
-  @DocsEditable
-  void setDragImage(ImageElement image, int x, int y) 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
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
 @DomName('CloseEvent')
 class CloseEvent extends Event native "*CloseEvent" {
 
@@ -1695,6 +1792,7 @@
 @Experimental
 class ContentElement extends Element native "*HTMLContentElement" {
 
+  @DomName('HTMLContentElement.HTMLContentElement')
   @DocsEditable
   factory ContentElement() => document.$dom_createElement("content");
 
@@ -1818,6 +1916,29 @@
 
 
 @DocsEditable
+@DomName('CSSHostRule')
+class CssHostRule extends CssRule native "*CSSHostRule" {
+
+  @DomName('CSSHostRule.cssRules')
+  @DocsEditable
+  @Returns('_CssRuleList')
+  @Creates('_CssRuleList')
+  final List<CssRule> cssRules;
+
+  @DomName('CSSHostRule.deleteRule')
+  @DocsEditable
+  void deleteRule(int index) native;
+
+  @DomName('CSSHostRule.insertRule')
+  @DocsEditable
+  int insertRule(String rule, 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
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('CSSImportRule')
 class CssImportRule extends CssRule native "*CSSImportRule" {
 
@@ -1888,21 +2009,24 @@
 
 @DocsEditable
 @DomName('WebKitCSSMatrix')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class CssMatrix native "*WebKitCSSMatrix" {
 
+  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
   @DocsEditable
   factory CssMatrix([String cssValue]) {
-    if (!?cssValue) {
-      return CssMatrix._create();
+    if (?cssValue) {
+      return CssMatrix._create_1(cssValue);
     }
-    return CssMatrix._create(cssValue);
+    return CssMatrix._create_2();
   }
-  static CssMatrix _create([String cssValue]) {
-    if (!?cssValue) {
-      return JS('CssMatrix', 'new WebKitCSSMatrix()');
-    }
-    return JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
-  }
+  static CssMatrix _create_1(cssValue) => JS('CssMatrix', 'new WebKitCSSMatrix(#)', cssValue);
+  static CssMatrix _create_2() => JS('CssMatrix', 'new WebKitCSSMatrix()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.WebKitCSSMatrix)');
 
   @DomName('WebKitCSSMatrix.a')
   @DocsEditable
@@ -2189,6 +2313,8 @@
 
   static const int FONT_FACE_RULE = 5;
 
+  static const int HOST_RULE = 1001;
+
   static const int IMPORT_RULE = 3;
 
   static const int MEDIA_RULE = 4;
@@ -5639,6 +5765,7 @@
 @DomName('HTMLDListElement')
 class DListElement extends Element native "*HTMLDListElement" {
 
+  @DomName('HTMLDListElement.HTMLDListElement')
   @DocsEditable
   factory DListElement() => document.$dom_createElement("dl");
 }
@@ -5655,6 +5782,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class DataListElement extends Element native "*HTMLDataListElement" {
 
+  @DomName('HTMLDataListElement.HTMLDataListElement')
   @DocsEditable
   factory DataListElement() => document.$dom_createElement("datalist");
 
@@ -5671,6 +5799,53 @@
 
 
 @DocsEditable
+@DomName('Clipboard')
+class DataTransfer native "*Clipboard" {
+
+  @DomName('Clipboard.dropEffect')
+  @DocsEditable
+  String dropEffect;
+
+  @DomName('Clipboard.effectAllowed')
+  @DocsEditable
+  String effectAllowed;
+
+  @DomName('Clipboard.files')
+  @DocsEditable
+  @Returns('FileList')
+  @Creates('FileList')
+  final List<File> files;
+
+  @DomName('Clipboard.items')
+  @DocsEditable
+  final DataTransferItemList items;
+
+  @DomName('Clipboard.types')
+  @DocsEditable
+  final List types;
+
+  @DomName('Clipboard.clearData')
+  @DocsEditable
+  void clearData([String type]) native;
+
+  @DomName('Clipboard.getData')
+  @DocsEditable
+  String getData(String type) native;
+
+  @DomName('Clipboard.setData')
+  @DocsEditable
+  bool setData(String type, String data) native;
+
+  @DomName('Clipboard.setDragImage')
+  @DocsEditable
+  void setDragImage(ImageElement image, int x, int y) 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
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('DataTransferItem')
 class DataTransferItem native "*DataTransferItem" {
 
@@ -5728,25 +5903,20 @@
 @DomName('DataView')
 class DataView extends ArrayBufferView native "*DataView" {
 
+  @DomName('DataView.DataView')
   @DocsEditable
   factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
-    if (!?byteOffset) {
-      return DataView._create(buffer);
+    if (?byteLength) {
+      return DataView._create_1(buffer, byteOffset, byteLength);
     }
-    if (!?byteLength) {
-      return DataView._create(buffer, byteOffset);
+    if (?byteOffset) {
+      return DataView._create_2(buffer, byteOffset);
     }
-    return DataView._create(buffer, byteOffset, byteLength);
+    return DataView._create_3(buffer);
   }
-  static DataView _create(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
-    if (!?byteOffset) {
-      return JS('DataView', 'new DataView(#)', buffer);
-    }
-    if (!?byteLength) {
-      return JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
-    }
-    return JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
-  }
+  static DataView _create_1(buffer, byteOffset, byteLength) => JS('DataView', 'new DataView(#,#,#)', buffer, byteOffset, byteLength);
+  static DataView _create_2(buffer, byteOffset) => JS('DataView', 'new DataView(#,#)', buffer, byteOffset);
+  static DataView _create_3(buffer) => JS('DataView', 'new DataView(#)', buffer);
 
   @DomName('DataView.getFloat32')
   @DocsEditable
@@ -5819,8 +5989,14 @@
 
 @DocsEditable
 @DomName('Database')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class Database native "*Database" {
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.openDatabase)');
+
   @DomName('Database.version')
   @DocsEditable
   final String version;
@@ -5852,6 +6028,9 @@
 
 @DocsEditable
 @DomName('DatabaseSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class DatabaseSync native "*DatabaseSync" {
 
   @DomName('DatabaseSync.lastErrorMessage')
@@ -5938,6 +6117,7 @@
 @Experimental
 class DetailsElement extends Element native "*HTMLDetailsElement" {
 
+  @DomName('HTMLDetailsElement.HTMLDetailsElement')
   @DocsEditable
   factory DetailsElement() => document.$dom_createElement("details");
 
@@ -6159,9 +6339,31 @@
 
 
 @DocsEditable
+/**
+ * Represents an HTML <div> element.
+ *
+ * The [DivElement] is a generic container for content and does not have any
+ * special significance. It is functionally similar to [SpanElement].
+ *
+ * The [DivElement] is a block-level element, as opposed to [SpanElement],
+ * which is an inline-level element.
+ *
+ * Example usage:
+ *
+ *     DivElement div = new DivElement();
+ *     div.text = 'Here's my new DivElem
+ *     document.body.elements.add(elem);
+ *
+ * See also:
+ *
+ * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
+ * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
+ */
 @DomName('HTMLDivElement')
 class DivElement extends Element native "*HTMLDivElement" {
 
+  @DomName('HTMLDivElement.HTMLDivElement')
   @DocsEditable
   factory DivElement() => document.$dom_createElement("div");
 }
@@ -6207,6 +6409,7 @@
     new DocumentEvents(this);
 
   @JSName('body')
+  /// Moved to [HtmlDocument].
   @DomName('Document.body')
   @DocsEditable
   Element $dom_body;
@@ -6236,6 +6439,7 @@
   final String domain;
 
   @JSName('head')
+  /// Moved to [HtmlDocument].
   @DomName('Document.head')
   @DocsEditable
   final HeadElement $dom_head;
@@ -6245,6 +6449,7 @@
   final DomImplementation implementation;
 
   @JSName('lastModified')
+  /// Moved to [HtmlDocument].
   @DomName('Document.lastModified')
   @DocsEditable
   final String $dom_lastModified;
@@ -6259,6 +6464,7 @@
   final String readyState;
 
   @JSName('referrer')
+  /// Moved to [HtmlDocument].
   @DomName('Document.referrer')
   @DocsEditable
   final String $dom_referrer;
@@ -6269,6 +6475,7 @@
   String $dom_selectedStylesheetSet;
 
   @JSName('styleSheets')
+  /// Moved to [HtmlDocument]
   @DomName('Document.styleSheets')
   @DocsEditable
   @Returns('_StyleSheetList')
@@ -6276,31 +6483,37 @@
   final List<StyleSheet> $dom_styleSheets;
 
   @JSName('title')
+  /// Moved to [HtmlDocument].
   @DomName('Document.title')
   @DocsEditable
   String $dom_title;
 
   @JSName('webkitFullscreenElement')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenElement')
   @DocsEditable
   final Element $dom_webkitFullscreenElement;
 
   @JSName('webkitFullscreenEnabled')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenEnabled')
   @DocsEditable
   final bool $dom_webkitFullscreenEnabled;
 
   @JSName('webkitHidden')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitHidden')
   @DocsEditable
   final bool $dom_webkitHidden;
 
   @JSName('webkitIsFullScreen')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitIsFullScreen')
   @DocsEditable
   final bool $dom_webkitIsFullScreen;
 
   @JSName('webkitPointerLockElement')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitPointerLockElement')
   @DocsEditable
   final Element $dom_webkitPointerLockElement;
@@ -6311,6 +6524,7 @@
   final String $dom_webkitVisibilityState;
 
   @JSName('caretRangeFromPoint')
+  /// Use the [Range] constructor instead.
   @DomName('Document.caretRangeFromPoint')
   @DocsEditable
   Range $dom_caretRangeFromPoint(int x, int y) native;
@@ -6325,6 +6539,7 @@
   DocumentFragment createDocumentFragment() native;
 
   @JSName('createElement')
+  /// Deprecated: use new Element.tag(tagName) instead.
   @DomName('Document.createElement')
   @DocsEditable
   Element $dom_createElement(String tagName) native;
@@ -6359,6 +6574,7 @@
   Touch _$dom_createTouch_1(Window window, target, identifier, pageX, pageY, screenX, screenY, webkitRadiusX, webkitRadiusY, webkitRotationAngle, webkitForce) native;
 
   @JSName('createTouchList')
+  /// Use the [TouchList] constructor instead.
   @DomName('Document.createTouchList')
   @DocsEditable
   TouchList $dom_createTouchList() native;
@@ -6373,11 +6589,13 @@
   bool execCommand(String command, bool userInterface, String value) native;
 
   @JSName('getCSSCanvasContext')
+  /// Moved to [HtmlDocument].
   @DomName('Document.getCSSCanvasContext')
   @DocsEditable
   CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native;
 
   @JSName('getElementById')
+  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.getElementById')
   @DocsEditable
   Element $dom_getElementById(String elementId) native;
@@ -6424,11 +6642,13 @@
   String queryCommandValue(String command) native;
 
   @JSName('querySelector')
+  /// Deprecated: renamed to the shorter name [query].
   @DomName('Document.querySelector')
   @DocsEditable
   Element $dom_querySelector(String selectors) native;
 
   @JSName('querySelectorAll')
+  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.querySelectorAll')
   @DocsEditable
   @Returns('NodeList')
@@ -6436,16 +6656,19 @@
   List<Node> $dom_querySelectorAll(String selectors) native;
 
   @JSName('webkitCancelFullScreen')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitCancelFullScreen')
   @DocsEditable
   void $dom_webkitCancelFullScreen() native;
 
   @JSName('webkitExitFullscreen')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitFullscreen')
   @DocsEditable
   void $dom_webkitExitFullscreen() native;
 
   @JSName('webkitExitPointerLock')
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitPointerLock')
   @DocsEditable
   void $dom_webkitExitPointerLock() native;
@@ -6996,7 +7219,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(DomMimeType element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(DomMimeType element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(DomMimeType element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<DomMimeType> where(bool f(DomMimeType element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7010,13 +7237,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<DomMimeType> takeWhile(bool test(DomMimeType value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<DomMimeType> skipWhile(bool test(DomMimeType value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -7061,8 +7288,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomMimeType> get reversed =>
-      new ReversedListView<DomMimeType>(this, 0, null);
+  List<DomMimeType> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(DomMimeType a, DomMimeType b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -7160,9 +7388,12 @@
 @DomName('DOMParser')
 class DomParser native "*DOMParser" {
 
+  @DomName('DOMParser.DOMParser')
   @DocsEditable
-  factory DomParser() => DomParser._create();
-  static DomParser _create() => JS('DomParser', 'new DOMParser()');
+  factory DomParser() {
+    return DomParser._create_1();
+  }
+  static DomParser _create_1() => JS('DomParser', 'new DOMParser()');
 
   @DomName('DOMParser.parseFromString')
   @DocsEditable
@@ -7242,7 +7473,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(DomPlugin element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(DomPlugin element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(DomPlugin element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<DomPlugin> where(bool f(DomPlugin element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7256,13 +7491,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<DomPlugin> takeWhile(bool test(DomPlugin value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<DomPlugin> skipWhile(bool test(DomPlugin value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -7307,8 +7542,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomPlugin> get reversed =>
-      new ReversedListView<DomPlugin>(this, 0, null);
+  List<DomPlugin> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(DomPlugin a, DomPlugin b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -7407,6 +7643,36 @@
 
 
 @DocsEditable
+@DomName('WebKitPoint')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
+class DomPoint native "*WebKitPoint" {
+
+  @DomName('WebKitPoint.WebKitPoint')
+  @DocsEditable
+  factory DomPoint(num x, num y) {
+    return DomPoint._create_1(x, y);
+  }
+  static DomPoint _create_1(x, y) => JS('DomPoint', 'new WebKitPoint(#,#)', x, y);
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.WebKitPoint)');
+
+  @DomName('WebKitPoint.x')
+  @DocsEditable
+  num x;
+
+  @DomName('WebKitPoint.y')
+  @DocsEditable
+  num y;
+}
+// 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.
+
+
+@DocsEditable
 @DomName('Selection')
 class DomSelection native "*Selection" {
 
@@ -7568,7 +7834,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(String element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(String element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7582,13 +7852,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<String> takeWhile(bool test(String value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<String> skipWhile(bool test(String value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -7633,8 +7903,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<String> get reversed =>
-      new ReversedListView<String>(this, 0, null);
+  List<String> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(String a, String b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -7822,6 +8093,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Element element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Element element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -7834,7 +8109,7 @@
     return _element.$dom_firstElementChild == null;
   }
 
-  List<Element> take(int n) {
+  Iterable<Element> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -7842,7 +8117,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Element> skip(int n) {
+  Iterable<Element> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -7898,8 +8173,9 @@
     }
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(this, 0, null);
+  List<Element> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -7917,7 +8193,7 @@
   void remove(Object object) {
     if (object is Element) {
       Element element = object;
-      if (identical(element.parentNode, this)) {
+      if (identical(element.parentNode, _element)) {
         _element.$dom_removeChild(element);
       }
     }
@@ -8034,6 +8310,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Element element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Element element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -8063,7 +8343,7 @@
   List<Element> toList() => new List<Element>.from(this);
   Set<Element> toSet() => new Set<Element>.from(this);
 
-  List<Element> take(int n) {
+  Iterable<Element> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -8071,7 +8351,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Element> skip(int n) {
+  Iterable<Element> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -8123,8 +8403,9 @@
     throw new UnsupportedError('');
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(this, 0, null);
+  List<Element> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('');
@@ -8469,27 +8750,20 @@
    * [style] property, which contains only the values specified directly on this
    * element.
    *
+   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+   * `::line-marker`.
+   *
    * See also:
    *
    * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
-   */
-  Future<CssStyleDeclaration> get computedStyle {
-     // TODO(jacobr): last param should be null, see b/5045788
-     return getComputedStyle('');
-  }
-
-  /**
-   * Returns the computed styles for pseudo-elements such as `::after`,
-   * `::before`, `::marker`, `::line-marker`.
-   *
-   * See also:
-   *
    * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
    */
-  Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) {
-    return _createMeasurementFuture(
-        () => window.$dom_getComputedStyle(this, pseudoElement),
-        new Completer<CssStyleDeclaration>());
+  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+    if (pseudoElement == null) {
+      pseudoElement = '';
+    }
+    // TODO(jacobr): last param should be null, see b/5045788
+    return window.$dom_getComputedStyle(this, pseudoElement);
   }
 
   /**
@@ -8666,6 +8940,7 @@
     } else if (JS('bool', '!!#.msMatchesSelector', this)) {
       return JS('bool', '#.msMatchesSelector(#)', this, selectors);
     }
+    throw new UnsupportedError("Not supported on this platform");
   }
 
 
@@ -9667,6 +9942,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class EmbedElement extends Element native "*HTMLEmbedElement" {
 
+  @DomName('HTMLEmbedElement.HTMLEmbedElement')
   @DocsEditable
   factory EmbedElement() => document.$dom_createElement("embed");
 
@@ -9949,7 +10225,7 @@
 
   @DomName('Event.clipboardData')
   @DocsEditable
-  final Clipboard clipboardData;
+  final DataTransfer clipboardData;
 
   EventTarget get currentTarget => _convertNativeToDart_EventTarget(this._currentTarget);
   @JSName('currentTarget')
@@ -10067,19 +10343,16 @@
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
+  @DomName('EventSource.EventSource')
   @DocsEditable
   factory EventSource(String url, [Map eventSourceInit]) {
-    if (!?eventSourceInit) {
-      return EventSource._create(url);
+    if (?eventSourceInit) {
+      return EventSource._create_1(url, eventSourceInit);
     }
-    return EventSource._create(url, eventSourceInit);
+    return EventSource._create_2(url);
   }
-  static EventSource _create(String url, [Map eventSourceInit]) {
-    if (!?eventSourceInit) {
-      return JS('EventSource', 'new EventSource(#)', url);
-    }
-    return JS('EventSource', 'new EventSource(#,#)', url, eventSourceInit);
-  }
+  static EventSource _create_1(url, eventSourceInit) => JS('EventSource', 'new EventSource(#,#)', url, eventSourceInit);
+  static EventSource _create_2(url) => JS('EventSource', 'new EventSource(#)', url);
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -10268,6 +10541,7 @@
 @DomName('HTMLFieldSetElement')
 class FieldSetElement extends Element native "*HTMLFieldSetElement" {
 
+  @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
   @DocsEditable
   factory FieldSetElement() => document.$dom_createElement("fieldset");
 
@@ -10501,7 +10775,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(File element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(File element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(File element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<File> where(bool f(File element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -10515,13 +10793,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<File> takeWhile(bool test(File value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<File> skipWhile(bool test(File value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -10566,8 +10844,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<File> get reversed =>
-      new ReversedListView<File>(this, 0, null);
+  List<File> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(File a, File b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -10685,9 +10964,12 @@
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
+  @DomName('FileReader.FileReader')
   @DocsEditable
-  factory FileReader() => FileReader._create();
-  static FileReader _create() => JS('FileReader', 'new FileReader()');
+  factory FileReader() {
+    return FileReader._create_1();
+  }
+  static FileReader _create_1() => JS('FileReader', 'new FileReader()');
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -10807,9 +11089,12 @@
 @DomName('FileReaderSync')
 class FileReaderSync native "*FileReaderSync" {
 
+  @DomName('FileReaderSync.FileReaderSync')
   @DocsEditable
-  factory FileReaderSync() => FileReaderSync._create();
-  static FileReaderSync _create() => JS('FileReaderSync', 'new FileReaderSync()');
+  factory FileReaderSync() {
+    return FileReaderSync._create_1();
+  }
+  static FileReaderSync _create_1() => JS('FileReaderSync', 'new FileReaderSync()');
 
   @DomName('FileReaderSync.readAsArrayBuffer')
   @DocsEditable
@@ -11059,12 +11344,18 @@
 @DomName('Float32Array')
 class Float32Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<num> native "*Float32Array" {
 
+  @DomName('Float32Array.Float32Array')
+  @DocsEditable
   factory Float32Array(int length) =>
     _TypedArrayFactoryProvider.createFloat32Array(length);
 
+  @DomName('Float32Array.fromList')
+  @DocsEditable
   factory Float32Array.fromList(List<num> list) =>
     _TypedArrayFactoryProvider.createFloat32Array_fromList(list);
 
+  @DomName('Float32Array.fromBuffer')
+  @DocsEditable
   factory Float32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createFloat32Array_fromBuffer(buffer, byteOffset, length);
 
@@ -11099,7 +11390,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(num element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(num element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -11113,13 +11408,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<num> takeWhile(bool test(num value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<num> skipWhile(bool test(num value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -11164,8 +11459,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed =>
-      new ReversedListView<num>(this, 0, null);
+  List<num> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(num a, num b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -11264,12 +11560,18 @@
 @DomName('Float64Array')
 class Float64Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<num> native "*Float64Array" {
 
+  @DomName('Float64Array.Float64Array')
+  @DocsEditable
   factory Float64Array(int length) =>
     _TypedArrayFactoryProvider.createFloat64Array(length);
 
+  @DomName('Float64Array.fromList')
+  @DocsEditable
   factory Float64Array.fromList(List<num> list) =>
     _TypedArrayFactoryProvider.createFloat64Array_fromList(list);
 
+  @DomName('Float64Array.fromBuffer')
+  @DocsEditable
   factory Float64Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createFloat64Array_fromBuffer(buffer, byteOffset, length);
 
@@ -11304,7 +11606,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(num element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(num element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -11318,13 +11624,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<num> takeWhile(bool test(num value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<num> skipWhile(bool test(num value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -11369,8 +11675,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed =>
-      new ReversedListView<num>(this, 0, null);
+  List<num> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(num a, num b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -11469,19 +11776,16 @@
 @DomName('FormData')
 class FormData native "*FormData" {
 
+  @DomName('DOMFormData.DOMFormData')
   @DocsEditable
   factory FormData([FormElement form]) {
-    if (!?form) {
-      return FormData._create();
+    if (?form) {
+      return FormData._create_1(form);
     }
-    return FormData._create(form);
+    return FormData._create_2();
   }
-  static FormData _create([FormElement form]) {
-    if (!?form) {
-      return JS('FormData', 'new FormData()');
-    }
-    return JS('FormData', 'new FormData(#)', form);
-  }
+  static FormData _create_1(form) => JS('FormData', 'new FormData(#)', form);
+  static FormData _create_2() => JS('FormData', 'new FormData()');
 
   @DomName('DOMFormData.append')
   @DocsEditable
@@ -11496,6 +11800,7 @@
 @DomName('HTMLFormElement')
 class FormElement extends Element native "*HTMLFormElement" {
 
+  @DomName('HTMLFormElement.HTMLFormElement')
   @DocsEditable
   factory FormElement() => document.$dom_createElement("form");
 
@@ -11627,6 +11932,7 @@
 @DomName('HTMLHRElement')
 class HRElement extends Element native "*HTMLHRElement" {
 
+  @DomName('HTMLHRElement.HTMLHRElement')
   @DocsEditable
   factory HRElement() => document.$dom_createElement("hr");
 }
@@ -11678,6 +11984,7 @@
 @DomName('HTMLHeadElement')
 class HeadElement extends Element native "*HTMLHeadElement" {
 
+  @DomName('HTMLHeadElement.HTMLHeadElement')
   @DocsEditable
   factory HeadElement() => document.$dom_createElement("head");
 }
@@ -11690,21 +11997,27 @@
 @DomName('HTMLHeadingElement')
 class HeadingElement extends Element native "*HTMLHeadingElement" {
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h1() => document.$dom_createElement("h1");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h2() => document.$dom_createElement("h2");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h3() => document.$dom_createElement("h3");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h4() => document.$dom_createElement("h4");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h5() => document.$dom_createElement("h5");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h6() => document.$dom_createElement("h6");
 }
@@ -11808,7 +12121,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -11822,13 +12139,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -11873,8 +12190,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -12010,7 +12328,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -12024,13 +12346,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -12075,8 +12397,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -12309,6 +12632,7 @@
 @DomName('HTMLHtmlElement')
 class HtmlElement extends Element native "*HTMLHtmlElement" {
 
+  @DomName('HTMLHtmlElement.HTMLHtmlElement')
   @DocsEditable
   factory HtmlElement() => document.$dom_createElement("html");
 }
@@ -12366,25 +12690,39 @@
  */
 @DomName('XMLHttpRequest')
 class HttpRequest extends EventTarget native "*XMLHttpRequest" {
-  /**
-   * Creates a URL get request for the specified `url`.
-   *
-   * After completing the request, the object will call the user-provided
-   * [onComplete] callback.
-   */
-  factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, false);
 
-  // 80 char issue for comments in lists: dartbug.com/7588.
   /**
-   * Creates a URL GET request for the specified `url` with
-   * credentials such a cookie (already) set in the header or
-   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
+   * Creates a URL get request for the specified [url].
    *
-   * After completing the request, the object will call the user-provided
-   * [onComplete] callback.
+   * The server response must be a `text/` mime type for this request to
+   * succeed.
    *
-   * A few other details to keep in mind when using credentials:
+   * This is similar to [request] but specialized for HTTP GET requests which
+   * return text content.
+   *
+   * See also:
+   *
+   * * [request]
+   */
+  static Future<String> getString(String url,
+      {bool withCredentials, void onProgress(ProgressEvent e)}) {
+    return request(url, withCredentials: withCredentials,
+        onProgress: onProgress).then((xhr) => xhr.responseText);
+  }
+
+  /**
+   * Creates a URL request for the specified [url].
+   *
+   * By default this will do an HTTP GET request, this can be overridden with
+   * [method].
+   *
+   * The Future is completed when the response is available.
+   *
+   * The [withCredentials] parameter specified that credentials such as a cookie
+   * (already) set in the header or
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+   * should be specified for the request. Details to keep in mind when using
+   * credentials:
    *
    * * Using credentials is only useful for cross-origin requests.
    * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
@@ -12393,11 +12731,59 @@
    *
    * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
    */
-  factory HttpRequest.getWithCredentials(String url,
-      onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, true);
+  static Future<HttpRequest> request(String url,
+      {String method, bool withCredentials, String responseType, sendData,
+      void onProgress(ProgressEvent e)}) {
+    var completer = new Completer<HttpRequest>();
+
+    var xhr = new HttpRequest();
+    if (method == null) {
+      method = 'GET';
+    }
+    xhr.open(method, url, true);
+
+    if (withCredentials != null) {
+      xhr.withCredentials = withCredentials;
+    }
+
+    if (responseType != null) {
+      xhr.responseType = responseType;
+    }
+
+    if (onProgress != null) {
+      xhr.onProgress.listen(onProgress);
+    }
+
+    xhr.onLoad.listen((e) {
+      if (xhr.status >= 200 && xhr.status < 300 ||
+          xhr.status == 304 ) {
+        completer.complete(xhr);
+      } else {
+        completer.completeError(e);
+      }
+    });
+
+    xhr.onError.listen((e) {
+      completer.completeError(e);
+    });
+
+    if (sendData != null) {
+      xhr.send(sendData);
+    } else {
+      xhr.send();
+    }
+
+    return completer.future;
+  }
 
 
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
   @DomName('XMLHttpRequest.abort')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
@@ -12426,9 +12812,26 @@
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');
 
+  /**
+   * General constructor for any type of request (GET, POST, etc).
+   *
+   * This call is used in conjunction with [open]:
+   *
+   *     var request = new HttpRequest();
+   *     request.open('GET', 'http://dartlang.org')
+   *     request.on.load.add((event) => print('Request complete'));
+   *
+   * is the (more verbose) equivalent of
+   *
+   *     var request = new HttpRequest.get('http://dartlang.org',
+   *         (event) => print('Request complete'));
+   */
+  @DomName('XMLHttpRequest.XMLHttpRequest')
   @DocsEditable
-  factory HttpRequest() => HttpRequest._create();
-  static HttpRequest _create() => JS('HttpRequest', 'new XMLHttpRequest()');
+  factory HttpRequest() {
+    return HttpRequest._create_1();
+  }
+  static HttpRequest _create_1() => JS('HttpRequest', 'new XMLHttpRequest()');
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -12446,44 +12849,128 @@
 
   static const int UNSENT = 0;
 
+  /**
+   * Indicator of the current state of the request:
+   *
+   * <table>
+   *   <tr>
+   *     <td>Value</td>
+   *     <td>State</td>
+   *     <td>Meaning</td>
+   *   </tr>
+   *   <tr>
+   *     <td>0</td>
+   *     <td>unsent</td>
+   *     <td><code>open()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>1</td>
+   *     <td>opened</td>
+   *     <td><code>send()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>2</td>
+   *     <td>headers received</td>
+   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
+   *   </tr>
+   *   <tr>
+   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
+   *   </tr>
+   *   <tr>
+   *     <td>4</td> <td>done</td> <td>request is complete</td>
+   *   </tr>
+   * </table>
+   */
   @DomName('XMLHttpRequest.readyState')
   @DocsEditable
   final int readyState;
 
+  /**
+   * The data received as a reponse from the request.
+   *
+   * The data could be in the
+   * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+   * [String]). `null` indicates request failure.
+   */
   @DomName('XMLHttpRequest.response')
   @DocsEditable
   @Creates('ArrayBuffer|Blob|Document|=Object|=List|String|num')
   final Object response;
 
+  /**
+   * The response in string form or `null on failure.
+   */
   @DomName('XMLHttpRequest.responseText')
   @DocsEditable
   final String responseText;
 
+  /**
+   * [String] telling the server the desired response format.
+   *
+   * Default is `String`.
+   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+   * `responseType` is set while performing a synchronous request.
+   *
+   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable
   String responseType;
 
   @JSName('responseXML')
+  /**
+   * The request response, or null on failure.
+   *
+   * The response is processed as
+   * `text/xml` stream, unless responseType = 'document' and the request is
+   * synchronous.
+   */
   @DomName('XMLHttpRequest.responseXML')
   @DocsEditable
   final Document responseXml;
 
+  /**
+   * The http result code from the request (200, 404, etc).
+   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   */
   @DomName('XMLHttpRequest.status')
   @DocsEditable
   final int status;
 
+  /**
+   * The request response string (such as \"200 OK\").
+   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   */
   @DomName('XMLHttpRequest.statusText')
   @DocsEditable
   final String statusText;
 
+  /**
+   * [EventTarget] that can hold listeners to track the progress of the request.
+   * The events fired will be members of [HttpRequestUploadEvents].
+   */
   @DomName('XMLHttpRequest.upload')
   @DocsEditable
   final HttpRequestUpload upload;
 
+  /**
+   * True if cross-site requests should use credentials such as cookies
+   * or authorization headers; false otherwise.
+   *
+   * This value is ignored for same-site requests.
+   */
   @DomName('XMLHttpRequest.withCredentials')
   @DocsEditable
   bool withCredentials;
 
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
   @DomName('XMLHttpRequest.abort')
   @DocsEditable
   void abort() native;
@@ -12497,18 +12984,51 @@
   @DocsEditable
   bool dispatchEvent(Event evt) native;
 
+  /**
+   * Retrieve all the response headers from a request.
+   *
+   * `null` if no headers have been received. For multipart requests,
+   * `getAllResponseHeaders` will return the response headers for the current
+   * part of the request.
+   *
+   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * for a list of common response headers.
+   */
   @DomName('XMLHttpRequest.getAllResponseHeaders')
   @DocsEditable
   String getAllResponseHeaders() native;
 
+  /**
+   * Return the response header named `header`, or `null` if not found.
+   *
+   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * for a list of common response headers.
+   */
   @DomName('XMLHttpRequest.getResponseHeader')
   @DocsEditable
   String getResponseHeader(String header) native;
 
+  /**
+   * Specify the desired `url`, and `method` to use in making the request.
+   *
+   * By default the request is done asyncronously, with no user or password
+   * authentication information. If `async` is false, the request will be send
+   * synchronously.
+   *
+   * Calling `open` again on a currently active request is equivalent to
+   * calling `abort`.
+   */
   @DomName('XMLHttpRequest.open')
   @DocsEditable
   void open(String method, String url, [bool async, String user, String password]) native;
 
+  /**
+   * Specify a particular MIME type (such as `text/xml`) desired for the
+   * response.
+   *
+   * This value must be set before the request has been sent. See also the list
+   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+   */
   @DomName('XMLHttpRequest.overrideMimeType')
   @DocsEditable
   void overrideMimeType(String override) native;
@@ -12518,6 +13038,13 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
 
+  /**
+   * Send the request with any given `data`.
+   *
+   * See also:
+   * [send() docs](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send())
+   * from MDN.
+   */
   @DomName('XMLHttpRequest.send')
   @DocsEditable
   void send([data]) native;
@@ -12526,6 +13053,13 @@
   @DocsEditable
   void setRequestHeader(String header, String value) native;
 
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
   @DomName('XMLHttpRequest.abort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
@@ -12746,6 +13280,7 @@
 @DomName('HTMLIFrameElement')
 class IFrameElement extends Element native "*HTMLIFrameElement" {
 
+  @DomName('HTMLIFrameElement.HTMLIFrameElement')
   @DocsEditable
   factory IFrameElement() => document.$dom_createElement("iframe");
 
@@ -12812,6 +13347,7 @@
 @DomName('HTMLImageElement')
 class ImageElement extends Element native "*HTMLImageElement" {
 
+  @DomName('HTMLImageElement.HTMLImageElement')
   @DocsEditable
   factory ImageElement({String src, int width, int height}) {
     var e = document.$dom_createElement("img");
@@ -13765,12 +14301,18 @@
 @DomName('Int16Array')
 class Int16Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Int16Array" {
 
+  @DomName('Int16Array.Int16Array')
+  @DocsEditable
   factory Int16Array(int length) =>
     _TypedArrayFactoryProvider.createInt16Array(length);
 
+  @DomName('Int16Array.fromList')
+  @DocsEditable
   factory Int16Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createInt16Array_fromList(list);
 
+  @DomName('Int16Array.fromBuffer')
+  @DocsEditable
   factory Int16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt16Array_fromBuffer(buffer, byteOffset, length);
 
@@ -13805,7 +14347,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -13819,13 +14365,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -13870,8 +14416,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -13970,12 +14517,18 @@
 @DomName('Int32Array')
 class Int32Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Int32Array" {
 
+  @DomName('Int32Array.Int32Array')
+  @DocsEditable
   factory Int32Array(int length) =>
     _TypedArrayFactoryProvider.createInt32Array(length);
 
+  @DomName('Int32Array.fromList')
+  @DocsEditable
   factory Int32Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createInt32Array_fromList(list);
 
+  @DomName('Int32Array.fromBuffer')
+  @DocsEditable
   factory Int32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt32Array_fromBuffer(buffer, byteOffset, length);
 
@@ -14010,7 +14563,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -14024,13 +14581,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -14075,8 +14632,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -14175,12 +14733,18 @@
 @DomName('Int8Array')
 class Int8Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Int8Array" {
 
+  @DomName('Int8Array.Int8Array')
+  @DocsEditable
   factory Int8Array(int length) =>
     _TypedArrayFactoryProvider.createInt8Array(length);
 
+  @DomName('Int8Array.fromList')
+  @DocsEditable
   factory Int8Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createInt8Array_fromList(list);
 
+  @DomName('Int8Array.fromBuffer')
+  @DocsEditable
   factory Int8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt8Array_fromBuffer(buffer, byteOffset, length);
 
@@ -14215,7 +14779,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -14229,13 +14797,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -14280,8 +14848,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -14524,6 +15093,7 @@
 @Experimental
 class KeygenElement extends Element native "*HTMLKeygenElement" {
 
+  @DomName('HTMLKeygenElement.HTMLKeygenElement')
   @DocsEditable
   factory KeygenElement() => document.$dom_createElement("keygen");
 
@@ -14593,6 +15163,7 @@
 @DomName('HTMLLIElement')
 class LIElement extends Element native "*HTMLLIElement" {
 
+  @DomName('HTMLLIElement.HTMLLIElement')
   @DocsEditable
   factory LIElement() => document.$dom_createElement("li");
 
@@ -14613,6 +15184,7 @@
 @DomName('HTMLLabelElement')
 class LabelElement extends Element native "*HTMLLabelElement" {
 
+  @DomName('HTMLLabelElement.HTMLLabelElement')
   @DocsEditable
   factory LabelElement() => document.$dom_createElement("label");
 
@@ -14637,6 +15209,7 @@
 @DomName('HTMLLegendElement')
 class LegendElement extends Element native "*HTMLLegendElement" {
 
+  @DomName('HTMLLegendElement.HTMLLegendElement')
   @DocsEditable
   factory LegendElement() => document.$dom_createElement("legend");
 
@@ -14653,6 +15226,7 @@
 @DomName('HTMLLinkElement')
 class LinkElement extends Element native "*HTMLLinkElement" {
 
+  @DomName('HTMLLinkElement.HTMLLinkElement')
   @DocsEditable
   factory LinkElement() => document.$dom_createElement("link");
 
@@ -14777,6 +15351,7 @@
 @DomName('HTMLMapElement')
 class MapElement extends Element native "*HTMLMapElement" {
 
+  @DomName('HTMLMapElement.HTMLMapElement')
   @DocsEditable
   factory MapElement() => document.$dom_createElement("map");
 
@@ -14797,9 +15372,12 @@
 @DomName('MediaController')
 class MediaController extends EventTarget native "*MediaController" {
 
+  @DomName('MediaController.MediaController')
   @DocsEditable
-  factory MediaController() => MediaController._create();
-  static MediaController _create() => JS('MediaController', 'new MediaController()');
+  factory MediaController() {
+    return MediaController._create_1();
+  }
+  static MediaController _create_1() => JS('MediaController', 'new MediaController()');
 
   @DomName('MediaController.buffered')
   @DocsEditable
@@ -15505,9 +16083,12 @@
 @DomName('MediaSource')
 class MediaSource extends EventTarget native "*MediaSource" {
 
+  @DomName('MediaSource.MediaSource')
   @DocsEditable
-  factory MediaSource() => MediaSource._create();
-  static MediaSource _create() => JS('MediaSource', 'new MediaSource()');
+  factory MediaSource() {
+    return MediaSource._create_1();
+  }
+  static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');
 
   @DomName('MediaSource.activeSourceBuffers')
   @DocsEditable
@@ -15564,9 +16145,23 @@
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
+  @DomName('MediaStream.MediaStream')
   @DocsEditable
-  factory MediaStream() => MediaStream._create();
-  static MediaStream _create() => JS('MediaStream', 'new MediaStream()');
+  factory MediaStream([stream_OR_tracks]) {
+    if (!?stream_OR_tracks) {
+      return MediaStream._create_1();
+    }
+    if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
+      return MediaStream._create_2(stream_OR_tracks);
+    }
+    if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
+      return MediaStream._create_3(stream_OR_tracks);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static MediaStream _create_1() => JS('MediaStream', 'new MediaStream()');
+  static MediaStream _create_2(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
+  static MediaStream _create_3(stream_OR_tracks) => JS('MediaStream', 'new MediaStream(#)', stream_OR_tracks);
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -15699,12 +16294,6 @@
   MediaStreamTrackEvents get on =>
     new MediaStreamTrackEvents(this);
 
-  static const int ENDED = 2;
-
-  static const int LIVE = 0;
-
-  static const int MUTED = 1;
-
   @DomName('MediaStreamTrack.enabled')
   @DocsEditable
   bool enabled;
@@ -15723,7 +16312,7 @@
 
   @DomName('MediaStreamTrack.readyState')
   @DocsEditable
-  final int readyState;
+  final String readyState;
 
   @JSName('addEventListener')
   @DomName('MediaStreamTrack.addEventListener')
@@ -15813,6 +16402,7 @@
 @DomName('HTMLMenuElement')
 class MenuElement extends Element native "*HTMLMenuElement" {
 
+  @DomName('HTMLMenuElement.HTMLMenuElement')
   @DocsEditable
   factory MenuElement() => document.$dom_createElement("menu");
 }
@@ -15825,9 +16415,12 @@
 @DomName('MessageChannel')
 class MessageChannel native "*MessageChannel" {
 
+  @DomName('MessageChannel.MessageChannel')
   @DocsEditable
-  factory MessageChannel() => MessageChannel._create();
-  static MessageChannel _create() => JS('MessageChannel', 'new MessageChannel()');
+  factory MessageChannel() {
+    return MessageChannel._create_1();
+  }
+  static MessageChannel _create_1() => JS('MessageChannel', 'new MessageChannel()');
 
   @DomName('MessageChannel.port1')
   @DocsEditable
@@ -16026,6 +16619,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class MeterElement extends Element native "*HTMLMeterElement" {
 
+  @DomName('HTMLMeterElement.HTMLMeterElement')
   @DocsEditable
   factory MeterElement() => document.$dom_createElement("meter");
 
@@ -16124,7 +16718,7 @@
 
   @DomName('MouseEvent.dataTransfer')
   @DocsEditable
-  final Clipboard dataTransfer;
+  final DataTransfer dataTransfer;
 
   @DomName('MouseEvent.fromElement')
   @DocsEditable
@@ -16285,9 +16879,6 @@
 @Experimental
 class MutationObserver native "*MutationObserver" {
 
-  @DocsEditable
-  factory MutationObserver(MutationCallback callback) => MutationObserver._create(callback);
-
   @DomName('MutationObserver.disconnect')
   @DocsEditable
   void disconnect() native;
@@ -16377,7 +16968,7 @@
   @JSName('observe')
   void _call(target, options) native;
 
-  static MutationObserver _create(MutationCallback callback) {
+  factory MutationObserver(MutationCallback callback) {
     // Dummy statement to mark types as instantiated.
     JS('MutationObserver|MutationRecord', '0');
 
@@ -16477,7 +17068,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -16491,13 +17086,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -16542,8 +17137,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -16942,6 +17538,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Node element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Node element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -16961,7 +17561,7 @@
 
   // From List<Node>:
 
-  List<Node> take(int n) {
+  Iterable<Node> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -16969,7 +17569,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) {
+  Iterable<Node> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -16993,8 +17593,9 @@
     return this[index];
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   // TODO(jacobr): this could be implemented for child node lists.
   // The exception we throw here is misleading.
@@ -17329,7 +17930,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -17343,13 +17948,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -17394,8 +17999,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -17527,19 +18133,16 @@
   @DocsEditable
   static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
 
+  @DomName('Notification.Notification')
   @DocsEditable
   factory Notification(String title, [Map options]) {
-    if (!?options) {
-      return Notification._create(title);
+    if (?options) {
+      return Notification._create_1(title, options);
     }
-    return Notification._create(title, options);
+    return Notification._create_2(title);
   }
-  static Notification _create(String title, [Map options]) {
-    if (!?options) {
-      return JS('Notification', 'new Notification(#)', title);
-    }
-    return JS('Notification', 'new Notification(#,#)', title, options);
-  }
+  static Notification _create_1(title, options) => JS('Notification', 'new Notification(#,#)', title, options);
+  static Notification _create_2(title) => JS('Notification', 'new Notification(#)', title);
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -17684,6 +18287,7 @@
 @DomName('HTMLOListElement')
 class OListElement extends Element native "*HTMLOListElement" {
 
+  @DomName('HTMLOListElement.HTMLOListElement')
   @DocsEditable
   factory OListElement() => document.$dom_createElement("ol");
 
@@ -17711,6 +18315,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ObjectElement extends Element native "*HTMLObjectElement" {
 
+  @DomName('HTMLObjectElement.HTMLObjectElement')
   @DocsEditable
   factory ObjectElement() => document.$dom_createElement("object");
 
@@ -17838,6 +18443,7 @@
 @DomName('HTMLOptGroupElement')
 class OptGroupElement extends Element native "*HTMLOptGroupElement" {
 
+  @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
   @DocsEditable
   factory OptGroupElement() => document.$dom_createElement("optgroup");
 
@@ -17858,37 +18464,28 @@
 @DomName('HTMLOptionElement')
 class OptionElement extends Element native "*HTMLOptionElement" {
 
+  @DomName('HTMLOptionElement.HTMLOptionElement')
   @DocsEditable
   factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
-    if (!?data) {
-      return OptionElement._create();
+    if (?selected) {
+      return OptionElement._create_1(data, value, defaultSelected, selected);
     }
-    if (!?value) {
-      return OptionElement._create(data);
+    if (?defaultSelected) {
+      return OptionElement._create_2(data, value, defaultSelected);
     }
-    if (!?defaultSelected) {
-      return OptionElement._create(data, value);
+    if (?value) {
+      return OptionElement._create_3(data, value);
     }
-    if (!?selected) {
-      return OptionElement._create(data, value, defaultSelected);
+    if (?data) {
+      return OptionElement._create_4(data);
     }
-    return OptionElement._create(data, value, defaultSelected, selected);
+    return OptionElement._create_5();
   }
-  static OptionElement _create([String data, String value, bool defaultSelected, bool selected]) {
-    if (!?data) {
-      return JS('OptionElement', 'new Option()');
-    }
-    if (!?value) {
-      return JS('OptionElement', 'new Option(#)', data);
-    }
-    if (!?defaultSelected) {
-      return JS('OptionElement', 'new Option(#,#)', data, value);
-    }
-    if (!?selected) {
-      return JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
-    }
-    return JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
-  }
+  static OptionElement _create_1(data, value, defaultSelected, selected) => JS('OptionElement', 'new Option(#,#,#,#)', data, value, defaultSelected, selected);
+  static OptionElement _create_2(data, value, defaultSelected) => JS('OptionElement', 'new Option(#,#,#)', data, value, defaultSelected);
+  static OptionElement _create_3(data, value) => JS('OptionElement', 'new Option(#,#)', data, value);
+  static OptionElement _create_4(data) => JS('OptionElement', 'new Option(#)', data);
+  static OptionElement _create_5() => JS('OptionElement', 'new Option()');
 
   @DomName('HTMLOptionElement.defaultSelected')
   @DocsEditable
@@ -17930,6 +18527,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class OutputElement extends Element native "*HTMLOutputElement" {
 
+  @DomName('HTMLOutputElement.HTMLOutputElement')
   @DocsEditable
   factory OutputElement() => document.$dom_createElement("output");
 
@@ -18060,6 +18658,7 @@
 @DomName('HTMLParagraphElement')
 class ParagraphElement extends Element native "*HTMLParagraphElement" {
 
+  @DomName('HTMLParagraphElement.HTMLParagraphElement')
   @DocsEditable
   factory ParagraphElement() => document.$dom_createElement("p");
 }
@@ -18072,6 +18671,7 @@
 @DomName('HTMLParamElement')
 class ParamElement extends Element native "*HTMLParamElement" {
 
+  @DomName('HTMLParamElement.HTMLParamElement')
   @DocsEditable
   factory ParamElement() => document.$dom_createElement("param");
 
@@ -18238,27 +18838,6 @@
 
 
 @DocsEditable
-@DomName('WebKitPoint')
-class Point native "*WebKitPoint" {
-
-  @DocsEditable
-  factory Point(num x, num y) => Point._create(x, y);
-  static Point _create(num x, num y) => JS('Point', 'new WebKitPoint(#,#)', x, y);
-
-  @DomName('WebKitPoint.x')
-  @DocsEditable
-  num x;
-
-  @DomName('WebKitPoint.y')
-  @DocsEditable
-  num y;
-}
-// 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.
-
-
-@DocsEditable
 @DomName('PopStateEvent')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -18322,6 +18901,7 @@
 @DomName('HTMLPreElement')
 class PreElement extends Element native "*HTMLPreElement" {
 
+  @DomName('HTMLPreElement.HTMLPreElement')
   @DocsEditable
   factory PreElement() => document.$dom_createElement("pre");
 
@@ -18363,6 +18943,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ProgressElement extends Element native "*HTMLProgressElement" {
 
+  @DomName('HTMLProgressElement.HTMLProgressElement')
   @DocsEditable
   factory ProgressElement() => document.$dom_createElement("progress");
 
@@ -18826,9 +19407,12 @@
 @DomName('RTCIceCandidate')
 class RtcIceCandidate native "*RTCIceCandidate" {
 
+  @DomName('RTCIceCandidate.RTCIceCandidate')
   @DocsEditable
-  factory RtcIceCandidate(Map dictionary) => RtcIceCandidate._create(dictionary);
-  static RtcIceCandidate _create(Map dictionary) => JS('RtcIceCandidate', 'new RTCIceCandidate(#)', dictionary);
+  factory RtcIceCandidate(Map dictionary) {
+    return RtcIceCandidate._create_1(dictionary);
+  }
+  static RtcIceCandidate _create_1(dictionary) => JS('RtcIceCandidate', 'new RTCIceCandidate(#)', dictionary);
 
   @DomName('RTCIceCandidate.candidate')
   @DocsEditable
@@ -18884,10 +19468,6 @@
   @DocsEditable
   static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');
 
-  @DomName('RTCPeerConnection.open')
-  @DocsEditable
-  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
-
   @DomName('RTCPeerConnection.removestream')
   @DocsEditable
   static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');
@@ -18896,19 +19476,16 @@
   @DocsEditable
   static const EventStreamProvider<Event> stateChangeEvent = const EventStreamProvider<Event>('statechange');
 
+  @DomName('RTCPeerConnection.RTCPeerConnection')
   @DocsEditable
   factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
-    if (!?mediaConstraints) {
-      return RtcPeerConnection._create(rtcIceServers);
+    if (?mediaConstraints) {
+      return RtcPeerConnection._create_1(rtcIceServers, mediaConstraints);
     }
-    return RtcPeerConnection._create(rtcIceServers, mediaConstraints);
+    return RtcPeerConnection._create_2(rtcIceServers);
   }
-  static RtcPeerConnection _create(Map rtcIceServers, [Map mediaConstraints]) {
-    if (!?mediaConstraints) {
-      return JS('RtcPeerConnection', 'new RTCPeerConnection(#)', rtcIceServers);
-    }
-    return JS('RtcPeerConnection', 'new RTCPeerConnection(#,#)', rtcIceServers, mediaConstraints);
-  }
+  static RtcPeerConnection _create_1(rtcIceServers, mediaConstraints) => JS('RtcPeerConnection', 'new RTCPeerConnection(#,#)', rtcIceServers, mediaConstraints);
+  static RtcPeerConnection _create_2(rtcIceServers) => JS('RtcPeerConnection', 'new RTCPeerConnection(#)', rtcIceServers);
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -18916,14 +19493,14 @@
   RtcPeerConnectionEvents get on =>
     new RtcPeerConnectionEvents(this);
 
+  @DomName('RTCPeerConnection.iceConnectionState')
+  @DocsEditable
+  final String iceConnectionState;
+
   @DomName('RTCPeerConnection.iceGatheringState')
   @DocsEditable
   final String iceGatheringState;
 
-  @DomName('RTCPeerConnection.iceState')
-  @DocsEditable
-  final String iceState;
-
   @DomName('RTCPeerConnection.localDescription')
   @DocsEditable
   final RtcSessionDescription localDescription;
@@ -18948,6 +19525,10 @@
   @Creates('_MediaStreamList')
   final List<MediaStream> remoteStreams;
 
+  @DomName('RTCPeerConnection.signalingState')
+  @DocsEditable
+  final String signalingState;
+
   @JSName('addEventListener')
   @DomName('RTCPeerConnection.addEventListener')
   @DocsEditable
@@ -19104,10 +19685,6 @@
   @DocsEditable
   Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.open')
-  @DocsEditable
-  Stream<Event> get onOpen => openEvent.forTarget(this);
-
   @DomName('RTCPeerConnection.removestream')
   @DocsEditable
   Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);
@@ -19136,9 +19713,6 @@
   EventListenerList get negotiationNeeded => this['negotiationneeded'];
 
   @DocsEditable
-  EventListenerList get open => this['open'];
-
-  @DocsEditable
   EventListenerList get removeStream => this['removestream'];
 
   @DocsEditable
@@ -19153,9 +19727,12 @@
 @DomName('RTCSessionDescription')
 class RtcSessionDescription native "*RTCSessionDescription" {
 
+  @DomName('RTCSessionDescription.RTCSessionDescription')
   @DocsEditable
-  factory RtcSessionDescription(Map dictionary) => RtcSessionDescription._create(dictionary);
-  static RtcSessionDescription _create(Map dictionary) => JS('RtcSessionDescription', 'new RTCSessionDescription(#)', dictionary);
+  factory RtcSessionDescription(Map dictionary) {
+    return RtcSessionDescription._create_1(dictionary);
+  }
+  static RtcSessionDescription _create_1(dictionary) => JS('RtcSessionDescription', 'new RTCSessionDescription(#)', dictionary);
 
   @DomName('RTCSessionDescription.sdp')
   @DocsEditable
@@ -19306,6 +19883,7 @@
 @DomName('HTMLScriptElement')
 class ScriptElement extends Element native "*HTMLScriptElement" {
 
+  @DomName('HTMLScriptElement.HTMLScriptElement')
   @DocsEditable
   factory ScriptElement() => document.$dom_createElement("script");
 
@@ -19420,6 +19998,7 @@
 @DomName('HTMLSelectElement')
 class SelectElement extends Element native "*HTMLSelectElement" {
 
+  @DomName('HTMLSelectElement.HTMLSelectElement')
   @DocsEditable
   factory SelectElement() => document.$dom_createElement("select");
 
@@ -19616,19 +20195,16 @@
 @DomName('SharedWorker')
 class SharedWorker extends AbstractWorker native "*SharedWorker" {
 
+  @DomName('SharedWorker.SharedWorker')
   @DocsEditable
   factory SharedWorker(String scriptURL, [String name]) {
-    if (!?name) {
-      return SharedWorker._create(scriptURL);
+    if (?name) {
+      return SharedWorker._create_1(scriptURL, name);
     }
-    return SharedWorker._create(scriptURL, name);
+    return SharedWorker._create_2(scriptURL);
   }
-  static SharedWorker _create(String scriptURL, [String name]) {
-    if (!?name) {
-      return JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
-    }
-    return JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
-  }
+  static SharedWorker _create_1(scriptURL, name) => JS('SharedWorker', 'new SharedWorker(#,#)', scriptURL, name);
+  static SharedWorker _create_2(scriptURL) => JS('SharedWorker', 'new SharedWorker(#)', scriptURL);
 
   @DomName('SharedWorker.port')
   @DocsEditable
@@ -19737,7 +20313,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SourceBuffer element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SourceBuffer element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SourceBuffer element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SourceBuffer> where(bool f(SourceBuffer element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -19751,13 +20331,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SourceBuffer> takeWhile(bool test(SourceBuffer value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SourceBuffer> skipWhile(bool test(SourceBuffer value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -19802,8 +20382,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SourceBuffer> get reversed =>
-      new ReversedListView<SourceBuffer>(this, 0, null);
+  List<SourceBuffer> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SourceBuffer a, SourceBuffer b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -19911,6 +20492,7 @@
 @DomName('HTMLSourceElement')
 class SourceElement extends Element native "*HTMLSourceElement" {
 
+  @DomName('HTMLSourceElement.HTMLSourceElement')
   @DocsEditable
   factory SourceElement() => document.$dom_createElement("source");
 
@@ -19935,6 +20517,7 @@
 @DomName('HTMLSpanElement')
 class SpanElement extends Element native "*HTMLSpanElement" {
 
+  @DomName('HTMLSpanElement.HTMLSpanElement')
   @DocsEditable
   factory SpanElement() => document.$dom_createElement("span");
 }
@@ -19947,9 +20530,12 @@
 @DomName('SpeechGrammar')
 class SpeechGrammar native "*SpeechGrammar" {
 
+  @DomName('SpeechGrammar.SpeechGrammar')
   @DocsEditable
-  factory SpeechGrammar() => SpeechGrammar._create();
-  static SpeechGrammar _create() => JS('SpeechGrammar', 'new SpeechGrammar()');
+  factory SpeechGrammar() {
+    return SpeechGrammar._create_1();
+  }
+  static SpeechGrammar _create_1() => JS('SpeechGrammar', 'new SpeechGrammar()');
 
   @DomName('SpeechGrammar.src')
   @DocsEditable
@@ -19968,9 +20554,12 @@
 @DomName('SpeechGrammarList')
 class SpeechGrammarList implements JavaScriptIndexingBehavior, List<SpeechGrammar> native "*SpeechGrammarList" {
 
+  @DomName('SpeechGrammarList.SpeechGrammarList')
   @DocsEditable
-  factory SpeechGrammarList() => SpeechGrammarList._create();
-  static SpeechGrammarList _create() => JS('SpeechGrammarList', 'new SpeechGrammarList()');
+  factory SpeechGrammarList() {
+    return SpeechGrammarList._create_1();
+  }
+  static SpeechGrammarList _create_1() => JS('SpeechGrammarList', 'new SpeechGrammarList()');
 
   @DomName('SpeechGrammarList.length')
   @DocsEditable
@@ -20004,7 +20593,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SpeechGrammar element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SpeechGrammar element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SpeechGrammar element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SpeechGrammar> where(bool f(SpeechGrammar element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -20018,13 +20611,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SpeechGrammar> takeWhile(bool test(SpeechGrammar value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SpeechGrammar> skipWhile(bool test(SpeechGrammar value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -20069,8 +20662,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechGrammar> get reversed =>
-      new ReversedListView<SpeechGrammar>(this, 0, null);
+  List<SpeechGrammar> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SpeechGrammar a, SpeechGrammar b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -20249,9 +20843,6 @@
   @DocsEditable
   static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');
 
-  @DocsEditable
-  factory SpeechRecognition() => SpeechRecognition._create();
-
   /// Checks if this type is supported on the current platform.
   static bool get supported => JS('bool', '!!(window.SpeechRecognition || window.webkitSpeechRecognition)');
 
@@ -20351,7 +20942,7 @@
   @DocsEditable
   Stream<Event> get onStart => startEvent.forTarget(this);
 
-  static SpeechRecognition _create() {
+  factory SpeechRecognition() {
     return JS('SpeechRecognition',
         'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
   }
@@ -20616,7 +21207,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Map element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Map element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Map element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Map> where(bool f(Map element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -20630,13 +21225,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Map> takeWhile(bool test(Map value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Map> skipWhile(bool test(Map value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -20681,8 +21276,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Map> get reversed =>
-      new ReversedListView<Map>(this, 0, null);
+  List<Map> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Map a, Map b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -20779,6 +21375,9 @@
 
 @DocsEditable
 @DomName('SQLTransaction')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class SqlTransaction native "*SQLTransaction" {
 
   @DomName('SQLTransaction.executeSql')
@@ -20792,6 +21391,9 @@
 
 @DocsEditable
 @DomName('SQLTransactionSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class SqlTransactionSync native "*SQLTransactionSync" {
 
   @DomName('SQLTransactionSync.executeSql')
@@ -20992,6 +21594,7 @@
 @DomName('HTMLStyleElement')
 class StyleElement extends Element native "*HTMLStyleElement" {
 
+  @DomName('HTMLStyleElement.HTMLStyleElement')
   @DocsEditable
   factory StyleElement() => document.$dom_createElement("style");
 
@@ -21078,6 +21681,7 @@
 @DomName('HTMLTableCaptionElement')
 class TableCaptionElement extends Element native "*HTMLTableCaptionElement" {
 
+  @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
   @DocsEditable
   factory TableCaptionElement() => document.$dom_createElement("caption");
 }
@@ -21090,6 +21694,7 @@
 @DomName('HTMLTableCellElement')
 class TableCellElement extends Element native "*HTMLTableCellElement" {
 
+  @DomName('HTMLTableCellElement.HTMLTableCellElement')
   @DocsEditable
   factory TableCellElement() => document.$dom_createElement("td");
 
@@ -21118,6 +21723,7 @@
 @DomName('HTMLTableColElement')
 class TableColElement extends Element native "*HTMLTableColElement" {
 
+  @DomName('HTMLTableColElement.HTMLTableColElement')
   @DocsEditable
   factory TableColElement() => document.$dom_createElement("col");
 
@@ -21133,6 +21739,7 @@
 @DomName('HTMLTableElement')
 class TableElement extends Element native "*HTMLTableElement" {
 
+  @DomName('HTMLTableElement.HTMLTableElement')
   @DocsEditable
   factory TableElement() => document.$dom_createElement("table");
 
@@ -21214,6 +21821,7 @@
 @DomName('HTMLTableRowElement')
 class TableRowElement extends Element native "*HTMLTableRowElement" {
 
+  @DomName('HTMLTableRowElement.HTMLTableRowElement')
   @DocsEditable
   factory TableRowElement() => document.$dom_createElement("tr");
 
@@ -21291,6 +21899,7 @@
 @DomName('HTMLTextAreaElement')
 class TextAreaElement extends Element native "*HTMLTextAreaElement" {
 
+  @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
   @DocsEditable
   factory TextAreaElement() => document.$dom_createElement("textarea");
 
@@ -21546,9 +22155,12 @@
   @DocsEditable
   static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');
 
+  @DomName('TextTrackCue.TextTrackCue')
   @DocsEditable
-  factory TextTrackCue(num startTime, num endTime, String text) => TextTrackCue._create(startTime, endTime, text);
-  static TextTrackCue _create(num startTime, num endTime, String text) => JS('TextTrackCue', 'new TextTrackCue(#,#,#)', startTime, endTime, text);
+  factory TextTrackCue(num startTime, num endTime, String text) {
+    return TextTrackCue._create_1(startTime, endTime, text);
+  }
+  static TextTrackCue _create_1(startTime, endTime, text) => JS('TextTrackCue', 'new TextTrackCue(#,#,#)', startTime, endTime, text);
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -21685,7 +22297,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(TextTrackCue element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(TextTrackCue element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(TextTrackCue element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<TextTrackCue> where(bool f(TextTrackCue element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -21699,13 +22315,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<TextTrackCue> takeWhile(bool test(TextTrackCue value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<TextTrackCue> skipWhile(bool test(TextTrackCue value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -21750,8 +22366,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrackCue> get reversed =>
-      new ReversedListView<TextTrackCue>(this, 0, null);
+  List<TextTrackCue> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(TextTrackCue a, TextTrackCue b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -21891,7 +22508,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(TextTrack element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(TextTrack element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(TextTrack element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<TextTrack> where(bool f(TextTrack element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -21905,13 +22526,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<TextTrack> takeWhile(bool test(TextTrack value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<TextTrack> skipWhile(bool test(TextTrack value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -21956,8 +22577,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrack> get reversed =>
-      new ReversedListView<TextTrack>(this, 0, null);
+  List<TextTrack> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(TextTrack a, TextTrack b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -22108,6 +22730,7 @@
 @DomName('HTMLTitleElement')
 class TitleElement extends Element native "*HTMLTitleElement" {
 
+  @DomName('HTMLTitleElement.HTMLTitleElement')
   @DocsEditable
   factory TitleElement() => document.$dom_createElement("title");
 }
@@ -22228,6 +22851,19 @@
   @DocsEditable
   void $dom_initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native;
 
+
+  /**
+   * Checks if touch events supported on the current platform.
+   *
+   * Note that touch events are only supported if the user is using a touch
+   * device.
+   */
+  static bool get supported {
+    if (JS('bool', '"ontouchstart" in window')) {
+      return Event._isTypeSupported('TouchEvent');
+    }
+    return false;
+  }
 }
 // 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
@@ -22270,7 +22906,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Touch element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Touch element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Touch element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Touch> where(bool f(Touch element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -22284,13 +22924,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Touch> takeWhile(bool test(Touch value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Touch> skipWhile(bool test(Touch value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -22335,8 +22975,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Touch> get reversed =>
-      new ReversedListView<Touch>(this, 0, null);
+  List<Touch> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Touch a, Touch b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -22433,6 +23074,7 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class TrackElement extends Element native "*HTMLTrackElement" {
 
+  @DomName('HTMLTrackElement.HTMLTrackElement')
   @DocsEditable
   factory TrackElement() => document.$dom_createElement("track");
 
@@ -22646,6 +23288,7 @@
 @DomName('HTMLUListElement')
 class UListElement extends Element native "*HTMLUListElement" {
 
+  @DomName('HTMLUListElement.HTMLUListElement')
   @DocsEditable
   factory UListElement() => document.$dom_createElement("ul");
 }
@@ -22658,12 +23301,18 @@
 @DomName('Uint16Array')
 class Uint16Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Uint16Array" {
 
+  @DomName('Uint16Array.Uint16Array')
+  @DocsEditable
   factory Uint16Array(int length) =>
     _TypedArrayFactoryProvider.createUint16Array(length);
 
+  @DomName('Uint16Array.fromList')
+  @DocsEditable
   factory Uint16Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint16Array_fromList(list);
 
+  @DomName('Uint16Array.fromBuffer')
+  @DocsEditable
   factory Uint16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint16Array_fromBuffer(buffer, byteOffset, length);
 
@@ -22698,7 +23347,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -22712,13 +23365,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -22763,8 +23416,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -22863,12 +23517,18 @@
 @DomName('Uint32Array')
 class Uint32Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Uint32Array" {
 
+  @DomName('Uint32Array.Uint32Array')
+  @DocsEditable
   factory Uint32Array(int length) =>
     _TypedArrayFactoryProvider.createUint32Array(length);
 
+  @DomName('Uint32Array.fromList')
+  @DocsEditable
   factory Uint32Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint32Array_fromList(list);
 
+  @DomName('Uint32Array.fromBuffer')
+  @DocsEditable
   factory Uint32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint32Array_fromBuffer(buffer, byteOffset, length);
 
@@ -22903,7 +23563,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -22917,13 +23581,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -22968,8 +23632,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -23068,12 +23733,18 @@
 @DomName('Uint8Array')
 class Uint8Array extends ArrayBufferView implements JavaScriptIndexingBehavior, List<int> native "*Uint8Array" {
 
+  @DomName('Uint8Array.Uint8Array')
+  @DocsEditable
   factory Uint8Array(int length) =>
     _TypedArrayFactoryProvider.createUint8Array(length);
 
+  @DomName('Uint8Array.fromList')
+  @DocsEditable
   factory Uint8Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint8Array_fromList(list);
 
+  @DomName('Uint8Array.fromBuffer')
+  @DocsEditable
   factory Uint8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint8Array_fromBuffer(buffer, byteOffset, length);
 
@@ -23108,7 +23779,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -23122,13 +23797,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -23173,8 +23848,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -23273,12 +23949,18 @@
 @DomName('Uint8ClampedArray')
 class Uint8ClampedArray extends Uint8Array implements JavaScriptIndexingBehavior, List<int> native "*Uint8ClampedArray" {
 
+  @DomName('Uint8ClampedArray.Uint8ClampedArray')
+  @DocsEditable
   factory Uint8ClampedArray(int length) =>
     _TypedArrayFactoryProvider.createUint8ClampedArray(length);
 
+  @DomName('Uint8ClampedArray.fromList')
+  @DocsEditable
   factory Uint8ClampedArray.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint8ClampedArray_fromList(list);
 
+  @DomName('Uint8ClampedArray.fromBuffer')
+  @DocsEditable
   factory Uint8ClampedArray.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint8ClampedArray_fromBuffer(buffer, byteOffset, length);
 
@@ -23310,7 +23992,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -23324,13 +24010,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -23375,8 +24061,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -23551,6 +24238,7 @@
 @DomName('HTMLVideoElement')
 class VideoElement extends MediaElement native "*HTMLVideoElement" {
 
+  @DomName('HTMLVideoElement.HTMLVideoElement')
   @DocsEditable
   factory VideoElement() => document.$dom_createElement("video");
 
@@ -23795,8 +24483,14 @@
 
 @DocsEditable
 @DomName('WebGLRenderingContext')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Experimental
 class WebGLRenderingContext extends CanvasRenderingContext native "*WebGLRenderingContext" {
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.WebGLRenderingContext)');
+
   static const int ACTIVE_ATTRIBUTES = 0x8B89;
 
   static const int ACTIVE_TEXTURE = 0x84E0;
@@ -25210,9 +25904,23 @@
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
+  @DomName('WebSocket.WebSocket')
   @DocsEditable
-  factory WebSocket(String url) => WebSocket._create(url);
-  static WebSocket _create(String url) => JS('WebSocket', 'new WebSocket(#)', url);
+  factory WebSocket(String url, [protocol_OR_protocols]) {
+    if ((url is String || url == null) && !?protocol_OR_protocols) {
+      return WebSocket._create_1(url);
+    }
+    if ((url is String || url == null) && (protocol_OR_protocols is List<String> || protocol_OR_protocols == null)) {
+      return WebSocket._create_2(url, protocol_OR_protocols);
+    }
+    if ((url is String || url == null) && (protocol_OR_protocols is String || protocol_OR_protocols == null)) {
+      return WebSocket._create_3(url, protocol_OR_protocols);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static WebSocket _create_1(url) => JS('WebSocket', 'new WebSocket(#)', url);
+  static WebSocket _create_2(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);
+  static WebSocket _create_3(url, protocol_OR_protocols) => JS('WebSocket', 'new WebSocket(#,#)', url, protocol_OR_protocols);
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => JS('bool', 'typeof window.WebSocket != "undefined"');
@@ -25589,12 +26297,13 @@
   }
 
   /**
-   * Executes a [callback] after the next batch of browser layout measurements
-   * has completed or would have completed if any browser layout measurements
-   * had been scheduled.
+   * Executes a [callback] after the immediate execution stack has completed.
+   *
+   * This will cause the callback to be executed after all processing has
+   * completed for the current event, but before any subsequent events.
    */
-  void requestLayoutFrame(TimeoutHandler callback) {
-    _addMeasurementFrameCallback(callback);
+  void setImmediate(TimeoutHandler callback) {
+    _addMicrotaskCallback(callback);
   }
 
   @DomName('DOMWindow.requestAnimationFrame')
@@ -25677,6 +26386,15 @@
   @DomName('Window.console')
   Console get console => Console.safeConsole;
 
+  /// Checks if _setImmediate is supported.
+  static bool get _supportsSetImmediate =>
+      JS('bool', '!!(window.setImmediate)');
+
+  // Set immediate implementation for IE
+  void _setImmediate(void callback()) {
+    JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0));
+  }
+
 
   @DomName('DOMWindow.DOMContentLoaded')
   @DocsEditable
@@ -26030,6 +26748,9 @@
 
   @DomName('DOMWindow.openDatabase')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
   @Creates('Database')
   @Creates('DatabaseSync')
   Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
@@ -26105,13 +26826,15 @@
   @DocsEditable
   void stop() native;
 
+  @JSName('webkitConvertPointFromNodeToPage')
   @DomName('DOMWindow.webkitConvertPointFromNodeToPage')
   @DocsEditable
-  Point webkitConvertPointFromNodeToPage(Node node, Point p) native;
+  DomPoint convertPointFromNodeToPage(Node node, DomPoint p) native;
 
+  @JSName('webkitConvertPointFromPageToNode')
   @DomName('DOMWindow.webkitConvertPointFromPageToNode')
   @DocsEditable
-  Point webkitConvertPointFromPageToNode(Node node, Point p) native;
+  DomPoint convertPointFromPageToNode(Node node, DomPoint p) native;
 
   @JSName('webkitRequestFileSystem')
   @DomName('DOMWindow.webkitRequestFileSystem')
@@ -26586,9 +27309,12 @@
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
+  @DomName('Worker.Worker')
   @DocsEditable
-  factory Worker(String scriptUrl) => Worker._create(scriptUrl);
-  static Worker _create(String scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);
+  factory Worker(String scriptUrl) {
+    return Worker._create_1(scriptUrl);
+  }
+  static Worker _create_1(scriptUrl) => JS('Worker', 'new Worker(#)', scriptUrl);
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -26698,10 +27424,16 @@
 
   @DomName('WorkerContext.openDatabase')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
   Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
 
   @DomName('WorkerContext.openDatabaseSync')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
   DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native;
 
   @JSName('removeEventListener')
@@ -26858,9 +27590,12 @@
 @DomName('XPathEvaluator')
 class XPathEvaluator native "*XPathEvaluator" {
 
+  @DomName('XPathEvaluator.XPathEvaluator')
   @DocsEditable
-  factory XPathEvaluator() => XPathEvaluator._create();
-  static XPathEvaluator _create() => JS('XPathEvaluator', 'new XPathEvaluator()');
+  factory XPathEvaluator() {
+    return XPathEvaluator._create_1();
+  }
+  static XPathEvaluator _create_1() => JS('XPathEvaluator', 'new XPathEvaluator()');
 
   @DomName('XPathEvaluator.createExpression')
   @DocsEditable
@@ -27004,9 +27739,12 @@
 @DomName('XMLSerializer')
 class XmlSerializer native "*XMLSerializer" {
 
+  @DomName('XMLSerializer.XMLSerializer')
   @DocsEditable
-  factory XmlSerializer() => XmlSerializer._create();
-  static XmlSerializer _create() => JS('XmlSerializer', 'new XMLSerializer()');
+  factory XmlSerializer() {
+    return XmlSerializer._create_1();
+  }
+  static XmlSerializer _create_1() => JS('XmlSerializer', 'new XMLSerializer()');
 
   @DomName('XMLSerializer.serializeToString')
   @DocsEditable
@@ -27019,11 +27757,20 @@
 
 @DocsEditable
 @DomName('XSLTProcessor')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class XsltProcessor native "*XSLTProcessor" {
 
+  @DomName('XSLTProcessor.XSLTProcessor')
   @DocsEditable
-  factory XsltProcessor() => XsltProcessor._create();
-  static XsltProcessor _create() => JS('XsltProcessor', 'new XSLTProcessor()');
+  factory XsltProcessor() {
+    return XsltProcessor._create_1();
+  }
+  static XsltProcessor _create_1() => JS('XsltProcessor', 'new XSLTProcessor()');
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.XSLTProcessor)');
 
   @DomName('XSLTProcessor.clearParameters')
   @DocsEditable
@@ -27116,7 +27863,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(ClientRect element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(ClientRect element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(ClientRect element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<ClientRect> where(bool f(ClientRect element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -27130,13 +27881,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<ClientRect> takeWhile(bool test(ClientRect value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<ClientRect> skipWhile(bool test(ClientRect value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -27181,8 +27932,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ClientRect> get reversed =>
-      new ReversedListView<ClientRect>(this, 0, null);
+  List<ClientRect> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(ClientRect a, ClientRect b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -27308,7 +28060,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(CssRule element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(CssRule element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(CssRule element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<CssRule> where(bool f(CssRule element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -27322,13 +28078,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<CssRule> takeWhile(bool test(CssRule value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<CssRule> skipWhile(bool test(CssRule value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -27373,8 +28129,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssRule> get reversed =>
-      new ReversedListView<CssRule>(this, 0, null);
+  List<CssRule> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(CssRule a, CssRule b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -27500,7 +28257,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(CssValue element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(CssValue element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(CssValue element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<CssValue> where(bool f(CssValue element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -27514,13 +28275,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<CssValue> takeWhile(bool test(CssValue value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<CssValue> skipWhile(bool test(CssValue value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -27565,8 +28326,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssValue> get reversed =>
-      new ReversedListView<CssValue>(this, 0, null);
+  List<CssValue> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(CssValue a, CssValue b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -27701,7 +28463,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Entry element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Entry element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Entry element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Entry> where(bool f(Entry element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -27715,13 +28481,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Entry> takeWhile(bool test(Entry value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Entry> skipWhile(bool test(Entry value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -27766,8 +28532,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Entry> get reversed =>
-      new ReversedListView<Entry>(this, 0, null);
+  List<Entry> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Entry a, Entry b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -27893,7 +28660,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(EntrySync element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(EntrySync element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(EntrySync element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<EntrySync> where(bool f(EntrySync element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -27907,13 +28678,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<EntrySync> takeWhile(bool test(EntrySync value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<EntrySync> skipWhile(bool test(EntrySync value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -27958,8 +28729,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<EntrySync> get reversed =>
-      new ReversedListView<EntrySync>(this, 0, null);
+  List<EntrySync> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(EntrySync a, EntrySync b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -28164,7 +28936,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Gamepad element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Gamepad element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Gamepad element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Gamepad> where(bool f(Gamepad element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -28178,13 +28954,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Gamepad> takeWhile(bool test(Gamepad value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Gamepad> skipWhile(bool test(Gamepad value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -28229,8 +29005,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Gamepad> get reversed =>
-      new ReversedListView<Gamepad>(this, 0, null);
+  List<Gamepad> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Gamepad a, Gamepad b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -28365,7 +29142,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(MediaStream element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(MediaStream element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(MediaStream element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<MediaStream> where(bool f(MediaStream element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -28379,13 +29160,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<MediaStream> takeWhile(bool test(MediaStream value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<MediaStream> skipWhile(bool test(MediaStream value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -28430,8 +29211,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<MediaStream> get reversed =>
-      new ReversedListView<MediaStream>(this, 0, null);
+  List<MediaStream> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(MediaStream a, MediaStream b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -28557,7 +29339,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SpeechInputResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SpeechInputResult element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SpeechInputResult element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SpeechInputResult> where(bool f(SpeechInputResult element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -28571,13 +29357,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SpeechInputResult> takeWhile(bool test(SpeechInputResult value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SpeechInputResult> skipWhile(bool test(SpeechInputResult value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -28622,8 +29408,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechInputResult> get reversed =>
-      new ReversedListView<SpeechInputResult>(this, 0, null);
+  List<SpeechInputResult> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SpeechInputResult a, SpeechInputResult b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -28749,7 +29536,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SpeechRecognitionResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SpeechRecognitionResult element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SpeechRecognitionResult element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SpeechRecognitionResult> where(bool f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -28763,13 +29554,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SpeechRecognitionResult> takeWhile(bool test(SpeechRecognitionResult value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SpeechRecognitionResult> skipWhile(bool test(SpeechRecognitionResult value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -28814,8 +29605,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechRecognitionResult> get reversed =>
-      new ReversedListView<SpeechRecognitionResult>(this, 0, null);
+  List<SpeechRecognitionResult> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SpeechRecognitionResult a, SpeechRecognitionResult b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -28941,7 +29733,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(StyleSheet element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(StyleSheet element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(StyleSheet element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<StyleSheet> where(bool f(StyleSheet element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -28955,13 +29751,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<StyleSheet> takeWhile(bool test(StyleSheet value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<StyleSheet> skipWhile(bool test(StyleSheet value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -29006,8 +29802,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<StyleSheet> get reversed =>
-      new ReversedListView<StyleSheet>(this, 0, null);
+  List<StyleSheet> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(StyleSheet a, StyleSheet b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -29487,6 +30284,8 @@
 
   String join([String separator]) => readClasses().join(separator);
 
+  Iterable map(f(String element)) => readClasses().map(f);
+
   Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
 
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
@@ -29584,7 +30383,7 @@
    * Helper method used to modify the set of css classes on this element.
    *
    *   f - callback with:
-   *      s - a Set of all the css class name currently on this element.
+   *   s - a Set of all the css class name currently on this element.
    *
    *   After f returns, the modified set is written to the
    *       className property of this element.
@@ -29667,7 +30466,7 @@
   _EventStream(this._target, this._eventType, this._useCapture);
 
   // DOM events are inherently multi-subscribers.
-  Stream<T> asMultiSubscriberStream() => this;
+  Stream<T> asBroadcastStream() => this;
 
   StreamSubscription<T> listen(void onData(T event),
       { void onError(AsyncError error),
@@ -29840,9 +30639,8 @@
   // The distance to shift from upper case alphabet Roman letters to lower case.
   final int _ROMAN_ALPHABET_OFFSET = "a".charCodes[0] - "A".charCodes[0];
 
-  // Instance members referring to the internal event handlers because closures
-  // are not hashable.
-  var _keyUp, _keyDown, _keyPress;
+  StreamSubscription _keyUpSubscription, _keyDownSubscription,
+      _keyPressSubscription;
 
   /**
    * An enumeration of key identifiers currently part of the W3C draft for DOM3
@@ -29898,9 +30696,6 @@
     _callbacks = [];
     _type = type;
     _target = target;
-    _keyDown = processKeyDown;
-    _keyUp = processKeyUp;
-    _keyPress = processKeyPress;
   }
 
   /**
@@ -29909,9 +30704,14 @@
    */
   void _initializeAllEventListeners() {
     _keyDownList = [];
-    _target.on.keyDown.add(_keyDown, true);
-    _target.on.keyPress.add(_keyPress, true);
-    _target.on.keyUp.add(_keyUp, true);
+    if (_keyDownSubscription == null) {
+      _keyDownSubscription = Element.keyDownEvent.forTarget(
+          _target, useCapture: true).listen(processKeyDown);
+      _keyPressSubscription = Element.keyPressEvent.forTarget(
+          _target, useCapture: true).listen(processKeyUp);
+      _keyUpSubscription = Element.keyUpEvent.forTarget(
+          _target, useCapture: true).listen(processKeyPress);
+    }
   }
 
   /** Add a callback that wishes to be notified when a KeyEvent occurs. */
@@ -29945,9 +30745,12 @@
     }
     if (_callbacks.length == 0) {
       // If we have no listeners, don't bother keeping track of keypresses.
-      _target.on.keyDown.remove(_keyDown);
-      _target.on.keyPress.remove(_keyPress);
-      _target.on.keyUp.remove(_keyUp);
+      _keyDownSubscription.cancel();
+      _keyDownSubscription = null;
+      _keyPressSubscription.cancel();
+      _keyPressSubscription = null;
+      _keyUpSubscription.cancel();
+      _keyUpSubscription = null;
     }
   }
 
@@ -31044,7 +31847,7 @@
 
     request.withCredentials = withCredentials;
 
-    request.on.readyStateChange.add((e) {
+    request.onReadyStateChange.listen((e) {
       if (request.readyState == HttpRequest.DONE) {
         onComplete(request);
       }
@@ -31284,46 +32087,38 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-typedef Object ComputeValue();
-
-class _MeasurementRequest<T> {
-  final ComputeValue computeValue;
-  final Completer<T> completer;
-  Object value;
-  bool exception = false;
-  _MeasurementRequest(this.computeValue, this.completer);
-}
-
-typedef void _MeasurementCallback();
+typedef void _MicrotaskCallback();
 
 /**
  * This class attempts to invoke a callback as soon as the current event stack
  * unwinds, but before the browser repaints.
  */
-abstract class _MeasurementScheduler {
-  bool _nextMeasurementFrameScheduled = false;
-  _MeasurementCallback _callback;
+abstract class _MicrotaskScheduler {
+  bool _nextMicrotaskFrameScheduled = false;
+  _MicrotaskCallback _callback;
 
-  _MeasurementScheduler(this._callback);
+  _MicrotaskScheduler(this._callback);
 
   /**
-   * Creates the best possible measurement scheduler for the current platform.
+   * Creates the best possible microtask scheduler for the current platform.
    */
-  factory _MeasurementScheduler.best(_MeasurementCallback callback) {
-    if (MutationObserver.supported) {
+  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+    if (Window._supportsSetImmediate) {
+      return new _SetImmediateScheduler(callback);
+    } else if (MutationObserver.supported) {
       return new _MutationObserverScheduler(callback);
     }
     return new _PostMessageScheduler(callback);
   }
 
   /**
-   * Schedules a measurement callback if one has not been scheduled already.
+   * Schedules a microtask callback if one has not been scheduled already.
    */
   void maybeSchedule() {
-    if (this._nextMeasurementFrameScheduled) {
+    if (this._nextMicrotaskFrameScheduled) {
       return;
     }
-    this._nextMeasurementFrameScheduled = true;
+    this._nextMicrotaskFrameScheduled = true;
     this._schedule();
   }
 
@@ -31333,14 +32128,14 @@
   void _schedule();
 
   /**
-   * Handles the measurement callback and forwards it if necessary.
+   * Handles the microtask callback and forwards it if necessary.
    */
   void _onCallback() {
     // Ignore spurious messages.
-    if (!_nextMeasurementFrameScheduled) {
+    if (!_nextMicrotaskFrameScheduled) {
       return;
     }
-    _nextMeasurementFrameScheduled = false;
+    _nextMicrotaskFrameScheduled = false;
     this._callback();
   }
 }
@@ -31348,22 +32143,22 @@
 /**
  * Scheduler which uses window.postMessage to schedule events.
  */
-class _PostMessageScheduler extends _MeasurementScheduler {
-  const _MEASUREMENT_MESSAGE = "DART-MEASURE";
+class _PostMessageScheduler extends _MicrotaskScheduler {
+  const _MICROTASK_MESSAGE = "DART-MICROTASK";
 
-  _PostMessageScheduler(_MeasurementCallback callback): super(callback) {
+  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
       // Messages from other windows do not cause a security risk as
       // all we care about is that _handleMessage is called
       // after the current event loop is unwound and calling the function is
       // a noop when zero requests are pending.
-      window.on.message.add(this._handleMessage);
+      window.onMessage.listen(this._handleMessage);
   }
 
   void _schedule() {
-    window.postMessage(_MEASUREMENT_MESSAGE, "*");
+    window.postMessage(_MICROTASK_MESSAGE, "*");
   }
 
-  _handleMessage(e) {
+  void _handleMessage(e) {
     this._onCallback();
   }
 }
@@ -31371,11 +32166,11 @@
 /**
  * Scheduler which uses a MutationObserver to schedule events.
  */
-class _MutationObserverScheduler extends _MeasurementScheduler {
+class _MutationObserverScheduler extends _MicrotaskScheduler {
   MutationObserver _observer;
   Element _dummy;
 
-  _MutationObserverScheduler(_MeasurementCallback callback): super(callback) {
+  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
     // Mutation events get fired as soon as the current event stack is unwound
     // so we just make a dummy event and listen for that.
     _observer = new MutationObserver(this._handleMutation);
@@ -31393,89 +32188,53 @@
   }
 }
 
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
 
-List<_MeasurementRequest> _pendingRequests;
-List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
-_MeasurementScheduler _measurementScheduler = null;
-
-void _maybeScheduleMeasurementFrame() {
-  if (_measurementScheduler == null) {
-    _measurementScheduler =
-      new _MeasurementScheduler.best(_completeMeasurementFutures);
+  void _schedule() {
+    window._setImmediate(_handleImmediate);
   }
-  _measurementScheduler.maybeSchedule();
+
+  void _handleImmediate() {
+    this._onCallback();
+  }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+  if (_microtaskScheduler == null) {
+    _microtaskScheduler =
+      new _MicrotaskScheduler.best(_completeMicrotasks);
+  }
+  _microtaskScheduler.maybeSchedule();
 }
 
 /**
- * Registers a [callback] which is called after the next batch of measurements
- * completes. Even if no measurements completed, the callback is triggered
- * when they would have completed to avoid confusing bugs if it happened that
- * no measurements were actually requested.
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
  */
-void _addMeasurementFrameCallback(TimeoutHandler callback) {
-  if (_pendingMeasurementFrameCallbacks == null) {
-    _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
-    _maybeScheduleMeasurementFrame();
+void _addMicrotaskCallback(TimeoutHandler callback) {
+  if (_pendingMicrotasks == null) {
+    _pendingMicrotasks = <TimeoutHandler>[];
+    _maybeScheduleMicrotaskFrame();
   }
-  _pendingMeasurementFrameCallbacks.add(callback);
+  _pendingMicrotasks.add(callback);
 }
 
-/**
- * Returns a [Future] whose value will be the result of evaluating
- * [computeValue] during the next safe measurement interval.
- * The next safe measurement interval is after the current event loop has
- * unwound but before the browser has rendered the page.
- * It is important that the [computeValue] function only queries the html
- * layout and html in any way.
- */
-Future _createMeasurementFuture(ComputeValue computeValue,
-                                Completer completer) {
-  if (_pendingRequests == null) {
-    _pendingRequests = <_MeasurementRequest>[];
-    _maybeScheduleMeasurementFrame();
-  }
-  _pendingRequests.add(new _MeasurementRequest(computeValue, completer));
-  return completer.future;
-}
 
 /**
- * Complete all pending measurement futures evaluating them in a single batch
- * so that the the browser is guaranteed to avoid multiple layouts.
+ * Complete all pending microtasks.
  */
-void _completeMeasurementFutures() {
-  // We must compute all new values before fulfilling the futures as
-  // the onComplete callbacks for the futures could modify the DOM making
-  // subsequent measurement calculations expensive to compute.
-  if (_pendingRequests != null) {
-    for (_MeasurementRequest request in _pendingRequests) {
-      try {
-        request.value = request.computeValue();
-      } catch (e) {
-        request.value = e;
-        request.exception = true;
-      }
-    }
-  }
-
-  final completedRequests = _pendingRequests;
-  final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
-  _pendingRequests = null;
-  _pendingMeasurementFrameCallbacks = null;
-  if (completedRequests != null) {
-    for (_MeasurementRequest request in completedRequests) {
-      if (request.exception) {
-        request.completer.completeError(request.value);
-      } else {
-        request.completer.complete(request.value);
-      }
-    }
-  }
-
-  if (readyMeasurementFrameCallbacks != null) {
-    for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
-      // TODO(jacobr): wrap each call to a handler in a try-catch block.
-      handler();
-    }
+void _completeMicrotasks() {
+  var callbacks = _pendingMicrotasks;
+  _pendingMicrotasks = null;
+  for (var callback in callbacks) {
+    callback();
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -31945,7 +32704,7 @@
     _parent.cancelBubble = cancel;
   }
   /** Accessor to the clipboardData available for this event. */
-  Clipboard get clipboardData => _parent.clipboardData;
+  DataTransfer get clipboardData => _parent.clipboardData;
   /** True if the ctrl key is pressed during this event. */
   bool get ctrlKey => _parent.ctrlKey;
   /** Accessor to the target this event is listening to for changes. */
@@ -32247,26 +33006,6 @@
   // copies the list.
   static ensureNative(List list) => list;  // TODO: make sure.
 }
-// 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.
-
-
-// TODO(rnystrom): add a way to supress public classes from DartDoc output.
-// TODO(jacobr): we can remove this class now that we are using the $dom_
-// convention for deprecated methods rather than truly private methods.
-/**
- * This class is intended for testing purposes only.
- */
-class Testing {
-  static void addEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
-    target.$dom_addEventListener(type, listener, useCapture);
-  }
-  static void removeEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
-    target.$dom_removeEventListener(type, listener, useCapture);
-  }
-
-}
 // 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.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index f44afd1..41f2758 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -1,8 +1,7 @@
-library html;
+library dart.dom.html;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -127,6 +126,7 @@
 class AnchorElement extends _Element_Merged {
   AnchorElement.internal() : super.internal();
 
+  @DomName('HTMLAnchorElement.HTMLAnchorElement')
   @DocsEditable
   factory AnchorElement({String href}) {
     var e = document.$dom_createElement("a");
@@ -458,6 +458,7 @@
 class AreaElement extends _Element_Merged {
   AreaElement.internal() : super.internal();
 
+  @DomName('HTMLAreaElement.HTMLAreaElement')
   @DocsEditable
   factory AreaElement() => document.$dom_createElement("area");
 
@@ -553,10 +554,10 @@
 @SupportedBrowser(SupportedBrowser.SAFARI)
 class ArrayBuffer extends NativeFieldWrapperClass1 {
   ArrayBuffer.internal();
+  factory ArrayBuffer(int length) => _create(length);
 
   @DocsEditable
-  factory ArrayBuffer(int length) => ArrayBuffer._create(length);
-  static ArrayBuffer _create(int length) native "ArrayBuffer_constructor_Callback";
+  static ArrayBuffer _create(length) native "ArrayBuffer_constructorCallback";
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -635,14 +636,14 @@
 class AudioElement extends MediaElement {
   AudioElement.internal() : super.internal();
 
+  @DomName('HTMLAudioElement.HTMLAudioElement')
   @DocsEditable
   factory AudioElement([String src]) {
-    if (!?src) {
-      return AudioElement._create();
-    }
-    return AudioElement._create(src);
+    return AudioElement._create_1(src);
   }
-  static AudioElement _create([String src]) native "HTMLAudioElement_constructor_Callback";
+
+  @DocsEditable
+  static AudioElement _create_1(src) native "HTMLAudioElement__create_1constructorCallback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -657,6 +658,7 @@
 class BRElement extends _Element_Merged {
   BRElement.internal() : super.internal();
 
+  @DomName('HTMLBRElement.HTMLBRElement')
   @DocsEditable
   factory BRElement() => document.$dom_createElement("br");
 
@@ -690,6 +692,7 @@
 class BaseElement extends _Element_Merged {
   BaseElement.internal() : super.internal();
 
+  @DomName('HTMLBaseElement.HTMLBaseElement')
   @DocsEditable
   factory BaseElement() => document.$dom_createElement("base");
 
@@ -833,18 +836,10 @@
 @DomName('Blob')
 class Blob extends NativeFieldWrapperClass1 {
   Blob.internal();
+  factory Blob(List blobParts, [String type, String endings]) => _create(blobParts, type, endings);
 
   @DocsEditable
-  factory Blob(List blobParts, [String type, String endings]) {
-    if (!?type) {
-      return Blob._create(blobParts);
-    }
-    if (!?endings) {
-      return Blob._create(blobParts, type);
-    }
-    return Blob._create(blobParts, type, endings);
-  }
-  static Blob _create(List blobParts, [String type, String endings]) native "Blob_constructor_Callback";
+  static Blob _create(blobParts, type, endings) native "Blob_constructorCallback";
 
   @DomName('Blob.size')
   @DocsEditable
@@ -949,6 +944,7 @@
   @DocsEditable
   static const EventStreamProvider<Event> unloadEvent = const EventStreamProvider<Event>('unload');
 
+  @DomName('HTMLBodyElement.HTMLBodyElement')
   @DocsEditable
   factory BodyElement() => document.$dom_createElement("body");
 
@@ -1069,6 +1065,7 @@
 class ButtonElement extends _Element_Merged {
   ButtonElement.internal() : super.internal();
 
+  @DomName('HTMLButtonElement.HTMLButtonElement')
   @DocsEditable
   factory ButtonElement() => document.$dom_createElement("button");
 
@@ -1203,6 +1200,7 @@
 class CanvasElement extends _Element_Merged {
   CanvasElement.internal() : super.internal();
 
+  @DomName('HTMLCanvasElement.HTMLCanvasElement')
   @DocsEditable
   factory CanvasElement({int width, int height}) {
     var e = document.$dom_createElement("canvas");
@@ -1211,32 +1209,96 @@
     return e;
   }
 
+  /// The height of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.height')
   @DocsEditable
   int get height native "HTMLCanvasElement_height_Getter";
 
+  /// The height of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.height')
   @DocsEditable
   void set height(int value) native "HTMLCanvasElement_height_Setter";
 
+  /// The width of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.width')
   @DocsEditable
   int get width native "HTMLCanvasElement_width_Getter";
 
+  /// The width of this canvas element in CSS pixels.
   @DomName('HTMLCanvasElement.width')
   @DocsEditable
   void set width(int value) native "HTMLCanvasElement_width_Setter";
 
   @DomName('HTMLCanvasElement.getContext')
   @DocsEditable
-  Object getContext(String contextId) native "HTMLCanvasElement_getContext_Callback";
+  CanvasRenderingContext getContext(String contextId, [Map attrs]) native "HTMLCanvasElement_getContext_Callback";
 
+  /**
+   * Returns a data URI containing a representation of the image in the
+   * format specified by type (defaults to 'image/png').
+   *
+   * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`
+   *
+   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]
+   * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default
+   * value is used. Note: the default value varies by browser.
+   *
+   * If the height or width of this canvas element is 0, then 'data:' is returned,
+   * representing no data.
+   *
+   * If the type requested is not 'image/png', and the returned value is
+   * 'data:image/png', then the requested type is not supported.
+   *
+   * Example usage:
+   *
+   *     CanvasElement canvas = new CanvasElement();
+   *     var ctx = canvas.context2d
+   *     ..fillStyle = "rgb(200,0,0)"
+   *     ..fillRect(10, 10, 55, 50);
+   *     var dataUrl = canvas.toDataURL("image/jpeg", 0.95);
+   *     // The Data Uri would look similar to
+   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
+   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
+   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='
+   *     //Create a new image element from the data URI.
+   *     var img = new ImageElement();
+   *     img.src = dataUrl;
+   *     document.body.children.add(img);
+   *
+   * See also:
+   *
+   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.
+   *
+   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.
+   *
+   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.
+   */
   @DomName('HTMLCanvasElement.toDataURL')
   @DocsEditable
   String toDataUrl(String type, [num quality]) native "HTMLCanvasElement_toDataURL_Callback";
 
-
   CanvasRenderingContext2D get context2d => getContext('2d');
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @Experimental
+  WebGLRenderingContext getContext3d({alpha: true, depth: true, stencil: false,
+    antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {
+
+    var options = {
+      'alpha': alpha,
+      'depth': depth,
+      'stencil': stencil,
+      'antialias': antialias,
+      'premultipliedAlpha': premultipliedAlpha,
+      'preserveDrawingBuffer': preserveDrawingBuffer,
+    };
+    var context = getContext('webgl', options);
+    if (context == null) {
+      context = getContext('experimental-webgl', options);
+    }
+    return context;
+  }
 }
 // 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
@@ -1246,10 +1308,48 @@
 
 
 @DocsEditable
+/**
+ * An opaque canvas object representing a gradient.
+ *
+ * Created by calling [createLinearGradient] or [createRadialGradient] on a
+ * [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ *     var canvas = new CanvasElement(width: 600, height: 600);
+ *     var ctx = canvas.context2d;
+ *     ctx.clearRect(0, 0, 600, 600);
+ *     ctx.save();
+ *     // Create radial gradient.
+ *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);
+ *     gradient.addColorStop(0, '#000');
+ *     gradient.addColorStop(1, 'rgb(255, 255, 255)');
+ *     // Assign gradients to fill.
+ *     ctx.fillStyle = gradient;
+ *     // Draw a rectangle with a gradient fill.
+ *     ctx.fillRect(0, 0, 600, 600);
+ *     ctx.save();
+ *     document.body.children.add(canvas);
+ *
+ * See also:
+ *
+ * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.
+ * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.
+ * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.
+ */
 @DomName('CanvasGradient')
 class CanvasGradient extends NativeFieldWrapperClass1 {
   CanvasGradient.internal();
 
+  /**
+   * Adds a color stop to this gradient at the offset.
+   *
+   * The [offset] can range between 0.0 and 1.0.
+   *
+   * See also:
+   *
+   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.
+   */
   @DomName('CanvasGradient.addColorStop')
   @DocsEditable
   void addColorStop(num offset, String color) native "CanvasGradient_addColorStop_Callback";
@@ -1263,6 +1363,33 @@
 
 
 @DocsEditable
+/**
+ * An opaque object representing a pattern of image, canvas, or video.
+ *
+ * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.
+ *
+ * Example usage:
+ *
+ *     var canvas = new CanvasElement(width: 600, height: 600);
+ *     var ctx = canvas.context2d;
+ *     var img = new ImageElement();
+ *     // Image src needs to be loaded before pattern is applied.
+ *     img.onLoad.listen((event) {
+ *       // When the image is loaded, create a pattern
+ *       // from the ImageElement.
+ *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');
+ *       ctx.rect(0, 0, canvas.width, canvas.height);
+ *       ctx.fillStyle = pattern;
+ *       ctx.fill();
+ *     });
+ *     img.src = "images/foo.jpg";
+ *     document.body.children.add(canvas);
+ *
+ * See also:
+ * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.
+ * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.
+ * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.
+ */
 @DomName('CanvasPattern')
 class CanvasPattern extends NativeFieldWrapperClass1 {
   CanvasPattern.internal();
@@ -1276,10 +1403,17 @@
 
 
 @DocsEditable
+/**
+ * A rendering context for a canvas element.
+ *
+ * This context is extended by [CanvasRenderingContext2D] and
+ * [WebGLRenderingContext].
+ */
 @DomName('CanvasRenderingContext')
 class CanvasRenderingContext extends NativeFieldWrapperClass1 {
   CanvasRenderingContext.internal();
 
+  /// Reference to the canvas element to which this context belongs.
   @DomName('CanvasRenderingContext.canvas')
   @DocsEditable
   CanvasElement get canvas native "CanvasRenderingContext_canvas_Getter";
@@ -1470,9 +1604,22 @@
   @DocsEditable
   void clearRect(num x, num y, num width, num height) native "CanvasRenderingContext2D_clearRect_Callback";
 
-  @DomName('CanvasRenderingContext2D.clip')
+  void clip([String winding]) {
+    if (?winding) {
+      _clip_1(winding);
+      return;
+    }
+    _clip_2();
+    return;
+  }
+
+  @DomName('CanvasRenderingContext2D._clip_1')
   @DocsEditable
-  void clip() native "CanvasRenderingContext2D_clip_Callback";
+  void _clip_1(winding) native "CanvasRenderingContext2D__clip_1_Callback";
+
+  @DomName('CanvasRenderingContext2D._clip_2')
+  @DocsEditable
+  void _clip_2() native "CanvasRenderingContext2D__clip_2_Callback";
 
   @DomName('CanvasRenderingContext2D.closePath')
   @DocsEditable
@@ -1598,9 +1745,22 @@
   @DocsEditable
   void _drawImage_9(canvas_OR_image_OR_video, sx_OR_x, sy_OR_y, sw_OR_width, height_OR_sh, dx, dy, dw, dh) native "CanvasRenderingContext2D__drawImage_9_Callback";
 
-  @DomName('CanvasRenderingContext2D.fill')
+  void fill([String winding]) {
+    if (?winding) {
+      _fill_1(winding);
+      return;
+    }
+    _fill_2();
+    return;
+  }
+
+  @DomName('CanvasRenderingContext2D._fill_1')
   @DocsEditable
-  void fill() native "CanvasRenderingContext2D_fill_Callback";
+  void _fill_1(winding) native "CanvasRenderingContext2D__fill_1_Callback";
+
+  @DomName('CanvasRenderingContext2D._fill_2')
+  @DocsEditable
+  void _fill_2() native "CanvasRenderingContext2D__fill_2_Callback";
 
   @DomName('CanvasRenderingContext2D.fillRect')
   @DocsEditable
@@ -1631,9 +1791,20 @@
   @DocsEditable
   List<num> getLineDash() native "CanvasRenderingContext2D_getLineDash_Callback";
 
-  @DomName('CanvasRenderingContext2D.isPointInPath')
+  bool isPointInPath(num x, num y, [String winding]) {
+    if (?winding) {
+      return _isPointInPath_1(x, y, winding);
+    }
+    return _isPointInPath_2(x, y);
+  }
+
+  @DomName('CanvasRenderingContext2D._isPointInPath_1')
   @DocsEditable
-  bool isPointInPath(num x, num y) native "CanvasRenderingContext2D_isPointInPath_Callback";
+  bool _isPointInPath_1(x, y, winding) native "CanvasRenderingContext2D__isPointInPath_1_Callback";
+
+  @DomName('CanvasRenderingContext2D._isPointInPath_2')
+  @DocsEditable
+  bool _isPointInPath_2(x, y) native "CanvasRenderingContext2D__isPointInPath_2_Callback";
 
   @DomName('CanvasRenderingContext2D.lineTo')
   @DocsEditable
@@ -1900,63 +2071,6 @@
 
 
 @DocsEditable
-@DomName('Clipboard')
-class Clipboard extends NativeFieldWrapperClass1 {
-  Clipboard.internal();
-
-  @DomName('Clipboard.dropEffect')
-  @DocsEditable
-  String get dropEffect native "Clipboard_dropEffect_Getter";
-
-  @DomName('Clipboard.dropEffect')
-  @DocsEditable
-  void set dropEffect(String value) native "Clipboard_dropEffect_Setter";
-
-  @DomName('Clipboard.effectAllowed')
-  @DocsEditable
-  String get effectAllowed native "Clipboard_effectAllowed_Getter";
-
-  @DomName('Clipboard.effectAllowed')
-  @DocsEditable
-  void set effectAllowed(String value) native "Clipboard_effectAllowed_Setter";
-
-  @DomName('Clipboard.files')
-  @DocsEditable
-  List<File> get files native "Clipboard_files_Getter";
-
-  @DomName('Clipboard.items')
-  @DocsEditable
-  DataTransferItemList get items native "Clipboard_items_Getter";
-
-  @DomName('Clipboard.types')
-  @DocsEditable
-  List get types native "Clipboard_types_Getter";
-
-  @DomName('Clipboard.clearData')
-  @DocsEditable
-  void clearData([String type]) native "Clipboard_clearData_Callback";
-
-  @DomName('Clipboard.getData')
-  @DocsEditable
-  String getData(String type) native "Clipboard_getData_Callback";
-
-  @DomName('Clipboard.setData')
-  @DocsEditable
-  bool setData(String type, String data) native "Clipboard_setData_Callback";
-
-  @DomName('Clipboard.setDragImage')
-  @DocsEditable
-  void setDragImage(ImageElement image, int x, int y) native "Clipboard_setDragImage_Callback";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('CloseEvent')
 class CloseEvent extends Event {
   CloseEvent.internal() : super.internal();
@@ -2132,6 +2246,7 @@
 class ContentElement extends _Element_Merged {
   ContentElement.internal() : super.internal();
 
+  @DomName('HTMLContentElement.HTMLContentElement')
   @DocsEditable
   factory ContentElement() => document.$dom_createElement("content");
 
@@ -2288,6 +2403,31 @@
 
 
 @DocsEditable
+@DomName('CSSHostRule')
+class CssHostRule extends CssRule {
+  CssHostRule.internal() : super.internal();
+
+  @DomName('CSSHostRule.cssRules')
+  @DocsEditable
+  List<CssRule> get cssRules native "CSSHostRule_cssRules_Getter";
+
+  @DomName('CSSHostRule.deleteRule')
+  @DocsEditable
+  void deleteRule(int index) native "CSSHostRule_deleteRule_Callback";
+
+  @DomName('CSSHostRule.insertRule')
+  @DocsEditable
+  int insertRule(String rule, int index) native "CSSHostRule_insertRule_Callback";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('CSSImportRule')
 class CssImportRule extends CssRule {
   CssImportRule.internal() : super.internal();
@@ -2376,17 +2516,23 @@
 
 @DocsEditable
 @DomName('WebKitCSSMatrix')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class CssMatrix extends NativeFieldWrapperClass1 {
   CssMatrix.internal();
 
+  @DomName('WebKitCSSMatrix.WebKitCSSMatrix')
   @DocsEditable
   factory CssMatrix([String cssValue]) {
-    if (!?cssValue) {
-      return CssMatrix._create();
-    }
-    return CssMatrix._create(cssValue);
+    return CssMatrix._create_1(cssValue);
   }
-  static CssMatrix _create([String cssValue]) native "WebKitCSSMatrix_constructor_Callback";
+
+  @DocsEditable
+  static CssMatrix _create_1(cssValue) native "WebKitCSSMatrix__create_1constructorCallback";
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
 
   @DomName('WebKitCSSMatrix.a')
   @DocsEditable
@@ -2778,6 +2924,8 @@
 
   static const int FONT_FACE_RULE = 5;
 
+  static const int HOST_RULE = 1001;
+
   static const int IMPORT_RULE = 3;
 
   static const int MEDIA_RULE = 4;
@@ -6271,6 +6419,7 @@
 class DListElement extends _Element_Merged {
   DListElement.internal() : super.internal();
 
+  @DomName('HTMLDListElement.HTMLDListElement')
   @DocsEditable
   factory DListElement() => document.$dom_createElement("dl");
 
@@ -6291,6 +6440,7 @@
 class DataListElement extends _Element_Merged {
   DataListElement.internal() : super.internal();
 
+  @DomName('HTMLDataListElement.HTMLDataListElement')
   @DocsEditable
   factory DataListElement() => document.$dom_createElement("datalist");
 
@@ -6310,6 +6460,63 @@
 
 
 @DocsEditable
+@DomName('Clipboard')
+class DataTransfer extends NativeFieldWrapperClass1 {
+  DataTransfer.internal();
+
+  @DomName('Clipboard.dropEffect')
+  @DocsEditable
+  String get dropEffect native "Clipboard_dropEffect_Getter";
+
+  @DomName('Clipboard.dropEffect')
+  @DocsEditable
+  void set dropEffect(String value) native "Clipboard_dropEffect_Setter";
+
+  @DomName('Clipboard.effectAllowed')
+  @DocsEditable
+  String get effectAllowed native "Clipboard_effectAllowed_Getter";
+
+  @DomName('Clipboard.effectAllowed')
+  @DocsEditable
+  void set effectAllowed(String value) native "Clipboard_effectAllowed_Setter";
+
+  @DomName('Clipboard.files')
+  @DocsEditable
+  List<File> get files native "Clipboard_files_Getter";
+
+  @DomName('Clipboard.items')
+  @DocsEditable
+  DataTransferItemList get items native "Clipboard_items_Getter";
+
+  @DomName('Clipboard.types')
+  @DocsEditable
+  List get types native "Clipboard_types_Getter";
+
+  @DomName('Clipboard.clearData')
+  @DocsEditable
+  void clearData([String type]) native "Clipboard_clearData_Callback";
+
+  @DomName('Clipboard.getData')
+  @DocsEditable
+  String getData(String type) native "Clipboard_getData_Callback";
+
+  @DomName('Clipboard.setData')
+  @DocsEditable
+  bool setData(String type, String data) native "Clipboard_setData_Callback";
+
+  @DomName('Clipboard.setDragImage')
+  @DocsEditable
+  void setDragImage(ImageElement image, int x, int y) native "Clipboard_setDragImage_Callback";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('DataTransferItem')
 class DataTransferItem extends NativeFieldWrapperClass1 {
   DataTransferItem.internal();
@@ -6391,18 +6598,10 @@
 @DomName('DataView')
 class DataView extends ArrayBufferView {
   DataView.internal() : super.internal();
+  factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) => _create(buffer, byteOffset, byteLength);
 
   @DocsEditable
-  factory DataView(ArrayBuffer buffer, [int byteOffset, int byteLength]) {
-    if (!?byteOffset) {
-      return DataView._create(buffer);
-    }
-    if (!?byteLength) {
-      return DataView._create(buffer, byteOffset);
-    }
-    return DataView._create(buffer, byteOffset, byteLength);
-  }
-  static DataView _create(ArrayBuffer buffer, [int byteOffset, int byteLength]) native "DataView_constructor_Callback";
+  static DataView _create(buffer, byteOffset, byteLength) native "DataView_constructorCallback";
 
   num getFloat32(int byteOffset, {bool littleEndian}) {
     if (?littleEndian) {
@@ -6622,9 +6821,15 @@
 
 @DocsEditable
 @DomName('Database')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class Database extends NativeFieldWrapperClass1 {
   Database.internal();
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('Database.version')
   @DocsEditable
   String get version native "Database_version_Getter";
@@ -6659,6 +6864,9 @@
 
 @DocsEditable
 @DomName('DatabaseSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class DatabaseSync extends NativeFieldWrapperClass1 {
   DatabaseSync.internal();
 
@@ -6739,6 +6947,7 @@
 class DetailsElement extends _Element_Merged {
   DetailsElement.internal() : super.internal();
 
+  @DomName('HTMLDetailsElement.HTMLDetailsElement')
   @DocsEditable
   factory DetailsElement() => document.$dom_createElement("details");
 
@@ -6911,10 +7120,32 @@
 
 
 @DocsEditable
+/**
+ * Represents an HTML <div> element.
+ *
+ * The [DivElement] is a generic container for content and does not have any
+ * special significance. It is functionally similar to [SpanElement].
+ *
+ * The [DivElement] is a block-level element, as opposed to [SpanElement],
+ * which is an inline-level element.
+ *
+ * Example usage:
+ *
+ *     DivElement div = new DivElement();
+ *     div.text = 'Here's my new DivElem
+ *     document.body.elements.add(elem);
+ *
+ * See also:
+ *
+ * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.
+ * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.
+ * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.
+ */
 @DomName('HTMLDivElement')
 class DivElement extends _Element_Merged {
   DivElement.internal() : super.internal();
 
+  @DomName('HTMLDivElement.HTMLDivElement')
   @DocsEditable
   factory DivElement() => document.$dom_createElement("div");
 
@@ -6961,10 +7192,12 @@
   DocumentEvents get on =>
     new DocumentEvents(this);
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.body')
   @DocsEditable
   Element get $dom_body native "Document_body_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.body')
   @DocsEditable
   void set $dom_body(Element value) native "Document_body_Setter";
@@ -6997,6 +7230,7 @@
   @DocsEditable
   String get domain native "Document_domain_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.head')
   @DocsEditable
   HeadElement get $dom_head native "Document_head_Getter";
@@ -7005,6 +7239,7 @@
   @DocsEditable
   DomImplementation get implementation native "Document_implementation_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.lastModified')
   @DocsEditable
   String get $dom_lastModified native "Document_lastModified_Getter";
@@ -7017,6 +7252,7 @@
   @DocsEditable
   String get readyState native "Document_readyState_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.referrer')
   @DocsEditable
   String get $dom_referrer native "Document_referrer_Getter";
@@ -7029,34 +7265,42 @@
   @DocsEditable
   void set $dom_selectedStylesheetSet(String value) native "Document_selectedStylesheetSet_Setter";
 
+  /// Moved to [HtmlDocument]
   @DomName('Document.styleSheets')
   @DocsEditable
   List<StyleSheet> get $dom_styleSheets native "Document_styleSheets_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.title')
   @DocsEditable
   String get $dom_title native "Document_title_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.title')
   @DocsEditable
   void set $dom_title(String value) native "Document_title_Setter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenElement')
   @DocsEditable
   Element get $dom_webkitFullscreenElement native "Document_webkitFullscreenElement_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitFullscreenEnabled')
   @DocsEditable
   bool get $dom_webkitFullscreenEnabled native "Document_webkitFullscreenEnabled_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitHidden')
   @DocsEditable
   bool get $dom_webkitHidden native "Document_webkitHidden_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitIsFullScreen')
   @DocsEditable
   bool get $dom_webkitIsFullScreen native "Document_webkitIsFullScreen_Getter";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitPointerLockElement')
   @DocsEditable
   Element get $dom_webkitPointerLockElement native "Document_webkitPointerLockElement_Getter";
@@ -7065,6 +7309,7 @@
   @DocsEditable
   String get $dom_webkitVisibilityState native "Document_webkitVisibilityState_Getter";
 
+  /// Use the [Range] constructor instead.
   @DomName('Document.caretRangeFromPoint')
   @DocsEditable
   Range $dom_caretRangeFromPoint(int x, int y) native "Document_caretRangeFromPoint_Callback";
@@ -7077,6 +7322,7 @@
   @DocsEditable
   DocumentFragment createDocumentFragment() native "Document_createDocumentFragment_Callback";
 
+  /// Deprecated: use new Element.tag(tagName) instead.
   @DomName('Document.createElement')
   @DocsEditable
   Element $dom_createElement(String tagName) native "Document_createElement_Callback";
@@ -7101,6 +7347,7 @@
   @DocsEditable
   Touch $dom_createTouch(Window window, EventTarget target, int identifier, int pageX, int pageY, int screenX, int screenY, int webkitRadiusX, int webkitRadiusY, num webkitRotationAngle, num webkitForce) native "Document_createTouch_Callback";
 
+  /// Use the [TouchList] constructor instead.
   @DomName('Document.createTouchList')
   @DocsEditable
   TouchList $dom_createTouchList() native "Document_createTouchList_Callback";
@@ -7113,10 +7360,12 @@
   @DocsEditable
   bool execCommand(String command, bool userInterface, String value) native "Document_execCommand_Callback";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.getCSSCanvasContext')
   @DocsEditable
   CanvasRenderingContext $dom_getCssCanvasContext(String contextId, String name, int width, int height) native "Document_getCSSCanvasContext_Callback";
 
+  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.getElementById')
   @DocsEditable
   Element $dom_getElementById(String elementId) native "Document_getElementById_Callback";
@@ -7153,22 +7402,27 @@
   @DocsEditable
   String queryCommandValue(String command) native "Document_queryCommandValue_Callback";
 
+  /// Deprecated: renamed to the shorter name [query].
   @DomName('Document.querySelector')
   @DocsEditable
   Element $dom_querySelector(String selectors) native "Document_querySelector_Callback";
 
+  /// Deprecated: use query("#$elementId") instead.
   @DomName('Document.querySelectorAll')
   @DocsEditable
   List<Node> $dom_querySelectorAll(String selectors) native "Document_querySelectorAll_Callback";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitCancelFullScreen')
   @DocsEditable
   void $dom_webkitCancelFullScreen() native "Document_webkitCancelFullScreen_Callback";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitFullscreen')
   @DocsEditable
   void $dom_webkitExitFullscreen() native "Document_webkitExitFullscreen_Callback";
 
+  /// Moved to [HtmlDocument].
   @DomName('Document.webkitExitPointerLock')
   @DocsEditable
   void $dom_webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
@@ -7725,7 +7979,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(DomMimeType element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(DomMimeType element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(DomMimeType element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<DomMimeType> where(bool f(DomMimeType element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7739,13 +7997,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<DomMimeType> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<DomMimeType> takeWhile(bool test(DomMimeType value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<DomMimeType> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<DomMimeType> skipWhile(bool test(DomMimeType value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -7790,8 +8048,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomMimeType> get reversed =>
-      new ReversedListView<DomMimeType>(this, 0, null);
+  List<DomMimeType> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(DomMimeType a, DomMimeType b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -7893,9 +8152,14 @@
 class DomParser extends NativeFieldWrapperClass1 {
   DomParser.internal();
 
+  @DomName('DOMParser.DOMParser')
   @DocsEditable
-  factory DomParser() => DomParser._create();
-  static DomParser _create() native "DOMParser_constructor_Callback";
+  factory DomParser() {
+    return DomParser._create_1();
+  }
+
+  @DocsEditable
+  static DomParser _create_1() native "DOMParser__create_1constructorCallback";
 
   @DomName('DOMParser.parseFromString')
   @DocsEditable
@@ -7983,7 +8247,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(DomPlugin element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(DomPlugin element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(DomPlugin element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<DomPlugin> where(bool f(DomPlugin element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7997,13 +8265,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<DomPlugin> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<DomPlugin> takeWhile(bool test(DomPlugin value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<DomPlugin> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<DomPlugin> skipWhile(bool test(DomPlugin value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -8048,8 +8316,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<DomPlugin> get reversed =>
-      new ReversedListView<DomPlugin>(this, 0, null);
+  List<DomPlugin> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(DomPlugin a, DomPlugin b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -8151,6 +8420,45 @@
 
 
 @DocsEditable
+@DomName('WebKitPoint')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
+class DomPoint extends NativeFieldWrapperClass1 {
+  DomPoint.internal();
+  factory DomPoint(num x, num y) => _create(x, y);
+
+  @DocsEditable
+  static DomPoint _create(x, y) native "WebKitPoint_constructorCallback";
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
+  @DomName('WebKitPoint.x')
+  @DocsEditable
+  num get x native "WebKitPoint_x_Getter";
+
+  @DomName('WebKitPoint.x')
+  @DocsEditable
+  void set x(num value) native "WebKitPoint_x_Setter";
+
+  @DomName('WebKitPoint.y')
+  @DocsEditable
+  num get y native "WebKitPoint_y_Getter";
+
+  @DomName('WebKitPoint.y')
+  @DocsEditable
+  void set y(num value) native "WebKitPoint_y_Setter";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('Selection')
 class DomSelection extends NativeFieldWrapperClass1 {
   DomSelection.internal();
@@ -8325,7 +8633,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(String element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(String element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -8339,13 +8651,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<String> takeWhile(bool test(String value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<String> skipWhile(bool test(String value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -8390,8 +8702,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<String> get reversed =>
-      new ReversedListView<String>(this, 0, null);
+  List<String> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(String a, String b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -8600,6 +8913,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Element element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Element element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -8612,7 +8929,7 @@
     return _element.$dom_firstElementChild == null;
   }
 
-  List<Element> take(int n) {
+  Iterable<Element> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -8620,7 +8937,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Element> skip(int n) {
+  Iterable<Element> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -8676,8 +8993,9 @@
     }
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(this, 0, null);
+  List<Element> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -8695,7 +9013,7 @@
   void remove(Object object) {
     if (object is Element) {
       Element element = object;
-      if (identical(element.parentNode, this)) {
+      if (identical(element.parentNode, _element)) {
         _element.$dom_removeChild(element);
       }
     }
@@ -8812,6 +9130,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Element element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Element element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -8841,7 +9163,7 @@
   List<Element> toList() => new List<Element>.from(this);
   Set<Element> toSet() => new Set<Element>.from(this);
 
-  List<Element> take(int n) {
+  Iterable<Element> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -8849,7 +9171,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Element> skip(int n) {
+  Iterable<Element> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -8901,8 +9223,9 @@
     throw new UnsupportedError('');
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(this, 0, null);
+  List<Element> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('');
@@ -9247,27 +9570,20 @@
    * [style] property, which contains only the values specified directly on this
    * element.
    *
+   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+   * `::line-marker`.
+   *
    * See also:
    *
    * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
-   */
-  Future<CssStyleDeclaration> get computedStyle {
-     // TODO(jacobr): last param should be null, see b/5045788
-     return getComputedStyle('');
-  }
-
-  /**
-   * Returns the computed styles for pseudo-elements such as `::after`,
-   * `::before`, `::marker`, `::line-marker`.
-   *
-   * See also:
-   *
    * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
    */
-  Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) {
-    return _createMeasurementFuture(
-        () => window.$dom_getComputedStyle(this, pseudoElement),
-        new Completer<CssStyleDeclaration>());
+  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+    if (pseudoElement == null) {
+      pseudoElement = '';
+    }
+    // TODO(jacobr): last param should be null, see b/5045788
+    return window.$dom_getComputedStyle(this, pseudoElement);
   }
 
   /**
@@ -10307,6 +10623,7 @@
 class EmbedElement extends _Element_Merged {
   EmbedElement.internal() : super.internal();
 
+  @DomName('HTMLEmbedElement.HTMLEmbedElement')
   @DocsEditable
   factory EmbedElement() => document.$dom_createElement("embed");
 
@@ -10659,7 +10976,7 @@
 
   @DomName('Event.clipboardData')
   @DocsEditable
-  Clipboard get clipboardData native "Event_clipboardData_Getter";
+  DataTransfer get clipboardData native "Event_clipboardData_Getter";
 
   @DomName('Event.currentTarget')
   @DocsEditable
@@ -10779,14 +11096,14 @@
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
+  @DomName('EventSource.EventSource')
   @DocsEditable
   factory EventSource(String url, [Map eventSourceInit]) {
-    if (!?eventSourceInit) {
-      return EventSource._create(url);
-    }
-    return EventSource._create(url, eventSourceInit);
+    return EventSource._create_1(url, eventSourceInit);
   }
-  static EventSource _create(String url, [Map eventSourceInit]) native "EventSource_constructor_Callback";
+
+  @DocsEditable
+  static EventSource _create_1(url, eventSourceInit) native "EventSource__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -10980,6 +11297,7 @@
 class FieldSetElement extends _Element_Merged {
   FieldSetElement.internal() : super.internal();
 
+  @DomName('HTMLFieldSetElement.HTMLFieldSetElement')
   @DocsEditable
   factory FieldSetElement() => document.$dom_createElement("fieldset");
 
@@ -11245,7 +11563,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(File element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(File element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(File element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<File> where(bool f(File element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -11259,13 +11581,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<File> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<File> takeWhile(bool test(File value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<File> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<File> skipWhile(bool test(File value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -11310,8 +11632,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<File> get reversed =>
-      new ReversedListView<File>(this, 0, null);
+  List<File> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(File a, File b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -11433,9 +11756,14 @@
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> progressEvent = const EventStreamProvider<ProgressEvent>('progress');
 
+  @DomName('FileReader.FileReader')
   @DocsEditable
-  factory FileReader() => FileReader._create();
-  static FileReader _create() native "FileReader_constructor_Callback";
+  factory FileReader() {
+    return FileReader._create_1();
+  }
+
+  @DocsEditable
+  static FileReader _create_1() native "FileReader__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -11568,9 +11896,14 @@
 class FileReaderSync extends NativeFieldWrapperClass1 {
   FileReaderSync.internal();
 
+  @DomName('FileReaderSync.FileReaderSync')
   @DocsEditable
-  factory FileReaderSync() => FileReaderSync._create();
-  static FileReaderSync _create() native "FileReaderSync_constructor_Callback";
+  factory FileReaderSync() {
+    return FileReaderSync._create_1();
+  }
+
+  @DocsEditable
+  static FileReaderSync _create_1() native "FileReaderSync__create_1constructorCallback";
 
   @DomName('FileReaderSync.readAsArrayBuffer')
   @DocsEditable
@@ -11848,12 +12181,18 @@
 class Float32Array extends ArrayBufferView implements List<num> {
   Float32Array.internal() : super.internal();
 
+  @DomName('Float32Array.Float32Array')
+  @DocsEditable
   factory Float32Array(int length) =>
     _TypedArrayFactoryProvider.createFloat32Array(length);
 
+  @DomName('Float32Array.fromList')
+  @DocsEditable
   factory Float32Array.fromList(List<num> list) =>
     _TypedArrayFactoryProvider.createFloat32Array_fromList(list);
 
+  @DomName('Float32Array.fromBuffer')
+  @DocsEditable
   factory Float32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createFloat32Array_fromBuffer(buffer, byteOffset, length);
 
@@ -11893,7 +12232,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(num element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(num element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -11907,13 +12250,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<num> takeWhile(bool test(num value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<num> skipWhile(bool test(num value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -11958,8 +12301,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed =>
-      new ReversedListView<num>(this, 0, null);
+  List<num> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(num a, num b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -12072,12 +12416,18 @@
 class Float64Array extends ArrayBufferView implements List<num> {
   Float64Array.internal() : super.internal();
 
+  @DomName('Float64Array.Float64Array')
+  @DocsEditable
   factory Float64Array(int length) =>
     _TypedArrayFactoryProvider.createFloat64Array(length);
 
+  @DomName('Float64Array.fromList')
+  @DocsEditable
   factory Float64Array.fromList(List<num> list) =>
     _TypedArrayFactoryProvider.createFloat64Array_fromList(list);
 
+  @DomName('Float64Array.fromBuffer')
+  @DocsEditable
   factory Float64Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createFloat64Array_fromBuffer(buffer, byteOffset, length);
 
@@ -12117,7 +12467,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(num element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(num element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(num element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<num> where(bool f(num element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -12131,13 +12485,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<num> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<num> takeWhile(bool test(num value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<num> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<num> skipWhile(bool test(num value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -12182,8 +12536,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<num> get reversed =>
-      new ReversedListView<num>(this, 0, null);
+  List<num> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(num a, num b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -12295,15 +12650,10 @@
 @DomName('FormData')
 class FormData extends NativeFieldWrapperClass1 {
   FormData.internal();
+  factory FormData([FormElement form]) => _create(form);
 
   @DocsEditable
-  factory FormData([FormElement form]) {
-    if (!?form) {
-      return FormData._create();
-    }
-    return FormData._create(form);
-  }
-  static FormData _create([FormElement form]) native "DOMFormData_constructor_Callback";
+  static FormData _create(form) native "DOMFormData_constructorCallback";
 
   @DomName('DOMFormData.append')
   @DocsEditable
@@ -12322,6 +12672,7 @@
 class FormElement extends _Element_Merged {
   FormElement.internal() : super.internal();
 
+  @DomName('HTMLFormElement.HTMLFormElement')
   @DocsEditable
   factory FormElement() => document.$dom_createElement("form");
 
@@ -12505,6 +12856,7 @@
 class HRElement extends _Element_Merged {
   HRElement.internal() : super.internal();
 
+  @DomName('HTMLHRElement.HTMLHRElement')
   @DocsEditable
   factory HRElement() => document.$dom_createElement("hr");
 
@@ -12558,6 +12910,7 @@
 class HeadElement extends _Element_Merged {
   HeadElement.internal() : super.internal();
 
+  @DomName('HTMLHeadElement.HTMLHeadElement')
   @DocsEditable
   factory HeadElement() => document.$dom_createElement("head");
 
@@ -12574,21 +12927,27 @@
 class HeadingElement extends _Element_Merged {
   HeadingElement.internal() : super.internal();
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h1() => document.$dom_createElement("h1");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h2() => document.$dom_createElement("h2");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h3() => document.$dom_createElement("h3");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h4() => document.$dom_createElement("h4");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h5() => document.$dom_createElement("h5");
 
+  @DomName('HTMLHeadingElement.HTMLHeadingElement')
   @DocsEditable
   factory HeadingElement.h6() => document.$dom_createElement("h6");
 
@@ -12693,7 +13052,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -12707,13 +13070,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -12758,8 +13121,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -12897,7 +13261,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -12911,13 +13279,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -12962,8 +13330,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -13200,6 +13569,7 @@
 class HtmlElement extends _Element_Merged {
   HtmlElement.internal() : super.internal();
 
+  @DomName('HTMLHtmlElement.HTMLHtmlElement')
   @DocsEditable
   factory HtmlElement() => document.$dom_createElement("html");
 
@@ -13270,25 +13640,39 @@
  */
 @DomName('XMLHttpRequest')
 class HttpRequest extends EventTarget {
-  /**
-   * Creates a URL get request for the specified `url`.
-   *
-   * After completing the request, the object will call the user-provided
-   * [onComplete] callback.
-   */
-  factory HttpRequest.get(String url, onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, false);
 
-  // 80 char issue for comments in lists: dartbug.com/7588.
   /**
-   * Creates a URL GET request for the specified `url` with
-   * credentials such a cookie (already) set in the header or
-   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
+   * Creates a URL get request for the specified [url].
    *
-   * After completing the request, the object will call the user-provided
-   * [onComplete] callback.
+   * The server response must be a `text/` mime type for this request to
+   * succeed.
    *
-   * A few other details to keep in mind when using credentials:
+   * This is similar to [request] but specialized for HTTP GET requests which
+   * return text content.
+   *
+   * See also:
+   *
+   * * [request]
+   */
+  static Future<String> getString(String url,
+      {bool withCredentials, void onProgress(ProgressEvent e)}) {
+    return request(url, withCredentials: withCredentials,
+        onProgress: onProgress).then((xhr) => xhr.responseText);
+  }
+
+  /**
+   * Creates a URL request for the specified [url].
+   *
+   * By default this will do an HTTP GET request, this can be overridden with
+   * [method].
+   *
+   * The Future is completed when the response is available.
+   *
+   * The [withCredentials] parameter specified that credentials such as a cookie
+   * (already) set in the header or
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+   * should be specified for the request. Details to keep in mind when using
+   * credentials:
    *
    * * Using credentials is only useful for cross-origin requests.
    * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
@@ -13297,12 +13681,60 @@
    *
    * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
    */
-  factory HttpRequest.getWithCredentials(String url,
-      onComplete(HttpRequest request)) =>
-      _HttpRequestUtils.get(url, onComplete, true);
+  static Future<HttpRequest> request(String url,
+      {String method, bool withCredentials, String responseType, sendData,
+      void onProgress(ProgressEvent e)}) {
+    var completer = new Completer<HttpRequest>();
+
+    var xhr = new HttpRequest();
+    if (method == null) {
+      method = 'GET';
+    }
+    xhr.open(method, url, true);
+
+    if (withCredentials != null) {
+      xhr.withCredentials = withCredentials;
+    }
+
+    if (responseType != null) {
+      xhr.responseType = responseType;
+    }
+
+    if (onProgress != null) {
+      xhr.onProgress.listen(onProgress);
+    }
+
+    xhr.onLoad.listen((e) {
+      if (xhr.status >= 200 && xhr.status < 300 ||
+          xhr.status == 304 ) {
+        completer.complete(xhr);
+      } else {
+        completer.completeError(e);
+      }
+    });
+
+    xhr.onError.listen((e) {
+      completer.completeError(e);
+    });
+
+    if (sendData != null) {
+      xhr.send(sendData);
+    } else {
+      xhr.send();
+    }
+
+    return completer.future;
+  }
 
   HttpRequest.internal() : super.internal();
 
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
   @DomName('XMLHttpRequest.abort')
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> abortEvent = const EventStreamProvider<ProgressEvent>('abort');
@@ -13331,9 +13763,28 @@
   @DocsEditable
   static const EventStreamProvider<ProgressEvent> readyStateChangeEvent = const EventStreamProvider<ProgressEvent>('readystatechange');
 
+  /**
+   * General constructor for any type of request (GET, POST, etc).
+   *
+   * This call is used in conjunction with [open]:
+   *
+   *     var request = new HttpRequest();
+   *     request.open('GET', 'http://dartlang.org')
+   *     request.on.load.add((event) => print('Request complete'));
+   *
+   * is the (more verbose) equivalent of
+   *
+   *     var request = new HttpRequest.get('http://dartlang.org',
+   *         (event) => print('Request complete'));
+   */
+  @DomName('XMLHttpRequest.XMLHttpRequest')
   @DocsEditable
-  factory HttpRequest() => HttpRequest._create();
-  static HttpRequest _create() native "XMLHttpRequest_constructor_Callback";
+  factory HttpRequest() {
+    return HttpRequest._create_1();
+  }
+
+  @DocsEditable
+  static HttpRequest _create_1() native "XMLHttpRequest__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -13351,50 +13802,150 @@
 
   static const int UNSENT = 0;
 
+  /**
+   * Indicator of the current state of the request:
+   *
+   * <table>
+   *   <tr>
+   *     <td>Value</td>
+   *     <td>State</td>
+   *     <td>Meaning</td>
+   *   </tr>
+   *   <tr>
+   *     <td>0</td>
+   *     <td>unsent</td>
+   *     <td><code>open()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>1</td>
+   *     <td>opened</td>
+   *     <td><code>send()</code> has not yet been called</td>
+   *   </tr>
+   *   <tr>
+   *     <td>2</td>
+   *     <td>headers received</td>
+   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>
+   *   </tr>
+   *   <tr>
+   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>
+   *   </tr>
+   *   <tr>
+   *     <td>4</td> <td>done</td> <td>request is complete</td>
+   *   </tr>
+   * </table>
+   */
   @DomName('XMLHttpRequest.readyState')
   @DocsEditable
   int get readyState native "XMLHttpRequest_readyState_Getter";
 
+  /**
+   * The data received as a reponse from the request.
+   *
+   * The data could be in the
+   * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+   * [String]). `null` indicates request failure.
+   */
   @DomName('XMLHttpRequest.response')
   @DocsEditable
   Object get response native "XMLHttpRequest_response_Getter";
 
+  /**
+   * The response in string form or `null on failure.
+   */
   @DomName('XMLHttpRequest.responseText')
   @DocsEditable
   String get responseText native "XMLHttpRequest_responseText_Getter";
 
+  /**
+   * [String] telling the server the desired response format.
+   *
+   * Default is `String`.
+   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+   * `responseType` is set while performing a synchronous request.
+   *
+   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable
   String get responseType native "XMLHttpRequest_responseType_Getter";
 
+  /**
+   * [String] telling the server the desired response format.
+   *
+   * Default is `String`.
+   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',
+   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if
+   * `responseType` is set while performing a synchronous request.
+   *
+   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)
+   */
   @DomName('XMLHttpRequest.responseType')
   @DocsEditable
   void set responseType(String value) native "XMLHttpRequest_responseType_Setter";
 
+  /**
+   * The request response, or null on failure.
+   *
+   * The response is processed as
+   * `text/xml` stream, unless responseType = 'document' and the request is
+   * synchronous.
+   */
   @DomName('XMLHttpRequest.responseXML')
   @DocsEditable
   Document get responseXml native "XMLHttpRequest_responseXML_Getter";
 
+  /**
+   * The http result code from the request (200, 404, etc).
+   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   */
   @DomName('XMLHttpRequest.status')
   @DocsEditable
   int get status native "XMLHttpRequest_status_Getter";
 
+  /**
+   * The request response string (such as \"200 OK\").
+   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+   */
   @DomName('XMLHttpRequest.statusText')
   @DocsEditable
   String get statusText native "XMLHttpRequest_statusText_Getter";
 
+  /**
+   * [EventTarget] that can hold listeners to track the progress of the request.
+   * The events fired will be members of [HttpRequestUploadEvents].
+   */
   @DomName('XMLHttpRequest.upload')
   @DocsEditable
   HttpRequestUpload get upload native "XMLHttpRequest_upload_Getter";
 
+  /**
+   * True if cross-site requests should use credentials such as cookies
+   * or authorization headers; false otherwise.
+   *
+   * This value is ignored for same-site requests.
+   */
   @DomName('XMLHttpRequest.withCredentials')
   @DocsEditable
   bool get withCredentials native "XMLHttpRequest_withCredentials_Getter";
 
+  /**
+   * True if cross-site requests should use credentials such as cookies
+   * or authorization headers; false otherwise.
+   *
+   * This value is ignored for same-site requests.
+   */
   @DomName('XMLHttpRequest.withCredentials')
   @DocsEditable
   void set withCredentials(bool value) native "XMLHttpRequest_withCredentials_Setter";
 
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
   @DomName('XMLHttpRequest.abort')
   @DocsEditable
   void abort() native "XMLHttpRequest_abort_Callback";
@@ -13407,18 +13958,51 @@
   @DocsEditable
   bool dispatchEvent(Event evt) native "XMLHttpRequest_dispatchEvent_Callback";
 
+  /**
+   * Retrieve all the response headers from a request.
+   *
+   * `null` if no headers have been received. For multipart requests,
+   * `getAllResponseHeaders` will return the response headers for the current
+   * part of the request.
+   *
+   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * for a list of common response headers.
+   */
   @DomName('XMLHttpRequest.getAllResponseHeaders')
   @DocsEditable
   String getAllResponseHeaders() native "XMLHttpRequest_getAllResponseHeaders_Callback";
 
+  /**
+   * Return the response header named `header`, or `null` if not found.
+   *
+   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)
+   * for a list of common response headers.
+   */
   @DomName('XMLHttpRequest.getResponseHeader')
   @DocsEditable
   String getResponseHeader(String header) native "XMLHttpRequest_getResponseHeader_Callback";
 
+  /**
+   * Specify the desired `url`, and `method` to use in making the request.
+   *
+   * By default the request is done asyncronously, with no user or password
+   * authentication information. If `async` is false, the request will be send
+   * synchronously.
+   *
+   * Calling `open` again on a currently active request is equivalent to
+   * calling `abort`.
+   */
   @DomName('XMLHttpRequest.open')
   @DocsEditable
   void open(String method, String url, [bool async, String user, String password]) native "XMLHttpRequest_open_Callback";
 
+  /**
+   * Specify a particular MIME type (such as `text/xml`) desired for the
+   * response.
+   *
+   * This value must be set before the request has been sent. See also the list
+   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)
+   */
   @DomName('XMLHttpRequest.overrideMimeType')
   @DocsEditable
   void overrideMimeType(String override) native "XMLHttpRequest_overrideMimeType_Callback";
@@ -13427,6 +14011,13 @@
   @DocsEditable
   void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "XMLHttpRequest_removeEventListener_Callback";
 
+  /**
+   * Send the request with any given `data`.
+   *
+   * See also:
+   * [send() docs](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send())
+   * from MDN.
+   */
   @DomName('XMLHttpRequest.send')
   @DocsEditable
   void send([data]) native "XMLHttpRequest_send_Callback";
@@ -13435,6 +14026,13 @@
   @DocsEditable
   void setRequestHeader(String header, String value) native "XMLHttpRequest_setRequestHeader_Callback";
 
+  /**
+   * Stop the current request.
+   *
+   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or
+   * `LOADING`. If this method is not in the process of being sent, the method
+   * has no effect.
+   */
   @DomName('XMLHttpRequest.abort')
   @DocsEditable
   Stream<ProgressEvent> get onAbort => abortEvent.forTarget(this);
@@ -13668,6 +14266,7 @@
 class IFrameElement extends _Element_Merged {
   IFrameElement.internal() : super.internal();
 
+  @DomName('HTMLIFrameElement.HTMLIFrameElement')
   @DocsEditable
   factory IFrameElement() => document.$dom_createElement("iframe");
 
@@ -13767,6 +14366,7 @@
 class ImageElement extends _Element_Merged {
   ImageElement.internal() : super.internal();
 
+  @DomName('HTMLImageElement.HTMLImageElement')
   @DocsEditable
   factory ImageElement({String src, int width, int height}) {
     var e = document.$dom_createElement("img");
@@ -14965,12 +15565,18 @@
 class Int16Array extends ArrayBufferView implements List<int> {
   Int16Array.internal() : super.internal();
 
+  @DomName('Int16Array.Int16Array')
+  @DocsEditable
   factory Int16Array(int length) =>
     _TypedArrayFactoryProvider.createInt16Array(length);
 
+  @DomName('Int16Array.fromList')
+  @DocsEditable
   factory Int16Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createInt16Array_fromList(list);
 
+  @DomName('Int16Array.fromBuffer')
+  @DocsEditable
   factory Int16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt16Array_fromBuffer(buffer, byteOffset, length);
 
@@ -15010,7 +15616,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -15024,13 +15634,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -15075,8 +15685,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -15189,12 +15800,18 @@
 class Int32Array extends ArrayBufferView implements List<int> {
   Int32Array.internal() : super.internal();
 
+  @DomName('Int32Array.Int32Array')
+  @DocsEditable
   factory Int32Array(int length) =>
     _TypedArrayFactoryProvider.createInt32Array(length);
 
+  @DomName('Int32Array.fromList')
+  @DocsEditable
   factory Int32Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createInt32Array_fromList(list);
 
+  @DomName('Int32Array.fromBuffer')
+  @DocsEditable
   factory Int32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt32Array_fromBuffer(buffer, byteOffset, length);
 
@@ -15234,7 +15851,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -15248,13 +15869,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -15299,8 +15920,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -15413,12 +16035,18 @@
 class Int8Array extends ArrayBufferView implements List<int> {
   Int8Array.internal() : super.internal();
 
+  @DomName('Int8Array.Int8Array')
+  @DocsEditable
   factory Int8Array(int length) =>
     _TypedArrayFactoryProvider.createInt8Array(length);
 
+  @DomName('Int8Array.fromList')
+  @DocsEditable
   factory Int8Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createInt8Array_fromList(list);
 
+  @DomName('Int8Array.fromBuffer')
+  @DocsEditable
   factory Int8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createInt8Array_fromBuffer(buffer, byteOffset, length);
 
@@ -15458,7 +16086,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -15472,13 +16104,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -15523,8 +16155,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -15769,6 +16402,7 @@
 class KeygenElement extends _Element_Merged {
   KeygenElement.internal() : super.internal();
 
+  @DomName('HTMLKeygenElement.HTMLKeygenElement')
   @DocsEditable
   factory KeygenElement() => document.$dom_createElement("keygen");
 
@@ -15860,6 +16494,7 @@
 class LIElement extends _Element_Merged {
   LIElement.internal() : super.internal();
 
+  @DomName('HTMLLIElement.HTMLLIElement')
   @DocsEditable
   factory LIElement() => document.$dom_createElement("li");
 
@@ -15892,6 +16527,7 @@
 class LabelElement extends _Element_Merged {
   LabelElement.internal() : super.internal();
 
+  @DomName('HTMLLabelElement.HTMLLabelElement')
   @DocsEditable
   factory LabelElement() => document.$dom_createElement("label");
 
@@ -15924,6 +16560,7 @@
 class LegendElement extends _Element_Merged {
   LegendElement.internal() : super.internal();
 
+  @DomName('HTMLLegendElement.HTMLLegendElement')
   @DocsEditable
   factory LegendElement() => document.$dom_createElement("legend");
 
@@ -15944,6 +16581,7 @@
 class LinkElement extends _Element_Merged {
   LinkElement.internal() : super.internal();
 
+  @DomName('HTMLLinkElement.HTMLLinkElement')
   @DocsEditable
   factory LinkElement() => document.$dom_createElement("link");
 
@@ -16138,6 +16776,7 @@
 class MapElement extends _Element_Merged {
   MapElement.internal() : super.internal();
 
+  @DomName('HTMLMapElement.HTMLMapElement')
   @DocsEditable
   factory MapElement() => document.$dom_createElement("map");
 
@@ -16166,9 +16805,14 @@
 class MediaController extends EventTarget {
   MediaController.internal() : super.internal();
 
+  @DomName('MediaController.MediaController')
   @DocsEditable
-  factory MediaController() => MediaController._create();
-  static MediaController _create() native "MediaController_constructor_Callback";
+  factory MediaController() {
+    return MediaController._create_1();
+  }
+
+  @DocsEditable
+  static MediaController _create_1() native "MediaController__create_1constructorCallback";
 
   @DomName('MediaController.buffered')
   @DocsEditable
@@ -17034,9 +17678,14 @@
 class MediaSource extends EventTarget {
   MediaSource.internal() : super.internal();
 
+  @DomName('MediaSource.MediaSource')
   @DocsEditable
-  factory MediaSource() => MediaSource._create();
-  static MediaSource _create() native "MediaSource_constructor_Callback";
+  factory MediaSource() {
+    return MediaSource._create_1();
+  }
+
+  @DocsEditable
+  static MediaSource _create_1() native "MediaSource__create_1constructorCallback";
 
   @DomName('MediaSource.activeSourceBuffers')
   @DocsEditable
@@ -17097,9 +17746,29 @@
   @DocsEditable
   static const EventStreamProvider<Event> endedEvent = const EventStreamProvider<Event>('ended');
 
+  @DomName('MediaStream.MediaStream')
   @DocsEditable
-  factory MediaStream() => MediaStream._create();
-  static MediaStream _create() native "MediaStream_constructor_Callback";
+  factory MediaStream([stream_OR_tracks]) {
+    if (!?stream_OR_tracks) {
+      return MediaStream._create_1();
+    }
+    if ((stream_OR_tracks is MediaStream || stream_OR_tracks == null)) {
+      return MediaStream._create_2(stream_OR_tracks);
+    }
+    if ((stream_OR_tracks is List<MediaStreamTrack> || stream_OR_tracks == null)) {
+      return MediaStream._create_3(stream_OR_tracks);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @DocsEditable
+  static MediaStream _create_1() native "MediaStream__create_1constructorCallback";
+
+  @DocsEditable
+  static MediaStream _create_2(stream_OR_tracks) native "MediaStream__create_2constructorCallback";
+
+  @DocsEditable
+  static MediaStream _create_3(stream_OR_tracks) native "MediaStream__create_3constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -17231,12 +17900,6 @@
   MediaStreamTrackEvents get on =>
     new MediaStreamTrackEvents(this);
 
-  static const int ENDED = 2;
-
-  static const int LIVE = 0;
-
-  static const int MUTED = 1;
-
   @DomName('MediaStreamTrack.enabled')
   @DocsEditable
   bool get enabled native "MediaStreamTrack_enabled_Getter";
@@ -17259,7 +17922,7 @@
 
   @DomName('MediaStreamTrack.readyState')
   @DocsEditable
-  int get readyState native "MediaStreamTrack_readyState_Getter";
+  String get readyState native "MediaStreamTrack_readyState_Getter";
 
   @DomName('MediaStreamTrack.addEventListener')
   @DocsEditable
@@ -17359,6 +18022,7 @@
 class MenuElement extends _Element_Merged {
   MenuElement.internal() : super.internal();
 
+  @DomName('HTMLMenuElement.HTMLMenuElement')
   @DocsEditable
   factory MenuElement() => document.$dom_createElement("menu");
 
@@ -17375,9 +18039,14 @@
 class MessageChannel extends NativeFieldWrapperClass1 {
   MessageChannel.internal();
 
+  @DomName('MessageChannel.MessageChannel')
   @DocsEditable
-  factory MessageChannel() => MessageChannel._create();
-  static MessageChannel _create() native "MessageChannel_constructor_Callback";
+  factory MessageChannel() {
+    return MessageChannel._create_1();
+  }
+
+  @DocsEditable
+  static MessageChannel _create_1() native "MessageChannel__create_1constructorCallback";
 
   @DomName('MessageChannel.port1')
   @DocsEditable
@@ -17578,6 +18247,7 @@
 class MeterElement extends _Element_Merged {
   MeterElement.internal() : super.internal();
 
+  @DomName('HTMLMeterElement.HTMLMeterElement')
   @DocsEditable
   factory MeterElement() => document.$dom_createElement("meter");
 
@@ -17714,7 +18384,7 @@
 
   @DomName('MouseEvent.dataTransfer')
   @DocsEditable
-  Clipboard get dataTransfer native "MouseEvent_dataTransfer_Getter";
+  DataTransfer get dataTransfer native "MouseEvent_dataTransfer_Getter";
 
   @DomName('MouseEvent.fromElement')
   @DocsEditable
@@ -17845,10 +18515,10 @@
 @Experimental
 class MutationObserver extends NativeFieldWrapperClass1 {
   MutationObserver.internal();
+  factory MutationObserver(MutationCallback callback) => _create(callback);
 
   @DocsEditable
-  factory MutationObserver(MutationCallback callback) => MutationObserver._create(callback);
-  static MutationObserver _create(MutationCallback callback) native "MutationObserver_constructor_Callback";
+  static MutationObserver _create(callback) native "MutationObserver_constructorCallback";
 
   @DomName('MutationObserver.disconnect')
   @DocsEditable
@@ -18025,7 +18695,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -18039,13 +18713,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -18090,8 +18764,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -18487,6 +19162,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Node element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Node element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -18506,7 +19185,7 @@
 
   // From List<Node>:
 
-  List<Node> take(int n) {
+  Iterable<Node> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -18514,7 +19193,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) {
+  Iterable<Node> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -18538,8 +19217,9 @@
     return this[index];
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   // TODO(jacobr): this could be implemented for child node lists.
   // The exception we throw here is misleading.
@@ -18871,7 +19551,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Node element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Node element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Node element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Node> where(bool f(Node element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -18885,13 +19569,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Node> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Node> takeWhile(bool test(Node value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Node> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Node> skipWhile(bool test(Node value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -18936,8 +19620,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Node a, Node b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -19076,14 +19761,14 @@
   @DocsEditable
   static const EventStreamProvider<Event> showEvent = const EventStreamProvider<Event>('show');
 
+  @DomName('Notification.Notification')
   @DocsEditable
   factory Notification(String title, [Map options]) {
-    if (!?options) {
-      return Notification._create(title);
-    }
-    return Notification._create(title, options);
+    return Notification._create_1(title, options);
   }
-  static Notification _create(String title, [Map options]) native "Notification_constructor_Callback";
+
+  @DocsEditable
+  static Notification _create_1(title, options) native "Notification__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -19245,6 +19930,7 @@
 class OListElement extends _Element_Merged {
   OListElement.internal() : super.internal();
 
+  @DomName('HTMLOListElement.HTMLOListElement')
   @DocsEditable
   factory OListElement() => document.$dom_createElement("ol");
 
@@ -19288,6 +19974,7 @@
 class ObjectElement extends _Element_Merged {
   ObjectElement.internal() : super.internal();
 
+  @DomName('HTMLObjectElement.HTMLObjectElement')
   @DocsEditable
   factory ObjectElement() => document.$dom_createElement("object");
 
@@ -19459,6 +20146,7 @@
 class OptGroupElement extends _Element_Merged {
   OptGroupElement.internal() : super.internal();
 
+  @DomName('HTMLOptGroupElement.HTMLOptGroupElement')
   @DocsEditable
   factory OptGroupElement() => document.$dom_createElement("optgroup");
 
@@ -19491,23 +20179,14 @@
 class OptionElement extends _Element_Merged {
   OptionElement.internal() : super.internal();
 
+  @DomName('HTMLOptionElement.HTMLOptionElement')
   @DocsEditable
   factory OptionElement([String data, String value, bool defaultSelected, bool selected]) {
-    if (!?data) {
-      return OptionElement._create();
-    }
-    if (!?value) {
-      return OptionElement._create(data);
-    }
-    if (!?defaultSelected) {
-      return OptionElement._create(data, value);
-    }
-    if (!?selected) {
-      return OptionElement._create(data, value, defaultSelected);
-    }
-    return OptionElement._create(data, value, defaultSelected, selected);
+    return OptionElement._create_1(data, value, defaultSelected, selected);
   }
-  static OptionElement _create([String data, String value, bool defaultSelected, bool selected]) native "HTMLOptionElement_constructor_Callback";
+
+  @DocsEditable
+  static OptionElement _create_1(data, value, defaultSelected, selected) native "HTMLOptionElement__create_1constructorCallback";
 
   @DomName('HTMLOptionElement.defaultSelected')
   @DocsEditable
@@ -19573,6 +20252,7 @@
 class OutputElement extends _Element_Merged {
   OutputElement.internal() : super.internal();
 
+  @DomName('HTMLOutputElement.HTMLOutputElement')
   @DocsEditable
   factory OutputElement() => document.$dom_createElement("output");
 
@@ -19733,6 +20413,7 @@
 class ParagraphElement extends _Element_Merged {
   ParagraphElement.internal() : super.internal();
 
+  @DomName('HTMLParagraphElement.HTMLParagraphElement')
   @DocsEditable
   factory ParagraphElement() => document.$dom_createElement("p");
 
@@ -19749,6 +20430,7 @@
 class ParamElement extends _Element_Merged {
   ParamElement.internal() : super.internal();
 
+  @DomName('HTMLParamElement.HTMLParamElement')
   @DocsEditable
   factory ParamElement() => document.$dom_createElement("param");
 
@@ -19938,39 +20620,6 @@
 
 
 @DocsEditable
-@DomName('WebKitPoint')
-class Point extends NativeFieldWrapperClass1 {
-  Point.internal();
-
-  @DocsEditable
-  factory Point(num x, num y) => Point._create(x, y);
-  static Point _create(num x, num y) native "WebKitPoint_constructor_Callback";
-
-  @DomName('WebKitPoint.x')
-  @DocsEditable
-  num get x native "WebKitPoint_x_Getter";
-
-  @DomName('WebKitPoint.x')
-  @DocsEditable
-  void set x(num value) native "WebKitPoint_x_Setter";
-
-  @DomName('WebKitPoint.y')
-  @DocsEditable
-  num get y native "WebKitPoint_y_Getter";
-
-  @DomName('WebKitPoint.y')
-  @DocsEditable
-  void set y(num value) native "WebKitPoint_y_Setter";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('PopStateEvent')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -20039,6 +20688,7 @@
 class PreElement extends _Element_Merged {
   PreElement.internal() : super.internal();
 
+  @DomName('HTMLPreElement.HTMLPreElement')
   @DocsEditable
   factory PreElement() => document.$dom_createElement("pre");
 
@@ -20096,6 +20746,7 @@
 class ProgressElement extends _Element_Merged {
   ProgressElement.internal() : super.internal();
 
+  @DomName('HTMLProgressElement.HTMLProgressElement')
   @DocsEditable
   factory ProgressElement() => document.$dom_createElement("progress");
 
@@ -20642,9 +21293,14 @@
 class RtcIceCandidate extends NativeFieldWrapperClass1 {
   RtcIceCandidate.internal();
 
+  @DomName('RTCIceCandidate.RTCIceCandidate')
   @DocsEditable
-  factory RtcIceCandidate(Map dictionary) => RtcIceCandidate._create(dictionary);
-  static RtcIceCandidate _create(Map dictionary) native "RTCIceCandidate_constructor_Callback";
+  factory RtcIceCandidate(Map dictionary) {
+    return RtcIceCandidate._create_1(dictionary);
+  }
+
+  @DocsEditable
+  static RtcIceCandidate _create_1(dictionary) native "RTCIceCandidate__create_1constructorCallback";
 
   @DomName('RTCIceCandidate.candidate')
   @DocsEditable
@@ -20708,10 +21364,6 @@
   @DocsEditable
   static const EventStreamProvider<Event> negotiationNeededEvent = const EventStreamProvider<Event>('negotiationneeded');
 
-  @DomName('RTCPeerConnection.open')
-  @DocsEditable
-  static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
-
   @DomName('RTCPeerConnection.removestream')
   @DocsEditable
   static const EventStreamProvider<MediaStreamEvent> removeStreamEvent = const EventStreamProvider<MediaStreamEvent>('removestream');
@@ -20720,14 +21372,14 @@
   @DocsEditable
   static const EventStreamProvider<Event> stateChangeEvent = const EventStreamProvider<Event>('statechange');
 
+  @DomName('RTCPeerConnection.RTCPeerConnection')
   @DocsEditable
   factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
-    if (!?mediaConstraints) {
-      return RtcPeerConnection._create(rtcIceServers);
-    }
-    return RtcPeerConnection._create(rtcIceServers, mediaConstraints);
+    return RtcPeerConnection._create_1(rtcIceServers, mediaConstraints);
   }
-  static RtcPeerConnection _create(Map rtcIceServers, [Map mediaConstraints]) native "RTCPeerConnection_constructor_Callback";
+
+  @DocsEditable
+  static RtcPeerConnection _create_1(rtcIceServers, mediaConstraints) native "RTCPeerConnection__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -20735,14 +21387,14 @@
   RtcPeerConnectionEvents get on =>
     new RtcPeerConnectionEvents(this);
 
+  @DomName('RTCPeerConnection.iceConnectionState')
+  @DocsEditable
+  String get iceConnectionState native "RTCPeerConnection_iceConnectionState_Getter";
+
   @DomName('RTCPeerConnection.iceGatheringState')
   @DocsEditable
   String get iceGatheringState native "RTCPeerConnection_iceGatheringState_Getter";
 
-  @DomName('RTCPeerConnection.iceState')
-  @DocsEditable
-  String get iceState native "RTCPeerConnection_iceState_Getter";
-
   @DomName('RTCPeerConnection.localDescription')
   @DocsEditable
   RtcSessionDescription get localDescription native "RTCPeerConnection_localDescription_Getter";
@@ -20763,6 +21415,10 @@
   @DocsEditable
   List<MediaStream> get remoteStreams native "RTCPeerConnection_remoteStreams_Getter";
 
+  @DomName('RTCPeerConnection.signalingState')
+  @DocsEditable
+  String get signalingState native "RTCPeerConnection_signalingState_Getter";
+
   @DomName('RTCPeerConnection.addEventListener')
   @DocsEditable
   void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "RTCPeerConnection_addEventListener_Callback";
@@ -20839,10 +21495,6 @@
   @DocsEditable
   Stream<Event> get onNegotiationNeeded => negotiationNeededEvent.forTarget(this);
 
-  @DomName('RTCPeerConnection.open')
-  @DocsEditable
-  Stream<Event> get onOpen => openEvent.forTarget(this);
-
   @DomName('RTCPeerConnection.removestream')
   @DocsEditable
   Stream<MediaStreamEvent> get onRemoveStream => removeStreamEvent.forTarget(this);
@@ -20872,9 +21524,6 @@
   EventListenerList get negotiationNeeded => this['negotiationneeded'];
 
   @DocsEditable
-  EventListenerList get open => this['open'];
-
-  @DocsEditable
   EventListenerList get removeStream => this['removestream'];
 
   @DocsEditable
@@ -20892,9 +21541,14 @@
 class RtcSessionDescription extends NativeFieldWrapperClass1 {
   RtcSessionDescription.internal();
 
+  @DomName('RTCSessionDescription.RTCSessionDescription')
   @DocsEditable
-  factory RtcSessionDescription(Map dictionary) => RtcSessionDescription._create(dictionary);
-  static RtcSessionDescription _create(Map dictionary) native "RTCSessionDescription_constructor_Callback";
+  factory RtcSessionDescription(Map dictionary) {
+    return RtcSessionDescription._create_1(dictionary);
+  }
+
+  @DocsEditable
+  static RtcSessionDescription _create_1(dictionary) native "RTCSessionDescription__create_1constructorCallback";
 
   @DomName('RTCSessionDescription.sdp')
   @DocsEditable
@@ -21073,6 +21727,7 @@
 class ScriptElement extends _Element_Merged {
   ScriptElement.internal() : super.internal();
 
+  @DomName('HTMLScriptElement.HTMLScriptElement')
   @DocsEditable
   factory ScriptElement() => document.$dom_createElement("script");
 
@@ -21228,6 +21883,7 @@
 class SelectElement extends _Element_Merged {
   SelectElement.internal() : super.internal();
 
+  @DomName('HTMLSelectElement.HTMLSelectElement')
   @DocsEditable
   factory SelectElement() => document.$dom_createElement("select");
 
@@ -21472,14 +22128,14 @@
 class SharedWorker extends AbstractWorker {
   SharedWorker.internal() : super.internal();
 
+  @DomName('SharedWorker.SharedWorker')
   @DocsEditable
   factory SharedWorker(String scriptURL, [String name]) {
-    if (!?name) {
-      return SharedWorker._create(scriptURL);
-    }
-    return SharedWorker._create(scriptURL, name);
+    return SharedWorker._create_1(scriptURL, name);
   }
-  static SharedWorker _create(String scriptURL, [String name]) native "SharedWorker_constructor_Callback";
+
+  @DocsEditable
+  static SharedWorker _create_1(scriptURL, name) native "SharedWorker__create_1constructorCallback";
 
   @DomName('SharedWorker.port')
   @DocsEditable
@@ -21604,7 +22260,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SourceBuffer element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SourceBuffer element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SourceBuffer element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SourceBuffer> where(bool f(SourceBuffer element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -21618,13 +22278,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SourceBuffer> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SourceBuffer> takeWhile(bool test(SourceBuffer value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SourceBuffer> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SourceBuffer> skipWhile(bool test(SourceBuffer value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -21669,8 +22329,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SourceBuffer> get reversed =>
-      new ReversedListView<SourceBuffer>(this, 0, null);
+  List<SourceBuffer> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SourceBuffer a, SourceBuffer b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -21780,6 +22441,7 @@
 class SourceElement extends _Element_Merged {
   SourceElement.internal() : super.internal();
 
+  @DomName('HTMLSourceElement.HTMLSourceElement')
   @DocsEditable
   factory SourceElement() => document.$dom_createElement("source");
 
@@ -21820,6 +22482,7 @@
 class SpanElement extends _Element_Merged {
   SpanElement.internal() : super.internal();
 
+  @DomName('HTMLSpanElement.HTMLSpanElement')
   @DocsEditable
   factory SpanElement() => document.$dom_createElement("span");
 
@@ -21836,9 +22499,14 @@
 class SpeechGrammar extends NativeFieldWrapperClass1 {
   SpeechGrammar.internal();
 
+  @DomName('SpeechGrammar.SpeechGrammar')
   @DocsEditable
-  factory SpeechGrammar() => SpeechGrammar._create();
-  static SpeechGrammar _create() native "SpeechGrammar_constructor_Callback";
+  factory SpeechGrammar() {
+    return SpeechGrammar._create_1();
+  }
+
+  @DocsEditable
+  static SpeechGrammar _create_1() native "SpeechGrammar__create_1constructorCallback";
 
   @DomName('SpeechGrammar.src')
   @DocsEditable
@@ -21869,9 +22537,14 @@
 class SpeechGrammarList extends NativeFieldWrapperClass1 implements List<SpeechGrammar> {
   SpeechGrammarList.internal();
 
+  @DomName('SpeechGrammarList.SpeechGrammarList')
   @DocsEditable
-  factory SpeechGrammarList() => SpeechGrammarList._create();
-  static SpeechGrammarList _create() native "SpeechGrammarList_constructor_Callback";
+  factory SpeechGrammarList() {
+    return SpeechGrammarList._create_1();
+  }
+
+  @DocsEditable
+  static SpeechGrammarList _create_1() native "SpeechGrammarList__create_1constructorCallback";
 
   @DomName('SpeechGrammarList.length')
   @DocsEditable
@@ -21905,7 +22578,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SpeechGrammar element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SpeechGrammar element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SpeechGrammar element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SpeechGrammar> where(bool f(SpeechGrammar element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -21919,13 +22596,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SpeechGrammar> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SpeechGrammar> takeWhile(bool test(SpeechGrammar value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SpeechGrammar> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SpeechGrammar> skipWhile(bool test(SpeechGrammar value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -21970,8 +22647,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechGrammar> get reversed =>
-      new ReversedListView<SpeechGrammar>(this, 0, null);
+  List<SpeechGrammar> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SpeechGrammar a, SpeechGrammar b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -22187,9 +22865,14 @@
   @DocsEditable
   static const EventStreamProvider<Event> startEvent = const EventStreamProvider<Event>('start');
 
+  @DomName('SpeechRecognition.SpeechRecognition')
   @DocsEditable
-  factory SpeechRecognition() => SpeechRecognition._create();
-  static SpeechRecognition _create() native "SpeechRecognition_constructor_Callback";
+  factory SpeechRecognition() {
+    return SpeechRecognition._create_1();
+  }
+
+  @DocsEditable
+  static SpeechRecognition _create_1() native "SpeechRecognition__create_1constructorCallback";
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -22596,7 +23279,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Map element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Map element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Map element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Map> where(bool f(Map element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -22610,13 +23297,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Map> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Map> takeWhile(bool test(Map value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Map> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Map> skipWhile(bool test(Map value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -22661,8 +23348,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Map> get reversed =>
-      new ReversedListView<Map>(this, 0, null);
+  List<Map> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Map a, Map b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -22757,6 +23445,9 @@
 
 @DocsEditable
 @DomName('SQLTransaction')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class SqlTransaction extends NativeFieldWrapperClass1 {
   SqlTransaction.internal();
 
@@ -22774,6 +23465,9 @@
 
 @DocsEditable
 @DomName('SQLTransactionSync')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.SAFARI)
+@Experimental
 class SqlTransactionSync extends NativeFieldWrapperClass1 {
   SqlTransactionSync.internal();
 
@@ -22978,6 +23672,7 @@
 class StyleElement extends _Element_Merged {
   StyleElement.internal() : super.internal();
 
+  @DomName('HTMLStyleElement.HTMLStyleElement')
   @DocsEditable
   factory StyleElement() => document.$dom_createElement("style");
 
@@ -23096,6 +23791,7 @@
 class TableCaptionElement extends _Element_Merged {
   TableCaptionElement.internal() : super.internal();
 
+  @DomName('HTMLTableCaptionElement.HTMLTableCaptionElement')
   @DocsEditable
   factory TableCaptionElement() => document.$dom_createElement("caption");
 
@@ -23112,6 +23808,7 @@
 class TableCellElement extends _Element_Merged {
   TableCellElement.internal() : super.internal();
 
+  @DomName('HTMLTableCellElement.HTMLTableCellElement')
   @DocsEditable
   factory TableCellElement() => document.$dom_createElement("td");
 
@@ -23156,6 +23853,7 @@
 class TableColElement extends _Element_Merged {
   TableColElement.internal() : super.internal();
 
+  @DomName('HTMLTableColElement.HTMLTableColElement')
   @DocsEditable
   factory TableColElement() => document.$dom_createElement("col");
 
@@ -23180,6 +23878,7 @@
 class TableElement extends _Element_Merged {
   TableElement.internal() : super.internal();
 
+  @DomName('HTMLTableElement.HTMLTableElement')
   @DocsEditable
   factory TableElement() => document.$dom_createElement("table");
 
@@ -23272,6 +23971,7 @@
 class TableRowElement extends _Element_Merged {
   TableRowElement.internal() : super.internal();
 
+  @DomName('HTMLTableRowElement.HTMLTableRowElement')
   @DocsEditable
   factory TableRowElement() => document.$dom_createElement("tr");
 
@@ -23358,6 +24058,7 @@
 class TextAreaElement extends _Element_Merged {
   TextAreaElement.internal() : super.internal();
 
+  @DomName('HTMLTextAreaElement.HTMLTextAreaElement')
   @DocsEditable
   factory TextAreaElement() => document.$dom_createElement("textarea");
 
@@ -23718,9 +24419,14 @@
   @DocsEditable
   static const EventStreamProvider<Event> exitEvent = const EventStreamProvider<Event>('exit');
 
+  @DomName('TextTrackCue.TextTrackCue')
   @DocsEditable
-  factory TextTrackCue(num startTime, num endTime, String text) => TextTrackCue._create(startTime, endTime, text);
-  static TextTrackCue _create(num startTime, num endTime, String text) native "TextTrackCue_constructor_Callback";
+  factory TextTrackCue(num startTime, num endTime, String text) {
+    return TextTrackCue._create_1(startTime, endTime, text);
+  }
+
+  @DocsEditable
+  static TextTrackCue _create_1(startTime, endTime, text) native "TextTrackCue__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -23902,7 +24608,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(TextTrackCue element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(TextTrackCue element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(TextTrackCue element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<TextTrackCue> where(bool f(TextTrackCue element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -23916,13 +24626,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<TextTrackCue> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<TextTrackCue> takeWhile(bool test(TextTrackCue value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<TextTrackCue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<TextTrackCue> skipWhile(bool test(TextTrackCue value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -23967,8 +24677,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrackCue> get reversed =>
-      new ReversedListView<TextTrackCue>(this, 0, null);
+  List<TextTrackCue> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(TextTrackCue a, TextTrackCue b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -24112,7 +24823,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(TextTrack element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(TextTrack element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(TextTrack element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<TextTrack> where(bool f(TextTrack element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -24126,13 +24841,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<TextTrack> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<TextTrack> takeWhile(bool test(TextTrack value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<TextTrack> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<TextTrack> skipWhile(bool test(TextTrack value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -24177,8 +24892,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<TextTrack> get reversed =>
-      new ReversedListView<TextTrack>(this, 0, null);
+  List<TextTrack> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(TextTrack a, TextTrack b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -24335,6 +25051,7 @@
 class TitleElement extends _Element_Merged {
   TitleElement.internal() : super.internal();
 
+  @DomName('HTMLTitleElement.HTMLTitleElement')
   @DocsEditable
   factory TitleElement() => document.$dom_createElement("title");
 
@@ -24456,6 +25173,19 @@
   @DocsEditable
   void $dom_initTouchEvent(TouchList touches, TouchList targetTouches, TouchList changedTouches, String type, Window view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey) native "TouchEvent_initTouchEvent_Callback";
 
+
+  /**
+   * Checks if touch events supported on the current platform.
+   *
+   * Note that touch events are only supported if the user is using a touch
+   * device.
+   */
+  static bool get supported {
+    // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
+    // Basically, this is a fairly common check and it'd be great if it did not
+    // throw exceptions.
+    return Event._isTypeSupported('TouchEvent');
+  }
 }
 // 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
@@ -24501,7 +25231,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Touch element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Touch element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Touch element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Touch> where(bool f(Touch element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -24515,13 +25249,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Touch> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Touch> takeWhile(bool test(Touch value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Touch> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Touch> skipWhile(bool test(Touch value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -24566,8 +25300,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Touch> get reversed =>
-      new ReversedListView<Touch>(this, 0, null);
+  List<Touch> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Touch a, Touch b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -24668,6 +25403,7 @@
 class TrackElement extends _Element_Merged {
   TrackElement.internal() : super.internal();
 
+  @DomName('HTMLTrackElement.HTMLTrackElement')
   @DocsEditable
   factory TrackElement() => document.$dom_createElement("track");
 
@@ -24914,6 +25650,7 @@
 class UListElement extends _Element_Merged {
   UListElement.internal() : super.internal();
 
+  @DomName('HTMLUListElement.HTMLUListElement')
   @DocsEditable
   factory UListElement() => document.$dom_createElement("ul");
 
@@ -24930,12 +25667,18 @@
 class Uint16Array extends ArrayBufferView implements List<int> {
   Uint16Array.internal() : super.internal();
 
+  @DomName('Uint16Array.Uint16Array')
+  @DocsEditable
   factory Uint16Array(int length) =>
     _TypedArrayFactoryProvider.createUint16Array(length);
 
+  @DomName('Uint16Array.fromList')
+  @DocsEditable
   factory Uint16Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint16Array_fromList(list);
 
+  @DomName('Uint16Array.fromBuffer')
+  @DocsEditable
   factory Uint16Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint16Array_fromBuffer(buffer, byteOffset, length);
 
@@ -24975,7 +25718,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -24989,13 +25736,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -25040,8 +25787,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -25154,12 +25902,18 @@
 class Uint32Array extends ArrayBufferView implements List<int> {
   Uint32Array.internal() : super.internal();
 
+  @DomName('Uint32Array.Uint32Array')
+  @DocsEditable
   factory Uint32Array(int length) =>
     _TypedArrayFactoryProvider.createUint32Array(length);
 
+  @DomName('Uint32Array.fromList')
+  @DocsEditable
   factory Uint32Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint32Array_fromList(list);
 
+  @DomName('Uint32Array.fromBuffer')
+  @DocsEditable
   factory Uint32Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint32Array_fromBuffer(buffer, byteOffset, length);
 
@@ -25199,7 +25953,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -25213,13 +25971,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -25264,8 +26022,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -25378,12 +26137,18 @@
 class Uint8Array extends ArrayBufferView implements List<int> {
   Uint8Array.internal() : super.internal();
 
+  @DomName('Uint8Array.Uint8Array')
+  @DocsEditable
   factory Uint8Array(int length) =>
     _TypedArrayFactoryProvider.createUint8Array(length);
 
+  @DomName('Uint8Array.fromList')
+  @DocsEditable
   factory Uint8Array.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint8Array_fromList(list);
 
+  @DomName('Uint8Array.fromBuffer')
+  @DocsEditable
   factory Uint8Array.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint8Array_fromBuffer(buffer, byteOffset, length);
 
@@ -25423,7 +26188,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -25437,13 +26206,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -25488,8 +26257,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -25602,12 +26372,18 @@
 class Uint8ClampedArray extends Uint8Array implements List<int> {
   Uint8ClampedArray.internal() : super.internal();
 
+  @DomName('Uint8ClampedArray.Uint8ClampedArray')
+  @DocsEditable
   factory Uint8ClampedArray(int length) =>
     _TypedArrayFactoryProvider.createUint8ClampedArray(length);
 
+  @DomName('Uint8ClampedArray.fromList')
+  @DocsEditable
   factory Uint8ClampedArray.fromList(List<int> list) =>
     _TypedArrayFactoryProvider.createUint8ClampedArray_fromList(list);
 
+  @DomName('Uint8ClampedArray.fromBuffer')
+  @DocsEditable
   factory Uint8ClampedArray.fromBuffer(ArrayBuffer buffer, [int byteOffset, int length]) => 
     _TypedArrayFactoryProvider.createUint8ClampedArray_fromBuffer(buffer, byteOffset, length);
 
@@ -25645,7 +26421,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(int element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(int element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(int element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<int> where(bool f(int element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -25659,13 +26439,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<int> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<int> takeWhile(bool test(int value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<int> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<int> skipWhile(bool test(int value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -25710,8 +26490,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<int> get reversed =>
-      new ReversedListView<int>(this, 0, null);
+  List<int> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(int a, int b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -25932,6 +26713,7 @@
 class VideoElement extends MediaElement {
   VideoElement.internal() : super.internal();
 
+  @DomName('HTMLVideoElement.HTMLVideoElement')
   @DocsEditable
   factory VideoElement() => document.$dom_createElement("video");
 
@@ -26263,9 +27045,15 @@
 
 @DocsEditable
 @DomName('WebGLRenderingContext')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@Experimental
 class WebGLRenderingContext extends CanvasRenderingContext {
   WebGLRenderingContext.internal() : super.internal();
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   static const int ACTIVE_ATTRIBUTES = 0x8B89;
 
   static const int ACTIVE_TEXTURE = 0x84E0;
@@ -27745,9 +28533,29 @@
   @DocsEditable
   static const EventStreamProvider<Event> openEvent = const EventStreamProvider<Event>('open');
 
+  @DomName('WebSocket.WebSocket')
   @DocsEditable
-  factory WebSocket(String url) => WebSocket._create(url);
-  static WebSocket _create(String url) native "WebSocket_constructor_Callback";
+  factory WebSocket(String url, [protocol_OR_protocols]) {
+    if ((url is String || url == null) && !?protocol_OR_protocols) {
+      return WebSocket._create_1(url);
+    }
+    if ((url is String || url == null) && (protocol_OR_protocols is List<String> || protocol_OR_protocols == null)) {
+      return WebSocket._create_2(url, protocol_OR_protocols);
+    }
+    if ((url is String || url == null) && (protocol_OR_protocols is String || protocol_OR_protocols == null)) {
+      return WebSocket._create_3(url, protocol_OR_protocols);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @DocsEditable
+  static WebSocket _create_1(url) native "WebSocket__create_1constructorCallback";
+
+  @DocsEditable
+  static WebSocket _create_2(url, protocol_OR_protocols) native "WebSocket__create_2constructorCallback";
+
+  @DocsEditable
+  static WebSocket _create_3(url, protocol_OR_protocols) native "WebSocket__create_3constructorCallback";
 
   /// Checks if this type is supported on the current platform.
   static bool get supported => true;
@@ -27946,12 +28754,13 @@
 class Window extends EventTarget implements WindowBase {
 
   /**
-   * Executes a [callback] after the next batch of browser layout measurements
-   * has completed or would have completed if any browser layout measurements
-   * had been scheduled.
+   * Executes a [callback] after the immediate execution stack has completed.
+   *
+   * This will cause the callback to be executed after all processing has
+   * completed for the current event, but before any subsequent events.
    */
-  void requestLayoutFrame(TimeoutHandler callback) {
-    _addMeasurementFrameCallback(callback);
+  void setImmediate(TimeoutHandler callback) {
+    _addMicrotaskCallback(callback);
   }
 
   /**
@@ -27973,6 +28782,14 @@
     document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
   }
 
+  /// Checks if _setImmediate is supported.
+  static bool get _supportsSetImmediate => false;
+
+  /// Dartium stub for IE's setImmediate.
+  void _setImmediate(void callback()) {
+    throw new UnsupportedError('setImmediate is not supported');
+  }
+
   Window.internal() : super.internal();
 
   @DomName('DOMWindow.DOMContentLoaded')
@@ -28349,6 +29166,9 @@
 
   @DomName('DOMWindow.openDatabase')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
   Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "DOMWindow_openDatabase_Callback";
 
   @DomName('DOMWindow.postMessage')
@@ -28413,11 +29233,11 @@
 
   @DomName('DOMWindow.webkitConvertPointFromNodeToPage')
   @DocsEditable
-  Point webkitConvertPointFromNodeToPage(Node node, Point p) native "DOMWindow_webkitConvertPointFromNodeToPage_Callback";
+  DomPoint convertPointFromNodeToPage(Node node, DomPoint p) native "DOMWindow_webkitConvertPointFromNodeToPage_Callback";
 
   @DomName('DOMWindow.webkitConvertPointFromPageToNode')
   @DocsEditable
-  Point webkitConvertPointFromPageToNode(Node node, Point p) native "DOMWindow_webkitConvertPointFromPageToNode_Callback";
+  DomPoint convertPointFromPageToNode(Node node, DomPoint p) native "DOMWindow_webkitConvertPointFromPageToNode_Callback";
 
   @DomName('DOMWindow.webkitRequestAnimationFrame')
   @DocsEditable
@@ -28897,9 +29717,14 @@
   @DocsEditable
   static const EventStreamProvider<MessageEvent> messageEvent = const EventStreamProvider<MessageEvent>('message');
 
+  @DomName('Worker.Worker')
   @DocsEditable
-  factory Worker(String scriptUrl) => Worker._create(scriptUrl);
-  static Worker _create(String scriptUrl) native "Worker_constructor_Callback";
+  factory Worker(String scriptUrl) {
+    return Worker._create_1(scriptUrl);
+  }
+
+  @DocsEditable
+  static Worker _create_1(scriptUrl) native "Worker__create_1constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -29006,10 +29831,16 @@
 
   @DomName('WorkerContext.openDatabase')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
   Database openDatabase(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "WorkerContext_openDatabase_Callback";
 
   @DomName('WorkerContext.openDatabaseSync')
   @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
   DatabaseSync openDatabaseSync(String name, String version, String displayName, int estimatedSize, [DatabaseCallback creationCallback]) native "WorkerContext_openDatabaseSync_Callback";
 
   @DomName('WorkerContext.removeEventListener')
@@ -29157,9 +29988,14 @@
 class XPathEvaluator extends NativeFieldWrapperClass1 {
   XPathEvaluator.internal();
 
+  @DomName('XPathEvaluator.XPathEvaluator')
   @DocsEditable
-  factory XPathEvaluator() => XPathEvaluator._create();
-  static XPathEvaluator _create() native "XPathEvaluator_constructor_Callback";
+  factory XPathEvaluator() {
+    return XPathEvaluator._create_1();
+  }
+
+  @DocsEditable
+  static XPathEvaluator _create_1() native "XPathEvaluator__create_1constructorCallback";
 
   @DomName('XPathEvaluator.createExpression')
   @DocsEditable
@@ -29322,9 +30158,14 @@
 class XmlSerializer extends NativeFieldWrapperClass1 {
   XmlSerializer.internal();
 
+  @DomName('XMLSerializer.XMLSerializer')
   @DocsEditable
-  factory XmlSerializer() => XmlSerializer._create();
-  static XmlSerializer _create() native "XMLSerializer_constructor_Callback";
+  factory XmlSerializer() {
+    return XmlSerializer._create_1();
+  }
+
+  @DocsEditable
+  static XmlSerializer _create_1() native "XMLSerializer__create_1constructorCallback";
 
   @DomName('XMLSerializer.serializeToString')
   @DocsEditable
@@ -29340,12 +30181,23 @@
 
 @DocsEditable
 @DomName('XSLTProcessor')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.FIREFOX)
+@SupportedBrowser(SupportedBrowser.SAFARI)
 class XsltProcessor extends NativeFieldWrapperClass1 {
   XsltProcessor.internal();
 
+  @DomName('XSLTProcessor.XSLTProcessor')
   @DocsEditable
-  factory XsltProcessor() => XsltProcessor._create();
-  static XsltProcessor _create() native "XSLTProcessor_constructor_Callback";
+  factory XsltProcessor() {
+    return XsltProcessor._create_1();
+  }
+
+  @DocsEditable
+  static XsltProcessor _create_1() native "XSLTProcessor__create_1constructorCallback";
+
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
 
   @DomName('XSLTProcessor.clearParameters')
   @DocsEditable
@@ -29450,7 +30302,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(ClientRect element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(ClientRect element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(ClientRect element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<ClientRect> where(bool f(ClientRect element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -29464,13 +30320,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<ClientRect> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<ClientRect> takeWhile(bool test(ClientRect value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<ClientRect> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<ClientRect> skipWhile(bool test(ClientRect value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -29515,8 +30371,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ClientRect> get reversed =>
-      new ReversedListView<ClientRect>(this, 0, null);
+  List<ClientRect> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(ClientRect a, ClientRect b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -29646,7 +30503,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(CssRule element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(CssRule element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(CssRule element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<CssRule> where(bool f(CssRule element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -29660,13 +30521,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<CssRule> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<CssRule> takeWhile(bool test(CssRule value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<CssRule> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<CssRule> skipWhile(bool test(CssRule value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -29711,8 +30572,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssRule> get reversed =>
-      new ReversedListView<CssRule>(this, 0, null);
+  List<CssRule> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(CssRule a, CssRule b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -29842,7 +30704,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(CssValue element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(CssValue element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(CssValue element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<CssValue> where(bool f(CssValue element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -29856,13 +30722,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<CssValue> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<CssValue> takeWhile(bool test(CssValue value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<CssValue> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<CssValue> skipWhile(bool test(CssValue value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -29907,8 +30773,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<CssValue> get reversed =>
-      new ReversedListView<CssValue>(this, 0, null);
+  List<CssValue> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(CssValue a, CssValue b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -30188,7 +31055,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Entry element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Entry element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Entry element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Entry> where(bool f(Entry element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -30202,13 +31073,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Entry> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Entry> takeWhile(bool test(Entry value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Entry> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Entry> skipWhile(bool test(Entry value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -30253,8 +31124,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Entry> get reversed =>
-      new ReversedListView<Entry>(this, 0, null);
+  List<Entry> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Entry a, Entry b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -30384,7 +31256,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(EntrySync element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(EntrySync element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(EntrySync element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<EntrySync> where(bool f(EntrySync element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -30398,13 +31274,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<EntrySync> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<EntrySync> takeWhile(bool test(EntrySync value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<EntrySync> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<EntrySync> skipWhile(bool test(EntrySync value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -30449,8 +31325,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<EntrySync> get reversed =>
-      new ReversedListView<EntrySync>(this, 0, null);
+  List<EntrySync> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(EntrySync a, EntrySync b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -30671,7 +31548,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Gamepad element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Gamepad element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Gamepad element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Gamepad> where(bool f(Gamepad element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -30685,13 +31566,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Gamepad> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Gamepad> takeWhile(bool test(Gamepad value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Gamepad> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Gamepad> skipWhile(bool test(Gamepad value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -30736,8 +31617,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<Gamepad> get reversed =>
-      new ReversedListView<Gamepad>(this, 0, null);
+  List<Gamepad> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Gamepad a, Gamepad b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -30880,7 +31762,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(MediaStream element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(MediaStream element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(MediaStream element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<MediaStream> where(bool f(MediaStream element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -30894,13 +31780,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<MediaStream> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<MediaStream> takeWhile(bool test(MediaStream value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<MediaStream> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<MediaStream> skipWhile(bool test(MediaStream value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -30945,8 +31831,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<MediaStream> get reversed =>
-      new ReversedListView<MediaStream>(this, 0, null);
+  List<MediaStream> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(MediaStream a, MediaStream b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -31076,7 +31963,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SpeechInputResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SpeechInputResult element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SpeechInputResult element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SpeechInputResult> where(bool f(SpeechInputResult element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -31090,13 +31981,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SpeechInputResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SpeechInputResult> takeWhile(bool test(SpeechInputResult value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SpeechInputResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SpeechInputResult> skipWhile(bool test(SpeechInputResult value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -31141,8 +32032,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechInputResult> get reversed =>
-      new ReversedListView<SpeechInputResult>(this, 0, null);
+  List<SpeechInputResult> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SpeechInputResult a, SpeechInputResult b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -31272,7 +32164,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(SpeechRecognitionResult element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(SpeechRecognitionResult element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(SpeechRecognitionResult element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<SpeechRecognitionResult> where(bool f(SpeechRecognitionResult element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -31286,13 +32182,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<SpeechRecognitionResult> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<SpeechRecognitionResult> takeWhile(bool test(SpeechRecognitionResult value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<SpeechRecognitionResult> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<SpeechRecognitionResult> skipWhile(bool test(SpeechRecognitionResult value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -31337,8 +32233,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<SpeechRecognitionResult> get reversed =>
-      new ReversedListView<SpeechRecognitionResult>(this, 0, null);
+  List<SpeechRecognitionResult> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(SpeechRecognitionResult a, SpeechRecognitionResult b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -31468,7 +32365,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(StyleSheet element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(StyleSheet element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(StyleSheet element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<StyleSheet> where(bool f(StyleSheet element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -31482,13 +32383,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<StyleSheet> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<StyleSheet> takeWhile(bool test(StyleSheet value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<StyleSheet> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<StyleSheet> skipWhile(bool test(StyleSheet value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -31533,8 +32434,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<StyleSheet> get reversed =>
-      new ReversedListView<StyleSheet>(this, 0, null);
+  List<StyleSheet> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(StyleSheet a, StyleSheet b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -32015,6 +32917,8 @@
 
   String join([String separator]) => readClasses().join(separator);
 
+  Iterable map(f(String element)) => readClasses().map(f);
+
   Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
 
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
@@ -32112,7 +33016,7 @@
    * Helper method used to modify the set of css classes on this element.
    *
    *   f - callback with:
-   *      s - a Set of all the css class name currently on this element.
+   *   s - a Set of all the css class name currently on this element.
    *
    *   After f returns, the modified set is written to the
    *       className property of this element.
@@ -32159,7 +33063,7 @@
   _EventStream(this._target, this._eventType, this._useCapture);
 
   // DOM events are inherently multi-subscribers.
-  Stream<T> asMultiSubscriberStream() => this;
+  Stream<T> asBroadcastStream() => this;
 
   StreamSubscription<T> listen(void onData(T event),
       { void onError(AsyncError error),
@@ -32332,9 +33236,8 @@
   // The distance to shift from upper case alphabet Roman letters to lower case.
   final int _ROMAN_ALPHABET_OFFSET = "a".charCodes[0] - "A".charCodes[0];
 
-  // Instance members referring to the internal event handlers because closures
-  // are not hashable.
-  var _keyUp, _keyDown, _keyPress;
+  StreamSubscription _keyUpSubscription, _keyDownSubscription,
+      _keyPressSubscription;
 
   /**
    * An enumeration of key identifiers currently part of the W3C draft for DOM3
@@ -32390,9 +33293,6 @@
     _callbacks = [];
     _type = type;
     _target = target;
-    _keyDown = processKeyDown;
-    _keyUp = processKeyUp;
-    _keyPress = processKeyPress;
   }
 
   /**
@@ -32401,9 +33301,14 @@
    */
   void _initializeAllEventListeners() {
     _keyDownList = [];
-    _target.on.keyDown.add(_keyDown, true);
-    _target.on.keyPress.add(_keyPress, true);
-    _target.on.keyUp.add(_keyUp, true);
+    if (_keyDownSubscription == null) {
+      _keyDownSubscription = Element.keyDownEvent.forTarget(
+          _target, useCapture: true).listen(processKeyDown);
+      _keyPressSubscription = Element.keyPressEvent.forTarget(
+          _target, useCapture: true).listen(processKeyUp);
+      _keyUpSubscription = Element.keyUpEvent.forTarget(
+          _target, useCapture: true).listen(processKeyPress);
+    }
   }
 
   /** Add a callback that wishes to be notified when a KeyEvent occurs. */
@@ -32437,9 +33342,12 @@
     }
     if (_callbacks.length == 0) {
       // If we have no listeners, don't bother keeping track of keypresses.
-      _target.on.keyDown.remove(_keyDown);
-      _target.on.keyPress.remove(_keyPress);
-      _target.on.keyUp.remove(_keyUp);
+      _keyDownSubscription.cancel();
+      _keyDownSubscription = null;
+      _keyPressSubscription.cancel();
+      _keyPressSubscription = null;
+      _keyUpSubscription.cancel();
+      _keyUpSubscription = null;
     }
   }
 
@@ -33536,7 +34444,7 @@
 
     request.withCredentials = withCredentials;
 
-    request.on.readyStateChange.add((e) {
+    request.onReadyStateChange.listen((e) {
       if (request.readyState == HttpRequest.DONE) {
         onComplete(request);
       }
@@ -33659,7 +34567,7 @@
     _parent.cancelBubble = cancel;
   }
   /** Accessor to the clipboardData available for this event. */
-  Clipboard get clipboardData => _parent.clipboardData;
+  DataTransfer get clipboardData => _parent.clipboardData;
   /** True if the ctrl key is pressed during this event. */
   bool get ctrlKey => _parent.ctrlKey;
   /** Accessor to the target this event is listening to for changes. */
@@ -34060,46 +34968,38 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-typedef Object ComputeValue();
-
-class _MeasurementRequest<T> {
-  final ComputeValue computeValue;
-  final Completer<T> completer;
-  Object value;
-  bool exception = false;
-  _MeasurementRequest(this.computeValue, this.completer);
-}
-
-typedef void _MeasurementCallback();
+typedef void _MicrotaskCallback();
 
 /**
  * This class attempts to invoke a callback as soon as the current event stack
  * unwinds, but before the browser repaints.
  */
-abstract class _MeasurementScheduler {
-  bool _nextMeasurementFrameScheduled = false;
-  _MeasurementCallback _callback;
+abstract class _MicrotaskScheduler {
+  bool _nextMicrotaskFrameScheduled = false;
+  _MicrotaskCallback _callback;
 
-  _MeasurementScheduler(this._callback);
+  _MicrotaskScheduler(this._callback);
 
   /**
-   * Creates the best possible measurement scheduler for the current platform.
+   * Creates the best possible microtask scheduler for the current platform.
    */
-  factory _MeasurementScheduler.best(_MeasurementCallback callback) {
-    if (MutationObserver.supported) {
+  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+    if (Window._supportsSetImmediate) {
+      return new _SetImmediateScheduler(callback);
+    } else if (MutationObserver.supported) {
       return new _MutationObserverScheduler(callback);
     }
     return new _PostMessageScheduler(callback);
   }
 
   /**
-   * Schedules a measurement callback if one has not been scheduled already.
+   * Schedules a microtask callback if one has not been scheduled already.
    */
   void maybeSchedule() {
-    if (this._nextMeasurementFrameScheduled) {
+    if (this._nextMicrotaskFrameScheduled) {
       return;
     }
-    this._nextMeasurementFrameScheduled = true;
+    this._nextMicrotaskFrameScheduled = true;
     this._schedule();
   }
 
@@ -34109,14 +35009,14 @@
   void _schedule();
 
   /**
-   * Handles the measurement callback and forwards it if necessary.
+   * Handles the microtask callback and forwards it if necessary.
    */
   void _onCallback() {
     // Ignore spurious messages.
-    if (!_nextMeasurementFrameScheduled) {
+    if (!_nextMicrotaskFrameScheduled) {
       return;
     }
-    _nextMeasurementFrameScheduled = false;
+    _nextMicrotaskFrameScheduled = false;
     this._callback();
   }
 }
@@ -34124,22 +35024,22 @@
 /**
  * Scheduler which uses window.postMessage to schedule events.
  */
-class _PostMessageScheduler extends _MeasurementScheduler {
-  const _MEASUREMENT_MESSAGE = "DART-MEASURE";
+class _PostMessageScheduler extends _MicrotaskScheduler {
+  const _MICROTASK_MESSAGE = "DART-MICROTASK";
 
-  _PostMessageScheduler(_MeasurementCallback callback): super(callback) {
+  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
       // Messages from other windows do not cause a security risk as
       // all we care about is that _handleMessage is called
       // after the current event loop is unwound and calling the function is
       // a noop when zero requests are pending.
-      window.on.message.add(this._handleMessage);
+      window.onMessage.listen(this._handleMessage);
   }
 
   void _schedule() {
-    window.postMessage(_MEASUREMENT_MESSAGE, "*");
+    window.postMessage(_MICROTASK_MESSAGE, "*");
   }
 
-  _handleMessage(e) {
+  void _handleMessage(e) {
     this._onCallback();
   }
 }
@@ -34147,11 +35047,11 @@
 /**
  * Scheduler which uses a MutationObserver to schedule events.
  */
-class _MutationObserverScheduler extends _MeasurementScheduler {
+class _MutationObserverScheduler extends _MicrotaskScheduler {
   MutationObserver _observer;
   Element _dummy;
 
-  _MutationObserverScheduler(_MeasurementCallback callback): super(callback) {
+  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
     // Mutation events get fired as soon as the current event stack is unwound
     // so we just make a dummy event and listen for that.
     _observer = new MutationObserver(this._handleMutation);
@@ -34169,89 +35069,53 @@
   }
 }
 
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
 
-List<_MeasurementRequest> _pendingRequests;
-List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
-_MeasurementScheduler _measurementScheduler = null;
-
-void _maybeScheduleMeasurementFrame() {
-  if (_measurementScheduler == null) {
-    _measurementScheduler =
-      new _MeasurementScheduler.best(_completeMeasurementFutures);
+  void _schedule() {
+    window._setImmediate(_handleImmediate);
   }
-  _measurementScheduler.maybeSchedule();
+
+  void _handleImmediate() {
+    this._onCallback();
+  }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+  if (_microtaskScheduler == null) {
+    _microtaskScheduler =
+      new _MicrotaskScheduler.best(_completeMicrotasks);
+  }
+  _microtaskScheduler.maybeSchedule();
 }
 
 /**
- * Registers a [callback] which is called after the next batch of measurements
- * completes. Even if no measurements completed, the callback is triggered
- * when they would have completed to avoid confusing bugs if it happened that
- * no measurements were actually requested.
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
  */
-void _addMeasurementFrameCallback(TimeoutHandler callback) {
-  if (_pendingMeasurementFrameCallbacks == null) {
-    _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
-    _maybeScheduleMeasurementFrame();
+void _addMicrotaskCallback(TimeoutHandler callback) {
+  if (_pendingMicrotasks == null) {
+    _pendingMicrotasks = <TimeoutHandler>[];
+    _maybeScheduleMicrotaskFrame();
   }
-  _pendingMeasurementFrameCallbacks.add(callback);
+  _pendingMicrotasks.add(callback);
 }
 
-/**
- * Returns a [Future] whose value will be the result of evaluating
- * [computeValue] during the next safe measurement interval.
- * The next safe measurement interval is after the current event loop has
- * unwound but before the browser has rendered the page.
- * It is important that the [computeValue] function only queries the html
- * layout and html in any way.
- */
-Future _createMeasurementFuture(ComputeValue computeValue,
-                                Completer completer) {
-  if (_pendingRequests == null) {
-    _pendingRequests = <_MeasurementRequest>[];
-    _maybeScheduleMeasurementFrame();
-  }
-  _pendingRequests.add(new _MeasurementRequest(computeValue, completer));
-  return completer.future;
-}
 
 /**
- * Complete all pending measurement futures evaluating them in a single batch
- * so that the the browser is guaranteed to avoid multiple layouts.
+ * Complete all pending microtasks.
  */
-void _completeMeasurementFutures() {
-  // We must compute all new values before fulfilling the futures as
-  // the onComplete callbacks for the futures could modify the DOM making
-  // subsequent measurement calculations expensive to compute.
-  if (_pendingRequests != null) {
-    for (_MeasurementRequest request in _pendingRequests) {
-      try {
-        request.value = request.computeValue();
-      } catch (e) {
-        request.value = e;
-        request.exception = true;
-      }
-    }
-  }
-
-  final completedRequests = _pendingRequests;
-  final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
-  _pendingRequests = null;
-  _pendingMeasurementFrameCallbacks = null;
-  if (completedRequests != null) {
-    for (_MeasurementRequest request in completedRequests) {
-      if (request.exception) {
-        request.completer.completeError(request.value);
-      } else {
-        request.completer.complete(request.value);
-      }
-    }
-  }
-
-  if (readyMeasurementFrameCallbacks != null) {
-    for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
-      // TODO(jacobr): wrap each call to a handler in a try-catch block.
-      handler();
-    }
+void _completeMicrotasks() {
+  var callbacks = _pendingMicrotasks;
+  _pendingMicrotasks = null;
+  for (var callback in callbacks) {
+    callback();
   }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -34433,26 +35297,6 @@
   }
 }
 
-// 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.
-
-
-// TODO(rnystrom): add a way to supress public classes from DartDoc output.
-// TODO(jacobr): we can remove this class now that we are using the $dom_
-// convention for deprecated methods rather than truly private methods.
-/**
- * This class is intended for testing purposes only.
- */
-class Testing {
-  static void addEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
-    target.$dom_addEventListener(type, listener, useCapture);
-  }
-  static void removeEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
-    target.$dom_removeEventListener(type, listener, useCapture);
-  }
-
-}
 // 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.
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index 2414539..a16d42c 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -69,8 +69,7 @@
     return element is Element && _childNodes.contains(element);
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(_filtered, 0, null);
+  List<Element> get reversed => _filtered.reversed;
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -102,7 +101,8 @@
     return result;
   }
 
-  Iterable mappedBy(f(Element element)) => _filtered.mappedBy(f);
+  Iterable map(f(Element element)) => _filtered.map(f);
+  List mappedBy(f(Element element)) => _filtered.mappedBy(f);
   Iterable<Element> where(bool f(Element element)) => _filtered.where(f);
 
   Element removeAt(int index) {
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index d4c2635..94ddf18 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -5,7 +5,6 @@
 library html_common;
 
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 
 import 'metadata.dart';
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index 3e2d10d..7392945 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -5,7 +5,6 @@
 library html_common;
 
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:_js_helper' show Creates, Returns;
 import 'dart:_foreign_helper' show JS;
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index e3f6e10..8a37de0 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1,4 +1,4 @@
-library indexed_db;
+library dart.dom.indexed_db;
 
 import 'dart:async';
 import 'dart:html';
@@ -161,23 +161,10 @@
   @DocsEditable
   void advance(int count) native;
 
-  void continueFunction([/*IDBKey*/ key]) {
-    if (?key) {
-      var key_1 = _convertDartToNative_IDBKey(key);
-      _continueFunction_1(key_1);
-      return;
-    }
-    _continueFunction_2();
-    return;
-  }
   @JSName('continue')
   @DomName('IDBCursor.continue')
   @DocsEditable
-  void _continueFunction_1(key) native;
-  @JSName('continue')
-  @DomName('IDBCursor.continue')
-  @DocsEditable
-  void _continueFunction_2() native;
+  void continueFunction([Object key]) native;
 
   @DomName('IDBCursor.delete')
   @DocsEditable
@@ -357,15 +344,9 @@
   }
 
 
-  int cmp(/*IDBKey*/ first, /*IDBKey*/ second) {
-    var first_1 = _convertDartToNative_IDBKey(first);
-    var second_2 = _convertDartToNative_IDBKey(second);
-    return _cmp_1(first_1, second_2);
-  }
-  @JSName('cmp')
   @DomName('IDBFactory.cmp')
   @DocsEditable
-  int _cmp_1(first, second) native;
+  int cmp(Object first, Object second) native;
 
   @DomName('IDBFactory.deleteDatabase')
   @DocsEditable
@@ -412,204 +393,38 @@
   @DocsEditable
   final bool unique;
 
-  Request count([key_OR_range]) {
-    if (!?key_OR_range) {
-      return _count_1();
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null)) {
-      return _count_2(key_OR_range);
-    }
-    if (?key_OR_range) {
-      var key_1 = _convertDartToNative_IDBKey(key_OR_range);
-      return _count_3(key_1);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('count')
   @DomName('IDBIndex.count')
   @DocsEditable
-  Request _count_1() native;
-  @JSName('count')
-  @DomName('IDBIndex.count')
-  @DocsEditable
-  Request _count_2(KeyRange range) native;
-  @JSName('count')
-  @DomName('IDBIndex.count')
-  @DocsEditable
-  Request _count_3(key) native;
+  Request count([key_OR_range]) native;
 
-  Request get(key) {
-    if ((key is KeyRange || key == null)) {
-      return _get_1(key);
-    }
-    if (?key) {
-      var key_1 = _convertDartToNative_IDBKey(key);
-      return _get_2(key_1);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('get')
   @DomName('IDBIndex.get')
   @DocsEditable
   @Returns('Request')
   @Creates('Request')
   @annotation_Creates_SerializedScriptValue
-  Request _get_1(KeyRange key) native;
-  @JSName('get')
-  @DomName('IDBIndex.get')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @annotation_Creates_SerializedScriptValue
-  Request _get_2(key) native;
+  Request get(key) native;
 
-  Request getKey(key) {
-    if ((key is KeyRange || key == null)) {
-      return _getKey_1(key);
-    }
-    if (?key) {
-      var key_1 = _convertDartToNative_IDBKey(key);
-      return _getKey_2(key_1);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('getKey')
   @DomName('IDBIndex.getKey')
   @DocsEditable
   @Returns('Request')
   @Creates('Request')
   @annotation_Creates_SerializedScriptValue
   @Creates('ObjectStore')
-  Request _getKey_1(KeyRange key) native;
-  @JSName('getKey')
-  @DomName('IDBIndex.getKey')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @annotation_Creates_SerializedScriptValue
-  @Creates('ObjectStore')
-  Request _getKey_2(key) native;
+  Request getKey(key) native;
 
-  Request openCursor([key_OR_range, String direction]) {
-    if (!?key_OR_range && !?direction) {
-      return _openCursor_1();
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null) && !?direction) {
-      return _openCursor_2(key_OR_range);
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null)) {
-      return _openCursor_3(key_OR_range, direction);
-    }
-    if (?key_OR_range && !?direction) {
-      var key_1 = _convertDartToNative_IDBKey(key_OR_range);
-      return _openCursor_4(key_1);
-    }
-    if (?key_OR_range) {
-      var key_2 = _convertDartToNative_IDBKey(key_OR_range);
-      return _openCursor_5(key_2, direction);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('openCursor')
   @DomName('IDBIndex.openCursor')
   @DocsEditable
   @Returns('Request')
   @Creates('Request')
   @Creates('Cursor')
-  Request _openCursor_1() native;
-  @JSName('openCursor')
-  @DomName('IDBIndex.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_2(KeyRange range) native;
-  @JSName('openCursor')
-  @DomName('IDBIndex.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_3(KeyRange range, direction) native;
-  @JSName('openCursor')
-  @DomName('IDBIndex.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_4(key) native;
-  @JSName('openCursor')
-  @DomName('IDBIndex.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_5(key, direction) native;
+  Request openCursor([key_OR_range, String direction]) native;
 
-  Request openKeyCursor([key_OR_range, String direction]) {
-    if (!?key_OR_range && !?direction) {
-      return _openKeyCursor_1();
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null) && !?direction) {
-      return _openKeyCursor_2(key_OR_range);
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null)) {
-      return _openKeyCursor_3(key_OR_range, direction);
-    }
-    if (?key_OR_range && !?direction) {
-      var key_1 = _convertDartToNative_IDBKey(key_OR_range);
-      return _openKeyCursor_4(key_1);
-    }
-    if (?key_OR_range) {
-      var key_2 = _convertDartToNative_IDBKey(key_OR_range);
-      return _openKeyCursor_5(key_2, direction);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('openKeyCursor')
   @DomName('IDBIndex.openKeyCursor')
   @DocsEditable
   @Returns('Request')
   @Creates('Request')
   @Creates('Cursor')
-  Request _openKeyCursor_1() native;
-  @JSName('openKeyCursor')
-  @DomName('IDBIndex.openKeyCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openKeyCursor_2(KeyRange range) native;
-  @JSName('openKeyCursor')
-  @DomName('IDBIndex.openKeyCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openKeyCursor_3(KeyRange range, direction) native;
-  @JSName('openKeyCursor')
-  @DomName('IDBIndex.openKeyCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openKeyCursor_4(key) native;
-  @JSName('openKeyCursor')
-  @DomName('IDBIndex.openKeyCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openKeyCursor_5(key, direction) 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
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
-@DomName('IDBKey')
-class Key native "*IDBKey" {
+  Request openKeyCursor([key_OR_range, String direction]) 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
@@ -637,96 +452,41 @@
           lower, upper, lowerOpen, upperOpen);
 
 
-  dynamic get lower => _convertNativeToDart_IDBKey(this._lower);
-  @JSName('lower')
   @DomName('IDBKeyRange.lower')
   @DocsEditable
-  final dynamic _lower;
+  final Object lower;
 
   @DomName('IDBKeyRange.lowerOpen')
   @DocsEditable
   final bool lowerOpen;
 
-  dynamic get upper => _convertNativeToDart_IDBKey(this._upper);
-  @JSName('upper')
   @DomName('IDBKeyRange.upper')
   @DocsEditable
-  final dynamic _upper;
+  final Object upper;
 
   @DomName('IDBKeyRange.upperOpen')
   @DocsEditable
   final bool upperOpen;
 
-  static KeyRange bound_(/*IDBKey*/ lower, /*IDBKey*/ upper, [bool lowerOpen, bool upperOpen]) {
-    if (?upperOpen) {
-      var lower_1 = _convertDartToNative_IDBKey(lower);
-      var upper_2 = _convertDartToNative_IDBKey(upper);
-      return _bound__1(lower_1, upper_2, lowerOpen, upperOpen);
-    }
-    if (?lowerOpen) {
-      var lower_3 = _convertDartToNative_IDBKey(lower);
-      var upper_4 = _convertDartToNative_IDBKey(upper);
-      return _bound__2(lower_3, upper_4, lowerOpen);
-    }
-    var lower_5 = _convertDartToNative_IDBKey(lower);
-    var upper_6 = _convertDartToNative_IDBKey(upper);
-    return _bound__3(lower_5, upper_6);
-  }
   @JSName('bound')
   @DomName('IDBKeyRange.bound')
   @DocsEditable
-  static KeyRange _bound__1(lower, upper, lowerOpen, upperOpen) native;
-  @JSName('bound')
-  @DomName('IDBKeyRange.bound')
-  @DocsEditable
-  static KeyRange _bound__2(lower, upper, lowerOpen) native;
-  @JSName('bound')
-  @DomName('IDBKeyRange.bound')
-  @DocsEditable
-  static KeyRange _bound__3(lower, upper) native;
+  static KeyRange bound_(Object lower, Object upper, [bool lowerOpen, bool upperOpen]) native;
 
-  static KeyRange lowerBound_(/*IDBKey*/ bound, [bool open]) {
-    if (?open) {
-      var bound_1 = _convertDartToNative_IDBKey(bound);
-      return _lowerBound__1(bound_1, open);
-    }
-    var bound_2 = _convertDartToNative_IDBKey(bound);
-    return _lowerBound__2(bound_2);
-  }
   @JSName('lowerBound')
   @DomName('IDBKeyRange.lowerBound')
   @DocsEditable
-  static KeyRange _lowerBound__1(bound, open) native;
-  @JSName('lowerBound')
-  @DomName('IDBKeyRange.lowerBound')
-  @DocsEditable
-  static KeyRange _lowerBound__2(bound) native;
+  static KeyRange lowerBound_(Object bound, [bool open]) native;
 
-  static KeyRange only_(/*IDBKey*/ value) {
-    var value_1 = _convertDartToNative_IDBKey(value);
-    return _only__1(value_1);
-  }
   @JSName('only')
   @DomName('IDBKeyRange.only')
   @DocsEditable
-  static KeyRange _only__1(value) native;
+  static KeyRange only_(Object value) native;
 
-  static KeyRange upperBound_(/*IDBKey*/ bound, [bool open]) {
-    if (?open) {
-      var bound_1 = _convertDartToNative_IDBKey(bound);
-      return _upperBound__1(bound_1, open);
-    }
-    var bound_2 = _convertDartToNative_IDBKey(bound);
-    return _upperBound__2(bound_2);
-  }
   @JSName('upperBound')
   @DomName('IDBKeyRange.upperBound')
   @DocsEditable
-  static KeyRange _upperBound__1(bound, open) native;
-  @JSName('upperBound')
-  @DomName('IDBKeyRange.upperBound')
-  @DocsEditable
-  static KeyRange _upperBound__2(bound) native;
+  static KeyRange upperBound_(Object bound, [bool open]) native;
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
@@ -760,10 +520,10 @@
   @DocsEditable
   final Transaction transaction;
 
-  Request add(/*any*/ value, [/*IDBKey*/ key]) {
+  Request add(/*any*/ value, [/*any*/ key]) {
     if (?key) {
       var value_1 = convertDartToNative_SerializedScriptValue(value);
-      var key_2 = _convertDartToNative_IDBKey(key);
+      var key_2 = convertDartToNative_SerializedScriptValue(key);
       return _add_1(value_1, key_2);
     }
     var value_3 = convertDartToNative_SerializedScriptValue(value);
@@ -788,31 +548,9 @@
   @DocsEditable
   Request clear() native;
 
-  Request count([key_OR_range]) {
-    if (!?key_OR_range) {
-      return _count_1();
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null)) {
-      return _count_2(key_OR_range);
-    }
-    if (?key_OR_range) {
-      var key_1 = _convertDartToNative_IDBKey(key_OR_range);
-      return _count_3(key_1);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('count')
   @DomName('IDBObjectStore.count')
   @DocsEditable
-  Request _count_1() native;
-  @JSName('count')
-  @DomName('IDBObjectStore.count')
-  @DocsEditable
-  Request _count_2(KeyRange range) native;
-  @JSName('count')
-  @DomName('IDBObjectStore.count')
-  @DocsEditable
-  Request _count_3(key) native;
+  Request count([key_OR_range]) native;
 
   Index createIndex(String name, keyPath, [Map options]) {
     if ((keyPath is List<String> || keyPath == null) && !?options) {
@@ -848,118 +586,37 @@
   @DocsEditable
   Index _createIndex_4(name, String keyPath, options) native;
 
-  Request delete(key_OR_keyRange) {
-    if ((key_OR_keyRange is KeyRange || key_OR_keyRange == null)) {
-      return _delete_1(key_OR_keyRange);
-    }
-    if (?key_OR_keyRange) {
-      var key_1 = _convertDartToNative_IDBKey(key_OR_keyRange);
-      return _delete_2(key_1);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('delete')
   @DomName('IDBObjectStore.delete')
   @DocsEditable
-  Request _delete_1(KeyRange keyRange) native;
-  @JSName('delete')
-  @DomName('IDBObjectStore.delete')
-  @DocsEditable
-  Request _delete_2(key) native;
+  Request delete(key_OR_keyRange) native;
 
   @DomName('IDBObjectStore.deleteIndex')
   @DocsEditable
   void deleteIndex(String name) native;
 
-  Request getObject(key) {
-    if ((key is KeyRange || key == null)) {
-      return _getObject_1(key);
-    }
-    if (?key) {
-      var key_1 = _convertDartToNative_IDBKey(key);
-      return _getObject_2(key_1);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
   @JSName('get')
   @DomName('IDBObjectStore.get')
   @DocsEditable
   @Returns('Request')
   @Creates('Request')
   @annotation_Creates_SerializedScriptValue
-  Request _getObject_1(KeyRange key) native;
-  @JSName('get')
-  @DomName('IDBObjectStore.get')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @annotation_Creates_SerializedScriptValue
-  Request _getObject_2(key) native;
+  Request getObject(key) native;
 
   @DomName('IDBObjectStore.index')
   @DocsEditable
   Index index(String name) native;
 
-  Request openCursor([key_OR_range, String direction]) {
-    if (!?key_OR_range && !?direction) {
-      return _openCursor_1();
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null) && !?direction) {
-      return _openCursor_2(key_OR_range);
-    }
-    if ((key_OR_range is KeyRange || key_OR_range == null)) {
-      return _openCursor_3(key_OR_range, direction);
-    }
-    if (?key_OR_range && !?direction) {
-      var key_1 = _convertDartToNative_IDBKey(key_OR_range);
-      return _openCursor_4(key_1);
-    }
-    if (?key_OR_range) {
-      var key_2 = _convertDartToNative_IDBKey(key_OR_range);
-      return _openCursor_5(key_2, direction);
-    }
-    throw new ArgumentError("Incorrect number or type of arguments");
-  }
-  @JSName('openCursor')
   @DomName('IDBObjectStore.openCursor')
   @DocsEditable
   @Returns('Request')
   @Creates('Request')
   @Creates('Cursor')
-  Request _openCursor_1() native;
-  @JSName('openCursor')
-  @DomName('IDBObjectStore.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_2(KeyRange range) native;
-  @JSName('openCursor')
-  @DomName('IDBObjectStore.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_3(KeyRange range, direction) native;
-  @JSName('openCursor')
-  @DomName('IDBObjectStore.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_4(key) native;
-  @JSName('openCursor')
-  @DomName('IDBObjectStore.openCursor')
-  @DocsEditable
-  @Returns('Request')
-  @Creates('Request')
-  @Creates('Cursor')
-  Request _openCursor_5(key, direction) native;
+  Request openCursor([key_OR_range, String direction]) native;
 
-  Request put(/*any*/ value, [/*IDBKey*/ key]) {
+  Request put(/*any*/ value, [/*any*/ key]) {
     if (?key) {
       var value_1 = convertDartToNative_SerializedScriptValue(value);
-      var key_2 = _convertDartToNative_IDBKey(key);
+      var key_2 = convertDartToNative_SerializedScriptValue(key);
       return _put_1(value_1, key_2);
     }
     var value_3 = convertDartToNative_SerializedScriptValue(value);
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index ea68244..184fb00 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -1,4 +1,4 @@
-library indexed_db;
+library dart.dom.indexed_db;
 
 import 'dart:async';
 import 'dart:html';
@@ -65,7 +65,7 @@
   @DocsEditable
   void advance(int count) native "IDBCursor_advance_Callback";
 
-  void continueFunction([/*IDBKey*/ key]) {
+  void continueFunction([Object key]) {
     if (?key) {
       _continue_1(key);
       return;
@@ -254,7 +254,7 @@
 
   @DomName('IDBFactory.cmp')
   @DocsEditable
-  int cmp(/*IDBKey*/ first, /*IDBKey*/ second) native "IDBFactory_cmp_Callback";
+  int cmp(Object first, Object second) native "IDBFactory_cmp_Callback";
 
   @DomName('IDBFactory.deleteDatabase')
   @DocsEditable
@@ -456,19 +456,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
-@DomName('IDBKey')
-class Key extends NativeFieldWrapperClass1 {
-  Key.internal();
-
-}
-// 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.
-
 
 @DomName('IDBKeyRange')
 class KeyRange extends NativeFieldWrapperClass1 {
@@ -494,7 +481,7 @@
 
   @DomName('IDBKeyRange.lower')
   @DocsEditable
-  dynamic get lower native "IDBKeyRange_lower_Getter";
+  Object get lower native "IDBKeyRange_lower_Getter";
 
   @DomName('IDBKeyRange.lowerOpen')
   @DocsEditable
@@ -502,13 +489,13 @@
 
   @DomName('IDBKeyRange.upper')
   @DocsEditable
-  dynamic get upper native "IDBKeyRange_upper_Getter";
+  Object get upper native "IDBKeyRange_upper_Getter";
 
   @DomName('IDBKeyRange.upperOpen')
   @DocsEditable
   bool get upperOpen native "IDBKeyRange_upperOpen_Getter";
 
-  static KeyRange bound_(/*IDBKey*/ lower, /*IDBKey*/ upper, [bool lowerOpen, bool upperOpen]) {
+  static KeyRange bound_(Object lower, Object upper, [bool lowerOpen, bool upperOpen]) {
     if (?upperOpen) {
       return _bound_1(lower, upper, lowerOpen, upperOpen);
     }
@@ -530,7 +517,7 @@
   @DocsEditable
   static KeyRange _bound_3(lower, upper) native "IDBKeyRange__bound_3_Callback";
 
-  static KeyRange lowerBound_(/*IDBKey*/ bound, [bool open]) {
+  static KeyRange lowerBound_(Object bound, [bool open]) {
     if (?open) {
       return _lowerBound_1(bound, open);
     }
@@ -547,9 +534,9 @@
 
   @DomName('IDBKeyRange.only_')
   @DocsEditable
-  static KeyRange only_(/*IDBKey*/ value) native "IDBKeyRange_only__Callback";
+  static KeyRange only_(Object value) native "IDBKeyRange_only__Callback";
 
-  static KeyRange upperBound_(/*IDBKey*/ bound, [bool open]) {
+  static KeyRange upperBound_(Object bound, [bool open]) {
     if (?open) {
       return _upperBound_1(bound, open);
     }
@@ -597,7 +584,7 @@
   @DocsEditable
   Transaction get transaction native "IDBObjectStore_transaction_Getter";
 
-  Request add(Object value, [/*IDBKey*/ key]) {
+  Request add(Object value, [Object key]) {
     if (?key) {
       return _add_1(value, key);
     }
@@ -742,7 +729,7 @@
   @DocsEditable
   Request _openCursor_5(key_OR_range, direction) native "IDBObjectStore__openCursor_5_Callback";
 
-  Request put(Object value, [/*IDBKey*/ key]) {
+  Request put(Object value, [Object key]) {
     if (?key) {
       return _put_1(value, key);
     }
diff --git a/sdk/lib/json/json.dart b/sdk/lib/json/json.dart
index e85d93f..4348767 100644
--- a/sdk/lib/json/json.dart
+++ b/sdk/lib/json/json.dart
@@ -507,7 +507,7 @@
         case BACKSLASH:
         case QUOTE:
           break;
-        case CHAR_u: {
+        case CHAR_u:
           int hexStart = position - 1;
           int value = 0;
           for (int i = 0; i < 4; i++) {
@@ -530,7 +530,6 @@
           }
           char = value;
           break;
-        }
         default:
           if (char < SPACE) fail(position, "Control character in string");
           fail(position, "Unrecognized string escape");
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index cefba24..be4a8ff 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -8,7 +8,7 @@
  * A random number generator. The default implementation supplies a stream of
  * pseudo-random bits which is not suitable for cryptographic purposes.
  */
-class Random {
+abstract class Random {
   /**
    * Creates a random-number generator. The optional parameter [seed] is used
    * to initialize the internal state of the generator. The implementation of
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index ca9734e..1f52ee3 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -1,8 +1,7 @@
-library svg;
+library dart.dom.svg;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, Returns, JavaScriptIndexingBehavior, JSName;
@@ -62,8 +61,9 @@
 
 @DocsEditable
 @DomName('SVGAElement')
-class AElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGAElement" {
+class AElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGAElement" {
 
+  @DomName('SVGAElement.SVGAElement')
   @DocsEditable
   factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
 
@@ -115,18 +115,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGAElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGAElement.requiredExtensions')
@@ -250,6 +238,7 @@
 @DomName('SVGAnimateColorElement')
 class AnimateColorElement extends AnimationElement native "*SVGAnimateColorElement" {
 
+  @DomName('SVGAnimateColorElement.SVGAnimateColorElement')
   @DocsEditable
   factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
 }
@@ -262,6 +251,7 @@
 @DomName('SVGAnimateElement')
 class AnimateElement extends AnimationElement native "*SVGAnimateElement" {
 
+  @DomName('SVGAnimateElement.SVGAnimateElement')
   @DocsEditable
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
 }
@@ -274,6 +264,7 @@
 @DomName('SVGAnimateMotionElement')
 class AnimateMotionElement extends AnimationElement native "*SVGAnimateMotionElement" {
 
+  @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
   @DocsEditable
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
 }
@@ -286,6 +277,7 @@
 @DomName('SVGAnimateTransformElement')
 class AnimateTransformElement extends AnimationElement native "*SVGAnimateTransformElement" {
 
+  @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
   @DocsEditable
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
 }
@@ -502,6 +494,7 @@
 @DomName('SVGAnimationElement')
 class AnimationElement extends SvgElement implements Tests, ElementTimeControl, ExternalResourcesRequired native "*SVGAnimationElement" {
 
+  @DomName('SVGAnimationElement.SVGAnimationElement')
   @DocsEditable
   factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
 
@@ -570,8 +563,9 @@
 
 @DocsEditable
 @DomName('SVGCircleElement')
-class CircleElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGCircleElement" {
+class CircleElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGCircleElement" {
 
+  @DomName('SVGCircleElement.SVGCircleElement')
   @DocsEditable
   factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
 
@@ -631,18 +625,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGCircleElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGCircleElement.requiredExtensions')
@@ -674,8 +656,9 @@
 
 @DocsEditable
 @DomName('SVGClipPathElement')
-class ClipPathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGClipPathElement" {
+class ClipPathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGClipPathElement" {
 
+  @DomName('SVGClipPathElement.SVGClipPathElement')
   @DocsEditable
   factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
 
@@ -727,18 +710,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGClipPathElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGClipPathElement.requiredExtensions')
@@ -860,6 +831,7 @@
 @DomName('SVGCursorElement')
 class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired native "*SVGCursorElement" {
 
+  @DomName('SVGCursorElement.SVGCursorElement')
   @DocsEditable
   factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
 
@@ -908,8 +880,9 @@
 
 @DocsEditable
 @DomName('SVGDefsElement')
-class DefsElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGDefsElement" {
+class DefsElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGDefsElement" {
 
+  @DomName('SVGDefsElement.SVGDefsElement')
   @DocsEditable
   factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
 
@@ -957,18 +930,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGDefsElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGDefsElement.requiredExtensions')
@@ -1000,8 +961,9 @@
 
 @DocsEditable
 @DomName('SVGDescElement')
-class DescElement extends SvgElement implements Stylable, LangSpace native "*SVGDescElement" {
+class DescElement extends StyledElement implements LangSpace native "*SVGDescElement" {
 
+  @DomName('SVGDescElement.SVGDescElement')
   @DocsEditable
   factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
 
@@ -1014,18 +976,6 @@
   @DomName('SVGDescElement.xmlspace')
   @DocsEditable
   String xmlspace;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGDescElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -1546,8 +1496,9 @@
 
 @DocsEditable
 @DomName('SVGEllipseElement')
-class EllipseElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGEllipseElement" {
+class EllipseElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGEllipseElement" {
 
+  @DomName('SVGEllipseElement.SVGEllipseElement')
   @DocsEditable
   factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
 
@@ -1611,18 +1562,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGEllipseElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGEllipseElement.requiredExtensions')
@@ -1664,7 +1603,7 @@
 
 @DocsEditable
 @DomName('SVGFEBlendElement')
-class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEBlendElement" {
+class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEBlendElement" {
 
   static const int SVG_FEBLEND_MODE_DARKEN = 4;
 
@@ -1711,18 +1650,6 @@
   @DomName('SVGFEBlendElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEBlendElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -1731,7 +1658,7 @@
 
 @DocsEditable
 @DomName('SVGFEColorMatrixElement')
-class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEColorMatrixElement" {
+class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEColorMatrixElement" {
 
   static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
 
@@ -1776,18 +1703,6 @@
   @DomName('SVGFEColorMatrixElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEColorMatrixElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -1796,7 +1711,7 @@
 
 @DocsEditable
 @DomName('SVGFEComponentTransferElement')
-class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEComponentTransferElement" {
+class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEComponentTransferElement" {
 
   @DomName('SVGFEComponentTransferElement.in1')
   @DocsEditable
@@ -1823,18 +1738,6 @@
   @DomName('SVGFEComponentTransferElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEComponentTransferElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -1843,7 +1746,7 @@
 
 @DocsEditable
 @DomName('SVGFECompositeElement')
-class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFECompositeElement" {
+class FECompositeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFECompositeElement" {
 
   static const int SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
 
@@ -1908,18 +1811,6 @@
   @DomName('SVGFECompositeElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFECompositeElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -1928,7 +1819,7 @@
 
 @DocsEditable
 @DomName('SVGFEConvolveMatrixElement')
-class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEConvolveMatrixElement" {
+class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEConvolveMatrixElement" {
 
   static const int SVG_EDGEMODE_DUPLICATE = 1;
 
@@ -2007,18 +1898,6 @@
   @DomName('SVGFEConvolveMatrixElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEConvolveMatrixElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2027,7 +1906,7 @@
 
 @DocsEditable
 @DomName('SVGFEDiffuseLightingElement')
-class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEDiffuseLightingElement" {
+class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDiffuseLightingElement" {
 
   @DomName('SVGFEDiffuseLightingElement.diffuseConstant')
   @DocsEditable
@@ -2070,18 +1949,6 @@
   @DomName('SVGFEDiffuseLightingElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEDiffuseLightingElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2090,7 +1957,7 @@
 
 @DocsEditable
 @DomName('SVGFEDisplacementMapElement')
-class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEDisplacementMapElement" {
+class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDisplacementMapElement" {
 
   static const int SVG_CHANNEL_A = 4;
 
@@ -2143,18 +2010,6 @@
   @DomName('SVGFEDisplacementMapElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEDisplacementMapElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2180,7 +2035,7 @@
 
 @DocsEditable
 @DomName('SVGFEDropShadowElement')
-class FEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEDropShadowElement" {
+class FEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEDropShadowElement" {
 
   @DomName('SVGFEDropShadowElement.dx')
   @DocsEditable
@@ -2227,18 +2082,6 @@
   @DomName('SVGFEDropShadowElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEDropShadowElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2247,7 +2090,7 @@
 
 @DocsEditable
 @DomName('SVGFEFloodElement')
-class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEFloodElement" {
+class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEFloodElement" {
 
   // From SVGFilterPrimitiveStandardAttributes
 
@@ -2270,18 +2113,6 @@
   @DomName('SVGFEFloodElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEFloodElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2326,7 +2157,7 @@
 
 @DocsEditable
 @DomName('SVGFEGaussianBlurElement')
-class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEGaussianBlurElement" {
+class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEGaussianBlurElement" {
 
   @DomName('SVGFEGaussianBlurElement.in1')
   @DocsEditable
@@ -2365,18 +2196,6 @@
   @DomName('SVGFEGaussianBlurElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEGaussianBlurElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2385,7 +2204,7 @@
 
 @DocsEditable
 @DomName('SVGFEImageElement')
-class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace native "*SVGFEImageElement" {
+class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace native "*SVGFEImageElement" {
 
   @DomName('SVGFEImageElement.preserveAspectRatio')
   @DocsEditable
@@ -2429,18 +2248,6 @@
   @DocsEditable
   String xmlspace;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEImageElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGURIReference
 
   @DomName('SVGFEImageElement.href')
@@ -2454,7 +2261,7 @@
 
 @DocsEditable
 @DomName('SVGFEMergeElement')
-class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEMergeElement" {
+class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEMergeElement" {
 
   // From SVGFilterPrimitiveStandardAttributes
 
@@ -2477,18 +2284,6 @@
   @DomName('SVGFEMergeElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEMergeElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2510,7 +2305,7 @@
 
 @DocsEditable
 @DomName('SVGFEMorphologyElement')
-class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEMorphologyElement" {
+class FEMorphologyElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEMorphologyElement" {
 
   static const int SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
 
@@ -2559,18 +2354,6 @@
   @DomName('SVGFEMorphologyElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEMorphologyElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2579,7 +2362,7 @@
 
 @DocsEditable
 @DomName('SVGFEOffsetElement')
-class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFEOffsetElement" {
+class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFEOffsetElement" {
 
   @DomName('SVGFEOffsetElement.dx')
   @DocsEditable
@@ -2614,18 +2397,6 @@
   @DomName('SVGFEOffsetElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFEOffsetElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2655,7 +2426,7 @@
 
 @DocsEditable
 @DomName('SVGFESpecularLightingElement')
-class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFESpecularLightingElement" {
+class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFESpecularLightingElement" {
 
   @DomName('SVGFESpecularLightingElement.in1')
   @DocsEditable
@@ -2694,18 +2465,6 @@
   @DomName('SVGFESpecularLightingElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFESpecularLightingElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2755,7 +2514,7 @@
 
 @DocsEditable
 @DomName('SVGFETileElement')
-class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFETileElement" {
+class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFETileElement" {
 
   @DomName('SVGFETileElement.in1')
   @DocsEditable
@@ -2782,18 +2541,6 @@
   @DomName('SVGFETileElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFETileElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2802,7 +2549,7 @@
 
 @DocsEditable
 @DomName('SVGFETurbulenceElement')
-class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes native "*SVGFETurbulenceElement" {
+class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes native "*SVGFETurbulenceElement" {
 
   static const int SVG_STITCHTYPE_NOSTITCH = 2;
 
@@ -2861,18 +2608,6 @@
   @DomName('SVGFETurbulenceElement.y')
   @DocsEditable
   final AnimatedLength y;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFETurbulenceElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -2881,8 +2616,9 @@
 
 @DocsEditable
 @DomName('SVGFilterElement')
-class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable, LangSpace native "*SVGFilterElement" {
+class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired, LangSpace native "*SVGFilterElement" {
 
+  @DomName('SVGFilterElement.SVGFilterElement')
   @DocsEditable
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
 
@@ -2938,18 +2674,6 @@
   @DocsEditable
   String xmlspace;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGFilterElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGURIReference
 
   @DomName('SVGFilterElement.href')
@@ -2962,7 +2686,7 @@
 
 
 @DomName('SVGFilterPrimitiveStandardAttributes')
-abstract class FilterPrimitiveStandardAttributes implements Stylable {
+abstract class FilterPrimitiveStandardAttributes {
 
   AnimatedLength height;
 
@@ -2973,14 +2697,6 @@
   AnimatedLength x;
 
   AnimatedLength y;
-
-  // From SVGStylable
-
-  AnimatedString $dom_svgClassName;
-
-  CssStyleDeclaration style;
-
-  CssValue getPresentationAttribute(String name);
 }
 // 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
@@ -3003,6 +2719,7 @@
 @DomName('SVGFontElement')
 class FontElement extends SvgElement native "*SVGFontElement" {
 
+  @DomName('SVGFontElement.SVGFontElement')
   @DocsEditable
   factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
 }
@@ -3015,6 +2732,7 @@
 @DomName('SVGFontFaceElement')
 class FontFaceElement extends SvgElement native "*SVGFontFaceElement" {
 
+  @DomName('SVGFontFaceElement.SVGFontFaceElement')
   @DocsEditable
   factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
 }
@@ -3027,6 +2745,7 @@
 @DomName('SVGFontFaceFormatElement')
 class FontFaceFormatElement extends SvgElement native "*SVGFontFaceFormatElement" {
 
+  @DomName('SVGFontFaceFormatElement.SVGFontFaceFormatElement')
   @DocsEditable
   factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
 }
@@ -3039,6 +2758,7 @@
 @DomName('SVGFontFaceNameElement')
 class FontFaceNameElement extends SvgElement native "*SVGFontFaceNameElement" {
 
+  @DomName('SVGFontFaceNameElement.SVGFontFaceNameElement')
   @DocsEditable
   factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
 }
@@ -3051,6 +2771,7 @@
 @DomName('SVGFontFaceSrcElement')
 class FontFaceSrcElement extends SvgElement native "*SVGFontFaceSrcElement" {
 
+  @DomName('SVGFontFaceSrcElement.SVGFontFaceSrcElement')
   @DocsEditable
   factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
 }
@@ -3063,6 +2784,7 @@
 @DomName('SVGFontFaceUriElement')
 class FontFaceUriElement extends SvgElement native "*SVGFontFaceUriElement" {
 
+  @DomName('SVGFontFaceUriElement.SVGFontFaceUriElement')
   @DocsEditable
   factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
 }
@@ -3073,8 +2795,9 @@
 
 @DocsEditable
 @DomName('SVGForeignObjectElement')
-class ForeignObjectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGForeignObjectElement" {
+class ForeignObjectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGForeignObjectElement" {
 
+  @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
   @DocsEditable
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
 
@@ -3138,18 +2861,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGForeignObjectElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGForeignObjectElement.requiredExtensions')
@@ -3181,8 +2892,9 @@
 
 @DocsEditable
 @DomName('SVGGElement')
-class GElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGGElement" {
+class GElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGGElement" {
 
+  @DomName('SVGGElement.SVGGElement')
   @DocsEditable
   factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
 
@@ -3230,18 +2942,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGGElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGGElement.requiredExtensions')
@@ -3275,6 +2975,7 @@
 @DomName('SVGGlyphElement')
 class GlyphElement extends SvgElement native "*SVGGlyphElement" {
 
+  @DomName('SVGGlyphElement.SVGGlyphElement')
   @DocsEditable
   factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
 }
@@ -3285,7 +2986,7 @@
 
 @DocsEditable
 @DomName('SVGGlyphRefElement')
-class GlyphRefElement extends SvgElement implements UriReference, Stylable native "*SVGGlyphRefElement" {
+class GlyphRefElement extends StyledElement implements UriReference native "*SVGGlyphRefElement" {
 
   @DomName('SVGGlyphRefElement.dx')
   @DocsEditable
@@ -3311,18 +3012,6 @@
   @DocsEditable
   num y;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGGlyphRefElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGURIReference
 
   @DomName('SVGGlyphRefElement.href')
@@ -3336,7 +3025,7 @@
 
 @DocsEditable
 @DomName('SVGGradientElement')
-class GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable native "*SVGGradientElement" {
+class GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired native "*SVGGradientElement" {
 
   static const int SVG_SPREADMETHOD_PAD = 1;
 
@@ -3364,18 +3053,6 @@
   @DocsEditable
   final AnimatedBoolean externalResourcesRequired;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGGradientElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGURIReference
 
   @DomName('SVGGradientElement.href')
@@ -3391,6 +3068,7 @@
 @DomName('SVGHKernElement')
 class HKernElement extends SvgElement native "*SVGHKernElement" {
 
+  @DomName('SVGHKernElement.SVGHKernElement')
   @DocsEditable
   factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
 }
@@ -3401,8 +3079,9 @@
 
 @DocsEditable
 @DomName('SVGImageElement')
-class ImageElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGImageElement" {
+class ImageElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGImageElement" {
 
+  @DomName('SVGImageElement.SVGImageElement')
   @DocsEditable
   factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
 
@@ -3470,18 +3149,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGImageElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGImageElement.requiredExtensions')
@@ -3622,7 +3289,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Length element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Length element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Length element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Length> where(bool f(Length element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -3636,13 +3307,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Length> takeWhile(bool test(Length value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Length> skipWhile(bool test(Length value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -3685,8 +3356,9 @@
 
   // clear() defined by IDL.
 
-  List<Length> get reversed =>
-      new ReversedListView<Length>(this, 0, null);
+  List<Length> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Length a, Length b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -3802,8 +3474,9 @@
 
 @DocsEditable
 @DomName('SVGLineElement')
-class LineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGLineElement" {
+class LineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGLineElement" {
 
+  @DomName('SVGLineElement.SVGLineElement')
   @DocsEditable
   factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
 
@@ -3867,18 +3540,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGLineElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGLineElement.requiredExtensions')
@@ -3912,6 +3573,7 @@
 @DomName('SVGLinearGradientElement')
 class LinearGradientElement extends GradientElement native "*SVGLinearGradientElement" {
 
+  @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
   @DocsEditable
   factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
 
@@ -3960,6 +3622,7 @@
 @DomName('SVGMPathElement')
 class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired native "*SVGMPathElement" {
 
+  @DomName('SVGMPathElement.SVGMPathElement')
   @DocsEditable
   factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
 
@@ -3982,8 +3645,9 @@
 
 @DocsEditable
 @DomName('SVGMarkerElement')
-class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace native "*SVGMarkerElement" {
+class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace native "*SVGMarkerElement" {
 
+  @DomName('SVGMarkerElement.SVGMarkerElement')
   @DocsEditable
   factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
 
@@ -4060,18 +3724,6 @@
   @DomName('SVGMarkerElement.xmlspace')
   @DocsEditable
   String xmlspace;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGMarkerElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -4080,8 +3732,9 @@
 
 @DocsEditable
 @DomName('SVGMaskElement')
-class MaskElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGMaskElement" {
+class MaskElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace native "*SVGMaskElement" {
 
+  @DomName('SVGMaskElement.SVGMaskElement')
   @DocsEditable
   factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
 
@@ -4125,18 +3778,6 @@
   @DocsEditable
   String xmlspace;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGMaskElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGMaskElement.requiredExtensions')
@@ -4248,7 +3889,7 @@
 
 @DocsEditable
 @DomName('SVGMissingGlyphElement')
-class MissingGlyphElement extends SvgElement native "*SVGMissingGlyphElement" {
+class MissingGlyphElement extends StyledElement native "*SVGMissingGlyphElement" {
 }
 // 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
@@ -4306,7 +3947,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Number element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Number element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Number element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Number> where(bool f(Number element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -4320,13 +3965,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Number> takeWhile(bool test(Number value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Number> skipWhile(bool test(Number value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -4369,8 +4014,9 @@
 
   // clear() defined by IDL.
 
-  List<Number> get reversed =>
-      new ReversedListView<Number>(this, 0, null);
+  List<Number> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Number a, Number b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -4531,8 +4177,9 @@
 
 @DocsEditable
 @DomName('SVGPathElement')
-class PathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPathElement" {
+class PathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGPathElement" {
 
+  @DomName('SVGPathElement.SVGPathElement')
   @DocsEditable
   factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
 
@@ -4707,18 +4354,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGPathElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGPathElement.requiredExtensions')
@@ -5212,7 +4847,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(PathSeg element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(PathSeg element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(PathSeg element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<PathSeg> where(bool f(PathSeg element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -5226,13 +4865,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<PathSeg> takeWhile(bool test(PathSeg value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<PathSeg> skipWhile(bool test(PathSeg value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -5275,8 +4914,9 @@
 
   // clear() defined by IDL.
 
-  List<PathSeg> get reversed =>
-      new ReversedListView<PathSeg>(this, 0, null);
+  List<PathSeg> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(PathSeg a, PathSeg b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -5426,8 +5066,9 @@
 
 @DocsEditable
 @DomName('SVGPatternElement')
-class PatternElement extends SvgElement implements FitToViewBox, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPatternElement" {
+class PatternElement extends StyledElement implements FitToViewBox, UriReference, Tests, ExternalResourcesRequired, LangSpace native "*SVGPatternElement" {
 
+  @DomName('SVGPatternElement.SVGPatternElement')
   @DocsEditable
   factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
 
@@ -5485,18 +5126,6 @@
   @DocsEditable
   String xmlspace;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGPatternElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGPatternElement.requiredExtensions')
@@ -5590,8 +5219,9 @@
 
 @DocsEditable
 @DomName('SVGPolygonElement')
-class PolygonElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPolygonElement" {
+class PolygonElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGPolygonElement" {
 
+  @DomName('SVGPolygonElement.SVGPolygonElement')
   @DocsEditable
   factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
 
@@ -5647,18 +5277,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGPolygonElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGPolygonElement.requiredExtensions')
@@ -5690,8 +5308,9 @@
 
 @DocsEditable
 @DomName('SVGPolylineElement')
-class PolylineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGPolylineElement" {
+class PolylineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGPolylineElement" {
 
+  @DomName('SVGPolylineElement.SVGPolylineElement')
   @DocsEditable
   factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
 
@@ -5747,18 +5366,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGPolylineElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGPolylineElement.requiredExtensions')
@@ -5837,6 +5444,7 @@
 @DomName('SVGRadialGradientElement')
 class RadialGradientElement extends GradientElement native "*SVGRadialGradientElement" {
 
+  @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
   @DocsEditable
   factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
 
@@ -5896,8 +5504,9 @@
 
 @DocsEditable
 @DomName('SVGRectElement')
-class RectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGRectElement" {
+class RectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGRectElement" {
 
+  @DomName('SVGRectElement.SVGRectElement')
   @DocsEditable
   factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
 
@@ -5969,18 +5578,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGRectElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGRectElement.requiredExtensions')
@@ -6035,6 +5632,7 @@
 @DomName('SVGScriptElement')
 class ScriptElement extends SvgElement implements UriReference, ExternalResourcesRequired native "*SVGScriptElement" {
 
+  @DomName('SVGScriptElement.SVGScriptElement')
   @DocsEditable
   factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
 
@@ -6063,6 +5661,7 @@
 @DomName('SVGSetElement')
 class SetElement extends AnimationElement native "*SVGSetElement" {
 
+  @DomName('SVGSetElement.SVGSetElement')
   @DocsEditable
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
 }
@@ -6073,26 +5672,15 @@
 
 @DocsEditable
 @DomName('SVGStopElement')
-class StopElement extends SvgElement implements Stylable native "*SVGStopElement" {
+class StopElement extends StyledElement native "*SVGStopElement" {
 
+  @DomName('SVGStopElement.SVGStopElement')
   @DocsEditable
   factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
 
   @DomName('SVGStopElement.offset')
   @DocsEditable
   final AnimatedNumber offset;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGStopElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -6137,7 +5725,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(String element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(String element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -6151,13 +5743,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<String> takeWhile(bool test(String value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<String> skipWhile(bool test(String value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -6200,8 +5792,9 @@
 
   // clear() defined by IDL.
 
-  List<String> get reversed =>
-      new ReversedListView<String>(this, 0, null);
+  List<String> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(String a, String b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -6315,24 +5908,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-@DomName('SVGStylable')
-abstract class Stylable {
-
-  AnimatedString $dom_svgClassName;
-
-  CssStyleDeclaration style;
-
-  CssValue getPresentationAttribute(String name);
-}
-// 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.
-
-
 @DocsEditable
 @DomName('SVGStyleElement')
 class StyleElement extends SvgElement implements LangSpace native "*SVGStyleElement" {
 
+  @DomName('SVGStyleElement.SVGStyleElement')
   @DocsEditable
   factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
 
@@ -6371,6 +5951,25 @@
 
 
 @DocsEditable
+@DomName('SVGStyledElement')
+class StyledElement extends SvgElement native "*SVGStyledElement" {
+
+  // Shadowing definition.
+  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
+
+  // Use implementation from Element.
+  // final CssStyleDeclaration style;
+
+  @DomName('SVGStyledElement.getPresentationAttribute')
+  @DocsEditable
+  CssValue getPresentationAttribute(String name) 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
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('SVGDocument')
 class SvgDocument extends Document native "*SVGDocument" {
 
@@ -6555,7 +6154,7 @@
 
 
 @DomName('SVGSVGElement')
-class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace native "*SVGSVGElement" {
+class SvgSvgElement extends StyledElement implements FitToViewBox, Transformable, Tests, ExternalResourcesRequired, ZoomAndPan, LangSpace native "*SVGSVGElement" {
   factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
 
 
@@ -6777,18 +6376,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGSVGElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGSVGElement.requiredExtensions')
@@ -6807,6 +6394,12 @@
   @DocsEditable
   bool hasExtension(String extension) native;
 
+  // From SVGTransformable
+
+  @DomName('SVGSVGElement.transform')
+  @DocsEditable
+  final AnimatedTransformList transform;
+
   // From SVGZoomAndPan
 
   @DomName('SVGSVGElement.zoomAndPan')
@@ -6821,8 +6414,9 @@
 
 @DocsEditable
 @DomName('SVGSwitchElement')
-class SwitchElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGSwitchElement" {
+class SwitchElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace native "*SVGSwitchElement" {
 
+  @DomName('SVGSwitchElement.SVGSwitchElement')
   @DocsEditable
   factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
 
@@ -6870,18 +6464,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGSwitchElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGSwitchElement.requiredExtensions')
@@ -6913,8 +6495,9 @@
 
 @DocsEditable
 @DomName('SVGSymbolElement')
-class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace native "*SVGSymbolElement" {
+class SymbolElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace native "*SVGSymbolElement" {
 
+  @DomName('SVGSymbolElement.SVGSymbolElement')
   @DocsEditable
   factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
 
@@ -6943,18 +6526,6 @@
   @DomName('SVGSymbolElement.xmlspace')
   @DocsEditable
   String xmlspace;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGSymbolElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -6965,6 +6536,7 @@
 @DomName('SVGTRefElement')
 class TRefElement extends TextPositioningElement implements UriReference native "*SVGTRefElement" {
 
+  @DomName('SVGTRefElement.SVGTRefElement')
   @DocsEditable
   factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
 
@@ -6983,6 +6555,7 @@
 @DomName('SVGTSpanElement')
 class TSpanElement extends TextPositioningElement native "*SVGTSpanElement" {
 
+  @DomName('SVGTSpanElement.SVGTSpanElement')
   @DocsEditable
   factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
 }
@@ -7009,7 +6582,7 @@
 
 @DocsEditable
 @DomName('SVGTextContentElement')
-class TextContentElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace native "*SVGTextContentElement" {
+class TextContentElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace native "*SVGTextContentElement" {
 
   static const int LENGTHADJUST_SPACING = 1;
 
@@ -7077,18 +6650,6 @@
   @DocsEditable
   String xmlspace;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGTextContentElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGTextContentElement.requiredExtensions')
@@ -7116,6 +6677,7 @@
 @DomName('SVGTextElement')
 class TextElement extends TextPositioningElement implements Transformable native "*SVGTextElement" {
 
+  @DomName('SVGTextElement.SVGTextElement')
   @DocsEditable
   factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
 
@@ -7228,8 +6790,9 @@
 
 @DocsEditable
 @DomName('SVGTitleElement')
-class TitleElement extends SvgElement implements Stylable, LangSpace native "*SVGTitleElement" {
+class TitleElement extends StyledElement implements LangSpace native "*SVGTitleElement" {
 
+  @DomName('SVGTitleElement.SVGTitleElement')
   @DocsEditable
   factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
 
@@ -7242,18 +6805,6 @@
   @DomName('SVGTitleElement.xmlspace')
   @DocsEditable
   String xmlspace;
-
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGTitleElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) 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
@@ -7357,7 +6908,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Transform element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Transform element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Transform element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Transform> where(bool f(Transform element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7371,13 +6926,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Transform> takeWhile(bool test(Transform value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Transform> skipWhile(bool test(Transform value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -7420,8 +6975,9 @@
 
   // clear() defined by IDL.
 
-  List<Transform> get reversed =>
-      new ReversedListView<Transform>(this, 0, null);
+  List<Transform> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Transform a, Transform b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -7595,8 +7151,9 @@
 
 @DocsEditable
 @DomName('SVGUseElement')
-class UseElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace native "*SVGUseElement" {
+class UseElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace native "*SVGUseElement" {
 
+  @DomName('SVGUseElement.SVGUseElement')
   @DocsEditable
   factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
 
@@ -7668,18 +7225,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native;
 
-  // From SVGStylable
-
-  // Shadowing definition.
-  AnimatedString get $dom_svgClassName => JS("AnimatedString", "#.className", this);
-
-  // Use implementation from Element.
-  // final CssStyleDeclaration style;
-
-  @DomName('SVGUseElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native;
-
   // From SVGTests
 
   @DomName('SVGUseElement.requiredExtensions')
@@ -7719,6 +7264,7 @@
 @DomName('SVGVKernElement')
 class VKernElement extends SvgElement native "*SVGVKernElement" {
 
+  @DomName('SVGVKernElement.SVGVKernElement')
   @DocsEditable
   factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
 }
@@ -7731,6 +7277,7 @@
 @DomName('SVGViewElement')
 class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan native "*SVGViewElement" {
 
+  @DomName('SVGViewElement.SVGViewElement')
   @DocsEditable
   factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
 
@@ -7891,7 +7438,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(ElementInstance element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(ElementInstance element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(ElementInstance element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<ElementInstance> where(bool f(ElementInstance element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -7905,13 +7456,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<ElementInstance> takeWhile(bool test(ElementInstance value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<ElementInstance> skipWhile(bool test(ElementInstance value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -7956,8 +7507,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ElementInstance> get reversed =>
-      new ReversedListView<ElementInstance>(this, 0, null);
+  List<ElementInstance> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(ElementInstance a, ElementInstance b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 8463359..17a4b29 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -1,8 +1,7 @@
-library svg;
+library dart.dom.svg;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
@@ -62,9 +61,10 @@
 
 @DocsEditable
 @DomName('SVGAElement')
-class AElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class AElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
   AElement.internal() : super.internal();
 
+  @DomName('SVGAElement.SVGAElement')
   @DocsEditable
   factory AElement() => _SvgElementFactoryProvider.createSvgElement_tag("a");
 
@@ -116,18 +116,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGAElement_getTransformToElement_Callback";
 
-  @DomName('SVGAElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGAElement_className_Getter";
-
-  @DomName('SVGAElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGAElement_style_Getter";
-
-  @DomName('SVGAElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGAElement_getPresentationAttribute_Callback";
-
   @DomName('SVGAElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGAElement_requiredExtensions_Getter";
@@ -283,6 +271,7 @@
 class AnimateColorElement extends AnimationElement {
   AnimateColorElement.internal() : super.internal();
 
+  @DomName('SVGAnimateColorElement.SVGAnimateColorElement')
   @DocsEditable
   factory AnimateColorElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateColor");
 
@@ -299,6 +288,7 @@
 class AnimateElement extends AnimationElement {
   AnimateElement.internal() : super.internal();
 
+  @DomName('SVGAnimateElement.SVGAnimateElement')
   @DocsEditable
   factory AnimateElement() => _SvgElementFactoryProvider.createSvgElement_tag("animate");
 
@@ -315,6 +305,7 @@
 class AnimateMotionElement extends AnimationElement {
   AnimateMotionElement.internal() : super.internal();
 
+  @DomName('SVGAnimateMotionElement.SVGAnimateMotionElement')
   @DocsEditable
   factory AnimateMotionElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateMotion");
 
@@ -331,6 +322,7 @@
 class AnimateTransformElement extends AnimationElement {
   AnimateTransformElement.internal() : super.internal();
 
+  @DomName('SVGAnimateTransformElement.SVGAnimateTransformElement')
   @DocsEditable
   factory AnimateTransformElement() => _SvgElementFactoryProvider.createSvgElement_tag("animateTransform");
 
@@ -619,6 +611,7 @@
 class AnimationElement extends SvgElement implements Tests, ElementTimeControl, ExternalResourcesRequired {
   AnimationElement.internal() : super.internal();
 
+  @DomName('SVGAnimationElement.SVGAnimationElement')
   @DocsEditable
   factory AnimationElement() => _SvgElementFactoryProvider.createSvgElement_tag("animation");
 
@@ -684,9 +677,10 @@
 
 @DocsEditable
 @DomName('SVGCircleElement')
-class CircleElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class CircleElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   CircleElement.internal() : super.internal();
 
+  @DomName('SVGCircleElement.SVGCircleElement')
   @DocsEditable
   factory CircleElement() => _SvgElementFactoryProvider.createSvgElement_tag("circle");
 
@@ -746,18 +740,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGCircleElement_getTransformToElement_Callback";
 
-  @DomName('SVGCircleElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGCircleElement_className_Getter";
-
-  @DomName('SVGCircleElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGCircleElement_style_Getter";
-
-  @DomName('SVGCircleElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGCircleElement_getPresentationAttribute_Callback";
-
   @DomName('SVGCircleElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGCircleElement_requiredExtensions_Getter";
@@ -788,9 +770,10 @@
 
 @DocsEditable
 @DomName('SVGClipPathElement')
-class ClipPathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class ClipPathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   ClipPathElement.internal() : super.internal();
 
+  @DomName('SVGClipPathElement.SVGClipPathElement')
   @DocsEditable
   factory ClipPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("clipPath");
 
@@ -842,18 +825,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGClipPathElement_getTransformToElement_Callback";
 
-  @DomName('SVGClipPathElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGClipPathElement_className_Getter";
-
-  @DomName('SVGClipPathElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGClipPathElement_style_Getter";
-
-  @DomName('SVGClipPathElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGClipPathElement_getPresentationAttribute_Callback";
-
   @DomName('SVGClipPathElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGClipPathElement_requiredExtensions_Getter";
@@ -981,6 +952,7 @@
 class CursorElement extends SvgElement implements UriReference, Tests, ExternalResourcesRequired {
   CursorElement.internal() : super.internal();
 
+  @DomName('SVGCursorElement.SVGCursorElement')
   @DocsEditable
   factory CursorElement() => _SvgElementFactoryProvider.createSvgElement_tag("cursor");
 
@@ -1026,9 +998,10 @@
 
 @DocsEditable
 @DomName('SVGDefsElement')
-class DefsElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class DefsElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   DefsElement.internal() : super.internal();
 
+  @DomName('SVGDefsElement.SVGDefsElement')
   @DocsEditable
   factory DefsElement() => _SvgElementFactoryProvider.createSvgElement_tag("defs");
 
@@ -1076,18 +1049,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGDefsElement_getTransformToElement_Callback";
 
-  @DomName('SVGDefsElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGDefsElement_className_Getter";
-
-  @DomName('SVGDefsElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGDefsElement_style_Getter";
-
-  @DomName('SVGDefsElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGDefsElement_getPresentationAttribute_Callback";
-
   @DomName('SVGDefsElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGDefsElement_requiredExtensions_Getter";
@@ -1118,9 +1079,10 @@
 
 @DocsEditable
 @DomName('SVGDescElement')
-class DescElement extends SvgElement implements Stylable, LangSpace {
+class DescElement extends StyledElement implements LangSpace {
   DescElement.internal() : super.internal();
 
+  @DomName('SVGDescElement.SVGDescElement')
   @DocsEditable
   factory DescElement() => _SvgElementFactoryProvider.createSvgElement_tag("desc");
 
@@ -1140,18 +1102,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGDescElement_xmlspace_Setter";
 
-  @DomName('SVGDescElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGDescElement_className_Getter";
-
-  @DomName('SVGDescElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGDescElement_style_Getter";
-
-  @DomName('SVGDescElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGDescElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -1689,9 +1639,10 @@
 
 @DocsEditable
 @DomName('SVGEllipseElement')
-class EllipseElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class EllipseElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   EllipseElement.internal() : super.internal();
 
+  @DomName('SVGEllipseElement.SVGEllipseElement')
   @DocsEditable
   factory EllipseElement() => _SvgElementFactoryProvider.createSvgElement_tag("ellipse");
 
@@ -1755,18 +1706,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGEllipseElement_getTransformToElement_Callback";
 
-  @DomName('SVGEllipseElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGEllipseElement_className_Getter";
-
-  @DomName('SVGEllipseElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGEllipseElement_style_Getter";
-
-  @DomName('SVGEllipseElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGEllipseElement_getPresentationAttribute_Callback";
-
   @DomName('SVGEllipseElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGEllipseElement_requiredExtensions_Getter";
@@ -1814,7 +1753,7 @@
 
 @DocsEditable
 @DomName('SVGFEBlendElement')
-class FEBlendElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEBlendElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEBlendElement.internal() : super.internal();
 
   static const int SVG_FEBLEND_MODE_DARKEN = 4;
@@ -1861,18 +1800,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEBlendElement_y_Getter";
 
-  @DomName('SVGFEBlendElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEBlendElement_className_Getter";
-
-  @DomName('SVGFEBlendElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEBlendElement_style_Getter";
-
-  @DomName('SVGFEBlendElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEBlendElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -1883,7 +1810,7 @@
 
 @DocsEditable
 @DomName('SVGFEColorMatrixElement')
-class FEColorMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEColorMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEColorMatrixElement.internal() : super.internal();
 
   static const int SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
@@ -1928,18 +1855,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEColorMatrixElement_y_Getter";
 
-  @DomName('SVGFEColorMatrixElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEColorMatrixElement_className_Getter";
-
-  @DomName('SVGFEColorMatrixElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEColorMatrixElement_style_Getter";
-
-  @DomName('SVGFEColorMatrixElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEColorMatrixElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -1950,7 +1865,7 @@
 
 @DocsEditable
 @DomName('SVGFEComponentTransferElement')
-class FEComponentTransferElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEComponentTransferElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEComponentTransferElement.internal() : super.internal();
 
   @DomName('SVGFEComponentTransferElement.in1')
@@ -1977,18 +1892,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEComponentTransferElement_y_Getter";
 
-  @DomName('SVGFEComponentTransferElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEComponentTransferElement_className_Getter";
-
-  @DomName('SVGFEComponentTransferElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEComponentTransferElement_style_Getter";
-
-  @DomName('SVGFEComponentTransferElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEComponentTransferElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -1999,7 +1902,7 @@
 
 @DocsEditable
 @DomName('SVGFECompositeElement')
-class FECompositeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FECompositeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FECompositeElement.internal() : super.internal();
 
   static const int SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
@@ -2064,18 +1967,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFECompositeElement_y_Getter";
 
-  @DomName('SVGFECompositeElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFECompositeElement_className_Getter";
-
-  @DomName('SVGFECompositeElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFECompositeElement_style_Getter";
-
-  @DomName('SVGFECompositeElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFECompositeElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2086,7 +1977,7 @@
 
 @DocsEditable
 @DomName('SVGFEConvolveMatrixElement')
-class FEConvolveMatrixElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEConvolveMatrixElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEConvolveMatrixElement.internal() : super.internal();
 
   static const int SVG_EDGEMODE_DUPLICATE = 1;
@@ -2165,18 +2056,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEConvolveMatrixElement_y_Getter";
 
-  @DomName('SVGFEConvolveMatrixElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEConvolveMatrixElement_className_Getter";
-
-  @DomName('SVGFEConvolveMatrixElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEConvolveMatrixElement_style_Getter";
-
-  @DomName('SVGFEConvolveMatrixElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEConvolveMatrixElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2187,7 +2066,7 @@
 
 @DocsEditable
 @DomName('SVGFEDiffuseLightingElement')
-class FEDiffuseLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEDiffuseLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEDiffuseLightingElement.internal() : super.internal();
 
   @DomName('SVGFEDiffuseLightingElement.diffuseConstant')
@@ -2230,18 +2109,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEDiffuseLightingElement_y_Getter";
 
-  @DomName('SVGFEDiffuseLightingElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEDiffuseLightingElement_className_Getter";
-
-  @DomName('SVGFEDiffuseLightingElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEDiffuseLightingElement_style_Getter";
-
-  @DomName('SVGFEDiffuseLightingElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEDiffuseLightingElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2252,7 +2119,7 @@
 
 @DocsEditable
 @DomName('SVGFEDisplacementMapElement')
-class FEDisplacementMapElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEDisplacementMapElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEDisplacementMapElement.internal() : super.internal();
 
   static const int SVG_CHANNEL_A = 4;
@@ -2305,18 +2172,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEDisplacementMapElement_y_Getter";
 
-  @DomName('SVGFEDisplacementMapElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEDisplacementMapElement_className_Getter";
-
-  @DomName('SVGFEDisplacementMapElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEDisplacementMapElement_style_Getter";
-
-  @DomName('SVGFEDisplacementMapElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEDisplacementMapElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2348,7 +2203,7 @@
 
 @DocsEditable
 @DomName('SVGFEDropShadowElement')
-class FEDropShadowElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEDropShadowElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEDropShadowElement.internal() : super.internal();
 
   @DomName('SVGFEDropShadowElement.dx')
@@ -2395,18 +2250,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEDropShadowElement_y_Getter";
 
-  @DomName('SVGFEDropShadowElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEDropShadowElement_className_Getter";
-
-  @DomName('SVGFEDropShadowElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEDropShadowElement_style_Getter";
-
-  @DomName('SVGFEDropShadowElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEDropShadowElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2417,7 +2260,7 @@
 
 @DocsEditable
 @DomName('SVGFEFloodElement')
-class FEFloodElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEFloodElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEFloodElement.internal() : super.internal();
 
   @DomName('SVGFEFloodElement.height')
@@ -2440,18 +2283,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEFloodElement_y_Getter";
 
-  @DomName('SVGFEFloodElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEFloodElement_className_Getter";
-
-  @DomName('SVGFEFloodElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEFloodElement_style_Getter";
-
-  @DomName('SVGFEFloodElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEFloodElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2514,7 +2345,7 @@
 
 @DocsEditable
 @DomName('SVGFEGaussianBlurElement')
-class FEGaussianBlurElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEGaussianBlurElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEGaussianBlurElement.internal() : super.internal();
 
   @DomName('SVGFEGaussianBlurElement.in1')
@@ -2553,18 +2384,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEGaussianBlurElement_y_Getter";
 
-  @DomName('SVGFEGaussianBlurElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEGaussianBlurElement_className_Getter";
-
-  @DomName('SVGFEGaussianBlurElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEGaussianBlurElement_style_Getter";
-
-  @DomName('SVGFEGaussianBlurElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEGaussianBlurElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2575,7 +2394,7 @@
 
 @DocsEditable
 @DomName('SVGFEImageElement')
-class FEImageElement extends SvgElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace {
+class FEImageElement extends StyledElement implements FilterPrimitiveStandardAttributes, UriReference, ExternalResourcesRequired, LangSpace {
   FEImageElement.internal() : super.internal();
 
   @DomName('SVGFEImageElement.preserveAspectRatio')
@@ -2622,18 +2441,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGFEImageElement_xmlspace_Setter";
 
-  @DomName('SVGFEImageElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEImageElement_className_Getter";
-
-  @DomName('SVGFEImageElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEImageElement_style_Getter";
-
-  @DomName('SVGFEImageElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEImageElement_getPresentationAttribute_Callback";
-
   @DomName('SVGFEImageElement.href')
   @DocsEditable
   AnimatedString get href native "SVGFEImageElement_href_Getter";
@@ -2648,7 +2455,7 @@
 
 @DocsEditable
 @DomName('SVGFEMergeElement')
-class FEMergeElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEMergeElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEMergeElement.internal() : super.internal();
 
   @DomName('SVGFEMergeElement.height')
@@ -2671,18 +2478,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEMergeElement_y_Getter";
 
-  @DomName('SVGFEMergeElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEMergeElement_className_Getter";
-
-  @DomName('SVGFEMergeElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEMergeElement_style_Getter";
-
-  @DomName('SVGFEMergeElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEMergeElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2710,7 +2505,7 @@
 
 @DocsEditable
 @DomName('SVGFEMorphologyElement')
-class FEMorphologyElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEMorphologyElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEMorphologyElement.internal() : super.internal();
 
   static const int SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
@@ -2759,18 +2554,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEMorphologyElement_y_Getter";
 
-  @DomName('SVGFEMorphologyElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEMorphologyElement_className_Getter";
-
-  @DomName('SVGFEMorphologyElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEMorphologyElement_style_Getter";
-
-  @DomName('SVGFEMorphologyElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEMorphologyElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2781,7 +2564,7 @@
 
 @DocsEditable
 @DomName('SVGFEOffsetElement')
-class FEOffsetElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FEOffsetElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FEOffsetElement.internal() : super.internal();
 
   @DomName('SVGFEOffsetElement.dx')
@@ -2816,18 +2599,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFEOffsetElement_y_Getter";
 
-  @DomName('SVGFEOffsetElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFEOffsetElement_className_Getter";
-
-  @DomName('SVGFEOffsetElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFEOffsetElement_style_Getter";
-
-  @DomName('SVGFEOffsetElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFEOffsetElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2863,7 +2634,7 @@
 
 @DocsEditable
 @DomName('SVGFESpecularLightingElement')
-class FESpecularLightingElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FESpecularLightingElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FESpecularLightingElement.internal() : super.internal();
 
   @DomName('SVGFESpecularLightingElement.in1')
@@ -2902,18 +2673,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFESpecularLightingElement_y_Getter";
 
-  @DomName('SVGFESpecularLightingElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFESpecularLightingElement_className_Getter";
-
-  @DomName('SVGFESpecularLightingElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFESpecularLightingElement_style_Getter";
-
-  @DomName('SVGFESpecularLightingElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFESpecularLightingElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -2969,7 +2728,7 @@
 
 @DocsEditable
 @DomName('SVGFETileElement')
-class FETileElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FETileElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FETileElement.internal() : super.internal();
 
   @DomName('SVGFETileElement.in1')
@@ -2996,18 +2755,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFETileElement_y_Getter";
 
-  @DomName('SVGFETileElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFETileElement_className_Getter";
-
-  @DomName('SVGFETileElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFETileElement_style_Getter";
-
-  @DomName('SVGFETileElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFETileElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -3018,7 +2765,7 @@
 
 @DocsEditable
 @DomName('SVGFETurbulenceElement')
-class FETurbulenceElement extends SvgElement implements FilterPrimitiveStandardAttributes {
+class FETurbulenceElement extends StyledElement implements FilterPrimitiveStandardAttributes {
   FETurbulenceElement.internal() : super.internal();
 
   static const int SVG_STITCHTYPE_NOSTITCH = 2;
@@ -3077,18 +2824,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFETurbulenceElement_y_Getter";
 
-  @DomName('SVGFETurbulenceElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFETurbulenceElement_className_Getter";
-
-  @DomName('SVGFETurbulenceElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFETurbulenceElement_style_Getter";
-
-  @DomName('SVGFETurbulenceElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFETurbulenceElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -3099,9 +2834,10 @@
 
 @DocsEditable
 @DomName('SVGFilterElement')
-class FilterElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable, LangSpace {
+class FilterElement extends StyledElement implements UriReference, ExternalResourcesRequired, LangSpace {
   FilterElement.internal() : super.internal();
 
+  @DomName('SVGFilterElement.SVGFilterElement')
   @DocsEditable
   factory FilterElement() => _SvgElementFactoryProvider.createSvgElement_tag("filter");
 
@@ -3161,18 +2897,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGFilterElement_xmlspace_Setter";
 
-  @DomName('SVGFilterElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFilterElement_className_Getter";
-
-  @DomName('SVGFilterElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFilterElement_style_Getter";
-
-  @DomName('SVGFilterElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFilterElement_getPresentationAttribute_Callback";
-
   @DomName('SVGFilterElement.href')
   @DocsEditable
   AnimatedString get href native "SVGFilterElement_href_Getter";
@@ -3187,7 +2911,7 @@
 
 @DocsEditable
 @DomName('SVGFilterPrimitiveStandardAttributes')
-class FilterPrimitiveStandardAttributes extends NativeFieldWrapperClass1 implements Stylable {
+class FilterPrimitiveStandardAttributes extends NativeFieldWrapperClass1 {
   FilterPrimitiveStandardAttributes.internal();
 
   @DomName('SVGFilterPrimitiveStandardAttributes.height')
@@ -3210,18 +2934,6 @@
   @DocsEditable
   AnimatedLength get y native "SVGFilterPrimitiveStandardAttributes_y_Getter";
 
-  @DomName('SVGFilterPrimitiveStandardAttributes.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGFilterPrimitiveStandardAttributes_className_Getter";
-
-  @DomName('SVGFilterPrimitiveStandardAttributes.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGFilterPrimitiveStandardAttributes_style_Getter";
-
-  @DomName('SVGFilterPrimitiveStandardAttributes.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGFilterPrimitiveStandardAttributes_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -3256,6 +2968,7 @@
 class FontElement extends SvgElement {
   FontElement.internal() : super.internal();
 
+  @DomName('SVGFontElement.SVGFontElement')
   @DocsEditable
   factory FontElement() => _SvgElementFactoryProvider.createSvgElement_tag("font");
 
@@ -3272,6 +2985,7 @@
 class FontFaceElement extends SvgElement {
   FontFaceElement.internal() : super.internal();
 
+  @DomName('SVGFontFaceElement.SVGFontFaceElement')
   @DocsEditable
   factory FontFaceElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face");
 
@@ -3288,6 +3002,7 @@
 class FontFaceFormatElement extends SvgElement {
   FontFaceFormatElement.internal() : super.internal();
 
+  @DomName('SVGFontFaceFormatElement.SVGFontFaceFormatElement')
   @DocsEditable
   factory FontFaceFormatElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-format");
 
@@ -3304,6 +3019,7 @@
 class FontFaceNameElement extends SvgElement {
   FontFaceNameElement.internal() : super.internal();
 
+  @DomName('SVGFontFaceNameElement.SVGFontFaceNameElement')
   @DocsEditable
   factory FontFaceNameElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-name");
 
@@ -3320,6 +3036,7 @@
 class FontFaceSrcElement extends SvgElement {
   FontFaceSrcElement.internal() : super.internal();
 
+  @DomName('SVGFontFaceSrcElement.SVGFontFaceSrcElement')
   @DocsEditable
   factory FontFaceSrcElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-src");
 
@@ -3336,6 +3053,7 @@
 class FontFaceUriElement extends SvgElement {
   FontFaceUriElement.internal() : super.internal();
 
+  @DomName('SVGFontFaceUriElement.SVGFontFaceUriElement')
   @DocsEditable
   factory FontFaceUriElement() => _SvgElementFactoryProvider.createSvgElement_tag("font-face-uri");
 
@@ -3349,9 +3067,10 @@
 
 @DocsEditable
 @DomName('SVGForeignObjectElement')
-class ForeignObjectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class ForeignObjectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   ForeignObjectElement.internal() : super.internal();
 
+  @DomName('SVGForeignObjectElement.SVGForeignObjectElement')
   @DocsEditable
   factory ForeignObjectElement() => _SvgElementFactoryProvider.createSvgElement_tag("foreignObject");
 
@@ -3415,18 +3134,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGForeignObjectElement_getTransformToElement_Callback";
 
-  @DomName('SVGForeignObjectElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGForeignObjectElement_className_Getter";
-
-  @DomName('SVGForeignObjectElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGForeignObjectElement_style_Getter";
-
-  @DomName('SVGForeignObjectElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGForeignObjectElement_getPresentationAttribute_Callback";
-
   @DomName('SVGForeignObjectElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGForeignObjectElement_requiredExtensions_Getter";
@@ -3457,9 +3164,10 @@
 
 @DocsEditable
 @DomName('SVGGElement')
-class GElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class GElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   GElement.internal() : super.internal();
 
+  @DomName('SVGGElement.SVGGElement')
   @DocsEditable
   factory GElement() => _SvgElementFactoryProvider.createSvgElement_tag("g");
 
@@ -3507,18 +3215,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGGElement_getTransformToElement_Callback";
 
-  @DomName('SVGGElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGGElement_className_Getter";
-
-  @DomName('SVGGElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGGElement_style_Getter";
-
-  @DomName('SVGGElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGGElement_getPresentationAttribute_Callback";
-
   @DomName('SVGGElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGGElement_requiredExtensions_Getter";
@@ -3552,6 +3248,7 @@
 class GlyphElement extends SvgElement {
   GlyphElement.internal() : super.internal();
 
+  @DomName('SVGGlyphElement.SVGGlyphElement')
   @DocsEditable
   factory GlyphElement() => _SvgElementFactoryProvider.createSvgElement_tag("glyph");
 
@@ -3565,7 +3262,7 @@
 
 @DocsEditable
 @DomName('SVGGlyphRefElement')
-class GlyphRefElement extends SvgElement implements UriReference, Stylable {
+class GlyphRefElement extends StyledElement implements UriReference {
   GlyphRefElement.internal() : super.internal();
 
   @DomName('SVGGlyphRefElement.dx')
@@ -3616,18 +3313,6 @@
   @DocsEditable
   void set y(num value) native "SVGGlyphRefElement_y_Setter";
 
-  @DomName('SVGGlyphRefElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGGlyphRefElement_className_Getter";
-
-  @DomName('SVGGlyphRefElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGGlyphRefElement_style_Getter";
-
-  @DomName('SVGGlyphRefElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGGlyphRefElement_getPresentationAttribute_Callback";
-
   @DomName('SVGGlyphRefElement.href')
   @DocsEditable
   AnimatedString get href native "SVGGlyphRefElement_href_Getter";
@@ -3642,7 +3327,7 @@
 
 @DocsEditable
 @DomName('SVGGradientElement')
-class GradientElement extends SvgElement implements UriReference, ExternalResourcesRequired, Stylable {
+class GradientElement extends StyledElement implements UriReference, ExternalResourcesRequired {
   GradientElement.internal() : super.internal();
 
   static const int SVG_SPREADMETHOD_PAD = 1;
@@ -3669,18 +3354,6 @@
   @DocsEditable
   AnimatedBoolean get externalResourcesRequired native "SVGGradientElement_externalResourcesRequired_Getter";
 
-  @DomName('SVGGradientElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGGradientElement_className_Getter";
-
-  @DomName('SVGGradientElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGGradientElement_style_Getter";
-
-  @DomName('SVGGradientElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGGradientElement_getPresentationAttribute_Callback";
-
   @DomName('SVGGradientElement.href')
   @DocsEditable
   AnimatedString get href native "SVGGradientElement_href_Getter";
@@ -3698,6 +3371,7 @@
 class HKernElement extends SvgElement {
   HKernElement.internal() : super.internal();
 
+  @DomName('SVGHKernElement.SVGHKernElement')
   @DocsEditable
   factory HKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("hkern");
 
@@ -3711,9 +3385,10 @@
 
 @DocsEditable
 @DomName('SVGImageElement')
-class ImageElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class ImageElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
   ImageElement.internal() : super.internal();
 
+  @DomName('SVGImageElement.SVGImageElement')
   @DocsEditable
   factory ImageElement() => _SvgElementFactoryProvider.createSvgElement_tag("image");
 
@@ -3781,18 +3456,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGImageElement_getTransformToElement_Callback";
 
-  @DomName('SVGImageElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGImageElement_className_Getter";
-
-  @DomName('SVGImageElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGImageElement_style_Getter";
-
-  @DomName('SVGImageElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGImageElement_getPresentationAttribute_Callback";
-
   @DomName('SVGImageElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGImageElement_requiredExtensions_Getter";
@@ -3964,7 +3627,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Length element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Length element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Length element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Length> where(bool f(Length element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -3978,13 +3645,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Length> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Length> takeWhile(bool test(Length value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Length> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Length> skipWhile(bool test(Length value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -4027,8 +3694,9 @@
 
   // clear() defined by IDL.
 
-  List<Length> get reversed =>
-      new ReversedListView<Length>(this, 0, null);
+  List<Length> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Length a, Length b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -4147,9 +3815,10 @@
 
 @DocsEditable
 @DomName('SVGLineElement')
-class LineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class LineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   LineElement.internal() : super.internal();
 
+  @DomName('SVGLineElement.SVGLineElement')
   @DocsEditable
   factory LineElement() => _SvgElementFactoryProvider.createSvgElement_tag("line");
 
@@ -4213,18 +3882,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGLineElement_getTransformToElement_Callback";
 
-  @DomName('SVGLineElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGLineElement_className_Getter";
-
-  @DomName('SVGLineElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGLineElement_style_Getter";
-
-  @DomName('SVGLineElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGLineElement_getPresentationAttribute_Callback";
-
   @DomName('SVGLineElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGLineElement_requiredExtensions_Getter";
@@ -4258,6 +3915,7 @@
 class LinearGradientElement extends GradientElement {
   LinearGradientElement.internal() : super.internal();
 
+  @DomName('SVGLinearGradientElement.SVGLinearGradientElement')
   @DocsEditable
   factory LinearGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("linearGradient");
 
@@ -4327,6 +3985,7 @@
 class MPathElement extends SvgElement implements UriReference, ExternalResourcesRequired {
   MPathElement.internal() : super.internal();
 
+  @DomName('SVGMPathElement.SVGMPathElement')
   @DocsEditable
   factory MPathElement() => _SvgElementFactoryProvider.createSvgElement_tag("mpath");
 
@@ -4348,9 +4007,10 @@
 
 @DocsEditable
 @DomName('SVGMarkerElement')
-class MarkerElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace {
+class MarkerElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace {
   MarkerElement.internal() : super.internal();
 
+  @DomName('SVGMarkerElement.SVGMarkerElement')
   @DocsEditable
   factory MarkerElement() => _SvgElementFactoryProvider.createSvgElement_tag("marker");
 
@@ -4430,18 +4090,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGMarkerElement_xmlspace_Setter";
 
-  @DomName('SVGMarkerElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGMarkerElement_className_Getter";
-
-  @DomName('SVGMarkerElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGMarkerElement_style_Getter";
-
-  @DomName('SVGMarkerElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGMarkerElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -4452,9 +4100,10 @@
 
 @DocsEditable
 @DomName('SVGMaskElement')
-class MaskElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class MaskElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace {
   MaskElement.internal() : super.internal();
 
+  @DomName('SVGMaskElement.SVGMaskElement')
   @DocsEditable
   factory MaskElement() => _SvgElementFactoryProvider.createSvgElement_tag("mask");
 
@@ -4502,18 +4151,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGMaskElement_xmlspace_Setter";
 
-  @DomName('SVGMaskElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGMaskElement_className_Getter";
-
-  @DomName('SVGMaskElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGMaskElement_style_Getter";
-
-  @DomName('SVGMaskElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGMaskElement_getPresentationAttribute_Callback";
-
   @DomName('SVGMaskElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGMaskElement_requiredExtensions_Getter";
@@ -4658,7 +4295,7 @@
 
 @DocsEditable
 @DomName('SVGMissingGlyphElement')
-class MissingGlyphElement extends SvgElement {
+class MissingGlyphElement extends StyledElement {
   MissingGlyphElement.internal() : super.internal();
 
 }
@@ -4729,7 +4366,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Number element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Number element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Number element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Number> where(bool f(Number element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -4743,13 +4384,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Number> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Number> takeWhile(bool test(Number value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Number> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Number> skipWhile(bool test(Number value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -4792,8 +4433,9 @@
 
   // clear() defined by IDL.
 
-  List<Number> get reversed =>
-      new ReversedListView<Number>(this, 0, null);
+  List<Number> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Number a, Number b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -4961,9 +4603,10 @@
 
 @DocsEditable
 @DomName('SVGPathElement')
-class PathElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class PathElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   PathElement.internal() : super.internal();
 
+  @DomName('SVGPathElement.SVGPathElement')
   @DocsEditable
   factory PathElement() => _SvgElementFactoryProvider.createSvgElement_tag("path");
 
@@ -5119,18 +4762,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGPathElement_getTransformToElement_Callback";
 
-  @DomName('SVGPathElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGPathElement_className_Getter";
-
-  @DomName('SVGPathElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGPathElement_style_Getter";
-
-  @DomName('SVGPathElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGPathElement_getPresentationAttribute_Callback";
-
   @DomName('SVGPathElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGPathElement_requiredExtensions_Getter";
@@ -5912,7 +5543,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(PathSeg element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(PathSeg element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(PathSeg element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<PathSeg> where(bool f(PathSeg element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -5926,13 +5561,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<PathSeg> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<PathSeg> takeWhile(bool test(PathSeg value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<PathSeg> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<PathSeg> skipWhile(bool test(PathSeg value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -5975,8 +5610,9 @@
 
   // clear() defined by IDL.
 
-  List<PathSeg> get reversed =>
-      new ReversedListView<PathSeg>(this, 0, null);
+  List<PathSeg> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(PathSeg a, PathSeg b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -6153,9 +5789,10 @@
 
 @DocsEditable
 @DomName('SVGPatternElement')
-class PatternElement extends SvgElement implements FitToViewBox, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class PatternElement extends StyledElement implements FitToViewBox, UriReference, Tests, ExternalResourcesRequired, LangSpace {
   PatternElement.internal() : super.internal();
 
+  @DomName('SVGPatternElement.SVGPatternElement')
   @DocsEditable
   factory PatternElement() => _SvgElementFactoryProvider.createSvgElement_tag("pattern");
 
@@ -6215,18 +5852,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGPatternElement_xmlspace_Setter";
 
-  @DomName('SVGPatternElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGPatternElement_className_Getter";
-
-  @DomName('SVGPatternElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGPatternElement_style_Getter";
-
-  @DomName('SVGPatternElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGPatternElement_getPresentationAttribute_Callback";
-
   @DomName('SVGPatternElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGPatternElement_requiredExtensions_Getter";
@@ -6335,9 +5960,10 @@
 
 @DocsEditable
 @DomName('SVGPolygonElement')
-class PolygonElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class PolygonElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   PolygonElement.internal() : super.internal();
 
+  @DomName('SVGPolygonElement.SVGPolygonElement')
   @DocsEditable
   factory PolygonElement() => _SvgElementFactoryProvider.createSvgElement_tag("polygon");
 
@@ -6393,18 +6019,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGPolygonElement_getTransformToElement_Callback";
 
-  @DomName('SVGPolygonElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGPolygonElement_className_Getter";
-
-  @DomName('SVGPolygonElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGPolygonElement_style_Getter";
-
-  @DomName('SVGPolygonElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGPolygonElement_getPresentationAttribute_Callback";
-
   @DomName('SVGPolygonElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGPolygonElement_requiredExtensions_Getter";
@@ -6435,9 +6049,10 @@
 
 @DocsEditable
 @DomName('SVGPolylineElement')
-class PolylineElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class PolylineElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   PolylineElement.internal() : super.internal();
 
+  @DomName('SVGPolylineElement.SVGPolylineElement')
   @DocsEditable
   factory PolylineElement() => _SvgElementFactoryProvider.createSvgElement_tag("polyline");
 
@@ -6493,18 +6108,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGPolylineElement_getTransformToElement_Callback";
 
-  @DomName('SVGPolylineElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGPolylineElement_className_Getter";
-
-  @DomName('SVGPolylineElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGPolylineElement_style_Getter";
-
-  @DomName('SVGPolylineElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGPolylineElement_getPresentationAttribute_Callback";
-
   @DomName('SVGPolylineElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGPolylineElement_requiredExtensions_Getter";
@@ -6595,6 +6198,7 @@
 class RadialGradientElement extends GradientElement {
   RadialGradientElement.internal() : super.internal();
 
+  @DomName('SVGRadialGradientElement.SVGRadialGradientElement')
   @DocsEditable
   factory RadialGradientElement() => _SvgElementFactoryProvider.createSvgElement_tag("radialGradient");
 
@@ -6677,9 +6281,10 @@
 
 @DocsEditable
 @DomName('SVGRectElement')
-class RectElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class RectElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   RectElement.internal() : super.internal();
 
+  @DomName('SVGRectElement.SVGRectElement')
   @DocsEditable
   factory RectElement() => _SvgElementFactoryProvider.createSvgElement_tag("rect");
 
@@ -6751,18 +6356,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGRectElement_getTransformToElement_Callback";
 
-  @DomName('SVGRectElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGRectElement_className_Getter";
-
-  @DomName('SVGRectElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGRectElement_style_Getter";
-
-  @DomName('SVGRectElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGRectElement_getPresentationAttribute_Callback";
-
   @DomName('SVGRectElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGRectElement_requiredExtensions_Getter";
@@ -6821,6 +6414,7 @@
 class ScriptElement extends SvgElement implements UriReference, ExternalResourcesRequired {
   ScriptElement.internal() : super.internal();
 
+  @DomName('SVGScriptElement.SVGScriptElement')
   @DocsEditable
   factory ScriptElement() => _SvgElementFactoryProvider.createSvgElement_tag("script");
 
@@ -6853,6 +6447,7 @@
 class SetElement extends AnimationElement {
   SetElement.internal() : super.internal();
 
+  @DomName('SVGSetElement.SVGSetElement')
   @DocsEditable
   factory SetElement() => _SvgElementFactoryProvider.createSvgElement_tag("set");
 
@@ -6866,9 +6461,10 @@
 
 @DocsEditable
 @DomName('SVGStopElement')
-class StopElement extends SvgElement implements Stylable {
+class StopElement extends StyledElement {
   StopElement.internal() : super.internal();
 
+  @DomName('SVGStopElement.SVGStopElement')
   @DocsEditable
   factory StopElement() => _SvgElementFactoryProvider.createSvgElement_tag("stop");
 
@@ -6876,18 +6472,6 @@
   @DocsEditable
   AnimatedNumber get offset native "SVGStopElement_offset_Getter";
 
-  @DomName('SVGStopElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGStopElement_className_Getter";
-
-  @DomName('SVGStopElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGStopElement_style_Getter";
-
-  @DomName('SVGStopElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGStopElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -6935,7 +6519,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(String element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(String element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(String element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<String> where(bool f(String element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -6949,13 +6537,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<String> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<String> takeWhile(bool test(String value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<String> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<String> skipWhile(bool test(String value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -6998,8 +6586,9 @@
 
   // clear() defined by IDL.
 
-  List<String> get reversed =>
-      new ReversedListView<String>(this, 0, null);
+  List<String> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(String a, String b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -7117,35 +6706,11 @@
 
 
 @DocsEditable
-@DomName('SVGStylable')
-class Stylable extends NativeFieldWrapperClass1 {
-  Stylable.internal();
-
-  @DomName('SVGStylable.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGStylable_className_Getter";
-
-  @DomName('SVGStylable.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGStylable_style_Getter";
-
-  @DomName('SVGStylable.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGStylable_getPresentationAttribute_Callback";
-
-}
-// 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.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('SVGStyleElement')
 class StyleElement extends SvgElement implements LangSpace {
   StyleElement.internal() : super.internal();
 
+  @DomName('SVGStyleElement.SVGStyleElement')
   @DocsEditable
   factory StyleElement() => _SvgElementFactoryProvider.createSvgElement_tag("style");
 
@@ -7206,6 +6771,31 @@
 
 
 @DocsEditable
+@DomName('SVGStyledElement')
+class StyledElement extends SvgElement {
+  StyledElement.internal() : super.internal();
+
+  @DomName('SVGStyledElement.className')
+  @DocsEditable
+  AnimatedString get $dom_svgClassName native "SVGStyledElement_className_Getter";
+
+  @DomName('SVGStyledElement.style')
+  @DocsEditable
+  CssStyleDeclaration get style native "SVGStyledElement_style_Getter";
+
+  @DomName('SVGStyledElement.getPresentationAttribute')
+  @DocsEditable
+  CssValue getPresentationAttribute(String name) native "SVGStyledElement_getPresentationAttribute_Callback";
+
+}
+// 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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('SVGDocument')
 class SvgDocument extends Document {
   SvgDocument.internal() : super.internal();
@@ -7400,7 +6990,7 @@
 
 
 @DomName('SVGSVGElement')
-class SvgSvgElement extends SvgElement implements FitToViewBox, Tests, Stylable, Locatable, ExternalResourcesRequired, ZoomAndPan, LangSpace {
+class SvgSvgElement extends StyledElement implements FitToViewBox, Transformable, Tests, ExternalResourcesRequired, ZoomAndPan, LangSpace {
   factory SvgSvgElement() => _SvgSvgElementFactoryProvider.createSvgSvgElement();
 
   SvgSvgElement.internal() : super.internal();
@@ -7621,18 +7211,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGSVGElement_getTransformToElement_Callback";
 
-  @DomName('SVGSVGElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGSVGElement_className_Getter";
-
-  @DomName('SVGSVGElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGSVGElement_style_Getter";
-
-  @DomName('SVGSVGElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGSVGElement_getPresentationAttribute_Callback";
-
   @DomName('SVGSVGElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGSVGElement_requiredExtensions_Getter";
@@ -7649,6 +7227,10 @@
   @DocsEditable
   bool hasExtension(String extension) native "SVGSVGElement_hasExtension_Callback";
 
+  @DomName('SVGSVGElement.transform')
+  @DocsEditable
+  AnimatedTransformList get transform native "SVGSVGElement_transform_Getter";
+
   @DomName('SVGSVGElement.zoomAndPan')
   @DocsEditable
   int get zoomAndPan native "SVGSVGElement_zoomAndPan_Getter";
@@ -7667,9 +7249,10 @@
 
 @DocsEditable
 @DomName('SVGSwitchElement')
-class SwitchElement extends SvgElement implements Transformable, Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class SwitchElement extends StyledElement implements Transformable, Tests, ExternalResourcesRequired, LangSpace {
   SwitchElement.internal() : super.internal();
 
+  @DomName('SVGSwitchElement.SVGSwitchElement')
   @DocsEditable
   factory SwitchElement() => _SvgElementFactoryProvider.createSvgElement_tag("switch");
 
@@ -7717,18 +7300,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGSwitchElement_getTransformToElement_Callback";
 
-  @DomName('SVGSwitchElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGSwitchElement_className_Getter";
-
-  @DomName('SVGSwitchElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGSwitchElement_style_Getter";
-
-  @DomName('SVGSwitchElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGSwitchElement_getPresentationAttribute_Callback";
-
   @DomName('SVGSwitchElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGSwitchElement_requiredExtensions_Getter";
@@ -7759,9 +7330,10 @@
 
 @DocsEditable
 @DomName('SVGSymbolElement')
-class SymbolElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, Stylable, LangSpace {
+class SymbolElement extends StyledElement implements FitToViewBox, ExternalResourcesRequired, LangSpace {
   SymbolElement.internal() : super.internal();
 
+  @DomName('SVGSymbolElement.SVGSymbolElement')
   @DocsEditable
   factory SymbolElement() => _SvgElementFactoryProvider.createSvgElement_tag("symbol");
 
@@ -7793,18 +7365,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGSymbolElement_xmlspace_Setter";
 
-  @DomName('SVGSymbolElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGSymbolElement_className_Getter";
-
-  @DomName('SVGSymbolElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGSymbolElement_style_Getter";
-
-  @DomName('SVGSymbolElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGSymbolElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -7818,6 +7378,7 @@
 class TRefElement extends TextPositioningElement implements UriReference {
   TRefElement.internal() : super.internal();
 
+  @DomName('SVGTRefElement.SVGTRefElement')
   @DocsEditable
   factory TRefElement() => _SvgElementFactoryProvider.createSvgElement_tag("tref");
 
@@ -7838,6 +7399,7 @@
 class TSpanElement extends TextPositioningElement {
   TSpanElement.internal() : super.internal();
 
+  @DomName('SVGTSpanElement.SVGTSpanElement')
   @DocsEditable
   factory TSpanElement() => _SvgElementFactoryProvider.createSvgElement_tag("tspan");
 
@@ -7880,7 +7442,7 @@
 
 @DocsEditable
 @DomName('SVGTextContentElement')
-class TextContentElement extends SvgElement implements Tests, Stylable, ExternalResourcesRequired, LangSpace {
+class TextContentElement extends StyledElement implements Tests, ExternalResourcesRequired, LangSpace {
   TextContentElement.internal() : super.internal();
 
   static const int LENGTHADJUST_SPACING = 1;
@@ -7953,18 +7515,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGTextContentElement_xmlspace_Setter";
 
-  @DomName('SVGTextContentElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGTextContentElement_className_Getter";
-
-  @DomName('SVGTextContentElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGTextContentElement_style_Getter";
-
-  @DomName('SVGTextContentElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGTextContentElement_getPresentationAttribute_Callback";
-
   @DomName('SVGTextContentElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGTextContentElement_requiredExtensions_Getter";
@@ -7994,6 +7544,7 @@
 class TextElement extends TextPositioningElement implements Transformable {
   TextElement.internal() : super.internal();
 
+  @DomName('SVGTextElement.SVGTextElement')
   @DocsEditable
   factory TextElement() => _SvgElementFactoryProvider.createSvgElement_tag("text");
 
@@ -8109,9 +7660,10 @@
 
 @DocsEditable
 @DomName('SVGTitleElement')
-class TitleElement extends SvgElement implements Stylable, LangSpace {
+class TitleElement extends StyledElement implements LangSpace {
   TitleElement.internal() : super.internal();
 
+  @DomName('SVGTitleElement.SVGTitleElement')
   @DocsEditable
   factory TitleElement() => _SvgElementFactoryProvider.createSvgElement_tag("title");
 
@@ -8131,18 +7683,6 @@
   @DocsEditable
   void set xmlspace(String value) native "SVGTitleElement_xmlspace_Setter";
 
-  @DomName('SVGTitleElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGTitleElement_className_Getter";
-
-  @DomName('SVGTitleElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGTitleElement_style_Getter";
-
-  @DomName('SVGTitleElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGTitleElement_getPresentationAttribute_Callback";
-
 }
 // 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
@@ -8253,7 +7793,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(Transform element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(Transform element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(Transform element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<Transform> where(bool f(Transform element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -8267,13 +7811,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<Transform> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<Transform> takeWhile(bool test(Transform value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<Transform> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<Transform> skipWhile(bool test(Transform value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -8316,8 +7860,9 @@
 
   // clear() defined by IDL.
 
-  List<Transform> get reversed =>
-      new ReversedListView<Transform>(this, 0, null);
+  List<Transform> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Transform a, Transform b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
@@ -8521,9 +8066,10 @@
 
 @DocsEditable
 @DomName('SVGUseElement')
-class UseElement extends SvgElement implements Transformable, Tests, UriReference, Stylable, ExternalResourcesRequired, LangSpace {
+class UseElement extends StyledElement implements UriReference, Tests, Transformable, ExternalResourcesRequired, LangSpace {
   UseElement.internal() : super.internal();
 
+  @DomName('SVGUseElement.SVGUseElement')
   @DocsEditable
   factory UseElement() => _SvgElementFactoryProvider.createSvgElement_tag("use");
 
@@ -8595,18 +8141,6 @@
   @DocsEditable
   Matrix getTransformToElement(SvgElement element) native "SVGUseElement_getTransformToElement_Callback";
 
-  @DomName('SVGUseElement.className')
-  @DocsEditable
-  AnimatedString get $dom_svgClassName native "SVGUseElement_className_Getter";
-
-  @DomName('SVGUseElement.style')
-  @DocsEditable
-  CssStyleDeclaration get style native "SVGUseElement_style_Getter";
-
-  @DomName('SVGUseElement.getPresentationAttribute')
-  @DocsEditable
-  CssValue getPresentationAttribute(String name) native "SVGUseElement_getPresentationAttribute_Callback";
-
   @DomName('SVGUseElement.requiredExtensions')
   @DocsEditable
   StringList get requiredExtensions native "SVGUseElement_requiredExtensions_Getter";
@@ -8644,6 +8178,7 @@
 class VKernElement extends SvgElement {
   VKernElement.internal() : super.internal();
 
+  @DomName('SVGVKernElement.SVGVKernElement')
   @DocsEditable
   factory VKernElement() => _SvgElementFactoryProvider.createSvgElement_tag("vkern");
 
@@ -8660,6 +8195,7 @@
 class ViewElement extends SvgElement implements FitToViewBox, ExternalResourcesRequired, ZoomAndPan {
   ViewElement.internal() : super.internal();
 
+  @DomName('SVGViewElement.SVGViewElement')
   @DocsEditable
   factory ViewElement() => _SvgElementFactoryProvider.createSvgElement_tag("view");
 
@@ -8845,7 +8381,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f(ElementInstance element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f(ElementInstance element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f(ElementInstance element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<ElementInstance> where(bool f(ElementInstance element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -8859,13 +8399,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<ElementInstance> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<ElementInstance> takeWhile(bool test(ElementInstance value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<ElementInstance> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<ElementInstance> skipWhile(bool test(ElementInstance value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -8910,8 +8450,9 @@
     throw new UnsupportedError("Cannot clear immutable List.");
   }
 
-  List<ElementInstance> get reversed =>
-      new ReversedListView<ElementInstance>(this, 0, null);
+  List<ElementInstance> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(ElementInstance a, ElementInstance b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
diff --git a/sdk/lib/utf/utf16.dart b/sdk/lib/utf/utf16.dart
index 4fbb80f..c451b1e 100644
--- a/sdk/lib/utf/utf16.dart
+++ b/sdk/lib/utf/utf16.dart
@@ -206,7 +206,7 @@
  * to produce the code unit (0-(2^16)-1). Relies on BOM to determine
  * endian-ness, and defaults to BE.
  */
-class Utf16BytesToCodeUnitsDecoder implements _ListRangeIterator {
+abstract class Utf16BytesToCodeUnitsDecoder implements _ListRangeIterator {
   final _ListRangeIterator utf16EncodedBytesIterator;
   final int replacementCodepoint;
   int _current = null;
diff --git a/sdk/lib/utf/utf32.dart b/sdk/lib/utf/utf32.dart
index b9d9e98..acf6ac3 100644
--- a/sdk/lib/utf/utf32.dart
+++ b/sdk/lib/utf/utf32.dart
@@ -195,7 +195,7 @@
 /**
  * Abstrace parent class converts encoded bytes to codepoints.
  */
-class Utf32BytesDecoder implements _ListRangeIterator {
+abstract class Utf32BytesDecoder implements _ListRangeIterator {
   final _ListRangeIterator utf32EncodedBytesIterator;
   final int replacementCodepoint;
   int _current = null;
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 5d466fd..5042795 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -1,8 +1,7 @@
-library web_audio;
+library dart.dom.web_audio;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_foreign_helper' show JS;
@@ -182,9 +181,6 @@
   static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
 
   @DocsEditable
-  factory AudioContext() => AudioContext._create();
-
-  @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
   @deprecated
   AudioContextEvents get on =>
@@ -286,7 +282,7 @@
   @DocsEditable
   Stream<Event> get onComplete => completeEvent.forTarget(this);
 
-  static AudioContext _create() => JS('AudioContext',
+  factory AudioContext() => JS('AudioContext',
       'new (window.AudioContext || window.webkitAudioContext)()');
 
   GainNode createGain() {
@@ -690,9 +686,12 @@
 @DomName('OfflineAudioContext')
 class OfflineAudioContext extends AudioContext implements EventTarget native "*OfflineAudioContext" {
 
+  @DomName('OfflineAudioContext.OfflineAudioContext')
   @DocsEditable
-  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) => OfflineAudioContext._create(numberOfChannels, numberOfFrames, sampleRate);
-  static OfflineAudioContext _create(int numberOfChannels, int numberOfFrames, num sampleRate) => JS('OfflineAudioContext', 'new OfflineAudioContext(#,#,#)', numberOfChannels, numberOfFrames, sampleRate);
+  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) {
+    return OfflineAudioContext._create_1(numberOfChannels, numberOfFrames, sampleRate);
+  }
+  static OfflineAudioContext _create_1(numberOfChannels, numberOfFrames, sampleRate) => JS('OfflineAudioContext', 'new OfflineAudioContext(#,#,#)', numberOfChannels, numberOfFrames, sampleRate);
 }
 // 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
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 44782ea..ec52898 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -1,8 +1,7 @@
-library web_audio;
+library dart.dom.web_audio;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
@@ -231,10 +230,10 @@
   @DomName('AudioContext.complete')
   @DocsEditable
   static const EventStreamProvider<Event> completeEvent = const EventStreamProvider<Event>('complete');
+  factory AudioContext() => _create();
 
   @DocsEditable
-  factory AudioContext() => AudioContext._create();
-  static AudioContext _create() native "AudioContext_constructor_Callback";
+  static AudioContext _create() native "AudioContext_constructorCallback";
 
   @DocsEditable
   @DomName('EventTarget.addEventListener, EventTarget.removeEventListener, EventTarget.dispatchEvent')
@@ -904,9 +903,14 @@
 class OfflineAudioContext extends AudioContext implements EventTarget {
   OfflineAudioContext.internal() : super.internal();
 
+  @DomName('OfflineAudioContext.OfflineAudioContext')
   @DocsEditable
-  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) => OfflineAudioContext._create(numberOfChannels, numberOfFrames, sampleRate);
-  static OfflineAudioContext _create(int numberOfChannels, int numberOfFrames, num sampleRate) native "OfflineAudioContext_constructor_Callback";
+  factory OfflineAudioContext(int numberOfChannels, int numberOfFrames, num sampleRate) {
+    return OfflineAudioContext._create_1(numberOfChannels, numberOfFrames, sampleRate);
+  }
+
+  @DocsEditable
+  static OfflineAudioContext _create_1(numberOfChannels, numberOfFrames, sampleRate) native "OfflineAudioContext__create_1constructorCallback";
 
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 3884bbd..aba9917 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -180,7 +180,7 @@
 
 
 [ $compiler == dart2js && $runtime == jsshell ]
-LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096 
+LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
 Language/05_Variables/05_Variables_A13_t02: Fail # TODO(ngeoaffray): Please triage these failure.
 Language/06_Functions/3_Type_of_a_Function_A01_t01: Fail # TODO(ngeoaffray): Please triage these failure.
 Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t02: Fail # TODO(ngeoaffray): Please triage these failure.
@@ -229,7 +229,6 @@
 Language/13_Libraries_and_Scripts/1_Imports_A03_t26: Fail # TODO(ahe): Please triage this failure.
 Language/13_Libraries_and_Scripts/1_Imports_A03_t46: Fail # TODO(ahe): Please triage this failure.
 Language/13_Libraries_and_Scripts/1_Imports_A03_t66: Fail # TODO(ahe): Please triage this failure.
-Language/14_Types/4_Interface_Types_A08_t03: Fail # TODO(ahe): Please triage this failure.
 Language/14_Types/8_Parameterized_Types_A02_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/AssertionError/column_A01_t02: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/AssertionError/failedAssertion_A01_t01: Fail # TODO(ahe): Please triage this failure.
@@ -784,10 +783,8 @@
 Language/14_Types/5_Function_Types_A01_t09: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A01_t11: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A02_t05: Fail # dartbug.com/7342
-Language/14_Types/5_Function_Types_A02_t07: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A02_t09: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A02_t10: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A03_t06: Fail # dartbug.com/7342
-Language/14_Types/5_Function_Types_A03_t08: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A03_t10: Fail # dartbug.com/7342
 Language/14_Types/5_Function_Types_A03_t11: Fail # dartbug.com/7342
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 0162524..9e1d365 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -45,6 +45,7 @@
   var handler = new CollectingDiagnosticHandler(provider);
   var compiler = new Compiler(
       provider.readStringFromUri,
+      null,
       handler.diagnosticHandler,
       libraryRoot, libraryRoot,
       <String>['--analyze-only', '--analyze-all',
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index ae90593..2e8e529 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -1023,6 +1023,17 @@
   result.checkNodeHasUnknownType('x');
 }
 
+testIsCheck() {
+  final String source = r"""
+    main () {
+      var x = (1 is String);
+      x;
+    }
+    """;
+  AnalysisResult result = analyze(source);
+  result.checkNodeHasType('x', [result.bool]);
+}
+
 void main() {
   testDynamicBackDoor();
   testLiterals();
@@ -1063,4 +1074,5 @@
   testLists();
   testListWithCapacity();
   testEmptyList();
+  testIsCheck();
 }
diff --git a/tests/compiler/dart2js/emit_const_fields_test.dart b/tests/compiler/dart2js/emit_const_fields_test.dart
new file mode 100644
index 0000000..290c50a
--- /dev/null
+++ b/tests/compiler/dart2js/emit_const_fields_test.dart
@@ -0,0 +1,24 @@
+// 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 unused static consts are not emitted.
+
+import 'compiler_helper.dart';
+
+const String TEST_GUIDE = r"""
+class Guide {
+  static const LTUAE = 42;
+  static const TITLE = 'Life, the Universe and Everything';
+}
+
+main() {
+  return "${Guide.LTUAE}, ${Guide.TITLE}";
+}
+""";
+
+main() {
+  String generated = compileAll(TEST_GUIDE);
+  Expect.isTrue(generated.contains("42"));
+  Expect.isFalse(generated.contains("TITLE"));
+}
+
diff --git a/tests/compiler/dart2js/erroneous_element_test.dart b/tests/compiler/dart2js/erroneous_element_test.dart
index d0a85a9..97078356 100644
--- a/tests/compiler/dart2js/erroneous_element_test.dart
+++ b/tests/compiler/dart2js/erroneous_element_test.dart
@@ -12,7 +12,8 @@
     show MessageKind;
 
 void main() {
-  ErroneousElement e = new ErroneousElementX(MessageKind.GENERIC, ['error'],
+  ErroneousElement e = new ErroneousElementX(MessageKind.GENERIC,
+                                             {'text': 'error'},
                                              buildSourceString('foo'), null);
   Expect.stringEquals('<foo: error>', '$e');
 }
diff --git a/tests/compiler/dart2js/interceptor_test.dart b/tests/compiler/dart2js/interceptor_test.dart
index 29a8a0d..c7be7c5 100644
--- a/tests/compiler/dart2js/interceptor_test.dart
+++ b/tests/compiler/dart2js/interceptor_test.dart
@@ -14,9 +14,23 @@
   }
 """;
 
+const String TEST_TWO = r"""
+  foo(a) {
+    var myVariableName = a + 42;
+    print(myVariableName);
+    print(myVariableName);
+  }
+""";
+
 main() {
   var generated = compile(TEST_ONE, entry: 'foo');
   // Check that the one shot interceptor got converted to a direct
   // call to the interceptor object.
   Expect.isTrue(generated.contains('CONSTANT.get\$toString(a + 42);'));
+
+  // Check that one-shot interceptors preserve variable names, see
+  // https://code.google.com/p/dart/issues/detail?id=8106.
+  generated = compile(TEST_TWO, entry: 'foo');
+  Expect.isTrue(generated.contains('\$.\$\$add(a, 42)'));
+  Expect.isTrue(generated.contains('myVariableName'));
 }
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index cd1bd89..b12336e 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -23,6 +23,8 @@
 import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
     hide TreeElementMapping;
 
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+
 class WarningMessage {
   Node node;
   Message message;
diff --git a/tests/compiler/dart2js/part_of_test.dart b/tests/compiler/dart2js/part_of_test.dart
index 54c0bc9..d80b8dc 100644
--- a/tests/compiler/dart2js/part_of_test.dart
+++ b/tests/compiler/dart2js/part_of_test.dart
@@ -32,6 +32,6 @@
   Expect.equals(1, compiler.warnings.length);
   Expect.equals(MessageKind.LIBRARY_NAME_MISMATCH,
                 compiler.warnings[0].message.kind);
-  Expect.equals("${MessageKind.LIBRARY_NAME_MISMATCH.error(['foo'])}",
-                compiler.warnings[0].message.toString());
+  Expect.equals('foo',
+      compiler.warnings[0].message.arguments['libraryName'].toString());
 }
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 720c85d..883ca27 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -40,46 +40,46 @@
 Element ensure(compiler,
                String name,
                Element lookup(name),
-               {bool isPatched: false,
-                bool isPatch: false,
-                bool isMethod: true,
-                bool isGetter: false,
-                bool isFound: true}) {
+               {bool expectIsPatched: false,
+                bool expectIsPatch: false,
+                bool checkHasBody: false,
+                bool expectIsGetter: false,
+                bool expectIsFound: true}) {
   var element = lookup(buildSourceString(name));
-  if (!isFound) {
+  if (!expectIsFound) {
     Expect.isNull(element);
     return element;
   }
   Expect.isNotNull(element);
-  if (isGetter) {
+  if (expectIsGetter) {
     Expect.isTrue(element is AbstractFieldElement);
     Expect.isNotNull(element.getter);
     element = element.getter;
   }
-  Expect.equals(isPatched, element.isPatched);
-  if (isPatched) {
+  Expect.equals(expectIsPatched, element.isPatched);
+  if (expectIsPatched) {
     Expect.isNull(element.origin);
     Expect.isNotNull(element.patch);
 
     Expect.equals(element, element.declaration);
     Expect.equals(element.patch, element.implementation);
 
-    if (isMethod) {
+    if (checkHasBody) {
       expectHasNoBody(compiler, element);
       expectHasBody(compiler, element.patch);
     }
   } else {
     Expect.isTrue(element.isImplementation);
   }
-  Expect.equals(isPatch, element.isPatch);
-  if (isPatch) {
+  Expect.equals(expectIsPatch, element.isPatch);
+  if (expectIsPatch) {
     Expect.isNotNull(element.origin);
     Expect.isNull(element.patch);
 
     Expect.equals(element.origin, element.declaration);
     Expect.equals(element, element.implementation);
 
-    if (isMethod) {
+    if (checkHasBody) {
       expectHasBody(compiler, element);
       expectHasNoBody(compiler, element.origin);
     }
@@ -93,7 +93,7 @@
     Expect.equals(element, element.declaration);
     Expect.equals(element, element.implementation);
 
-    if (isMethod) {
+    if (checkHasBody) {
       expectHasBody(compiler, element);
     }
   }
@@ -105,8 +105,10 @@
   var compiler = applyPatch(
       "external test();",
       "patch test() { return 'string'; } ");
-  ensure(compiler, "test", compiler.coreLibrary.find, isPatched: true);
-  ensure(compiler, "test", compiler.coreLibrary.patch.find, isPatch: true);
+  ensure(compiler, "test", compiler.coreLibrary.find,
+         expectIsPatched: true, checkHasBody: true);
+  ensure(compiler, "test", compiler.coreLibrary.patch.find,
+         expectIsPatch: true, checkHasBody: true);
 
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
@@ -127,15 +129,15 @@
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
-                         isMethod: false, isPatched: true);
+                         expectIsPatched: true);
   container.parseNode(compiler);
   ensure(compiler, "Class", compiler.coreLibrary.patch.find,
-         isMethod: false, isPatch: true);
+         expectIsPatch: true);
 
   ensure(compiler, "toString", container.lookupLocalMember,
-         isPatched: true);
+         expectIsPatched: true, checkHasBody: true);
   ensure(compiler, "toString", container.patch.lookupLocalMember,
-         isPatch: true);
+         expectIsPatch: true, checkHasBody: true);
 
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
@@ -156,18 +158,20 @@
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
-                         isPatched: true, isMethod: false);
+                         expectIsPatched: true);
   container.parseNode(compiler);
   ensure(compiler,
          "field",
          container.lookupLocalMember,
-         isGetter: true,
-         isPatched: true);
+         expectIsGetter: true,
+         expectIsPatched: true,
+         checkHasBody: true);
   ensure(compiler,
          "field",
          container.patch.lookupLocalMember,
-         isGetter: true,
-         isPatch: true);
+         expectIsGetter: true,
+         expectIsPatch: true,
+         checkHasBody: true);
 
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
@@ -187,13 +191,15 @@
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
-                         isMethod: false, isPatched: true);
+                         expectIsPatched: true);
   container.parseNode(compiler);
   ensure(compiler, "Class", compiler.coreLibrary.patch.find,
-         isMethod: false, isPatch: true);
+         expectIsPatch: true);
 
-  ensure(compiler, "regular", container.lookupLocalMember);
-  ensure(compiler, "regular", container.patch.lookupLocalMember);
+  ensure(compiler, "regular", container.lookupLocalMember,
+         checkHasBody: true);
+  ensure(compiler, "regular", container.patch.lookupLocalMember,
+         checkHasBody: true);
 
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
@@ -213,13 +219,15 @@
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
-                         isMethod: false, isPatched: true);
+                         expectIsPatched: true);
   container.parseNode(compiler);
   ensure(compiler, "Class", compiler.coreLibrary.patch.find,
-         isMethod: false, isPatch: true);
+         expectIsPatch: true);
 
-  ensure(compiler, "ghost", container.lookupLocalMember, isFound: false);
-  ensure(compiler, "ghost", container.patch.lookupLocalMember);
+  ensure(compiler, "ghost", container.lookupLocalMember,
+         expectIsFound: false);
+  ensure(compiler, "ghost", container.patch.lookupLocalMember,
+         checkHasBody: true);
 
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
@@ -234,10 +242,11 @@
   ensure(compiler,
          "_function",
          compiler.coreLibrary.find,
-         isFound: false);
+         expectIsFound: false);
   ensure(compiler,
          "_function",
-         compiler.coreLibrary.patch.find);
+         compiler.coreLibrary.patch.find,
+         checkHasBody: true);
 
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
@@ -272,13 +281,13 @@
       }
       """);
   var container = ensure(compiler, "Class", compiler.coreLibrary.find,
-                         isMethod: false, isPatched: true);
+                         expectIsPatched: true);
   container.ensureResolved(compiler);
   container.parseNode(compiler);
 
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method1", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -288,7 +297,7 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method2", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -298,7 +307,7 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method3", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -308,7 +317,7 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method4", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -318,7 +327,7 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method5", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -328,7 +337,7 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method6", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -338,7 +347,7 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method7", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
@@ -348,13 +357,65 @@
   compiler.errors.clear();
   compiler.resolver.resolveMethodElement(
       ensure(compiler, "method8", container.lookupLocalMember,
-          isPatched: true));
+          expectIsPatched: true, checkHasBody: true));
   Expect.isTrue(compiler.warnings.isEmpty,
                 "Unexpected warnings: ${compiler.warnings}");
   Expect.isFalse(compiler.errors.isEmpty);
   print('method8:${compiler.errors}');
 }
 
+testExternalWithoutImplementationTopLevel() {
+  var compiler = applyPatch(
+      """
+      external void foo();
+      """,
+      """
+      // patch void foo() {}
+      """);
+  var function = ensure(compiler, "foo", compiler.coreLibrary.find);
+  compiler.resolver.resolve(function);
+  Expect.isTrue(compiler.warnings.isEmpty,
+                "Unexpected warnings: ${compiler.warnings}");
+  print('testExternalWithoutImplementationTopLevel:${compiler.errors}');
+  Expect.equals(1, compiler.errors.length);
+  Expect.isTrue(
+      compiler.errors[0].message.kind ==
+          MessageKind.EXTERNAL_WITHOUT_IMPLEMENTATION);
+  Expect.equals('External method without an implementation.',
+                compiler.errors[0].message.toString());
+}
+
+testExternalWithoutImplementationMember() {
+  var compiler = applyPatch(
+      """
+      class Class {
+        external void foo();
+      }
+      """,
+      """
+      patch class Class {
+        // patch void foo() {}
+      }
+      """);
+  var container = ensure(compiler, "Class", compiler.coreLibrary.find,
+                         expectIsPatched: true);
+  container.parseNode(compiler);
+
+  compiler.warnings.clear();
+  compiler.errors.clear();
+  compiler.resolver.resolveMethodElement(
+      ensure(compiler, "foo", container.lookupLocalMember));
+  Expect.isTrue(compiler.warnings.isEmpty,
+                "Unexpected warnings: ${compiler.warnings}");
+  print('testExternalWithoutImplementationMember:${compiler.errors}');
+  Expect.equals(1, compiler.errors.length);
+  Expect.isTrue(
+      compiler.errors[0].message.kind ==
+          MessageKind.EXTERNAL_WITHOUT_IMPLEMENTATION);
+  Expect.equals('External method without an implementation.',
+                compiler.errors[0].message.toString());
+}
+
 main() {
   testPatchFunction();
   testPatchMember();
@@ -363,4 +424,7 @@
   testGhostMember();
   testInjectFunction();
   testPatchSignatureCheck();
+
+  testExternalWithoutImplementationTopLevel();
+  testExternalWithoutImplementationMember();
 }
diff --git a/tests/compiler/dart2js/pretty_parameter_test.dart b/tests/compiler/dart2js/pretty_parameter_test.dart
index 82309e6..28c8d1f 100644
--- a/tests/compiler/dart2js/pretty_parameter_test.dart
+++ b/tests/compiler/dart2js/pretty_parameter_test.dart
@@ -72,7 +72,7 @@
   Expect.isTrue(generated.contains(r"function(a, b) {"));
 
   generated = compile(BAR, entry: 'bar');
-  Expect.isTrue(generated.contains(r"function(eval, $$eval) {"));
+  Expect.isTrue(generated.contains(r"function($eval, $$eval) {"));
 
   generated = compile(PARAMETER_AND_TEMP, entry: 'bar');
   Expect.isTrue(generated.contains(r"print(t00)"));
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index fbe3db2..a2e3742 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -15,6 +15,7 @@
 
 import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart"
     hide TreeElementMapping, TreeElements, SourceString;
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 
 Node buildIdentifier(String name) => new Identifier(scan(name));
 
@@ -219,7 +220,7 @@
   MockCompiler compiler = testLocals([["foo", false], ["foo", false]]);
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
-      new Message(MessageKind.DUPLICATE_DEFINITION, ['foo']),
+      new Message(MessageKind.DUPLICATE_DEFINITION, {'name': 'foo'}),
       compiler.errors[0].message);
 }
 
@@ -401,7 +402,7 @@
   Node warningNode = compiler.warnings[0].node;
 
   Expect.equals(
-      new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Foo']),
+      new Message(MessageKind.CANNOT_RESOLVE_TYPE,  {'typeName': 'Foo'}),
       compiler.warnings[0].message);
   VariableDefinitions definition = compiler.parsedTree;
   Expect.equals(warningNode, definition.type);
@@ -427,7 +428,8 @@
   // ClassResolverVisitor, and once from ClassSupertypeResolver. We
   // should only the get the error once.
   Expect.equals(2, compiler.errors.length);
-  var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['Bar']);
+  var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE,
+                                     {'typeName': 'Bar'});
   Expect.equals(cannotResolveBar, compiler.errors[0].message);
   Expect.equals(cannotResolveBar, compiler.errors[1].message);
   compiler.clearErrors();
@@ -452,7 +454,7 @@
   compiler.resolveStatement("Foo bar;");
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
-      new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['var']),
+      new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'var'}),
       compiler.errors[0].message);
   compiler.clearErrors();
 }
@@ -463,7 +465,7 @@
   compiler.resolveStatement("Foo bar;");
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
-      new Message(MessageKind.CANNOT_RESOLVE_TYPE, ['bar']),
+      new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'bar'}),
       compiler.errors[0].message);
   compiler.clearErrors();
 
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 85dcbd8..e51a50f 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -14,6 +14,8 @@
 import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
     hide SourceString;
 
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
+
 DartType intType;
 DartType boolType;
 DartType stringType;
@@ -35,7 +37,9 @@
                 testConditionalExpression,
                 testIfStatement,
                 testThis,
-                testFunctionSubtyping];
+                testFunctionSubtyping,
+                testFunctionSubtypingOptional,
+                testFunctionSubtypingNamed];
   for (Function test in tests) {
     setup();
     test();
@@ -360,8 +364,12 @@
   bool isSubtype(List<DartType> in1, DartType out1, List<DartType> in2,
                  DartType out2) {
     return compiler.types.isSubtype(
-        new FunctionType(out1, new Link<DartType>.fromList(in1), null),
-        new FunctionType(out2, new Link<DartType>.fromList(in2), null));
+        new FunctionType(null, out1, new Link<DartType>.fromList(in1),
+                         const Link<DartType>(),
+                         const Link<SourceString>(), const Link<DartType>()),
+        new FunctionType(null, out2, new Link<DartType>.fromList(in2),
+                         const Link<DartType>(),
+                         const Link<SourceString>(), const Link<DartType>()));
   }
   Expect.isTrue(isSubtype([], intType, [], intType));
   Expect.isTrue(isSubtype([], intType, [], objectType));
@@ -373,6 +381,129 @@
   Expect.isFalse(isSubtype([intType, intType], intType, [intType], intType));
 }
 
+testFunctionSubtypingOptional() {
+  // Checks whether the type (in1,[opt1] -> void) is a subtype of
+  // (in2,[opt2] -> void).
+  expect(bool value, List<DartType> in1, List<DartType> opt1,
+                     List<DartType> in2, List<DartType> opt2) {
+    var fn1 = new FunctionType(null,
+        compiler.types.dynamicType,
+        new Link<DartType>.fromList(in1),
+        new Link<DartType>.fromList(opt1),
+        const Link<SourceString>(), const Link<DartType>());
+    var fn2 = new FunctionType(null,
+        compiler.types.dynamicType,
+        new Link<DartType>.fromList(in2),
+        new Link<DartType>.fromList(opt2),
+        const Link<SourceString>(), const Link<DartType>());
+    Expect.equals(value, compiler.types.isSubtype(fn1, fn2), "$fn1 <: $fn2");
+  }
+
+  // Test ()->void <: ()->void.
+  expect(true, [], [], [], []);
+  // Test ([int])->void <: ()->void.
+  expect(true, [], [intType], [], []);
+  // Test ([int])->void <: (int)->void.
+  expect(false, [], [intType], [intType], []);
+  // Test (int)->void <: ([int])->void.
+  expect(false, [intType], [], [], [intType]);
+  // Test ([int])->void <: ([int])->void.
+  expect(true, [], [intType], [], [intType]);
+  // Test ([Object])->void <: ([int])->void.
+  expect(true, [], [objectType], [], [intType]);
+  // Test ([int])->void <: ([Object])->void.
+  expect(true, [], [intType], [], [objectType]);
+  // Test (int,[int])->void <: (int,[int])->void.
+  expect(true, [intType], [intType], [intType], [intType]);
+  // Test ([int])->void <: ([double])->void.
+  expect(false, [], [intType], [], [doubleType]);
+  // Test ([int])->void <: ([int,int])->void.
+  expect(false, [], [intType], [], [intType, intType]);
+  // Test ([int,int])->void <: ([int])->void.
+  expect(true, [], [intType, intType], [], [intType]);
+  // Test ([Object,int])->void <: ([int])->void.
+  expect(true, [], [objectType, intType], [], [intType]);
+}
+
+
+testFunctionSubtypingNamed() {
+  // Checks whether the type (in1,{nm1} -> out1) is a subtype of
+  // (in2,{nm2} -> out2).
+  expect(bool value, List<DartType> in1, Map<String,DartType> nm1,
+                     List<DartType> in2, Map<String,DartType> nm2) {
+
+    SourceString convertString(String string) => new SourceString(string);
+    int compareString(a, b) => a.compareTo(b);
+
+    Link<SourceString> createNames(Map<String,DartType> nm) {
+      List<String> nmSorted = new List<String>.from(nm.keys)..sort();
+      List<SourceString> nmSourceStrings =
+          nmSorted.map((string) => new SourceString(string)).toList();
+      return new Link<SourceString>.fromList(nmSourceStrings);
+    }
+
+    Link<DartType> createTypes(Map<String,DartType> nm,
+                               Link<SourceString> names) {
+      var types = new LinkBuilder<DartType>();
+      for (SourceString name in names) {
+        types.addLast(nm[name.slowToString()]);
+      }
+      return types.toLink();
+    }
+
+    Link<SourceString> names1 = createNames(nm1);
+    Link<DartType> types1 = createTypes(nm1, names1);
+    Link<SourceString> names2 = createNames(nm2);
+    Link<DartType> types2 = createTypes(nm2, names2);
+    var fn1 = new FunctionType(null,
+        compiler.types.dynamicType,
+        new Link<DartType>.fromList(in1),
+        const Link<DartType>(),
+        names1, types1);
+    var fn2 = new FunctionType(null,
+        compiler.types.dynamicType,
+        new Link<DartType>.fromList(in2),
+        const Link<DartType>(),
+        names2, types2);
+    Expect.equals(value, compiler.types.isSubtype(fn1, fn2), "$fn1 <: $fn2");
+  }
+
+  // Test ()->void <: ()->void.
+  expect(true, [], {}, [], {});
+  // Test ({int a})->void <: ()->void.
+  expect(true, [], {'a': intType}, [], {});
+  // Test ({int a})->void <: (int)->void.
+  expect(false, [], {'a': intType}, [intType], {});
+  // Test (int)->void <: ({int a})->void.
+  expect(false, [intType], {}, [], {'a': intType});
+  // Test ({int a})->void <: ({int a})->void.
+  expect(true, [], {'a': intType}, [], {'a': intType});
+  // Test ({int a})->void <: ({int b})->void.
+  expect(false, [], {'a': intType}, [], {'b': intType});
+  // Test ({Object a})->void <: ({int a})->void.
+  expect(true, [], {'a': objectType}, [], {'a': intType});
+  // Test ({int a})->void <: ([Object])->void.
+  expect(true, [], {'a': intType}, [], {'a': objectType});
+  // Test (int,{int a})->void <: (int,{int a})->void.
+  expect(true, [intType], {'a': intType}, [intType], {'a': intType});
+  // Test ({int a})->void <: ({double a})->void.
+  expect(false, [], {'a': intType}, [], {'a': doubleType});
+  // Test ({int a})->void <: ({int a,int b})->void.
+  expect(false, [], {'a': intType}, [], {'a': intType, 'b': intType});
+  // Test ({int a,int b})->void <: ({int a})->void.
+  expect(true, [], {'a': intType, 'b': intType}, [], {'a': intType});
+  // Test ({int a,int b,int c})->void <: ({int a,int c})->void.
+  expect(true, [], {'a': intType, 'b': intType, 'c': intType},
+               [], {'a': intType, 'c': intType});
+  // Test ({int a,int b,int c})->void <: ({int b,int c})->void.
+  expect(true, [], {'a': intType, 'b': intType, 'c': intType},
+               [], {'b': intType, 'c': intType});
+  // Test ({int a,int b,int c})->void <: ({int c})->void.
+  expect(true, [], {'a': intType, 'b': intType, 'c': intType},
+               [], {'c': intType});
+}
+
+
 const CLASS_WITH_METHODS = '''
 class ClassWithMethods {
   untypedNoArgumentMethod() {}
diff --git a/tests/compiler/dart2js/type_equals_test.dart b/tests/compiler/dart2js/type_equals_test.dart
index 3c621a0..57d468b 100644
--- a/tests/compiler/dart2js/type_equals_test.dart
+++ b/tests/compiler/dart2js/type_equals_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
diff --git a/tests/compiler/dart2js/type_substitution_test.dart b/tests/compiler/dart2js/type_substitution_test.dart
index fb32d7e..0c4ee89 100644
--- a/tests/compiler/dart2js/type_substitution_test.dart
+++ b/tests/compiler/dart2js/type_substitution_test.dart
@@ -5,6 +5,7 @@
 library type_substitution_test;
 
 import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
+import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
@@ -237,4 +238,21 @@
   testSubstitution(compiler, arguments, parameters, "Typedef1c", "Typedef2c");
   testSubstitution(compiler, arguments, parameters, "Typedef1d", "Typedef2d");
   testSubstitution(compiler, arguments, parameters, "Typedef1e", "Typedef2e");
+
+  // Substitution in unalias.
+  DartType Typedef2_int_String = getType(compiler, "Typedef2a");
+  Expect.isNotNull(Typedef2_int_String);
+  DartType Function_int_String = getType(compiler, "Function2b");
+  Expect.isNotNull(Function_int_String);
+  DartType unalias1 = Typedef2_int_String.unalias(compiler);
+  Expect.equals(Function_int_String, unalias1,
+      '$Typedef2_int_String.unalias=$unalias1 != $Function_int_String');
+
+  DartType Typedef1 = getType(compiler, "Typedef1c");
+  Expect.isNotNull(Typedef1);
+  DartType Function_dynamic_dynamic = getType(compiler, "Function1c");
+  Expect.isNotNull(Function_dynamic_dynamic);
+  DartType unalias2 = Typedef1.unalias(compiler);
+  Expect.equals(Function_dynamic_dynamic, unalias2,
+      '$Typedef1.unalias=$unalias2 != $Function_dynamic_dynamic');
 }
diff --git a/tests/compiler/dart2js_native/foreign_test.dart b/tests/compiler/dart2js_native/foreign_test.dart
index b9feea9..f7fd7c6d 100644
--- a/tests/compiler/dart2js_native/foreign_test.dart
+++ b/tests/compiler/dart2js_native/foreign_test.dart
@@ -30,4 +30,10 @@
   Expect.equals(998, foreign2());
   Expect.equals('1234567891011',
       foreign11('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'));
+  // Ensure there will be isNaN and NaN variable names.
+  var isNaN = called ? 42 : 44;
+  var NaN = called ? 52 : 54;
+  Expect.isFalse(JS('bool', 'isNaN(#)', isNaN));
+  Expect.isFalse(JS('bool', 'isNaN(#)', NaN));
+  Expect.isTrue(JS('bool', 'isNaN(#)', double.NAN));
 }
diff --git a/tests/compiler/dart2js_native/native_field_name_test.dart b/tests/compiler/dart2js_native/native_field_name_test.dart
index c1bb426..5d1e7bc 100644
--- a/tests/compiler/dart2js_native/native_field_name_test.dart
+++ b/tests/compiler/dart2js_native/native_field_name_test.dart
@@ -23,7 +23,7 @@
 function setter(x) {
   this.getValue += 10;
 }
-  
+
 function A(){
   var a = Object.create(
       { constructor: { name: 'A'}},
diff --git a/tests/compiler/dart2js_native/native_mixin_field_test.dart b/tests/compiler/dart2js_native/native_mixin_field_test.dart
new file mode 100644
index 0000000..4cf361e
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_mixin_field_test.dart
@@ -0,0 +1,60 @@
+// 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 native classes can use ordinary Dart classes with fields
+// as mixins.
+
+class A native "*A" {
+  var foo;
+}
+
+class B extends A with M1, M2 native "*B" {
+  var bar;
+}
+
+class M1 {
+  var baz;
+}
+
+class M2 {
+  var bar;
+  var buz;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() native """
+function A() {this.foo='A-foo';}
+function B() {A.call(this);this.bar='B-bar';this.baz='M1-baz';}
+makeA = function(){return new A;};
+makeB = function(){return new B;};
+""";
+
+main() {
+  setup();
+  A a = makeA();
+  Expect.equals("A-foo", a.foo);
+  Expect.throws(() => a.bar, (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.baz, (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.buz, (e) => e is NoSuchMethodError);
+
+  B b = makeB();
+  Expect.equals("A-foo", b.foo);
+  Expect.equals("B-bar", b.bar);
+  Expect.equals("M1-baz", b.baz);
+  Expect.isNull(b.buz);
+
+  M1 m1 = new M1();
+  Expect.throws(() => m1.foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => m1.bar, (e) => e is NoSuchMethodError);
+  Expect.isNull(m1.baz);
+  Expect.throws(() => m1.buz, (e) => e is NoSuchMethodError);
+
+  M2 m2 = new M2();
+  Expect.throws(() => m2.foo, (e) => e is NoSuchMethodError);
+  Expect.isNull(m2.bar);
+  Expect.throws(() => m2.baz, (e) => e is NoSuchMethodError);
+  Expect.isNull(m2.buz);
+}
diff --git a/tests/compiler/dart2js_native/native_mixin_multiple_test.dart b/tests/compiler/dart2js_native/native_mixin_multiple_test.dart
new file mode 100644
index 0000000..bd917cb
--- /dev/null
+++ b/tests/compiler/dart2js_native/native_mixin_multiple_test.dart
@@ -0,0 +1,72 @@
+// 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 native classes can use ordinary Dart classes as mixins.
+
+class A native "*A" {
+  foo() => "A-foo";
+  baz() => "A-baz";
+}
+
+class B extends A with M1, M2 native "*B" {
+  bar() => baz();
+}
+
+class M1 {
+  foo() => "M1-foo";
+  baz() => "M1-baz";
+}
+
+class M2 {
+  foo() => "M2-foo";
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() native """
+function A() {}
+function B() {}
+makeA = function(){return new A;};
+makeB = function(){return new B;};
+""";
+
+main() {
+  setup();
+  A a = makeA();
+  Expect.equals("A-foo", a.foo());
+  Expect.throws(() => a.bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("A-baz", a.baz());
+  Expect.isTrue(a is A);
+  Expect.isFalse(a is B);
+  Expect.isFalse(a is M1);
+  Expect.isFalse(a is M2);
+
+  B b = makeB();
+  Expect.equals("M2-foo", b.foo());
+  Expect.equals("M1-baz", b.bar());
+  Expect.equals("M1-baz", b.baz());
+  Expect.isTrue(b is A);
+  Expect.isTrue(b is B);
+  Expect.isTrue(b is M1);
+  Expect.isTrue(b is M2);
+
+  M1 m1 = new M1();
+  Expect.equals("M1-foo", m1.foo());
+  Expect.throws(() => m1.bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("M1-baz", m1.baz());
+  Expect.isFalse(m1 is A);
+  Expect.isFalse(m1 is B);
+  Expect.isTrue(m1 is M1);
+  Expect.isFalse(m1 is M2);
+
+  M2 m2 = new M2();
+  Expect.equals("M2-foo", m2.foo());
+  Expect.throws(() => m2.bar(), (error) => error is NoSuchMethodError);
+  Expect.throws(() => m2.baz(), (error) => error is NoSuchMethodError);
+  Expect.isFalse(m2 is A);
+  Expect.isFalse(m2 is B);
+  Expect.isFalse(m2 is M1);
+  Expect.isTrue(m2 is M2);
+}
diff --git a/tests/compiler/dart2js_native/native_mixin_test.dart b/tests/compiler/dart2js_native/native_mixin_test.dart
index 197a085..7dfdd5d 100644
--- a/tests/compiler/dart2js_native/native_mixin_test.dart
+++ b/tests/compiler/dart2js_native/native_mixin_test.dart
@@ -5,8 +5,8 @@
 // Test that native classes can use ordinary Dart classes as mixins.
 
 class A native "*A" {
-  foo() => 42;
-  baz() => 99;
+  foo() => "A-foo";
+  baz() => "A-baz";
 }
 
 class B extends A with M native "*B" {
@@ -14,8 +14,8 @@
 }
 
 class M {
-  foo() => 87;
-  bar() => 101;
+  foo() => "M-foo";
+  bar() => "M-bar";
 }
 
 A makeA() native;
@@ -31,24 +31,24 @@
 main() {
   setup();
   A a = makeA();
-  Expect.equals(42, a.foo());
+  Expect.equals("A-foo", a.foo());
   Expect.throws(() => a.bar(), (error) => error is NoSuchMethodError);
-  Expect.equals(99, a.baz());
+  Expect.equals("A-baz", a.baz());
   Expect.isTrue(a is A);
   Expect.isFalse(a is B);
   Expect.isFalse(a is M);
 
   B b = makeB();
-  Expect.equals(87, b.foo());
-  Expect.equals(99, b.bar());
-  Expect.equals(99, b.baz());
+  Expect.equals("M-foo", b.foo());
+  Expect.equals("A-baz", b.bar());
+  Expect.equals("A-baz", b.baz());
   Expect.isTrue(b is A);
   Expect.isTrue(b is B);
   Expect.isTrue(b is M);
 
   M m = new M();
-  Expect.equals(87, m.foo());
-  Expect.equals(101, m.bar());
+  Expect.equals("M-foo", m.foo());
+  Expect.equals("M-bar", m.bar());
   Expect.throws(() => m.baz(), (error) => error is NoSuchMethodError);
   Expect.isFalse(m is A);
   Expect.isFalse(m is B);
diff --git a/tests/corelib/iterable_join_test.dart b/tests/corelib/iterable_join_test.dart
index a1df9b7..707abf1 100644
--- a/tests/corelib/iterable_join_test.dart
+++ b/tests/corelib/iterable_join_test.dart
@@ -42,7 +42,7 @@
 
   void testArray(array) {
     testJoin("1,3,5,7,9", array.where((i) => i.isOdd), ",");
-    testJoin("0,2,4,6,8,10,12,14,16,18", array.mappedBy((i) => i * 2), ",");
+    testJoin("0,2,4,6,8,10,12,14,16,18", array.map((i) => i * 2), ",");
     testJoin("5,6,7,8,9", array.skip(5), ",");
     testJoin("5,6,7,8,9", array.skipWhile((i) => i < 5), ",");
     testJoin("0,1,2,3,4", array.take(5), ",");
diff --git a/tests/corelib/iterable_length_test.dart b/tests/corelib/iterable_length_test.dart
index 8dd6cda..e70f82f 100644
--- a/tests/corelib/iterable_length_test.dart
+++ b/tests/corelib/iterable_length_test.dart
@@ -36,6 +36,6 @@
   a = new A(0);
   Expect.equals(0, a.length);
   a = new A(5);
-  Expect.equals(5, a.mappedBy((e) => e + 1).length);
+  Expect.equals(5, a.map((e) => e + 1).length);
   Expect.equals(3, a.where((e) => e >= 3).length);
 }
diff --git a/tests/corelib/iterable_mapping_test.dart b/tests/corelib/iterable_mapping_test.dart
index 4cb7b97..eae0a2d 100644
--- a/tests/corelib/iterable_mapping_test.dart
+++ b/tests/corelib/iterable_mapping_test.dart
@@ -10,46 +10,40 @@
   set1.addAll([11, 12, 13]);
   Set set2 = new Set();
 
-  Iterable mapped = list1.mappedBy((x) => x + 1);
-  Expect.isTrue(mapped is List);
-  Expect.listEquals([2, 3, 4], mapped);
+  Iterable mapped = list1.map((x) => x + 1);
+  Expect.listEquals([2, 3, 4], mapped.toList());
 
-  mapped = mapped.mappedBy((x) => x + 1);
-  Expect.isTrue(mapped is List);
-  Expect.listEquals([3, 4, 5], mapped);
+  mapped = mapped.map((x) => x + 1);
+  Expect.listEquals([3, 4, 5], mapped.toList());
 
-  mapped = list2.mappedBy((x) => x + 1);
-  Expect.isTrue(mapped is List);
-  Expect.listEquals([5, 6], mapped);
+  mapped = list2.map((x) => x + 1);
+  Expect.listEquals([5, 6], mapped.toList());
 
-  mapped = mapped.mappedBy((x) => x + 1);
-  Expect.isTrue(mapped is List);
-  Expect.listEquals([6, 7], mapped);
+  mapped = mapped.map((x) => x + 1);
+  Expect.listEquals([6, 7], mapped.toList());
 
-  mapped = list3.mappedBy((x) => x + 1);
-  Expect.isTrue(mapped is List);
-  Expect.listEquals([], mapped);
+  mapped = list3.map((x) => x + 1);
+  Expect.listEquals([], mapped.toList());
 
-  mapped = mapped.mappedBy((x) => x + 1);
-  Expect.isTrue(mapped is List);
-  Expect.listEquals([], mapped);
+  mapped = mapped.map((x) => x + 1);
+  Expect.listEquals([], mapped.toList());
 
   var expected = new Set<int>()..addAll([12, 13, 14]);
-  mapped = set1.mappedBy((x) => x + 1);
+  mapped = set1.map((x) => x + 1);
   Expect.isFalse(mapped is List);
   Expect.setEquals(expected, mapped.toSet());
 
   expected = new Set<int>()..addAll([13, 14, 15]);
-  mapped = mapped.mappedBy((x) => x + 1);
+  mapped = mapped.map((x) => x + 1);
   Expect.isFalse(mapped is List);
   Expect.setEquals(expected, mapped.toSet());
 
-  mapped = set2.mappedBy((x) => x + 1);
+  mapped = set2.map((x) => x + 1);
   Expect.isFalse(mapped is List);
   Expect.listEquals([], mapped.toList());
 
-  mapped = mapped.mappedBy((x) => x + 1);
+  mapped = mapped.map((x) => x + 1);
   Expect.isFalse(mapped is List);
   Expect.listEquals([], mapped.toList());
 
-}
\ No newline at end of file
+}
diff --git a/tests/corelib/list_growable_test.dart b/tests/corelib/list_growable_test.dart
index 5066c12..616b450 100644
--- a/tests/corelib/list_growable_test.dart
+++ b/tests/corelib/list_growable_test.dart
@@ -33,28 +33,4 @@
   a.clear();
   Expect.equals(0, a.length);
   Expect.throws(() => a[0], (e) => e is RangeError);
-
-  a = new List.filled(42, -1);
-  Expect.equals(42, a.length);
-  a.add(499);
-  Expect.equals(43, a.length);
-  Expect.equals(499, a[42]);
-  for (int i = 0; i < 42; i++) {
-    Expect.equals(-1, a[i]);
-  }
-  a.clear();
-  Expect.equals(0, a.length);
-  Expect.throws(() => a[0], (e) => e is RangeError);
-
-  a = new List<int>.filled(42, -1);
-  Expect.equals(42, a.length);
-  a.add(499);
-  Expect.equals(43, a.length);
-  Expect.equals(499, a[42]);
-  for (int i = 0; i < 42; i++) {
-    Expect.equals(-1, a[i]);
-  }
-  a.clear();
-  Expect.equals(0, a.length);
-  Expect.throws(() => a[0], (e) => e is RangeError);
 }
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index 970eba5..5aa5ae9 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -21,7 +21,7 @@
 
   static void testClosures(List list) {
     testMap(val) {return val * 2 + 10; }
-    List mapped = list.mappedBy(testMap).toList();
+    List mapped = list.map(testMap).toList();
     Expect.equals(mapped.length, list.length);
     for (var i = 0; i < list.length; i++) {
       Expect.equals(mapped[i], list[i]*2 + 10);
diff --git a/tests/corelib/queue_test.dart b/tests/corelib/queue_test.dart
index 11f6e3c..bc0e381 100644
--- a/tests/corelib/queue_test.dart
+++ b/tests/corelib/queue_test.dart
@@ -43,7 +43,7 @@
       return (value == 10);
     }
 
-    Queue mapped = new Queue.from(queue.mappedBy(mapTest));
+    Queue mapped = new Queue.from(queue.map(mapTest));
     checkQueue(mapped, 3, 111);
     checkQueue(queue, 3, 1110);
     Expect.equals(1, mapped.removeFirst());
diff --git a/tests/corelib/reg_exp_all_matches_test.dart b/tests/corelib/reg_exp_all_matches_test.dart
index 27c8ea7..bc31c0b 100644
--- a/tests/corelib/reg_exp_all_matches_test.dart
+++ b/tests/corelib/reg_exp_all_matches_test.dart
@@ -40,7 +40,7 @@
 
   static testMap() {
     var matches = new RegExp("foo?").allMatches("foo fo foo fo");
-    var mapped = matches.mappedBy((Match m) => "${m.group(0)}bar");
+    var mapped = matches.map((Match m) => "${m.group(0)}bar");
     Expect.equals(4, mapped.length);
     var strbuf = new StringBuffer();
     for (String s in mapped) {
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index 2a9cd1b..efe8cf1 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -51,7 +51,7 @@
       return val * val;
     }
 
-    Set mapped = set.mappedBy(testMap).toSet();
+    Set mapped = set.map(testMap).toSet();
     Expect.equals(10, mapped.length);
 
     Expect.equals(true, mapped.contains(0));
diff --git a/tests/html/async_window_test.dart b/tests/html/async_window_test.dart
index 59b3dee..1e55448 100644
--- a/tests/html/async_window_test.dart
+++ b/tests/html/async_window_test.dart
@@ -11,18 +11,20 @@
   test('Window.setInterval', () {
     int counter = 0;
     int id = null;
-    id = window.setInterval(expectAsync0(() {
-      if (counter == 3) {
-        counter = 1024;
-        window.clearInterval(id);
-        // Wait some more time to be sure callback won't be invoked any more.
-        window.setTimeout(expectAsync0((){}), 50);
-        return;
-      }
-      // As callback should have been cleared on 4th invocation, counter
-      // should never be greater than 3.
-      assert(counter < 3);
-      counter++;
-    }, 3), 10);
+    id = window.setInterval(expectAsyncUntil0(
+      () {
+        if (counter == 3) {
+          counter = 1024;
+          window.clearInterval(id);
+          // Wait some more time to be sure callback won't be invoked any more.
+          window.setTimeout(expectAsync0((){}), 50);
+          return;
+        }
+        // As callback should have been cleared on 4th invocation, counter
+        // should never be greater than 3.
+        assert(counter < 3);
+        counter++;
+      },
+      () => counter == 3), 10);
   });
 }
diff --git a/tests/html/canvas_test.dart b/tests/html/canvas_test.dart
index 79c48cb..6d95d3a 100644
--- a/tests/html/canvas_test.dart
+++ b/tests/html/canvas_test.dart
@@ -37,10 +37,10 @@
     var url = canvas.toDataUrl('image/png');
 
     var img = new ImageElement();
-    img.on.load.add(expectAsync1((_) {
+    img.onLoad.listen(expectAsync1((_) {
       expect(img.complete, true);
     }));
-    img.on.error.add((_) {
+    img.onError.listen((_) {
       guardAsync(() {
         expect(true, isFalse, reason: 'URL failed to load.');
       });
diff --git a/tests/html/css_test.dart b/tests/html/css_test.dart
index d827ab3..13418f3 100644
--- a/tests/html/css_test.dart
+++ b/tests/html/css_test.dart
@@ -1,43 +1,64 @@
 library CssTest;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
 main() {
-  useHtmlConfiguration();
-  test('CssMatrix', () {
-    CssMatrix matrix1 = new CssMatrix();
-    expect(matrix1.m11.round(), equals(1));
-    expect(matrix1.m12.round(), isZero);
+  useHtmlIndividualConfiguration();
 
-    CssMatrix matrix2 = new CssMatrix('matrix(1, 0, 0, 1, -835, 0)');
-    expect(matrix2.a.round(), equals(1));
-    expect(matrix2.e.round(), equals(-835));
+  group('supported_CssMatrix', () {
+    test('supported', () {
+      expect(CssMatrix.supported, true);
+    });
   });
-  test('Point', () {
-    Element element = new Element.tag('div');
-    element.attributes['style'] =
-      '''
-      position: absolute;
-      width: 60px;
-      height: 100px;
-      left: 0px;
-      top: 0px;
-      background-color: red;
-      -webkit-transform: translate3d(250px, 100px, 0px) perspective(500px) rotateX(30deg);
-      ''';
-    document.body.nodes.add(element);
 
-    Point point = new Point(5, 2);
-    checkPoint(5, 2, point);
-    checkPoint(256, 110, window.webkitConvertPointFromNodeToPage(element, point));
-    point.y = 100;
-    checkPoint(5, 100, point);
-    checkPoint(254, 196, window.webkitConvertPointFromNodeToPage(element, point));
+  group('supported_DomPoint', () {
+    test('supported', () {
+      expect(DomPoint.supported, true);
+    });
+  });
+
+  group('functional', () {
+    test('CssMatrix', () {
+      var expectation = CssMatrix.supported ? returnsNormally : throws;
+      expect(() {
+        CssMatrix matrix1 = new CssMatrix();
+        expect(matrix1.m11.round(), equals(1));
+        expect(matrix1.m12.round(), isZero);
+
+        CssMatrix matrix2 = new CssMatrix('matrix(1, 0, 0, 1, -835, 0)');
+        expect(matrix2.a.round(), equals(1));
+        expect(matrix2.e.round(), equals(-835));
+      }, expectation);
+    });
+    test('DomPoint', () {
+      var expectation = DomPoint.supported ? returnsNormally : throws;
+      expect(() {
+        Element element = new Element.tag('div');
+        element.attributes['style'] =
+          '''
+          position: absolute;
+          width: 60px;
+          height: 100px;
+          left: 0px;
+          top: 0px;
+          background-color: red;
+          -webkit-transform: translate3d(250px, 100px, 0px);
+          ''';
+        document.body.nodes.add(element);
+
+        DomPoint point = new DomPoint(5, 2);
+        checkPoint(5, 2, point);
+        checkPoint(255, 102, window.convertPointFromNodeToPage(element, point));
+        point.y = 100;
+        checkPoint(5, 100, point);
+        checkPoint(255, 200, window.convertPointFromNodeToPage(element, point));
+      }, expectation);
+    });
   });
 }
 
-void checkPoint(expectedX, expectedY, Point point) {
+void checkPoint(expectedX, expectedY, DomPoint point) {
   expect(point.x.round(), equals(expectedX), reason: 'Wrong point.x');
   expect(point.y.round(), equals(expectedY), reason: 'Wrong point.y');
 }
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index b176436..a0ef366 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -72,13 +72,10 @@
     element.style.transform = 'translateX(10px)';
     document.body.children.add(element);
 
-    element.getComputedStyle('').then(expectAsync1(
-      (CssStyleDeclaration style) {
-        // Some browsers will normalize this, so it'll be a matrix rather than
-        // the original string. Just check that it's something other than null.
-        expect(style.transform.length, greaterThan(3));
-      }
-    ));
+    var style = element.getComputedStyle();
+    // Some browsers will normalize this, so it'll be a matrix rather than
+    // the original string. Just check that it's something other than null.
+    expect(style.transform.length, greaterThan(3));
   });
 
   // IE9 requires an extra poke for some properties to get applied.
@@ -89,11 +86,8 @@
     // Need to wait one tick after the element has been added to the page.
     window.setTimeout(expectAsync0(() {
       element.style.textDecoration = 'underline';
-      element.getComputedStyle('').then(expectAsync1(
-        (CssStyleDeclaration style) {
-          expect(style.textDecoration, equals('underline'));
-        }
-      ));
+      var style = element.getComputedStyle();
+      expect(style.textDecoration, equals('underline'));
     }), 10);
   });
 }
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
new file mode 100644
index 0000000..fbae236
--- /dev/null
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.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.
+
+library dromaeo;
+import 'dart:html';
+import 'dart:json' as json;
+import '../../../samples/third_party/dromaeo/common/common.dart';
+import 'dart:math' as Math;
+import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/unittest/lib/html_config.dart';
+part '../../../samples/third_party/dromaeo/tests/Common.dart';
+part '../../../samples/third_party/dromaeo/tests/RunnerSuite.dart';
+
+/**
+ * The smoketest equivalent of an individual test run, much like
+ * dom-attr-html.dart, dom-modify-html.dart, dom-query-html.dart and others.
+ */
+void main() {
+  new Suite(window, 'dom-nothing')
+    .prep(() {})
+    .test('no-op', () {})
+    .end();
+}
+
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart.js b/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
new file mode 100644
index 0000000..d1f3214
--- /dev/null
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart.js
@@ -0,0 +1,9 @@
+// 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.
+
+window.onload = function(){
+  startTest("dom-nothing");
+  test( "no-op", function(){});
+  endTest();
+};
diff --git a/tests/html/dromaeo_smoke-html.html b/tests/html/dromaeo_smoke-html.html
new file mode 100644
index 0000000..96d65b4
--- /dev/null
+++ b/tests/html/dromaeo_smoke-html.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<!-- The inner smoketest iframe, corresponds to dom-attr-html.html,
+dom-modify-html.html and others in the dromaeo tests directory. -->
+<html>
+<head>
+<script type="application/dart" src="dromaeo_noop/dromaeo_smoke.dart"></script>
+<script src='../../pkg/browser/lib/dart.js'></script>
+<script src='../../samples/third_party/dromaeo/htmlrunner.js'></script>
+</head>
+<body>
+</body>
+</html>
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
new file mode 100644
index 0000000..946ddbc
--- /dev/null
+++ b/tests/html/dromaeo_smoke_test.dart
@@ -0,0 +1,55 @@
+// 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 dromaeo;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import '../../samples/third_party/dromaeo/Dromaeo.dart' as originalTest;
+import 'dart:html';
+import 'dart:async';
+
+/** A variant of the Dromaeo test shoehorned into a unit test. */
+void main() {
+  var combo = '?dartANDhtmlANDnothing';
+  if (!window.location.search.toString().contains(combo)) {
+    if (window.location.href.toString().indexOf("?") == -1) {
+      window.location.href = '${window.location.href}${combo}';
+    } else {
+      window.location.href = '${window.location.href.toString().substring(0,
+          window.location.href.toString().indexOf("?"))}${combo}';
+    }
+  }
+
+  useHtmlConfiguration();
+
+  var scriptSrc = new ScriptElement();
+  scriptSrc.src = '../../../../pkg/browser/lib/dart.js';
+  document.head.children.add(scriptSrc);
+  document.body.innerHtml = '''${document.body.innerHtml}
+  <div id="main">
+    <h1 id="overview" class="test"><span>Performance Tests</span>
+    <input type="button" id="pause" class="pause" value="Loading..."/>
+    <div class="bar">
+      <div id="timebar" style="width:25%;">
+        <span class="left">Est.&nbsp;Time:&nbsp;<strong id="left">0:00</strong>
+        </span>
+      </div>
+    </div>
+    <ul id="tests">
+      <li><a href="?dom">Smoke Tests</a></li>
+    </ul>
+  </div>''';
+
+  bool isDone = false;
+  originalTest.main();
+
+  test('dromaeo runs', () {
+    new Timer.repeating(500, expectAsyncUntil1((timer) {
+      if (document.query('.alldone') != null) {
+        timer.cancel();
+        isDone = true;
+      }
+    }, () => isDone));
+  });
+}
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index 809ef47..89434fc 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -67,7 +67,7 @@
   });
 
   test('mappedBy', () {
-    expect(makeClassSet().mappedBy((c) => c.toUpperCase()).toList(),
+    expect(makeClassSet().map((c) => c.toUpperCase()).toList(),
         unorderedEquals(['FOO', 'BAR', 'BAZ']));
   });
 
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index d849731..4ec1bfc 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -5,6 +5,7 @@
 library ElementTest;
 import '../../pkg/unittest/lib/unittest.dart';
 import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:async';
 import 'dart:html';
 import 'dart:svg' as svg;
 
@@ -17,34 +18,6 @@
   expect(rect.right, rect.left + rect.width);
 }
 
-void testEventHelper(EventListenerList listenerList, String type,
-    [Function registerOnEventListener = null]) {
-  testMultipleEventHelper(listenerList, [type], registerOnEventListener);
-}
-// Allows testing where we polyfill different browsers firing different events.
-void testMultipleEventHelper(EventListenerList listenerList, List<String> types,
-    [Function registerOnEventListener = null]) {
-  bool firedWhenAddedToListenerList = false;
-  bool firedOnEvent = false;
-  listenerList.add((e) {
-    firedWhenAddedToListenerList = true;
-  });
-  if (registerOnEventListener != null) {
-    registerOnEventListener((e) {
-      firedOnEvent = true;
-    });
-  }
-  for (var type in types) {
-    final event = new Event(type);
-    listenerList.dispatch(event);
-  }
-
-  expect(firedWhenAddedToListenerList, isTrue);
-  if (registerOnEventListener != null) {
-    expect(firedOnEvent, isTrue);
-  }
-}
-
 main() {
   useHtmlIndividualConfiguration();
 
@@ -69,33 +42,34 @@
   Element makeElementWithChildren() =>
     new Element.html("<div><br/><img/><input/></div>");
 
-  test('computedStyle', () {
-    final element = document.body;
-    element.computedStyle.then(expectAsync1((style) {
+  group('position', () {
+    test('computedStyle', () {
+      final element = document.body;
+      var style = element.getComputedStyle();
       expect(style.getPropertyValue('left'), 'auto');
-    }));
-  });
+    });
 
-  test('client position synchronous', () {
-    final container = new Element.tag("div");
-    container.style.position = 'absolute';
-    container.style.top = '8px';
-    container.style.left = '8px';
-    final element = new Element.tag("div");
-    element.style.width = '200px';
-    element.style.height = '200px';
-    container.children.add(element);
-    document.body.children.add(container);
+    test('client position synchronous', () {
+      final container = new Element.tag("div");
+      container.style.position = 'absolute';
+      container.style.top = '8px';
+      container.style.left = '8px';
+      final element = new Element.tag("div");
+      element.style.width = '200px';
+      element.style.height = '200px';
+      container.children.add(element);
+      document.body.children.add(container);
 
-    expect(element.clientWidth, greaterThan(100));
-    expect(element.clientHeight, greaterThan(100));
-    expect(element.offsetWidth, greaterThan(100));
-    expect(element.offsetHeight, greaterThan(100));
-    expect(element.scrollWidth, greaterThan(100));
-    expect(element.scrollHeight, greaterThan(100));
-    expect(element.getBoundingClientRect().left, 8);
-    expect(element.getBoundingClientRect().top, 8);
-    container.remove();
+      expect(element.clientWidth, greaterThan(100));
+      expect(element.clientHeight, greaterThan(100));
+      expect(element.offsetWidth, greaterThan(100));
+      expect(element.offsetHeight, greaterThan(100));
+      expect(element.scrollWidth, greaterThan(100));
+      expect(element.scrollHeight, greaterThan(100));
+      expect(element.getBoundingClientRect().left, 8);
+      expect(element.getBoundingClientRect().top, 8);
+      container.remove();
+    });
   });
 
   group('constructors', () {
@@ -135,7 +109,7 @@
       expect(node.tHead.rows[0].cells.length, 3);
       expect(node.tBodies.length, 1);
       expect(node.tBodies[0].rows.length, 2);
-      expect(node.tBodies[0].rows[1].cells.mappedBy((c) => c.innerHtml),
+      expect(node.tBodies[0].rows[1].cells.map((c) => c.innerHtml),
           [' Failing\n   ', ' Grade\n   ', ' Passing\n']);
     });
 
@@ -208,7 +182,7 @@
           'is a TableRowElement'));
       expect(node.tagName, 'TR');
       expect(node.parent, isNull);
-      expect(node.cells.mappedBy((c) => c.innerHtml), ['foo', 'bar']);
+      expect(node.cells.map((c) => c.innerHtml), ['foo', 'bar']);
     });
 
     test('.html td', () {
@@ -231,143 +205,65 @@
   });
 
   group('eventListening', () {
-    test('eventListeners', () {
-      final element = new Element.tag('div');
-      final on = element.on;
+    test('streams', () {
+      final target = new Element.tag('div');
 
-      testEventHelper(on.abort, 'abort',
-          (listener) => Testing.addEventListener(
-              element, 'abort', listener, true));
-      testEventHelper(on.beforeCopy, 'beforecopy',
-          (listener) => Testing.addEventListener(
-              element, 'beforecopy', listener, true));
-      testEventHelper(on.beforeCut, 'beforecut',
-          (listener) => Testing.addEventListener(
-              element, 'beforecut', listener, true));
-      testEventHelper(on.beforePaste, 'beforepaste',
-          (listener) => Testing.addEventListener(
-              element, 'beforepaste', listener, true));
-      testEventHelper(on.blur, 'blur',
-          (listener) => Testing.addEventListener(
-              element, 'blur', listener, true));
-      testEventHelper(on.change, 'change',
-          (listener) => Testing.addEventListener(
-              element, 'change', listener, true));
-      testEventHelper(on.contextMenu, 'contextmenu',
-          (listener) => Testing.addEventListener(
-              element, 'contextmenu', listener, true));
-      testEventHelper(on.copy, 'copy',
-          (listener) => Testing.addEventListener(
-              element, 'copy', listener, true));
-      testEventHelper(on.cut, 'cut',
-          (listener) => Testing.addEventListener(
-              element, 'cut', listener, true));
-      testEventHelper(on.doubleClick, 'dblclick',
-          (listener) => Testing.addEventListener(
-              element, 'dblclick', listener, true));
-      testEventHelper(on.drag, 'drag',
-          (listener) => Testing.addEventListener(
-              element, 'drag', listener, true));
-      testEventHelper(on.dragEnd, 'dragend',
-          (listener) => Testing.addEventListener(
-              element, 'dragend', listener, true));
-      testEventHelper(on.dragEnter, 'dragenter',
-          (listener) => Testing.addEventListener(
-              element, 'dragenter', listener, true));
-      testEventHelper(on.dragLeave, 'dragleave',
-          (listener) => Testing.addEventListener(
-              element, 'dragleave', listener, true));
-      testEventHelper(on.dragOver, 'dragover',
-          (listener) => Testing.addEventListener(
-              element, 'dragover', listener, true));
-      testEventHelper(on.dragStart, 'dragstart',
-          (listener) => Testing.addEventListener(
-              element, 'dragstart', listener, true));
-      testEventHelper(on.drop, 'drop',
-          (listener) => Testing.addEventListener(
-              element, 'drop', listener, true));
-      testEventHelper(on.error, 'error',
-          (listener) => Testing.addEventListener(
-              element, 'error', listener, true));
-      testEventHelper(on.focus, 'focus',
-          (listener) => Testing.addEventListener(
-              element, 'focus', listener, true));
-      testEventHelper(on.input, 'input',
-          (listener) => Testing.addEventListener(
-              element, 'input', listener, true));
-      testEventHelper(on.invalid, 'invalid',
-          (listener) => Testing.addEventListener(
-              element, 'invalid', listener, true));
-      testEventHelper(on.keyDown, 'keydown',
-          (listener) => Testing.addEventListener(
-              element, 'keydown', listener, true));
-      testEventHelper(on.keyPress, 'keypress',
-          (listener) => Testing.addEventListener(
-              element, 'keypress', listener, true));
-      testEventHelper(on.keyUp, 'keyup',
-          (listener) => Testing.addEventListener(
-              element, 'keyup', listener, true));
-      testEventHelper(on.load, 'load',
-          (listener) => Testing.addEventListener(
-              element, 'load', listener, true));
-      testEventHelper(on.mouseDown, 'mousedown',
-          (listener) => Testing.addEventListener(
-              element, 'mousedown', listener, true));
-      testEventHelper(on.mouseMove, 'mousemove',
-          (listener) => Testing.addEventListener(
-              element, 'mousemove', listener, true));
-      testEventHelper(on.mouseOut, 'mouseout',
-          (listener) => Testing.addEventListener(
-              element, 'mouseout', listener, true));
-      testEventHelper(on.mouseOver, 'mouseover',
-          (listener) => Testing.addEventListener(
-              element, 'mouseover', listener, true));
-      testEventHelper(on.mouseUp, 'mouseup',
-          (listener) => Testing.addEventListener(
-              element, 'mouseup', listener, true));
-      // Browsers have different events that they use, so fire all variants.
-      testMultipleEventHelper(on.mouseWheel,
-          ['mousewheel', 'wheel', 'DOMMouseScroll'],
-          (listener) => Testing.addEventListener(
-              element, 'mousewheel', listener, true));
-      testEventHelper(on.paste, 'paste',
-          (listener) => Testing.addEventListener(
-              element, 'paste', listener, true));
-      testEventHelper(on.reset, 'reset',
-          (listener) => Testing.addEventListener(
-              element, 'reset', listener, true));
-      testEventHelper(on.scroll, 'scroll',
-          (listener) => Testing.addEventListener(
-              element, 'scroll', listener, true));
-      testEventHelper(on.search, 'search',
-          (listener) => Testing.addEventListener(
-              element, 'search', listener, true));
-      testEventHelper(on.select, 'select',
-          (listener) => Testing.addEventListener(
-              element, 'select', listener, true));
-      testEventHelper(on.selectStart, 'selectstart',
-          (listener) => Testing.addEventListener(
-              element, 'selectstart', listener, true));
-      testEventHelper(on.submit, 'submit',
-          (listener) => Testing.addEventListener(
-              element, 'submit', listener, true));
-      testEventHelper(on.touchCancel, 'touchcancel',
-          (listener) => Testing.addEventListener(
-              element, 'touchcancel', listener, true));
-      testEventHelper(on.touchEnd, 'touchend',
-          (listener) => Testing.addEventListener(
-              element, 'touchend', listener, true));
-      testEventHelper(on.touchLeave, 'touchleave');
-      testEventHelper(on.touchMove, 'touchmove',
-          (listener) => Testing.addEventListener(
-              element, 'touchmove', listener, true));
-      testEventHelper(on.touchStart, 'touchstart',
-          (listener) => Testing.addEventListener(
-              element, 'touchstart', listener, true));
-      testEventHelper(on.transitionEnd, 'webkitTransitionEnd');
-      testEventHelper(on.fullscreenChange, 'webkitfullscreenchange',
-          (listener) => Testing.addEventListener(element,
-             'webkitfullscreenchange', listener, true));
+      void testEvent(Stream stream, String type) {
+        var firedOnEvent = false;
+        stream.listen((e) {
+          firedOnEvent = true;
+        });
+        expect(firedOnEvent, isFalse);
+        var event = new Event(type);
+        target.dispatchEvent(event);
+
+        expect(firedOnEvent, isTrue);
+      }
+
+      testEvent(target.onAbort, 'abort');
+      testEvent(target.onBeforeCopy, 'beforecopy');
+      testEvent(target.onBeforeCut, 'beforecut');
+      testEvent(target.onBeforePaste, 'beforepaste');
+      testEvent(target.onBlur, 'blur');
+      testEvent(target.onChange, 'change');
+      testEvent(target.onContextMenu, 'contextmenu');
+      testEvent(target.onCopy, 'copy');
+      testEvent(target.onCut, 'cut');
+      testEvent(target.onDoubleClick, 'dblclick');
+      testEvent(target.onDrag, 'drag');
+      testEvent(target.onDragEnd, 'dragend');
+      testEvent(target.onDragEnter, 'dragenter');
+      testEvent(target.onDragLeave, 'dragleave');
+      testEvent(target.onDragOver, 'dragover');
+      testEvent(target.onDragStart, 'dragstart');
+      testEvent(target.onDrop, 'drop');
+      testEvent(target.onError, 'error');
+      testEvent(target.onFocus, 'focus');
+      testEvent(target.onFullscreenChange, 'webkitfullscreenchange');
+      testEvent(target.onInput, 'input');
+      testEvent(target.onInvalid, 'invalid');
+      testEvent(target.onKeyDown, 'keydown');
+      testEvent(target.onKeyPress, 'keypress');
+      testEvent(target.onKeyUp, 'keyup');
+      testEvent(target.onLoad, 'load');
+      testEvent(target.onMouseDown, 'mousedown');
+      testEvent(target.onMouseMove, 'mousemove');
+      testEvent(target.onMouseOut, 'mouseout');
+      testEvent(target.onMouseOver, 'mouseover');
+      testEvent(target.onMouseUp, 'mouseup');
+      testEvent(target.onPaste, 'paste');
+      testEvent(target.onReset, 'reset');
+      testEvent(target.onScroll, 'scroll');
+      testEvent(target.onSearch, 'search');
+      testEvent(target.onSelect, 'select');
+      testEvent(target.onSelectStart, 'selectstart');
+      testEvent(target.onSubmit, 'submit');
+      testEvent(target.onTouchCancel, 'touchcancel');
+      testEvent(target.onTouchEnd, 'touchend');
+      testEvent(target.onTouchLeave, 'touchleave');
+      testEvent(target.onTouchMove, 'touchmove');
+      testEvent(target.onTouchStart, 'touchstart');
+      testEvent(target.onTransitionEnd, 'webkitTransitionEnd');
     });
   });
 
@@ -375,7 +271,7 @@
     test('clickEvent', () {
       var e = new DivElement();
       var firedEvent = false;
-      e.on.click.add((event) {
+      e.onClick.listen((event) {
         firedEvent = true;
       });
       expect(firedEvent, false);
@@ -643,7 +539,7 @@
     });
 
     test('mappedBy', () {
-      var texts = getQueryAll().mappedBy((el) => el.text).toList();
+      var texts = getQueryAll().map((el) => el.text).toList();
       expect(texts, equals(['Dart!', 'Hello', '']));
     });
 
diff --git a/tests/html/event_customevent_test.dart b/tests/html/event_customevent_test.dart
index 2f50627..4e0ed48 100644
--- a/tests/html/event_customevent_test.dart
+++ b/tests/html/event_customevent_test.dart
@@ -26,9 +26,19 @@
 main() {
   useHtmlConfiguration();
 
-  eventTest('CustomEvent.initCustomEvent', () {
-    return new CustomEvent('foo', canBubble: false, cancelable: false,
+  test('custom events', () {
+    var provider = new EventStreamProvider<CustomEvent>('foo');
+    var el = new DivElement();
+
+    var fired = false;
+    provider.forTarget(el).listen((ev) {
+      fired = true;
+      expect(ev.detail, 'detail');
+    });
+
+    var ev = new CustomEvent('foo', canBubble: false, cancelable: false,
         detail: 'detail');
-  },
-  (ev) { expect(ev.detail, equals('detail')); });
+    el.dispatchEvent(ev);
+    expect(fired, isTrue);
+  });
 }
diff --git a/tests/html/events_test.dart b/tests/html/events_test.dart
index 11a9623..a88d631 100644
--- a/tests/html/events_test.dart
+++ b/tests/html/events_test.dart
@@ -29,27 +29,29 @@
     Event event = new Event('test');
 
     invocationCounter = 0;
-    element.on['test'].dispatch(event);
+    element.dispatchEvent(event);
     expect(invocationCounter, isZero);
 
-    element.on['test'].add(handler, false);
+    var provider = new EventStreamProvider<CustomEvent>('test');
+
+    var sub = provider.forTarget(element).listen(handler);
     invocationCounter = 0;
-    element.on['test'].dispatch(event);
+    element.dispatchEvent(event);
     expect(invocationCounter, 1);
 
-    element.on['test'].remove(handler, false);
+    sub.cancel();
     invocationCounter = 0;
-    element.on['test'].dispatch(event);
+    element.dispatchEvent(event);
     expect(invocationCounter, isZero);
 
-    element.on['test'].add(handler, false);
+    provider.forTarget(element).listen(handler);
     invocationCounter = 0;
-    element.on['test'].dispatch(event);
+    element.dispatchEvent(event);
     expect(invocationCounter, 1);
 
-    element.on['test'].add(handler, false);
+    provider.forTarget(element).listen(handler);
     invocationCounter = 0;
-    element.on['test'].dispatch(event);
+    element.dispatchEvent(event);
     expect(invocationCounter, 1);
   });
   test('InitMouseEvent', () {
diff --git a/tests/html/form_data_test.dart b/tests/html/form_data_test.dart
index cdcca7e..0ddd97d 100644
--- a/tests/html/form_data_test.dart
+++ b/tests/html/form_data_test.dart
@@ -61,10 +61,10 @@
     var xhr = new HttpRequest();
     xhr.open("POST", "http://localhost:${window.location.port}/echo");
 
-    xhr.on.load.add(expectAsync1((e) {
+    xhr.onLoad.listen(expectAsync1((e) {
       expect(xhr.responseText.contains(blobString), true);
     }));
-    xhr.on.error.add((e) {
+    xhr.onError.listen((e) {
       fail('$e');
     });
     xhr.send(form);
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index 6f4eb3a..f2c7c12 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -3,16 +3,6 @@
 import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
-/// Waits for a callback once, then removes the event handler.
-void expectAsync1Once(EventListenerList list, void callback(arg)) {
-  var fn = null;
-  fn = expectAsync1((arg) {
-    list.remove(fn);
-    callback(arg);
-  });
-  list.add(fn);
-}
-
 main() {
   useHtmlIndividualConfiguration();
 
@@ -53,10 +43,10 @@
 
         // Need to wait a frame or two to let the pushState events occur.
         window.setTimeout(expectAsync0(() {
-          expectAsync1Once(window.on.popState, (_) {
+          window.onPopState.first.then(expectAsync1((_){
             expect(window.history.length, length);
             expect(window.location.href.endsWith('dummy1'), isTrue);
-          });
+          }));
 
           window.history.back();
         }), 100);
diff --git a/tests/html/html.status b/tests/html/html.status
index 36b8e1a..1853065 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -5,7 +5,6 @@
 window_open_test: Skip # http://dartbug.com/5151
 
 event_test: Skip  # Issue 1996
-webgl_1_test: Skip  # Issue 1495
 
 # Layout tests are only supported on DRT.
 [ $runtime == ie9 || $runtime == ie10 || $runtime == safari || $runtime == ff || $runtime == chrome || $runtime == opera ]
@@ -21,12 +20,15 @@
 input_element_test/supported_week: Fail
 speechrecognition_test/supported: Pass, Fail       # Chrome stable does not support it.
 shadow_dom_test/supported: Fail
-css_test: Pass, Fail # Issue 7978
 speechrecognition_test/types: Pass, Fail
+touchevent_test/supported: Fail
 
-[ $runtime == chrome || $runtime == drt]
-audiobuffersourcenode_test: Pass, Fail, Timeout # AudiobufferSourceNode is flaky on Chrome and Dartium - filed issue 8021 for the timeout.
-audiocontext_test: Pass, Timeout  # Issue 8021.
+[$runtime == drt || $runtime == dartium || $runtime == chrome]
+webgl_1_test: Pass, Fail # Issue 8219
+
+[ $runtime == drt || $runtime == chrome]
+audiobuffersourcenode_test: Pass, Fail, Timeout, Crash # AudiobufferSourceNode is flaky on Chrome and Dartium - filed issue 8021 for the timeout.
+audiocontext_test: Pass, Timeout, Crash  # Issue 8021.
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 request_animation_frame_test: Skip   # drt hangs; requestAnimationFrame not implemented
@@ -48,8 +50,10 @@
 # TODO(efortuna, blois): Triage.
 audiobuffersourcenode_test: Fail
 audiocontext_test: Fail
-css_test: Fail
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
 document_test/supports_cssCanvasContext: Fail
+dromaeo_smoke_test: Skip #TODO(efortuna): investigating.
 element_test/click: Fail                # IE does not support firing this event.
 element_types_test/supported_content: Fail
 element_types_test/supported_details: Fail
@@ -74,6 +78,7 @@
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
 messageevent_test: Fail
+microtask_test: Fail, Pass # Appears to be flaky
 mutationobserver_test/supported: Fail
 native_gc_test: Fail, Pass # BUG(7774): Untriaged.
 notifications_test/supported: Fail
@@ -83,16 +88,19 @@
 storage_test: Fail, Pass
 svgelement_test/additionalConstructors: Fail
 svgelement2_test: Fail
-svg_3_test: Fail
-websql_test: Fail
+touchevent_test/supported: Fail
+webgl_1_test/supported: Fail
+websql_test/supported: Fail
 websocket_test/websocket: Fail # TODO(efortuna): Issue 7875.
 window_open_test: Skip
 xhr_cross_origin_test: Fail # TODO(efortuna): Issue 7875.
 xhr_test/supported_HttpRequestProgressEvent: Fail
-xsltprocessor_test: Fail
+xsltprocessor_test/supported: Fail
+history_test/history: Pass, Fail # issue 8183
 
 [ $runtime == ie9 ]
 document_test/supports_cssCanvasContext: Fail
+dromaeo_smoke_test: Skip #TODO(efortuna): investigating.
 element_test/click: Fail                # IE does not support firing this event.
 element_types_test/supported_content: Fail
 element_types_test/supported_datalist: Fail
@@ -109,7 +117,8 @@
 inner_frame_test: Skip # Issue 5727 (timeout)
 typed_arrays_1_test/supported: Fail
 localstorage_test: Fail
-websql_test: Fail # IE does not support web SQL
+webgl_1_test/supported: Fail
+websql_test/supported: Fail
 #
 # Investigate and triage the following into bug reports.
 #
@@ -117,7 +126,8 @@
 audiocontext_test: Fail
 blob_constructor_test: Fail
 cache_test/supported: Fail
-css_test: Fail
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
 dom_constructors_test: Fail
 element_test/matches: Fail # IE9 does not support matches
 fileapi_test/supported: Fail
@@ -149,25 +159,19 @@
 svg_3_test: Fail
 svgelement_test/additionalConstructors: Fail
 svgelement2_test: Fail
+touchevent_test/supported: Fail
 url_test: Fail              # IE9 does not support createObjectURL (it is supported in IE10)
 websocket_test/supported: Fail
 window_open_test: Skip      # BUG(4016)
-xsltprocessor_test: Skip    # BUG(4016)
 isolates_test: Skip         # BUG(4016)
 xhr_test: Skip              # BUG(4016)
 xhr_test/supported_HttpRequestProgressEvent: Fail
 xhr_cross_origin_test: Fail # Issue 6016.
+xsltprocessor_test/supported: Fail
 
 [ $runtime == safari ]
 element_types_test/supported_content: Fail
 element_types_test/supported_datalist: Fail
-element_types_test/supported_details: Fail
-element_types_test/supported_embed: Fail
-element_types_test/supported_keygen: Fail
-element_types_test/supported_meter: Fail
-element_types_test/supported_object: Fail
-element_types_test/supported_output: Fail
-element_types_test/supported_progress: Fail
 element_types_test/supported_shadow: Fail
 element_types_test/supported_track: Pass, Fail
 fileapi_test/supported: Fail
@@ -175,12 +179,8 @@
 input_element_test/supported_date: Fail
 input_element_test/supported_datetime-local: Fail
 input_element_test/supported_datetime: Fail
-input_element_test/supported_email: Fail
 input_element_test/supported_month: Fail, Crash
-input_element_test/supported_number: Fail
-input_element_test/supported_range: Fail, Crash    # TODO(efortuna): Please triage this failure.
 input_element_test/supported_time: Fail, Crash
-input_element_test/supported_url: Fail
 input_element_test/supported_week: Fail, Crash
 media_stream_test/supported_media: Fail
 media_stream_test/supported_MediaStreamEvent: Fail
@@ -189,25 +189,13 @@
 performance_api_test/supported: Fail
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
+touchevent_test/supported: Fail
+webgl_1_test: Pass, Fail # Issue 8219
 
 audiocontext_test: Crash, Fail # Issue: 7414
 datalistelement_test: Fail # Issue: 7414
 element_test/elements: Crash, Fail # Issue: 7414
-element_types_test/constructors: Fail
-fileapi_test/getDirectory: Fail # Issue: 7414
-fileapi_test/getFile: Pass, Fail # Issue: 7414
-fileapi_test/unsupported_throws: Fail # Issue: 7414
-input_element_test/constructors: Fail # Issue: 7414
-input_element_test/supported_tel: Pass, Fail # Issue: 7414
-media_stream_test/constructors: Pass, Fail # Issue: 7414
-node_test: Skip # Issue 6457
-notifications_test/unsupported_throws: Fail # Issue: 7414
-notifications_test/webkitNotifications: Fail # Issue: 7414
-performance_api_test/performance: Fail # Issue: 7414
-shadow_dom_test/ShadowDOM_tests: Fail # Issue: 7414
 wheelevent_test: Fail # Issue: 7414
-speechrecognition_test/types: Pass, Fail
-
 
 [ $runtime == opera ]
 document_test/supports_cssCanvasContext: Fail
@@ -222,7 +210,8 @@
 blob_constructor_test: Fail
 canvas_using_html_test: Fail
 canvas_test: Fail
-css_test: Fail
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
 cssstyledeclaration_test: Fail
 element_add_test: Fail
 element_constructor_1_test: Fail
@@ -248,12 +237,13 @@
 js_interop_3_test: Skip # Timeout.
 js_interop_4_test: Skip # Timeout.
 isolates_test: Skip # Timeout.
-websql_test: Skip # Timeout.
+websql_test/supported: Fail
 
 [ $runtime == ff ]
 audiobuffersourcenode_test: Fail # FF only has Audio element.
 audiocontext_test: Fail      # FF only has Audio element
-css_test: Fail               # No analog to WebKitCssMatrix
+css_test/supported_CssMatrix: Fail
+css_test/supported_DomPoint: Fail
 dart_object_local_storage_test: Skip  # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
 document_test/supports_cssCanvasContext: Fail
 element_types_test/supported_content: Fail
@@ -282,9 +272,12 @@
 svg_3_test: Fail
 svgelement_test/additionalConstructors: Fail
 svgelement2_test: Fail
+touchevent_test/supported: Fail
 transferables_test: Fail   # Issue 3392.
-websql_test: Fail # FF does not support web SQL
+webgl_1_test: Pass, Fail   # Issue 8219
+websql_test/supported: Fail
 xhr_test/supported_HttpRequestProgressEvent: Fail
+dromaeo_smoke_test: Pass, Fail # Issue: 8257
 
 [ $runtime == ie9 && ($system == linux || $system == macos) ]
 *: Skip
diff --git a/tests/html/indexeddb_1_test.dart b/tests/html/indexeddb_1_test.dart
index f9ae43f..92eef20 100644
--- a/tests/html/indexeddb_1_test.dart
+++ b/tests/html/indexeddb_1_test.dart
@@ -28,19 +28,19 @@
   step2(e) {
     var transaction = db.transaction(storeName, 'readonly');
     var request = transaction.objectStore(storeName).getObject(key);
-    request.on.success.add(expectAsync1((e) {
+    request.onSuccess.listen(expectAsync1((e) {
       var object = e.target.result;
       db.close();
       expect(object, matcher);
     }));
-    request.on.error.add(fail);
+    request.onError.listen(fail);
   }
 
   step1() {
     var transaction = db.transaction([storeName], 'readwrite');
     var request = transaction.objectStore(storeName).put(value, key);
-    request.on.success.add(expectAsync1(step2));
-    request.on.error.add(fail);
+    request.onSuccess.listen(expectAsync1(step2));
+    request.onError.listen(fail);
   }
 
   initDb(e) {
@@ -48,15 +48,15 @@
     if (version != db.version) {
       // Legacy 'setVersion' upgrade protocol. Chrome 23 and earlier.
       var request = db.setVersion('$version');
-      request.on.success.add(
+      request.onSuccess.listen(
         expectAsync1((e) {
           createObjectStore(db);
           var transaction = e.target.result;
-          transaction.on.complete.add(expectAsync1((e) => step1()));
-          transaction.on.error.add(fail);
+          transaction.onComplete.listen(expectAsync1((e) => step1()));
+          transaction.onError.listen(fail);
         })
       );
-      request.on.error.add(fail);
+      request.onError.listen(fail);
     } else {
       step1();
     }
@@ -65,12 +65,12 @@
   openDb(e) {
     var request = html.window.indexedDB.open(dbName, version);
     expect(request, isNotNull);
-    request.on.success.add(expectAsync1(initDb));
-    request.on.error.add(fail);
+    request.onSuccess.listen(expectAsync1(initDb));
+    request.onError.listen(fail);
     if (request is idb.OpenDBRequest) {
       // New upgrade protocol.  Old API has no 'upgradeNeeded' and uses
       // setVersion instead. This path take by FireFox 15, Chrome 24.
-      request.on.upgradeNeeded.add((e) {
+      request.onUpgradeNeeded.listen((e) {
           guardAsync(() {
               createObjectStore(e.target.result);
             });
@@ -80,8 +80,8 @@
 
   // Delete any existing DB.
   var deleteRequest = html.window.indexedDB.deleteDatabase(dbName);
-  deleteRequest.on.success.add(expectAsync1(openDb));
-  deleteRequest.on.error.add(fail);
+  deleteRequest.onSuccess.listen(expectAsync1(openDb));
+  deleteRequest.onError.listen(fail);
 };
 
 testReadWriteTyped(key, value, matcher,
@@ -104,19 +104,19 @@
   step2(e) {
     idb.Transaction transaction = db.transaction(storeName, 'readonly');
     idb.Request request = transaction.objectStore(storeName).getObject(key);
-    request.on.success.add(expectAsync1((e) {
+    request.onSuccess.listen(expectAsync1((e) {
       var object = e.target.result;
       db.close();
       expect(object, matcher);
     }));
-    request.on.error.add(fail);
+    request.onError.listen(fail);
   }
 
   step1() {
     idb.Transaction transaction = db.transaction([storeName], 'readwrite');
     idb.Request request = transaction.objectStore(storeName).put(value, key);
-    request.on.success.add(expectAsync1(step2));
-    request.on.error.add(fail);
+    request.onSuccess.listen(expectAsync1(step2));
+    request.onError.listen(fail);
   }
 
   initDb(e) {
@@ -124,15 +124,15 @@
     if (version != db.version) {
       // Legacy 'setVersion' upgrade protocol.
       idb.Request request = db.setVersion('$version');
-      request.on.success.add(
+      request.onSuccess.listen(
         expectAsync1((e) {
           createObjectStore(db);
           idb.Transaction transaction = e.target.result;
-          transaction.on.complete.add(expectAsync1((e) => step1()));
-          transaction.on.error.add(fail);
+          transaction.onComplete.listen(expectAsync1((e) => step1()));
+          transaction.onError.listen(fail);
         })
       );
-      request.on.error.add(fail);
+      request.onError.listen(fail);
     } else {
       step1();
     }
@@ -141,12 +141,12 @@
   openDb(e) {
     idb.Request request = html.window.indexedDB.open(dbName, version);
     expect(request, isNotNull);
-    request.on.success.add(expectAsync1(initDb));
-    request.on.error.add(fail);
+    request.onSuccess.listen(expectAsync1(initDb));
+    request.onError.listen(fail);
     if (request is idb.OpenDBRequest) {
       // New upgrade protocol.  Old API has no 'upgradeNeeded' and uses
       // setVersion instead.
-      request.on.upgradeNeeded.add((e) {
+      request.onUpgradeNeeded.listen((e) {
           guardAsync(() {
               createObjectStore(e.target.result);
             });
@@ -156,8 +156,8 @@
 
   // Delete any existing DB.
   idb.Request deleteRequest = html.window.indexedDB.deleteDatabase(dbName);
-  deleteRequest.on.success.add(expectAsync1(openDb));
-  deleteRequest.on.error.add(fail);
+  deleteRequest.onSuccess.listen(expectAsync1(openDb));
+  deleteRequest.onError.listen(fail);
 };
 
 tests_dynamic() {
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index ac41b3d..66fef6c 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -32,19 +32,19 @@
   step2(e) {
     var transaction = db.transaction(storeName, 'readonly');
     var request = transaction.objectStore(storeName).getObject(key);
-    request.on.success.add(expectAsync1((e) {
+    request.onSuccess.listen(expectAsync1((e) {
       var object = e.target.result;
       db.close();
       check(value, object);
     }));
-    request.on.error.add(fail);
+    request.onError.listen(fail);
   }
 
   step1() {
     var transaction = db.transaction([storeName], 'readwrite');
     var request = transaction.objectStore(storeName).put(value, key);
-    request.on.success.add(expectAsync1(step2));
-    request.on.error.add(fail);
+    request.onSuccess.listen(expectAsync1(step2));
+    request.onError.listen(fail);
   }
 
   initDb(e) {
@@ -52,15 +52,15 @@
     if (version != db.version) {
       // Legacy 'setVersion' upgrade protocol.
       var request = db.setVersion('$version');
-      request.on.success.add(
+      request.onSuccess.listen(
         expectAsync1((e) {
           createObjectStore(db);
           var transaction = e.target.result;
-          transaction.on.complete.add(expectAsync1((e) => step1()));
-          transaction.on.error.add(fail);
+          transaction.onComplete.listen(expectAsync1((e) => step1()));
+          transaction.onError.listen(fail);
         })
       );
-      request.on.error.add(fail);
+      request.onError.listen(fail);
     } else {
       step1();
     }
@@ -69,12 +69,12 @@
   openDb(e) {
     var request = html.window.indexedDB.open(dbName, version);
     expect(request, isNotNull);
-    request.on.success.add(expectAsync1(initDb));
-    request.on.error.add(fail);
+    request.onSuccess.listen(expectAsync1(initDb));
+    request.onError.listen(fail);
     if (request is idb.OpenDBRequest) {
       // New upgrade protocol.  Old API has no 'upgradeNeeded' and uses
       // setVersion instead.
-      request.on.upgradeNeeded.add((e) {
+      request.onUpgradeNeeded.listen((e) {
           guardAsync(() {
               createObjectStore(e.target.result);
             });
@@ -84,8 +84,8 @@
 
   // Delete any existing DB.
   var deleteRequest = html.window.indexedDB.deleteDatabase(dbName);
-  deleteRequest.on.success.add(expectAsync1(openDb));
-  deleteRequest.on.error.add(fail);
+  deleteRequest.onSuccess.listen(expectAsync1(openDb));
+  deleteRequest.onError.listen(fail);
 };
 
 
diff --git a/tests/html/indexeddb_3_test.dart b/tests/html/indexeddb_3_test.dart
index 5a4f7e5..436b125 100644
--- a/tests/html/indexeddb_3_test.dart
+++ b/tests/html/indexeddb_3_test.dart
@@ -34,43 +34,43 @@
     var request = window.indexedDB.open(DB_NAME, VERSION);
     if (request is OpenDBRequest) {
       // New upgrade protocol. FireFox 15, Chrome 24, hopefully IE10.
-      request.on.success.add(expectAsync1((e) {
+      request.onSuccess.listen(expectAsync1((e) {
             db = e.target.result;
             afterOpen();
           }));
-      request.on.upgradeNeeded.add((e) {
+      request.onUpgradeNeeded.listen((e) {
           guardAsync(() {
               _createObjectStore(e.target.result);
             });
         });
-      request.on.error.add(fail('open'));
+      request.onError.listen(fail('open'));
     } else {
       // Legacy setVersion upgrade protocol. Chrome < 23.
-      request.on.success.add(expectAsync1((e) {
+      request.onSuccess.listen(expectAsync1((e) {
             db = e.target.result;
             if (db.version != '$VERSION') {
               var setRequest = db.setVersion('$VERSION');
-              setRequest.on.success.add(
+              setRequest.onSuccess.listen(
                   expectAsync1((e) {
                       _createObjectStore(db);
                       var transaction = e.target.result;
-                      transaction.on.complete.add(
+                      transaction.onComplete.listen(
                           expectAsync1((e) => afterOpen()));
-                      transaction.on.error.add(fail('Upgrade'));
+                      transaction.onError.listen(fail('Upgrade'));
                     }));
-              setRequest.on.error.add(fail('setVersion error'));
+              setRequest.onError.listen(fail('setVersion error'));
             } else {
               afterOpen();
             }
           }));
-      request.on.error.add(fail('open'));
+      request.onError.listen(fail('open'));
     }
   }
 
   _createAndOpenDb(afterOpen()) {
     var request = window.indexedDB.deleteDatabase(DB_NAME);
-    request.on.success.add(expectAsync1((e) { _openDb(afterOpen); }));
-    request.on.error.add(fail('delete old Db'));
+    request.onSuccess.listen(expectAsync1((e) { _openDb(afterOpen); }));
+    request.onError.listen(fail('delete old Db'));
   }
 
   writeItems(int index) {
@@ -78,11 +78,11 @@
       var transaction = db.transaction([STORE_NAME], 'readwrite');
       var request = transaction.objectStore(STORE_NAME)
           .put('Item $index', index);
-      request.on.success.add(expectAsync1((e) {
+      request.onSuccess.listen(expectAsync1((e) {
           writeItems(index + 1);
         }
       ));
-      request.on.error.add(fail('put'));
+      request.onError.listen(fail('put'));
     }
   }
 
@@ -95,7 +95,7 @@
     int itemCount = 0;
     int sumKeys = 0;
     int lastKey = null;
-    cursorRequest.on.success.add(expectAsync1((e) {
+    cursorRequest.onSuccess.listen(expectAsync1((e) {
       var cursor = e.target.result;
       if (cursor != null) {
         lastKey = cursor.key;
@@ -111,7 +111,7 @@
         expect(sumKeys, (100 * 99) ~/ 2);
       }
     }, count:101));
-    cursorRequest.on.error.add(fail('openCursor'));
+    cursorRequest.onError.listen(fail('openCursor'));
   }
 
   readAllReversedViaCursor() {
@@ -122,7 +122,7 @@
     int itemCount = 0;
     int sumKeys = 0;
     int lastKey = null;
-    cursorRequest.on.success.add(expectAsync1((e) {
+    cursorRequest.onSuccess.listen(expectAsync1((e) {
       var cursor = e.target.result;
       if (cursor != null) {
         lastKey = cursor.key;
@@ -137,7 +137,7 @@
         expect(sumKeys, (100 * 99) ~/ 2);
       }
     }, count:101));
-    cursorRequest.on.error.add(fail('openCursor'));
+    cursorRequest.onError.listen(fail('openCursor'));
   }
 }
 
diff --git a/tests/html/indexeddb_4_test.dart b/tests/html/indexeddb_4_test.dart
index d8a1341..6704af0 100644
--- a/tests/html/indexeddb_4_test.dart
+++ b/tests/html/indexeddb_4_test.dart
@@ -32,43 +32,43 @@
     var request = window.indexedDB.open(DB_NAME, VERSION);
     if (request is OpenDBRequest) {
       // New upgrade protocol.
-      request.on.success.add(expectAsync1((e) {
+      request.onSuccess.listen(expectAsync1((e) {
             db = e.target.result;
             afterOpen();
           }));
-      request.on.upgradeNeeded.add((e) {
+      request.onUpgradeNeeded.listen((e) {
           guardAsync(() {
               _createObjectStore(e.target.result);
             });
         });
-      request.on.error.add(fail('open'));
+      request.onError.listen(fail('open'));
     } else {
       // Legacy setVersion upgrade protocol.
-      request.on.success.add(expectAsync1((e) {
+      request.onSuccess.listen(expectAsync1((e) {
             db = e.target.result;
             if (db.version != '$VERSION') {
               var setRequest = db.setVersion('$VERSION');
-              setRequest.on.success.add(
+              setRequest.onSuccess.listen(
                   expectAsync1((e) {
                       _createObjectStore(db);
                       var transaction = e.target.result;
-                      transaction.on.complete.add(
+                      transaction.onComplete.listen(
                           expectAsync1((e) => afterOpen()));
-                      transaction.on.error.add(fail('Upgrade'));
+                      transaction.onError.listen(fail('Upgrade'));
                     }));
-              setRequest.on.error.add(fail('setVersion error'));
+              setRequest.onError.listen(fail('setVersion error'));
             } else {
               afterOpen();
             }
           }));
-      request.on.error.add(fail('open'));
+      request.onError.listen(fail('open'));
     }
   }
 
   _createAndOpenDb(afterOpen()) {
     var request = window.indexedDB.deleteDatabase(DB_NAME);
-    request.on.success.add(expectAsync1((e) { _openDb(afterOpen); }));
-    request.on.error.add(fail('delete old Db'));
+    request.onSuccess.listen(expectAsync1((e) { _openDb(afterOpen); }));
+    request.onError.listen(fail('delete old Db'));
   }
 
   writeItems(int index) {
@@ -76,11 +76,11 @@
       var transaction = db.transaction([STORE_NAME], 'readwrite');
       var request = transaction.objectStore(STORE_NAME)
           .put('Item $index', index);
-      request.on.success.add(expectAsync1((e) {
+      request.onSuccess.listen(expectAsync1((e) {
           writeItems(index + 1);
         }
       ));
-      request.on.error.add(fail('put'));
+      request.onError.listen(fail('put'));
     }
   }
 
@@ -93,7 +93,7 @@
     int itemCount = 0;
     int firstKey = null;
     int lastKey = null;
-    cursorRequest.on.success.add(expectAsync1((e) {
+    cursorRequest.onSuccess.listen(expectAsync1((e) {
       var cursor = e.target.result;
       if (cursor != null) {
         if (firstKey == null) firstKey = cursor.key;
@@ -114,7 +114,7 @@
     },
     count: 1 + ((expectedFirst == null) ?
            0 : (expectedLast - expectedFirst + 1))));
-    cursorRequest.on.error.add(fail('openCursor'));
+    cursorRequest.onError.listen(fail('openCursor'));
   }
 
   only1() => testRange(new KeyRange.only(55), 55, 55);
diff --git a/tests/html/inner_frame_test.dart b/tests/html/inner_frame_test.dart
index ef42a84..3001925 100644
--- a/tests/html/inner_frame_test.dart
+++ b/tests/html/inner_frame_test.dart
@@ -10,7 +10,7 @@
     // The child's frame should not be able to access its parent's
     // document.
 
-    window.on.message.add((Event e) {
+    window.onMessage.listen((Event e) {
       switch (e.data) {
       case 'frameElement': {
         // Check window.frameElement.
@@ -74,13 +74,13 @@
   var child;
 
   test('prepare', () {
-      iframe.on.load.add(expectAsync1((e) { child = iframe.contentWindow;}));
+      iframe.onLoad.listen(expectAsync1((e) { child = iframe.contentWindow;}));
       document.body.nodes.add(iframe);
     });
 
   final validate = (testName, verify) {
     final expectedVerify = expectAsync0(verify);
-    window.on.message.add((e) {
+    window.onMessage.listen((e) {
       guardAsync(() {
           if (e.data == 'pass_$testName') {
             expectedVerify();
diff --git a/tests/html/js_interop_1_test.dart b/tests/html/js_interop_1_test.dart
index 3d63ac1..3bf0951 100644
--- a/tests/html/js_interop_1_test.dart
+++ b/tests/html/js_interop_1_test.dart
@@ -19,15 +19,16 @@
   var callback;
 
   test('js-to-dart-post-message', () {
-    var onSuccess = expectAsync1((e) {
-      window.on.message.remove(callback);
-    });
-    callback = (e) {
-      if (e.data == 'hello') {
-        onSuccess(e);
-      }
-    };
-    window.on.message.add(callback);
+    var subscription = null;
+    var complete = false;
+    subscription = window.onMessage.listen(expectAsyncUntil1(
+        (e) {
+          if (e.data == 'hello') {
+            subscription.cancel();
+            complete = true;
+          }
+        },
+        () => complete));
     injectSource("window.postMessage('hello', '*');");
   });
 }
diff --git a/tests/html/keyboard_event_test.dart b/tests/html/keyboard_event_test.dart
index 0fe4fdb..da0842a 100644
--- a/tests/html/keyboard_event_test.dart
+++ b/tests/html/keyboard_event_test.dart
@@ -26,7 +26,7 @@
     var controller = new KeyboardEventController.keydown(document.body);
     var func = keydownHandlerTest;
     controller.add(func);
-    document.body.on.keyDown.add((e) => print('regular listener'), false);
+    document.body.onKeyDown.listen((e) => print('regular listener'));
   });
 }
 
diff --git a/tests/html/measurement_test.dart b/tests/html/measurement_test.dart
deleted file mode 100644
index 7d77bb8..0000000
--- a/tests/html/measurement_test.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library MeasurementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
-import 'dart:html';
-
-main() {
-  useHtmlConfiguration();
-
-  test('measurement is async but before setTimout 0', () {
-    final element = document.body;
-    bool fnComplete = false;
-    bool timeout0 = false;
-    window.setTimeout(() { timeout0 = true; }, 0);
-    final computedStyle = element.computedStyle;
-    computedStyle.then(expectAsync1((style) {
-      expect(style.getPropertyValue('left'), equals('auto'));
-      expect(fnComplete, isTrue);
-      expect(timeout0, isFalse);
-    }));
-    fnComplete = true;
-  });
-
-  test('requestLayoutFrame', () {
-    var computedStyle;
-    var computedStyleCalled = false;
-    window.requestLayoutFrame(expectAsync0(() {
-      expect(computedStyleCalled, true);
-    }));
-
-    final element = document.body;
-    computedStyle = element.computedStyle;
-    computedStyle.then(expectAsync1((style) {
-      computedStyleCalled = true;
-    }));
-  });
-
-  // TODO(jacobr): add more tests that the results return by measurement
-  // functions are correct.
-}
diff --git a/tests/html/microtask_test.dart b/tests/html/microtask_test.dart
new file mode 100644
index 0000000..0dfcc53
--- /dev/null
+++ b/tests/html/microtask_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library microtask_;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlConfiguration();
+
+  test('setImmediate', () {
+    var timeoutCalled = false;
+    var rafCalled = false;
+    var immediateCalled = false;
+
+    window.setTimeout(expectAsync0(() {
+      timeoutCalled = true;
+      expect(immediateCalled, true);
+    }), 0);
+
+
+    window.requestAnimationFrame((_) {
+      rafCalled = true;
+    });
+
+    window.setImmediate(expectAsync0(() {
+      expect(timeoutCalled, false);
+      expect(rafCalled, false);
+      immediateCalled = true;
+    }));
+    expect(immediateCalled, false);
+  });
+}
diff --git a/tests/html/native_gc_test.dart b/tests/html/native_gc_test.dart
index e85acfb..45a89e9 100644
--- a/tests/html/native_gc_test.dart
+++ b/tests/html/native_gc_test.dart
@@ -3,6 +3,8 @@
 import '../../pkg/unittest/lib/html_config.dart';
 import 'dart:html';
 
+var testEvent = new EventStreamProvider<Event>('test');
+
 main() {
   useHtmlConfiguration();
 
@@ -20,15 +22,15 @@
         l[N - 1] = i;
 
         div = new Element.tag('div');
-        div.on['test'].add((_) {
+        testEvent.forTarget(div).listen((_) {
             // Only the final iteration's listener should be invoked.
             // Note: the reference to l keeps the entire list alive.
             expect(l[N - 1], M - 1);
-          }, false);
+          });
       }
 
       final event = new Event('test');
-      div.on['test'].dispatch(event);
+      div.dispatchEvent(event);
   });
 
   test('WindowEventListener', () {
@@ -37,7 +39,7 @@
     Element testDiv = new DivElement();
     testDiv.id = '#TestDiv';
     document.body.nodes.add(testDiv);
-    window.on.message.add((e) {
+    window.onMessage.listen((e) {
       if (e.data == message) testDiv.click();
     });
 
@@ -45,7 +47,7 @@
       triggerMajorGC();
     }
 
-    testDiv.on.click.add(expectAsync1((e) {}));
+    testDiv.onClick.listen(expectAsync1((e) {}));
     window.postMessage(message, '*');
   });
 }
@@ -53,5 +55,5 @@
 void triggerMajorGC() {
   List list = new List.fixedLength(1000000);
   Element div = new DivElement();
-  div.on.click.add((e) => print(list[0]));
+  div.onClick.listen((e) => print(list[0]));
 }
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index 8581dc2..0eb79f4 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -26,20 +26,18 @@
       final JS_CODE = """
         window.postMessage({eggs: 3}, '*');
         """;
-      var callback;
-      var onSuccess = expectAsync1((e) {
-          window.on.message.remove(callback);
-        });
-      callback = (e) {
-        guardAsync(() {
-            var data = e.data;
-            if (data is String) return;    // Messages from unit test protocol.
-            expect(data, isMap);
-            expect(data['eggs'], equals(3));
-            onSuccess(e);
-          });
-      };
-      window.on.message.add(callback);
+      var completed = false;
+      var subscription = null;
+      subscription = window.onMessage.listen(expectAsyncUntil1(
+        (e) {
+          var data = e.data;
+          if (data is String) return;    // Messages from unit test protocol.
+          completed = true;
+          subscription.cancel();
+          expect(data, isMap);
+          expect(data['eggs'], equals(3));
+        },
+        () => completed));
       injectSource(JS_CODE);
     });
 
@@ -58,21 +56,19 @@
           window.postMessage(response, '*');
         }
         """;
-      var callback;
-      var onSuccess = expectAsync1((e) {
-          window.on.message.remove(callback);
-        });
-      callback = (e) {
-        guardAsync(() {
-            var data = e.data;
-            if (data is String) return;    // Messages from unit test protocol.
-            expect(data, isMap);
-            if (data['recipient'] != 'DART') return;  // Hearing the sent message.
-            expect(data['peas'], equals(50));
-            onSuccess(e);
-          });
-      };
-      window.on.message.add(callback);
+      var completed = false;
+      var subscription = null;
+      subscription = window.onMessage.listen(expectAsyncUntil1(
+        (e) {
+          var data = e.data;
+          if (data is String) return;    // Messages from unit test protocol.
+          if (data['recipient'] != 'DART') return;  // Hearing the sent message.
+          completed = true;
+          subscription.cancel();
+          expect(data, isMap);
+          expect(data['peas'], equals(50));
+        },
+        () => completed));
       injectSource(JS_CODE);
       window.postMessage({'recipient': 'JS', 'curry': 'peas'}, '*');
     });
@@ -93,22 +89,21 @@
               window.postMessage(response, '*');
             }
             """;
-          var onSuccess = expectAsync0(() {});
-          callback(e) {
-            guardAsync(() {
-                var data = e.data;
-                if (data is String) return;    // Messages from unit test protocol.
-                expect(data, isMap);
-                if (data['recipient'] != 'DART') return;  // Not for me.
-                var returnedValue = data['data'];
-
-                window.on.message.remove(callback);
-                expect(returnedValue, isNot(same(value)));
-                verifyGraph(value, returnedValue);
-                onSuccess();
-              });
-          };
-          window.on.message.add(callback);
+          var completed = false;
+          var subscription = null;
+          subscription = window.onMessage.listen(expectAsyncUntil1(
+            (e) {
+              var data = e.data;
+              if (data is String) return; // Messages from unit test protocol.
+              if (data['recipient'] != 'DART') return;  // Not for me.
+              completed = true;
+              subscription.cancel();
+              expect(data, isMap);
+              var returnedValue = data['data'];
+              expect(returnedValue, isNot(same(value)));
+              verifyGraph(value, returnedValue);
+            },
+            () => completed));
           injectSource(JS_CODE);
           window.postMessage({'recipient': 'JS', 'data': value}, '*');
         });
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 07d77a6..6c75dfe 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -169,4 +169,111 @@
     helper.pulse();
     expect(callCountOne, 1);
   });
+
+  var stream = new StreamHelper().stream;
+  // Streams have had some type-checking issues, these tests just validate that
+  // those are OK.
+  test('first', () {
+    stream.first.then((_) {});
+  });
+
+  test('asBroadcastStream', () {
+    stream.asBroadcastStream().listen((_) {});
+  });
+
+  test('where', () {
+    stream.where((_) => true).listen((_) {});
+  });
+
+  test('mappedBy', () {
+    stream.map((_) => null).listen((_) {});
+  });
+
+  test('reduce', () {
+    stream.reduce(null, (a, b) => null).then((_) {});
+  });
+
+  test('contains', () {
+    stream.contains((_) => true).then((_) {});
+  });
+
+  test('every', () {
+    stream.every((_) => true).then((_) {});
+  });
+
+  test('any', () {
+    stream.any((_) => true).then((_) {});
+  });
+
+  test('length', () {
+    stream.length.then((_) {});
+  });
+
+  test('min', () {
+    stream.min((a, b) => 0).then((_) {});
+  });
+
+  test('max', () {
+    stream.max((a, b) => 0).then((_) {});
+  });
+
+  test('isEmpty', () {
+    stream.isEmpty.then((_) {});
+  });
+
+  test('toList', () {
+    stream.toList().then((_) {});
+  });
+
+  test('toSet', () {
+    stream.toSet().then((_) {});
+  });
+
+  test('take', () {
+    stream.take(1).listen((_) {});
+  });
+
+  test('takeWhile', () {
+    stream.takeWhile((_) => false).listen((_) {});
+  });
+
+  test('skip', () {
+    stream.skip(0).listen((_) {});
+  });
+
+  test('skipWhile', () {
+    stream.skipWhile((_) => false).listen((_) {});
+  });
+
+  test('distinct', () {
+    stream.distinct((a, b) => false).listen((_) {});
+  });
+
+  test('first', () {
+    stream.first.then((_) {});
+  });
+
+  test('last', () {
+    stream.last.then((_) {});
+  });
+
+  test('single', () {
+    stream.single.then((_) {});
+  });
+
+  test('firstMatching', () {
+    stream.firstMatching((_) => true).then((_) {});
+  });
+
+  test('lastMatching', () {
+    stream.lastMatching((_) => true).then((_) {});
+  });
+
+  test('singleMatching', () {
+    stream.singleMatching((_) => true).then((_) {});
+  });
+
+  test('elementAt', () {
+    stream.elementAt(0).then((_) {});
+  });
 }
diff --git a/tests/html/svg_2_test.dart b/tests/html/svg_2_test.dart
index 89f4fe2..b2c4547 100644
--- a/tests/html/svg_2_test.dart
+++ b/tests/html/svg_2_test.dart
@@ -32,7 +32,6 @@
   var isSvgExternalResourcesRequired =
       predicate((x) => x is svg.ExternalResourcesRequired,
           'is a svg.ExternalResourcesRequired');
-  var isSvgStylable = predicate((x) => x is svg.Stylable, 'is a svg.Stylable');
   var isSvgTransformable =
       predicate((x) => x is svg.Transformable, 'is a svg.Transformable');
   var isSvgLocatable =
@@ -53,7 +52,6 @@
       expect(r, isSvgTests);
       expect(r, isSvgLangSpace);
       expect(r, isSvgExternalResourcesRequired);
-      expect(r, isSvgStylable);
       expect(r, isSvgTransformable);
       expect(r, isSvgLocatable);
 
diff --git a/tests/html/svg_3_test.dart b/tests/html/svg_3_test.dart
index 06271da..91e2eee 100644
--- a/tests/html/svg_3_test.dart
+++ b/tests/html/svg_3_test.dart
@@ -81,20 +81,6 @@
   }
 
   /**
-   * Verifies that [e] supports the operations on the svg.Stylable interface.
-   */
-  checkSvgStylable(e) {
-    var className = e.$dom_svgClassName;
-    expect(className, isSvgAnimatedString);
-
-    var s = e.style;
-    expect(s, isCssStyleDeclaration);
-
-    var attributeA = e.getPresentationAttribute('A');
-    expect(attributeA, anyOf(isNull, isCssValue));
-  }
-
-  /**
    * Verifies that [e] supports the operations on the svg.Locatable interface.
    */
   checkSvgLocatable(e) {
@@ -137,7 +123,6 @@
   testRect('rect_SvgLangSpace', checkSvgLangSpace);
   testRect('rect_SvgExternalResourcesRequired',
            checkSvgExternalResourcesRequired);
-  testRect('rect_SvgStylable', checkSvgStylable);
   testRect('rect_SvgLocatable', checkSvgLocatable);
   testRect('rect_SvgTransformable', checkSvgTransformable);
 
diff --git a/tests/html/touchevent_test.dart b/tests/html/touchevent_test.dart
new file mode 100644
index 0000000..8d90e5b
--- /dev/null
+++ b/tests/html/touchevent_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library touch_event_test;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  group('supported', () {
+    test('supported', () {
+      expect(TouchEvent.supported, true);
+    });
+  });
+
+  group('functional', () {
+    test('unsupported throws', () {
+      var expectation = TouchEvent.supported ? returnsNormally : throws;
+
+      expect(() {
+        var e = new TouchEvent(null, null, null, 'touch');
+        expect(e is TouchEvent, true);
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/html/transferables_test.dart b/tests/html/transferables_test.dart
index 0a709a5..3db9c42 100644
--- a/tests/html/transferables_test.dart
+++ b/tests/html/transferables_test.dart
@@ -14,7 +14,7 @@
       predicate((x) => x is ArrayBuffer, 'is an ArrayBuffer');
 
   test('TransferableTest', () {
-    window.on.message.add(expectAsync1((messageEvent) {
+    window.onMessage.listen(expectAsync1((messageEvent) {
       expect(messageEvent.data, isArrayBuffer);
     }));
     final buffer = (new Float32Array(3)).buffer;
diff --git a/tests/html/url_test.dart b/tests/html/url_test.dart
index c52b7c6..f332b30 100644
--- a/tests/html/url_test.dart
+++ b/tests/html/url_test.dart
@@ -41,10 +41,10 @@
       expect(url, startsWith('blob:'));
 
       var img = new ImageElement();
-      img.on.load.add(expectAsync1((_) {
+      img.onLoad.listen(expectAsync1((_) {
         expect(img.complete, true);
       }));
-      img.on.error.add((_) {
+      img.onError.listen((_) {
         guardAsync(() {
           expect(true, isFalse, reason: 'URL failed to load.');
         });
@@ -60,9 +60,9 @@
 
       var img = new ImageElement();
       // Image should fail to load since the URL was revoked.
-      img.on.error.add(expectAsync1((_) {
+      img.onError.listen(expectAsync1((_) {
       }));
-      img.on.load.add((_) {
+      img.onLoad.listen((_) {
         guardAsync(() {
           expect(true, isFalse, reason: 'URL should not have loaded.');
         });
diff --git a/tests/html/webgl_1_test.dart b/tests/html/webgl_1_test.dart
index 87073d3..32c076a 100644
--- a/tests/html/webgl_1_test.dart
+++ b/tests/html/webgl_1_test.dart
@@ -1,21 +1,57 @@
-library WebGL1Test;
+// 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 web_gl_test;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
 // Test that WebGL is present in dart:html API
 
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
-  test('simple', () {
-      var canvas = document.createElement("canvas");
-      var gl = canvas.getContext("experimental-webgl");
-      var shader = gl.createShader(WebGLRenderingContext.VERTEX_SHADER);
-      gl.shaderSource(shader, "void main() { }");
-      gl.compileShader(shader);
-      var success =
-          gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS);
-      expect(success, isTrue);
+  group('supported', () {
+    test('supported', () {
+      expect(WebGLRenderingContext.supported, isTrue);
+    });
+  });
+
+  group('functional', () {
+    test('unsupported fails', () {
+      var canvas = new CanvasElement();
+      var gl = canvas.getContext3d();
+      if (WebGLRenderingContext.supported) {
+        expect(gl, isNotNull);
+        expect(gl, new isInstanceOf<WebGLRenderingContext>());
+      } else {
+        expect(gl, isNull);
+      }
+    });
+
+    if (WebGLRenderingContext.supported) {
+      test('simple', () {
+        var canvas = new CanvasElement();
+        var gl = canvas.getContext('experimental-webgl');
+        var shader = gl.createShader(WebGLRenderingContext.VERTEX_SHADER);
+        gl.shaderSource(shader, 'void main() { }');
+        gl.compileShader(shader);
+        var success =
+            gl.getShaderParameter(shader, WebGLRenderingContext.COMPILE_STATUS);
+        expect(success, isTrue);
+      });
+
+      test('getContext3d', () {
+        var canvas = new CanvasElement();
+        var gl = canvas.getContext3d();
+        expect(gl, isNotNull);
+        expect(gl, new isInstanceOf<WebGLRenderingContext>());
+
+        gl = canvas.getContext3d(depth: false);
+        expect(gl, isNotNull);
+        expect(gl, new isInstanceOf<WebGLRenderingContext>());
+      });
+    }
   });
 }
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index 338c618..16871b8 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -1,6 +1,6 @@
 library WebDBTest;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:async';
 import 'dart:html';
 
@@ -87,31 +87,51 @@
 };
 
 main() {
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
-  test('Web Database', () {
-    final tableName = 'test_table';
-    final columnName = 'test_data';
+  group('supported', () {
+    test('supported', () {
+      expect(Database.supported, true);
+    });
+  });
 
-    final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+  group('functional', () {
+    test('unsupported throws', () {
+      var expectation = Database.supported ? returnsNormally : throws;
+      expect(() {
+        window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+      }, expectation);
 
-    expect(db, isNotNull, reason: 'Unable to open database');
+    });
+    test('Web Database', () {
+      // Skip if not supported.
+      if (!Database.supported) {
+        return;
+      }
 
-    createTransaction(db)
-      // Attempt to clear out any tables which may be lurking from previous
-      // runs.
-      .then(dropTable(tableName, true))
-      .then(createTable(tableName, columnName))
-      .then(insert(tableName, columnName, 'Some text data'))
-      .then(queryTable(tableName, (resultSet) {
-        guardAsync(() {
-          expect(resultSet.rows.length, 1);
-          var row = resultSet.rows.item(0);
-          expect(row.containsKey(columnName), isTrue);
-          expect(row[columnName], 'Some text data');
-        });
-      }))
-      .then(dropTable(tableName))
-      .then(expectAsync1((tx) {}));
+      final tableName = 'test_table';
+      final columnName = 'test_data';
+
+      final db = window.openDatabase('test_db', '1.0', 'test_db', 1024 * 1024);
+
+      expect(db, isNotNull, reason: 'Unable to open database');
+
+      createTransaction(db)
+        // Attempt to clear out any tables which may be lurking from previous
+        // runs.
+        .then(dropTable(tableName, true))
+        .then(createTable(tableName, columnName))
+        .then(insert(tableName, columnName, 'Some text data'))
+        .then(queryTable(tableName, (resultSet) {
+          guardAsync(() {
+            expect(resultSet.rows.length, 1);
+            var row = resultSet.rows.item(0);
+            expect(row.containsKey(columnName), isTrue);
+            expect(row[columnName], 'Some text data');
+          });
+        }))
+        .then(dropTable(tableName))
+        .then(expectAsync1((tx) {}));
+    });
   });
 }
diff --git a/tests/html/wheelevent_test.dart b/tests/html/wheelevent_test.dart
index b4c3c9b..f5b7e2d 100644
--- a/tests/html/wheelevent_test.dart
+++ b/tests/html/wheelevent_test.dart
@@ -30,7 +30,7 @@
 
   test('wheelEvent', () {
     var element = new DivElement();
-    element.on.mouseWheel.add(expectAsync1((e) {
+    element.onMouseWheel.listen(expectAsync1((e) {
       expect(e.screenX, 100);
       expect(e.deltaX, 0);
       expect(e.deltaY, 240);
diff --git a/tests/html/xhr_cross_origin_test.dart b/tests/html/xhr_cross_origin_test.dart
index fabc5a1..3bbb5ca 100644
--- a/tests/html/xhr_cross_origin_test.dart
+++ b/tests/html/xhr_cross_origin_test.dart
@@ -38,7 +38,7 @@
       expect(data['feed'], contains('entry'));
       expect(data, isMap);
     });
-    xhr.on.readyStateChange.add((e) {
+    xhr.onReadyStateChange.listen((e) {
       guardAsync(() {
         if (xhr.readyState == HttpRequest.DONE) {
           validate(json.parse(xhr.response));
@@ -50,7 +50,7 @@
 
   test('XHR.get Cross-domain', () {
     var url = "http://localhost:$port/tests/html/xhr_cross_origin_data.txt";
-    new HttpRequest.get(url, expectAsync1((xhr) {
+    HttpRequest.request(url).then(expectAsync1((xhr) {
       var data = json.parse(xhr.response);
       expect(data, contains('feed'));
       expect(data['feed'], contains('entry'));
@@ -60,7 +60,7 @@
 
   test('XHR.getWithCredentials Cross-domain', () {
     var url = "http://localhost:$port/tests/html/xhr_cross_origin_data.txt";
-    new HttpRequest.getWithCredentials(url, expectAsync1((xhr) {
+    HttpRequest.request(url, withCredentials: true).then(expectAsync1((xhr) {
       var data = json.parse(xhr.response);
       expect(data, contains('feed'));
       expect(data['feed'], contains('entry'));
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index c5d16a3..d590ace 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -8,6 +8,12 @@
 import 'dart:html';
 import 'dart:json' as json;
 
+void fail(message) {
+  guardAsync(() {
+    expect(false, isTrue, reason: message);
+  });
+}
+
 main() {
   useHtmlIndividualConfiguration();
   var url = "/tests/html/xhr_cross_origin_data.txt";
@@ -35,7 +41,7 @@
     test('XHR No file', () {
       HttpRequest xhr = new HttpRequest();
       xhr.open("GET", "NonExistingFile", true);
-      xhr.on.readyStateChange.add(expectAsyncUntil1((event) {
+      xhr.onReadyStateChange.listen(expectAsyncUntil1((event) {
         if (xhr.readyState == HttpRequest.DONE) {
           validate404(xhr);
         }
@@ -46,42 +52,90 @@
     test('XHR file', () {
       var xhr = new HttpRequest();
       xhr.open('GET', url, true);
-      xhr.on.readyStateChange.add(expectAsyncUntil1((e) {
+      xhr.onReadyStateChange.listen(expectAsyncUntil1((e) {
         if (xhr.readyState == HttpRequest.DONE) {
           validate200Response(xhr);
         }
       }, () => xhr.readyState == HttpRequest.DONE));
+
+      xhr.onLoadEnd.listen(expectAsync1((ProgressEvent e) {
+        expect(e.currentTarget, xhr);
+        expect(e.target, xhr);
+      }));
       xhr.send();
     });
 
-    test('XHR.get No file', () {
-      new HttpRequest.get("NonExistingFile", expectAsync1((xhr) {
-        expect(xhr.readyState, equals(HttpRequest.DONE));
-        validate404(xhr);
-      }));
+    test('XHR.request No file', () {
+      HttpRequest.request('NonExistingFile').then(
+        (_) { fail('Request should not have succeeded.'); },
+        onError: expectAsync1((e) {
+          var xhr = e.error.target;
+          expect(xhr.readyState, equals(HttpRequest.DONE));
+          validate404(xhr);
+        }));
     });
 
-    test('XHR.get file', () {
-      var xhr = new HttpRequest.get(url, expectAsync1((event) {
-        expect(event.readyState, equals(HttpRequest.DONE));
-        validate200Response(event);
-      }));
-    });
-
-    test('XHR.getWithCredentials No file', () {
-      new HttpRequest.getWithCredentials("NonExistingFile", expectAsync1((xhr) {
-        expect(xhr.readyState, equals(HttpRequest.DONE));
-        validate404(xhr);
-      }));
-    });
-
-    test('XHR.getWithCredentials file', () {
-      new HttpRequest.getWithCredentials(url, expectAsync1((xhr) {
+    test('XHR.request file', () {
+      HttpRequest.request(url).then(expectAsync1((xhr) {
         expect(xhr.readyState, equals(HttpRequest.DONE));
         validate200Response(xhr);
       }));
     });
 
+    test('XHR.request onProgress', () {
+      var progressCalled = false;
+      HttpRequest.request(url,
+        onProgress: (_) {
+          progressCalled = true;
+        }).then(expectAsync1(
+          (xhr) {
+            expect(xhr.readyState, equals(HttpRequest.DONE));
+            expect(progressCalled, isTrue);
+            validate200Response(xhr);
+          }));
+    });
+
+    test('XHR.request withCredentials No file', () {
+      HttpRequest.request('NonExistingFile', withCredentials: true).then(
+        (_) { fail('Request should not have succeeded.'); },
+        onError: expectAsync1((e) {
+          var xhr = e.error.target;
+          expect(xhr.readyState, equals(HttpRequest.DONE));
+          validate404(xhr);
+        }));
+    });
+
+    test('XHR.request withCredentials file', () {
+      HttpRequest.request(url, withCredentials: true).then(expectAsync1((xhr) {
+        expect(xhr.readyState, equals(HttpRequest.DONE));
+        validate200Response(xhr);
+      }));
+    });
+
+    test('XHR.getString file', () {
+      HttpRequest.getString(url).then(expectAsync1((str) {}));
+    });
+
+    test('XHR.getString No file', () {
+      HttpRequest.getString('NonExistingFile').then(
+        (_) { fail('Succeeded for non-existing file.'); },
+        onError: expectAsync1((e) {
+          validate404(e.error.target);
+        }));
+    });
+
+    test('XHR.request responseType', () {
+      if (ArrayBuffer.supported) {
+        HttpRequest.request(url, responseType: 'arraybuffer').then(
+          expectAsync1((xhr) {
+            expect(xhr.status, equals(200));
+            var arrayBuffer = xhr.response;
+            expect(arrayBuffer, new isInstanceOf<ArrayBuffer>());
+            expect(arrayBuffer, isNotNull);
+          }));
+      }
+    });
+
     test('HttpRequestProgressEvent', () {
       var expectation = HttpRequestProgressEvent.supported ?
           returnsNormally : throws;
diff --git a/tests/html/xsltprocessor_test.dart b/tests/html/xsltprocessor_test.dart
index ea803f6..48d7b10 100644
--- a/tests/html/xsltprocessor_test.dart
+++ b/tests/html/xsltprocessor_test.dart
@@ -1,18 +1,31 @@
 library XSLTProcessorTest;
 import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
 import 'dart:html';
 
 main() {
 
-  useHtmlConfiguration();
+  useHtmlIndividualConfiguration();
 
-  var isXsltProcessor =
+  group('supported', () {
+    test('supported', () {
+      expect(XsltProcessor.supported, true);
+    });
+  });
+
+  group('functional', () {
+    var isXsltProcessor =
       predicate((x) => x is XsltProcessor, 'is an XsltProcessor');
 
-  test('constructorTest', () {
-      var processor = new XsltProcessor();
-      expect(processor, isNotNull);
-      expect(processor, isXsltProcessor);
+    var expectation = XsltProcessor.supported ? returnsNormally : throws;
+
+    test('constructorTest', () {
+      expect(() {
+        var processor = new XsltProcessor();
+        expect(processor, isNotNull);
+        expect(processor, isXsltProcessor);
+      }, expectation);
     });
+  });
+
 }
diff --git a/tests/language/bailout5_test.dart b/tests/language/bailout5_test.dart
new file mode 100644
index 0000000..157e1ca
--- /dev/null
+++ b/tests/language/bailout5_test.dart
@@ -0,0 +1,55 @@
+// 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 to make sure the bailout environment in dart2js is correct.
+
+var global;
+
+class A {
+  var array;
+
+  initArray() {
+    return global[0] == null ? [null] : new Map(); 
+  }
+
+  bar() {
+    array = initArray();
+    do {
+      var element = array[0]; // bailout here
+      if (element is Map) continue;
+      if (element == null) break;
+    } while (true);
+    return global[0]; // bailout here
+  }
+
+  baz() {
+    do {
+      var element = bar();
+      if (element == null) return global[0]; // bailout here
+      if (element is Map) continue;
+      if (element is num) break;
+    } while (true);
+    return global[0]; // bailout here
+  }
+}
+
+
+void main() {
+  global = [1];
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(1, new A().baz());
+    Expect.equals(1, new A().bar());
+  }
+  global = new Map();
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(null, new A().baz());
+    Expect.equals(null, new A().bar());
+  }
+
+  global[0] = 42;
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(42, new A().baz());
+    Expect.equals(42, new A().bar());
+  }
+}
diff --git a/tests/language/bailout6_test.dart b/tests/language/bailout6_test.dart
new file mode 100644
index 0000000..5227f65
--- /dev/null
+++ b/tests/language/bailout6_test.dart
@@ -0,0 +1,38 @@
+// 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 for dart2js to make sure the computed bailout environment is
+// correct.
+
+var global;
+
+class A {
+  var array;
+
+  foo() {
+    do {
+      var element = global;
+      if (element is Map) continue;
+      if (element is num) break;
+    } while (true);
+    return array[0]; // bailout here.
+  }
+}
+
+void main() {
+  var a = new A();
+  a.array = [42];
+  global = 42;
+
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(42, a.foo());
+  }
+
+  a.array = new Map();
+  a.array[0] = 42;
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(42, a.foo());
+  }
+  global = null;
+}
diff --git a/tests/language/bailout7_test.dart b/tests/language/bailout7_test.dart
new file mode 100644
index 0000000..e61d688
--- /dev/null
+++ b/tests/language/bailout7_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test to make sure the do/while loop exit condition is generated.
+
+var global;
+
+class A {
+  var array;
+
+  initArray() {
+    if (global[0] == null) {
+      return [2];
+    } else {
+      var map = new Map();
+      map[0] = 2;
+      return map;
+    }
+  }
+
+  bar() {
+    array = initArray();
+    var element;
+    do {
+      element = array[0]; // bailout here
+      if (element is Map) continue;
+      if (element == null) break;
+    } while (element != 2);
+    return global[0]; // bailout here
+  }
+}
+
+
+void main() {
+  global = [2];
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(2, new A().bar());
+  }
+
+  global = new Map();
+  global[0] = 2;
+  for (int i = 0; i < 2; i++) {
+    Expect.equals(2, new A().bar());
+  }
+}
diff --git a/tests/language/constructor8_test.dart b/tests/language/constructor8_test.dart
new file mode 100644
index 0000000..0cfcc76
--- /dev/null
+++ b/tests/language/constructor8_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to crash on this program.
+
+class A {
+  var b;
+
+  // The parameter check here used to confuse the SSA builder when it
+  // created the call to the constructor body.
+  A([Map a]) : b = ?a {
+    Expect.isTrue(b);
+  }
+
+  // The closure in the constructor body used to confuse the SSA builder
+  // when it created the call to the constructor body.
+  A.withClosure(Map a) {
+    var c;
+    var f = () { return c = 42; };
+    b = f();
+    Expect.equals(42, b);
+    Expect.equals(42, c);
+  }
+}
+
+main() {
+  new A(null);
+  new A({});
+  new A.withClosure(null);
+  new A.withClosure({});
+}
diff --git a/tests/language/double_modulo_test.dart b/tests/language/double_modulo_test.dart
new file mode 100644
index 0000000..6a9a15a
--- /dev/null
+++ b/tests/language/double_modulo_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart test optimization of modulo operator on Double.
+
+main() {
+  double k = -0.33333;
+  double firstResPos = doMod(k, 1.0);
+  double firstResNeg = doMod(k, -1.0);
+  for (int i = 0; i < 5000; i++) {
+    Expect.equals(firstResPos, doMod(k, 1.0));
+    Expect.equals(firstResNeg, doMod(k, -1.0));
+  }
+}
+
+doMod(a, b) => a % b;
diff --git a/tests/language/emit_const_fields_test.dart b/tests/language/emit_const_fields_test.dart
new file mode 100644
index 0000000..17e5ab5
--- /dev/null
+++ b/tests/language/emit_const_fields_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.
+// Test that used static consts are emitted.
+
+class Guide {
+  static const LTUAE = 42;
+  static const TITLE = "Life, the Universe and Everything";
+  static const EARTH = const {
+    "Sector": "ZZ9 Plural Z Alpha",
+    "Status": const [ "Scheduled for demolition", "1978-03-08" ],
+    "Description": "Mostly harmless"
+  };
+}
+
+main() {
+  Expect.isTrue(42 == Guide.LTUAE);
+  Expect.isTrue("1978-03-08" == Guide.EARTH["Status"][1]);
+}
+
diff --git a/tests/language/language.status b/tests/language/language.status
index 43ca19a..85b14a8 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -109,9 +109,13 @@
 list_literal1_negative_test: Fail
 map_literal1_negative_test: Fail
 
+
+# test issue 8129
+redirecting_factory_infinite_steps_test/01: Fail
+
+
 library_juxtaposition_test: Fail # Issue 6881
 new_expression_type_args_test/0*: Fail # Wrongly reports compile-time error.
-redirecting_factory_infinite_steps_test/01: Fail # http://dartbug.com/6560
 implicit_this_test/none: Fail # should not warn about allocating SubAbstract2
 metadata_test: Fail
 const_locals_test: Fail
@@ -292,8 +296,10 @@
 # test issue 7523 (const declared without type, so not-a-function warning should not be reported)
 call_through_getter_test: Fail
 
-mixin_illegal_cycles_test/01: Fail # issue 8027
-mixin_illegal_cycles_test/02: Fail # issue 8027
+
+# test issue 8127 (using mixin application as mixin)
+mixin_mixin_test: Fail
+
 
 #
 # Add new dartc annotations above in alphabetical order
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 0f9ec67..6551691 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -115,7 +115,6 @@
 bad_constructor_test/06: Fail # http://dartbug.com/5519
 call_nonexistent_constructor_test: Fail
 constructor_named_arguments_test/01: Fail # http://dartbug.com/5519
-external_test/10: Fail # http://dartbug.com/5519
 getter_no_setter2_test/01: Fail # http://dartbug.com/5519
 getter_no_setter_test/01: Fail # http://dartbug.com/5519
 illegal_invocation_test/03: Fail # http://dartbug.com/5519
@@ -350,6 +349,7 @@
 expect_test: Fail
 factory3_test: Fail
 stack_overflow_test: Fail
+stack_overflow_stacktrace_test: Fail
 type_checks_in_factory_method_test: Fail
 
 
@@ -374,6 +374,7 @@
 method_invocation_test: Fail
 null_pointer_exception_test: Fail
 stack_overflow_test: Fail
+stack_overflow_stacktrace_test: Fail
 string_interpolate_npe_test: Fail
 closure_call_wrong_argument_count_negative_test: Skip
 label_test: Skip
diff --git a/tests/language/modulo_test.dart b/tests/language/modulo_test.dart
index 70e1a9f..7fac3bc 100644
--- a/tests/language/modulo_test.dart
+++ b/tests/language/modulo_test.dart
@@ -1,7 +1,7 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// Dart test optimization of modulo oeprator on Smi.
+// Dart test optimization of modulo operator on Smi.
 
 
 main() {
diff --git a/tests/language/stack_overflow_stacktrace_test.dart b/tests/language/stack_overflow_stacktrace_test.dart
new file mode 100644
index 0000000..3bef1d6
--- /dev/null
+++ b/tests/language/stack_overflow_stacktrace_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart program testing stack overflow.
+
+class StackOverflowTest {
+
+  static void curseTheRecurse(a, b, c) {
+    curseTheRecurse(b, c, a);
+  }
+
+  static void testMain() {
+    bool exceptionCaught = false;
+    try {
+      curseTheRecurse(1, 2, 3);
+    } on StackOverflowError catch (e, stacktrace) {
+      String s = stacktrace.toString();
+      Expect.equals(-1, s.indexOf("-1:-1"));
+      exceptionCaught = true;
+    }
+    Expect.equals(true, exceptionCaught);
+  }
+}
+
+main() {
+  StackOverflowTest.testMain();
+}
diff --git a/tests/language/type_variable_initializer_test.dart b/tests/language/type_variable_initializer_test.dart
new file mode 100644
index 0000000..721be03
--- /dev/null
+++ b/tests/language/type_variable_initializer_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js where the reference to [:this:] in a
+// constructor was not propagated to the super initializers.
+
+class A<T> {
+  var map;
+  // Usage of type variables in the intializer makes the SSA builder
+  // want to access [:this:]. And because the initializers of A are
+  // inlined in the constructor of B, we have to make sure the
+  // [:this:] in the A constructor has a corresponding
+  // SSA instruction.
+  A() : map = new Map<T, T>();
+}
+
+class B<T> extends A<T> {
+}
+
+main() {
+  Expect.isTrue(new B<int>().map is Map<int, int>);
+}
diff --git a/tests/language/typedef_is_test.dart b/tests/language/typedef_is_test.dart
new file mode 100644
index 0000000..56c6d37
--- /dev/null
+++ b/tests/language/typedef_is_test.dart
@@ -0,0 +1,123 @@
+// 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.
+
+// Test is-test of typedefs with optional and named parameters.
+
+typedef int Func1(int a);
+typedef int Func2(int a, [int b]);
+typedef int Func3(int a, [int b, int c]);
+typedef int Func4([int a, int b, int c]);
+typedef int Func5(int a, {int b});
+typedef int Func6(int a, {int b, int c});
+typedef int Func7({int a, int b, int c});
+
+void main() {
+  int func1(int i) {}
+  Expect.isTrue(func1 is Func1);
+  Expect.isFalse(func1 is Func2);
+  Expect.isFalse(func1 is Func3);
+  Expect.isFalse(func1 is Func4);
+  Expect.isFalse(func1 is Func5);
+  Expect.isFalse(func1 is Func6);
+  Expect.isFalse(func1 is Func7);
+
+  int func2(int i, int j) {}
+  Expect.isFalse(func2 is Func1);
+  Expect.isFalse(func2 is Func2);
+  Expect.isFalse(func2 is Func3);
+  Expect.isFalse(func2 is Func4);
+  Expect.isFalse(func2 is Func5);
+  Expect.isFalse(func2 is Func6);
+  Expect.isFalse(func2 is Func7);
+
+  int func3(int i, int j, int k) {}
+  Expect.isFalse(func3 is Func1);
+  Expect.isFalse(func3 is Func2);
+  Expect.isFalse(func3 is Func3);
+  Expect.isFalse(func3 is Func4);
+  Expect.isFalse(func3 is Func5);
+  Expect.isFalse(func3 is Func6);
+  Expect.isFalse(func3 is Func7);
+
+  int func4(int i, [int j]) {}
+  Expect.isTrue(func4 is Func1);
+  Expect.isTrue(func4 is Func2);
+  Expect.isFalse(func4 is Func3);
+  Expect.isFalse(func4 is Func4);
+  Expect.isFalse(func4 is Func5);
+  Expect.isFalse(func4 is Func6);
+  Expect.isFalse(func4 is Func7);
+
+  int func5(int i, [int j, int k]) {}
+  Expect.isTrue(func5 is Func1);
+  Expect.isTrue(func5 is Func2);
+  Expect.isTrue(func5 is Func3);
+  Expect.isFalse(func5 is Func4);
+  Expect.isFalse(func5 is Func5);
+  Expect.isFalse(func5 is Func6);
+  Expect.isFalse(func5 is Func7);
+
+  int func6([int i, int j, int k]) {}
+  Expect.isFalse(func6 is Func1);
+  Expect.isFalse(func6 is Func2);
+  Expect.isFalse(func6 is Func3);
+  Expect.isTrue(func6 is Func4);
+  Expect.isFalse(func6 is Func5);
+  Expect.isFalse(func6 is Func6);
+  Expect.isFalse(func6 is Func7);
+
+  int func7(int i, {int j}) {}
+  Expect.isTrue(func7 is Func1);
+  Expect.isFalse(func7 is Func2);
+  Expect.isFalse(func7 is Func3);
+  Expect.isFalse(func7 is Func4);
+  Expect.isFalse(func7 is Func5);
+  Expect.isFalse(func7 is Func6);
+  Expect.isFalse(func7 is Func7);
+
+  int func8(int i, {int b}) {}
+  Expect.isTrue(func8 is Func1);
+  Expect.isFalse(func8 is Func2);
+  Expect.isFalse(func8 is Func3);
+  Expect.isFalse(func8 is Func4);
+  Expect.isTrue(func8 is Func5);
+  Expect.isFalse(func8 is Func6);
+  Expect.isFalse(func8 is Func7);
+
+  int func9(int i, {int b, int c}) {}
+  Expect.isTrue(func9 is Func1);
+  Expect.isFalse(func9 is Func2);
+  Expect.isFalse(func9 is Func3);
+  Expect.isFalse(func9 is Func4);
+  Expect.isTrue(func9 is Func5);
+  Expect.isTrue(func9 is Func6);
+  Expect.isFalse(func9 is Func7);
+
+  int func10(int i, {int c, int b}) {}
+  Expect.isTrue(func10 is Func1);
+  Expect.isFalse(func10 is Func2);
+  Expect.isFalse(func10 is Func3);
+  Expect.isFalse(func10 is Func4);
+  Expect.isTrue(func10 is Func5);
+  Expect.isTrue(func10 is Func6);
+  Expect.isFalse(func10 is Func7);
+
+  int func11({int a, int b, int c}) {}
+  Expect.isFalse(func11 is Func1);
+  Expect.isFalse(func11 is Func2);
+  Expect.isFalse(func11 is Func3);
+  Expect.isFalse(func11 is Func4);
+  Expect.isFalse(func11 is Func5);
+  Expect.isFalse(func11 is Func6);
+  Expect.isTrue(func11 is Func7);
+
+  int func12({int c, int a, int b}) {}
+  Expect.isFalse(func12 is Func1);
+  Expect.isFalse(func12 is Func2);
+  Expect.isFalse(func12 is Func3);
+  Expect.isFalse(func12 is Func4);
+  Expect.isFalse(func12 is Func5);
+  Expect.isFalse(func12 is Func6);
+  Expect.isTrue(func12 is Func7);
+}
\ No newline at end of file
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index 844721b6..e6816e6 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 
-class Event {
+abstract class Event {
   void replay(StreamSink sink);
 }
 
@@ -121,9 +121,6 @@
     throw new StateError("Not capturing events.");
   }
 
-  /** Whether the underlying subscription has been paused. */
-  bool get isPaused => false;
-
   /**
    * Sets an action to be called when this [Events] receives a 'done' event.
    */
@@ -165,8 +162,6 @@
     subscription.resume();
   }
 
-  bool get isPaused => subscription.isPaused;
-
   void onDone(void action()) {
     onDoneSignal.future.whenComplete(action);
   }
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 373a131..19c09f8 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -16,6 +16,31 @@
   });
 }
 
+testOf() {
+  compare(func) {
+    // Compare the results of the following two futures.
+    Future f1 = new Future.of(func);
+    Future f2 = new Future.immediate(null).then((_) => func());
+    f2.catchError((_){});  // I'll get the error later.
+    f1.then((v1) { f2.then((v2) { Expect.equals(v1, v2); }); },
+            onError: (e1) {
+              f2.then((_) { Expect.fail("Expected error"); },
+                      onError: (e2) {
+                         Expect.equals(e1.error, e2.error);
+                      });
+            });
+  }
+  Future val = new Future.immediate(42);
+  Future err1 = new Future.immediateError("Error")..catchError((_){});
+  Future err2 = new Future.immediateError(new AsyncError("AsyncError"))..catchError((_){});
+  compare(() => 42);
+  compare(() => val);
+  compare(() { throw "Flif"; });
+  compare(() { throw new AsyncError("AsyncFlif"); });
+  compare(() => err1);
+  compare(() => err2);
+}
+
 testNeverComplete() {
   final completer = new Completer<int>();
   final future = completer.future;
@@ -559,6 +584,7 @@
 
 main() {
   testImmediate();
+  testOf();
   testNeverComplete();
 
   testComplete();
@@ -599,3 +625,4 @@
   testChainedFutureError();
 }
 
+
diff --git a/tests/lib/async/merge_stream_test.dart b/tests/lib/async/merge_stream_test.dart
deleted file mode 100644
index 924f5d3..0000000
--- a/tests/lib/async/merge_stream_test.dart
+++ /dev/null
@@ -1,174 +0,0 @@
-// 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.
-
-// Test merging streams.
-library merge_stream_test;
-
-import "dart:async";
-import '../../../pkg/unittest/lib/unittest.dart';
-import 'event_helper.dart';
-
-testSupercedeStream() {
-  { // Simple case of superceding lower priority streams.
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
-    Events expected = new Events()..add(1)..add(2)..add(3)..add(4)..close();
-    Events actual = new Events.capture(merge);
-    s1.add(1);
-    s2.add(2);
-    s1.add(1);  // Ignored.
-    s2.add(3);
-    s3.add(4);
-    s2.add(3);  // Ignored.
-    s3.close();
-    Expect.listEquals(expected.events, actual.events);
-  }
-
-  { // Superceding more than one stream at a time.
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
-    Events expected = new Events()..add(1)..add(2)..close();
-    Events actual = new Events.capture(merge);
-    s1.add(1);
-    s3.add(2);
-    s1.add(1);  // Ignored.
-    s2.add(1);  // Ignored.
-    s3.close();
-    Expect.listEquals(expected.events, actual.events);
-  }
-
-  { // Closing a stream before superceding it.
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
-    Events expected = new Events()..add(1)..add(2)..add(3)..close();
-    Events actual = new Events.capture(merge);
-    s1.add(1);
-    s1.close();
-    s3.close();
-    s2.add(2);
-    s2.add(3);
-    s2.close();
-    Expect.listEquals(expected.events, actual.events);
-  }
-
-  { // Errors from all non-superceded streams are forwarded.
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
-    Events expected =
-        new Events()..add(1)..error("1")..error("2")..error("3")
-                    ..add(3)..error("6")..add(4)..close();
-    Events actual = new Events.capture(merge);
-    s1.add(1);
-    s1.signalError(new AsyncError("1"));
-    s2.signalError(new AsyncError("2"));
-    s3.signalError(new AsyncError("3"));
-    s3.add(3);
-    s1.signalError(new AsyncError("4"));
-    s2.signalError(new AsyncError("5"));
-    s3.signalError(new AsyncError("6"));
-    s1.close();
-    s2.close();
-    s3.add(4);
-    s3.close();
-    Expect.listEquals(expected.events, actual.events);
-  }
-
-  test("Pausing on a superceding stream", () {
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.superceding([s1.stream, s2.stream, s3.stream]);
-    Events expected = new Events()..add(1)..add(2)..add(3);
-    Events actual = new Events.capture(merge);
-    s1.add(1);
-    s2.add(2);
-    s2.add(3);
-    Expect.listEquals(expected.events, actual.events);
-    actual.pause();  // Pauses the stream that feeds the actual Events.
-    Events expected2 = expected.copy();
-    expected..add(5)..add(6)..close();
-    expected2..add(6)..close();
-    s1.add(4);
-    s2.add(5);  // May or may not arrive before '6' when resuming.
-    s3.add(6);
-    s3.close();
-    actual.onDone(expectAsync0(() {
-      if (expected.events.length == actual.events.length) {
-        Expect.listEquals(expected.events, actual.events);
-      } else {
-        Expect.listEquals(expected2.events, actual.events);
-      }
-    }));
-    actual.resume();
-  });
-}
-
-void testCyclicStream() {
-  test("Simple case of superceding lower priority streams", () {
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.cyclic([s1.stream, s2.stream, s3.stream]);
-    Events expected =
-        new Events()..add(1)..add(2)..add(3)..add(4)..add(5)..add(6)..close();
-    Events actual = new Events.capture(merge);
-    Expect.isFalse(s1.isPaused);
-    Expect.isTrue(s2.isPaused);
-    Expect.isTrue(s3.isPaused);
-    s3.add(3);
-    s1.add(1);
-    s1.add(4);
-    s1.add(6);
-    s1.close();
-    s2.add(2);
-    s2.add(5);
-    s2.close();
-    s3.close();
-    actual.onDone(expectAsync0(() {
-      Expect.listEquals(expected.events, actual.events);
-    }));
-  });
-
-  test("Cyclic merge with errors", () {
-    StreamController s1 = new StreamController.broadcast();
-    StreamController s2 = new StreamController.broadcast();
-    StreamController s3 = new StreamController.broadcast();
-    Stream merge = new Stream.cyclic([s1.stream, s2.stream, s3.stream]);
-    Events expected =
-        new Events()..add(1)..error("1")..add(2)..add(3)..error("2")
-                    ..add(4)..add(5)..error("3")..add(6)..close();
-    Events actual = new Events.capture(merge);
-    Expect.isFalse(s1.isPaused);
-    Expect.isTrue(s2.isPaused);
-    Expect.isTrue(s3.isPaused);
-    s3.add(3);
-    s3.signalError(new AsyncError("3"));  // Error just before a "done".
-    s1.add(1);
-    s1.signalError(new AsyncError("2"));  // Error between events.
-    s1.add(4);
-    s1.add(6);
-    s1.close();
-    s2.signalError(new AsyncError("1"));  // Error as first event.
-    s2.add(2);
-    s2.add(5);
-    s2.close();
-    s3.close();
-    actual.onDone(expectAsync0(() {
-      Expect.listEquals(expected.events, actual.events);
-    }));
-  });
-}
-
-main() {
-  testSupercedeStream();
-  testCyclicStream();
-}
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index d35e0c1..79b8568 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -439,7 +439,7 @@
   }
 
   testStream("where", (s, act) => s.where(act));
-  testStream("mappedBy", (s, act) => s.mappedBy(act));
+  testStream("mappedBy", (s, act) => s.map(act));
   testStream("expand", (s, act) => s.expand(act));
   testStream("where", (s, act) => s.where(act));
   testStreamError("handleError", (s, act) => s.handleError(act));
diff --git a/tests/lib/async/stream_controller_test.dart b/tests/lib/async/stream_controller_test.dart
index 9dd7509..8cfabf5 100644
--- a/tests/lib/async/stream_controller_test.dart
+++ b/tests/lib/async/stream_controller_test.dart
@@ -53,7 +53,7 @@
   c = new StreamController.broadcast();
   expectedEvents = new Events()..add("abab")..error("error")..close();
   sentEvents = new Events()..add("ab")..error("error")..close();
-  actualEvents = new Events.capture(c.stream.mappedBy((v) => "$v$v"));
+  actualEvents = new Events.capture(c.stream.map((v) => "$v$v"));
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
@@ -93,10 +93,10 @@
   expectedEvents =
       new Events()..error("a")..add(42)..error("b")..add("foo")..close();
   actualEvents = new Events.capture(c.stream.transform(
-      new StreamTransformer.from(
-          onData: (v, s) { s.signalError(new AsyncError(v)); },
-          onError: (e, s) { s.add(e.error); },
-          onDone: (s) {
+      new StreamTransformer(
+          handleData: (v, s) { s.signalError(new AsyncError(v)); },
+          handleError: (e, s) { s.add(e.error); },
+          handleDone: (s) {
             s.add("foo");
             s.close();
           })));
@@ -114,7 +114,7 @@
   expectedEvents = new Events()..add(42)..error("not FormatException");
   actualEvents = new Events.capture(
       c.stream.where((v) => v is String)
-       .mappedBy((v) => int.parse(v))
+       .map((v) => int.parse(v))
        .handleError((v) {
           if (v.error is! FormatException) throw v;
         })
@@ -194,7 +194,7 @@
   c = new StreamController();
   expectedEvents = new Events()..add("abab")..error("error")..close();
   sentEvents = new Events()..add("ab")..error("error")..close();
-  actualEvents = new Events.capture(c.stream.mappedBy((v) => "$v$v"));
+  actualEvents = new Events.capture(c.stream.map((v) => "$v$v"));
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
@@ -240,16 +240,52 @@
   c.add(9);
   c.close();
 
+  // test contains.
+  {
+    c = new StreamController();
+    // Error after match is not important.
+    sentEvents = new Events()..add("a")..add("x")..error("FAIL")..close();
+    Future<bool> contains = c.stream.contains("x");
+    contains.then((var c) {
+      Expect.isTrue(c);
+    });
+    sentEvents.replay(c);
+  }
+
+  {
+    c = new StreamController();
+    // Not matching is ok.
+    sentEvents = new Events()..add("a")..add("x")..add("b")..close();
+    Future<bool> contains = c.stream.contains("y");
+    contains.then((var c) {
+      Expect.isFalse(c);
+    });
+    sentEvents.replay(c);
+  }
+
+  {
+    c = new StreamController();
+    // Error before match makes future err.
+    sentEvents = new Events()..add("a")..error("FAIL")..add("b")..close();
+    Future<bool> contains = c.stream.contains("b");
+    contains.then((var c) {
+      Expect.fail("no value expected");
+    }).catchError((AsyncError e) {
+      Expect.equals("FAIL", e.error);
+    });
+    sentEvents.replay(c);
+  }
+
   // Test transform.
   c = new StreamController();
   sentEvents = new Events()..add("a")..error(42)..add("b")..close();
   expectedEvents =
       new Events()..error("a")..add(42)..error("b")..add("foo")..close();
   actualEvents = new Events.capture(c.stream.transform(
-      new StreamTransformer.from(
-          onData: (v, s) { s.signalError(new AsyncError(v)); },
-          onError: (e, s) { s.add(e.error); },
-          onDone: (s) {
+      new StreamTransformer(
+          handleData: (v, s) { s.signalError(new AsyncError(v)); },
+          handleError: (e, s) { s.add(e.error); },
+          handleDone: (s) {
             s.add("foo");
             s.close();
           })));
@@ -267,7 +303,7 @@
   expectedEvents = new Events()..add(42)..error("not FormatException");
   actualEvents = new Events.capture(
       c.stream.where((v) => v is String)
-       .mappedBy((v) => int.parse(v))
+       .map((v) => int.parse(v))
        .handleError((v) {
           if (v.error is! FormatException) throw v;
         })
diff --git a/tests/lib/async/stream_event_transform_test.dart b/tests/lib/async/stream_event_transform_test.dart
new file mode 100644
index 0000000..debc2c0c
--- /dev/null
+++ b/tests/lib/async/stream_event_transform_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library stream_event_transform_test;
+
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+import 'event_helper.dart';
+
+void handleData(int data, StreamSink<int> sink) {
+  sink.signalError(new AsyncError("$data"));
+  sink.add(data + 1);
+}
+
+void handleError(AsyncError e, StreamSink<int> sink) {
+  String value = e.error;
+  int data = int.parse(value);
+  sink.add(data);
+  sink.signalError(new AsyncError("${data + 1}"));
+}
+
+void handleDone(StreamSink<int> sink) {
+  sink.add(99);
+  sink.close();
+}
+
+class EventTransformer extends StreamEventTransformer<int,int> {
+  void handleData(int data, StreamSink<int> sink) {
+    sink.signalError(new AsyncError("$data"));
+    sink.add(data + 1);
+  }
+
+  void handleError(AsyncError e, StreamSink<int> sink) {
+    String value = e.error;
+    int data = int.parse(value);
+    sink.add(data);
+    sink.signalError(new AsyncError("${data + 1}"));
+  }
+
+  void handleDone(StreamSink<int> sink) {
+    sink.add(99);
+    sink.close();
+  }
+}
+
+main() {
+  {
+    StreamController c = new StreamController();
+    Events expected = new Events()..error("0")..add(1)
+                                  ..error("1")..add(2)
+                                  ..add(3)..error("4")
+                                  ..add(99)..close();
+    Events input = new Events()..add(0)..add(1)..error("3")..close();
+    Events actual = new Events.capture(
+        c.stream.transform(new EventTransformer()));
+    actual.onDone(() {
+      Expect.listEquals(expected.events, actual.events);
+    });
+    input.replay(c);
+  }
+
+  {
+    StreamController c = new StreamController();
+    Events expected = new Events()..error("0")..add(1)
+                                  ..error("1")..add(2)
+                                  ..add(3)..error("4")
+                                  ..add(99)..close();
+    Events input = new Events()..add(0)..add(1)..error("3")..close();
+    Events actual = new Events.capture(
+        c.stream.transform(new StreamTransformer(
+            handleData: handleData,
+            handleError: handleError,
+            handleDone: handleDone
+        )));
+    actual.onDone(() {
+      Expect.listEquals(expected.events, actual.events);
+    });
+    input.replay(c);
+  }
+}
diff --git a/tests/lib/async/stream_from_iterable_test.dart b/tests/lib/async/stream_from_iterable_test.dart
index f724bf4..182bf1c 100644
--- a/tests/lib/async/stream_from_iterable_test.dart
+++ b/tests/lib/async/stream_from_iterable_test.dart
@@ -33,7 +33,7 @@
   new IterableTest<String>(["one", "two", "three", "four"]).run();
   new IterableTest<int>(new Iterable<int>.generate(1000, (i) => i)).run();
   new IterableTest<String>(new Iterable<int>.generate(1000, (i) => i)
-                                            .mappedBy((i) => "$i")).run();
+                                            .map((i) => "$i")).run();
 
   Iterable<int> iter = new Iterable.generate(25, (i) => i * 2);
 
@@ -47,10 +47,10 @@
 
   test("iterable-mapped-toList", () {
     new Stream.fromIterable(iter)
-      .mappedBy((i) => i * 3)
+      .map((i) => i * 3)
       .toList()
       .then(expectAsync1((actual) {
-         List expected = iter.mappedBy((i) => i * 3).toList();
+         List expected = iter.map((i) => i * 3).toList();
          Expect.listEquals(expected, actual);
       }));
   });
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index 82a115b..6a38ca4 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -8,7 +8,7 @@
 
 import "dart:io";
 import "dart:utf";
-import "dart:json";
+import "dart:json" as JSON;
 
 // TODO(hausner): need to select a different port number for each
 // test that runs in parallel.
@@ -430,7 +430,7 @@
       if (errorsDetected) {
         error("Error while handling script entry ${script.currentIndex}");
         error("Message received from debug target: $msg");
-        close();
+        close(killDebugee: true);
         return;
       }
       if (shutdownEventSeen) {
@@ -471,27 +471,29 @@
         handleMessages();
       } catch(e, trace) {
         print("Unexpected exception:\n$e\n$trace");
-        close();
+        close(killDebugee: true);
       }
     };
     from.onClosed = () {
       print("Connection closed by debug target");
-      close();
+      close(killDebugee: true);
     };
     from.onError = (e) {
       print("Error '$e' detected in input stream from debug target");
-      close();
+      close(killDebugee: true);
     };
   }
 
-  void close() {
+  void close({killDebugee: false}) {
     if (errorsDetected) {
       for (int i = 0; i < errors.length; i++) print(errors[i]);
     }
     to.close();
     socket.close();
-    targetProcess.kill();
-    print("Target process killed");
+    if (killDebugee) {
+      targetProcess.kill();
+      print("Target process killed");
+    }
     Expect.isTrue(!errorsDetected);
     stdin.close();
     stdout.close();
@@ -519,11 +521,12 @@
     process.stdout.onData = process.stdout.read;
     process.stderr.onData = process.stderr.read;
     process.onExit = (int exitCode) {
+      Expect.equals(0, exitCode);
       print("Debug target process exited with exit code $exitCode");
     };
     var debugger = new Debugger(process, debugPort);
-    stdin.onClosed = () => debugger.close();
-    stdin.onError = (error) => debugger.close();
+    stdin.onClosed = () => debugger.close(killDebugee: true);
+    stdin.onError = (error) => debugger.close(killDebugee: true);
     debugger.runScript(script);
   });
   return true;
diff --git a/tests/standalone/int_array_deopt.dart b/tests/standalone/int_array_deopt.dart
new file mode 100644
index 0000000..4f4bf89
--- /dev/null
+++ b/tests/standalone/int_array_deopt.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart deoptimization of Uint32Array and Int32Array loads.
+
+import 'dart:scalarlist';
+
+loadI32(a) => a[0] + 1;
+loadUi32(a) => a[0] + 1;
+
+main() {
+  var i32 = new Int32List(10);
+  var ui32 = new Uint32List(10);
+  i32[0] = ui32[0] = 8;
+  // Optimize loadI32 and LoadUi32 for Smi result of indexed load.
+  for (int i = 0; i < 2000; i++) {
+    Expect.equals(9, loadI32(i32));
+    Expect.equals(9, loadUi32(ui32));
+  }
+  // On ia32, deoptimize when attempting to load a value that exceeds
+  // Smi range.
+  i32[0] = ui32[0] = 2147483647;
+  Expect.equals(2147483648, loadI32(i32));
+  Expect.equals(2147483648, loadUi32(ui32));
+  // Reoptimize again, but this time assume mixed Smi/Mint results
+  i32[0] = ui32[0] = 10;
+  for (int i = 0; i < 2000; i++) {
+    Expect.equals(11, loadI32(i32));
+    Expect.equals(11, loadUi32(ui32));
+  }
+}
diff --git a/tests/standalone/io/skipping_dart2js_compilations_test.dart b/tests/standalone/io/skipping_dart2js_compilations_test.dart
index 9409fc0..74058a7 100644
--- a/tests/standalone/io/skipping_dart2js_compilations_test.dart
+++ b/tests/standalone/io/skipping_dart2js_compilations_test.dart
@@ -206,8 +206,9 @@
     fs_upToDate.touchFile(fs_upToDate.testJs);
 
     void runTest(String name, FileUtils fileUtils, bool shouldRun) {
-      new runner.RunningProcess(makeTestCase(name,
-          new TestCompletedHandler(fileUtils, shouldRun))).start();
+      var testCase = makeTestCase(
+          name, new TestCompletedHandler(fileUtils, shouldRun));
+      new runner.RunningProcess(testCase, testCase.commands[0]).start();
     }
     runTest("fs_noTestJs", fs_noTestJs, true);
     runTest("fs_noTestJsDeps", fs_noTestJsDeps, true);
diff --git a/tests/standalone/io/test_extension_fail_test.dart b/tests/standalone/io/test_extension_fail_test.dart
index 0bde0a9..7109416 100644
--- a/tests/standalone/io/test_extension_fail_test.dart
+++ b/tests/standalone/io/test_extension_fail_test.dart
@@ -59,6 +59,7 @@
     print("ERR: ${result.stderr}\n\n");
     print("OUT: ${result.stdout}\n\n");
     Expect.equals(255, result.exitCode);
-    Expect.isTrue(result.stderr.contains("Unhandled exception:\nball\n"));
+    Expect.isTrue(result.stderr.contains("Unhandled exception:"));
+    Expect.isTrue(result.stderr.contains("ball"));
   }).whenComplete(() => tempDirectory.deleteSync(recursive: true));
 }
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index c492161..65a0ea9 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -2,74 +2,99 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "dart:io";
 import "dart:isolate";
 import "dart:async";
 import "dart:utf";
 import "../../../tools/testing/dart/test_runner.dart";
+import "../../../tools/testing/dart/test_suite.dart";
 import "../../../tools/testing/dart/status_file_parser.dart";
 import "../../../tools/testing/dart/test_options.dart";
 import "process_test_util.dart";
 
+final DEFAULT_TIMEOUT = 2;
+final LONG_TIMEOUT = 30;
+
 class TestController {
-  static const int numTests = 4;
+  static int numTests = 0;
   static int numCompletedTests = 0;
 
   // Used as TestCase.completedCallback.
   static processCompletedTest(TestCase testCase) {
+    numCompletedTests++;
     CommandOutput output = testCase.lastCommandOutput;
-    print("Test: ${testCase.commands.last.commandLine}");
-    if (output.unexpectedOutput) {
-      throw "Unexpected output: ${output.result}";
+    if (testCase.displayName == "fail-unexpected") {
+      Expect.isTrue(output.unexpectedOutput);
+    } else {
+      Expect.isFalse(output.unexpectedOutput);
     }
-    print("stdout: ");
-    print(decodeUtf8(output.stdout));
-    print("stderr: ");
-    print(decodeUtf8(output.stderr));
+  }
 
-    print("Time: ${output.time}");
-    print("Exit code: ${output.exitCode}");
-
-    ++numCompletedTests;
-    print("$numCompletedTests/$numTests");
-    if (numCompletedTests == numTests) {
-      print("test_runner_test.dart PASSED");
-    }
+  static void finished() {
+    Expect.equals(numTests, numCompletedTests);
   }
 }
 
-TestCase MakeTestCase(String testName, List<String> expectations) {
-  var configuration = new TestOptionsParser().parse(['--timeout', '2'])[0];
-  return new TestCase(testName,
-                      [new Command(new Options().executable,
-                                   <String>[new Options().script,
-                                            testName])],
-                      configuration,
-                      TestController.processCompletedTest,
-                      new Set<String>.from(expectations));
+
+class CustomTestSuite extends TestSuite {
+  CustomTestSuite() : super({}, "CustomTestSuite");
+
+  void forEachTest(TestCaseEvent onTest, Map testCache, [onDone]) {
+    void enqueueTestCase(testCase) {
+      TestController.numTests++;
+      onTest(testCase);
+    }
+
+    var testCaseCrash = _makeCrashTestCase("crash", [CRASH]);
+    var testCasePass = _makeNormalTestCase("pass", [PASS]);
+    var testCaseFail = _makeNormalTestCase("fail", [FAIL]);
+    var testCaseTimeout = _makeNormalTestCase("timeout", [TIMEOUT]);
+    var testCaseFailUnexpected =
+        _makeNormalTestCase("fail-unexpected", [PASS]);
+
+    enqueueTestCase(testCaseCrash);
+    enqueueTestCase(testCasePass);
+    enqueueTestCase(testCaseFail);
+    enqueueTestCase(testCaseTimeout);
+    enqueueTestCase(testCaseFailUnexpected);
+
+    if (onDone != null) {
+      onDone();
+    }
+  }
+
+  TestCase _makeNormalTestCase(name, expectations) {
+    var command = new Command(new Options().executable,
+                              [new Options().script, name]);
+    return _makeTestCase(name, DEFAULT_TIMEOUT, command, expectations);
+  }
+
+  _makeCrashTestCase(name, expectations) {
+    var crashCommand = new Command(getProcessTestFileName(),
+                                   ["0", "0", "1", "1"]);
+    // The crash test sometimes times out. Run it with a large timeout
+    // to help diagnose the delay. 
+    // The test loads a new executable, which may sometimes take a long time. 
+    // It involves a wait on the VM event loop, and possible system
+    // delays.
+    return _makeTestCase(name, LONG_TIMEOUT, crashCommand, expectations);
+  }
+
+  _makeTestCase(name, timeout, command, expectations) {
+    var configuration = new TestOptionsParser()
+        .parse(['--timeout', '$timeout'])[0];
+    return new TestCase(name,
+                        [command],
+                        configuration,
+                        TestController.processCompletedTest,
+                        new Set<String>.from(expectations));
+  }
 }
 
-void testTestRunner() {
-  new RunningProcess(MakeTestCase("pass", [PASS])).start();
-  new RunningProcess(MakeTestCase("fail", [FAIL])).start();
-  new RunningProcess(MakeTestCase("timeout", [TIMEOUT])).start();
-
-  // The crash test sometimes times out.  Run it with a large timeout to help
-  // diagnose the delay.
-  // The test loads a new executable, which may sometimes take a long time.
-  // It involves a wait on the VM event loop, and possible system delays.
-  var configuration = new TestOptionsParser().parse(['--timeout', '60'])[0];
-  new RunningProcess(new TestCase("CrashTest",
-                                  [new Command(getProcessTestFileName(),
-                                               const ["0", "0", "1", "1"])],
-                                  configuration,
-                                  TestController.processCompletedTest,
-                                  new Set<String>.from([CRASH]))).start();
-  Expect.equals(4, TestController.numTests);
-  // Test that the test runner throws an exception if a test with
-  // expectation SKIP is run.  The RunningProcess constructor must throw
-  // the exception synchronously, for it to be caught here at the call site.
-  Expect.throws(new RunningProcess(MakeTestCase("pass", [SKIP])).start);
+void testProcessQueue() {
+  var maxProcesses = 2;
+  var maxBrowserProcesses = maxProcesses;
+  new ProcessQueue(maxProcesses, maxBrowserProcesses, "silent",
+      new Date.now(), false, [new CustomTestSuite()], TestController.finished);
 }
 
 void main() {
@@ -78,14 +103,15 @@
   // fail, or timeout.
   var arguments = new Options().arguments;
   if (arguments.isEmpty) {
-    testTestRunner();
+    testProcessQueue();
   } else {
     switch (arguments[0]) {
       case 'pass':
         return;
+      case 'fail-unexpected':
       case 'fail':
         Expect.fail("This test always fails, to test the test scripts.");
-	break;
+        break;
       case 'timeout':
         // Run for 10 seconds, then exit.  This tests a 2 second timeout.
         new Timer(10 * 1000, (t){ });
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index fdcfa9d..35a839c 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -6,7 +6,6 @@
 
 [ $runtime == vm ]
 package/package_isolate_test: Fail # Issue 7520.
-io/test_runner_test: Pass, Fail # Issue 1947
 
 [ $runtime == vm && $checked ]
 # These tests have type errors on purpose.
@@ -22,7 +21,11 @@
 [ $runtime == vm && $system == macos && $arch == x64 ]
 io/regress_7191_test: Pass, Timeout # http://dartbug.com/8091
 
-[ $runtime == vm && $system == macos ]
+[ $runtime == vm ]
+# Fails with a connection refused error on the buildbot.
+# Issue 8232.
+debugger/basic_debugger_test: Pass, Fail
+
 # This test fails with "Too many open files" on the Mac OS buildbot.
 # This is expected as MacOS by default runs with a very low number
 # of allowed open files ('ulimit -n' says something like 256).
@@ -41,12 +44,6 @@
 
 [ $runtime == vm && $system == windows ]
 io/file_system_links_test: Skip  # No links on Windows.
-io/test_extension_fail_test: Fail  # Issue 7157
-io/secure_no_builtin_roots_test: Pass, Crash  # Issue 7157
-io/secure_socket_bad_certificate_test: Pass, Crash, Fail, Timeout  # Issue 7157
-io/directory_list_nonexistent_test: Skip # Issue 7157
-io/web_socket_test: Skip # Issue 7157
-io/web_socket_no_secure_test: Pass # Issue 7157 - Remove test when fixed.
 
 [ $compiler == none && $runtime == drt ]
 io/*: Skip # Don't run tests using dart:io in the browser
diff --git a/tools/VERSION b/tools/VERSION
index 2a2b2cb..0445e6e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 3
-BUILD 2
+BUILD 3
 PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index a995bcc..fbcaeb3 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -162,12 +162,6 @@
      - test_set: Specification of a non standard test set, default None
   """
 
-  if system.startswith('win') and runtime.startswith('ie'):
-    # There should not be more than one InternetExplorerDriver instance
-    # running at a time. For details, see
-    # http://code.google.com/p/selenium/wiki/InternetExplorerDriver.
-    flags += ['-j1']
-
   def GetPath(runtime):
     """ Helper to get the path to the Chrome or Firefox executable for a
     particular platform on the buildbot. Throws a KeyError if runtime is not
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 1cb8fa8..053f110 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -110,8 +110,8 @@
     CopyShellScript(os.path.join(home, 'sdk', 'bin', executable),
                     os.path.join(sdk_root, 'bin'))
 
-  subprocess.call([os.path.join(build_dir, 'gen_snapshot'),
-                   '--script_snapshot=%s' %
+  subprocess.call([os.path.join(build_dir, 'dart'),
+                   '--generate-script-snapshot=%s' %
                    os.path.join(sdk_root, 'lib', '_internal', 'compiler',
                                 'implementation', 'dart2js.dart.snapshot'),
                    os.path.join(sdk_root, 'lib', '_internal', 'compiler',
@@ -221,8 +221,8 @@
   # Create and populate pkg/{args, intl, logging, meta, unittest, ...}
   #
 
-  for library in ['args', 'http', 'intl', 'logging',
-                  'meta', 'oauth2', 'path', 'serialization', 'unittest']:
+  for library in ['args', 'http', 'intl', 'logging', 'meta', 'oauth2', 'path',
+                  'serialization', 'unittest', 'yaml']:
 
     copytree(join(HOME, 'pkg', library), join(PKG, library),
              ignore=ignore_patterns('*.svn', 'doc', 'docs',
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index 9e26dfe..89087ea 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -1 +1,414 @@
-{}
\ No newline at end of file
+{
+  "dart.dom.html": {
+    "CanvasGradient": {
+      "comment": [
+        "/**",
+        " * An opaque canvas object representing a gradient.",
+        " *",
+        " * Created by calling [createLinearGradient] or [createRadialGradient] on a",
+        " * [CanvasRenderingContext2D] object.",
+        " *",
+        " * Example usage:",
+        " *",
+        " *     var canvas = new CanvasElement(width: 600, height: 600);",
+        " *     var ctx = canvas.context2d;",
+        " *     ctx.clearRect(0, 0, 600, 600);",
+        " *     ctx.save();",
+        " *     // Create radial gradient.",
+        " *     CanvasGradient gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 600);",
+        " *     gradient.addColorStop(0, '#000');",
+        " *     gradient.addColorStop(1, 'rgb(255, 255, 255)');",
+        " *     // Assign gradients to fill.",
+        " *     ctx.fillStyle = gradient;",
+        " *     // Draw a rectangle with a gradient fill.",
+        " *     ctx.fillRect(0, 0, 600, 600);",
+        " *     ctx.save();",
+        " *     document.body.children.add(canvas);",
+        " *",
+        " * See also:",
+        " *",
+        " * * [CanvasGradient](https://developer.mozilla.org/en-US/docs/DOM/CanvasGradient) from MDN.",
+        " * * [CanvasGradient](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasgradient) from whatwg.",
+        " * * [CanvasGradient](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvasgradient) from W3C.",
+        " */"
+      ],
+      "members": {
+        "addColorStop": [
+          "/**",
+          "   * Adds a color stop to this gradient at the offset.",
+          "   *",
+          "   * The [offset] can range between 0.0 and 1.0.",
+          "   *",
+          "   * See also:",
+          "   *",
+          "   * * [Multiple Color Stops](https://developer.mozilla.org/en-US/docs/CSS/linear-gradient#Gradient_with_multiple_color_stops) from MDN.",
+          "   */"
+        ]
+      }
+    },
+    "CanvasPattern": {
+      "comment": [
+        "/**",
+        " * An opaque object representing a pattern of image, canvas, or video.",
+        " *",
+        " * Created by calling [createPattern] on a [CanvasRenderingContext2D] object.",
+        " *",
+        " * Example usage:",
+        " *",
+        " *     var canvas = new CanvasElement(width: 600, height: 600);",
+        " *     var ctx = canvas.context2d;",
+        " *     var img = new ImageElement();",
+        " *     // Image src needs to be loaded before pattern is applied.",
+        " *     img.onLoad.listen((event) {",
+        " *       // When the image is loaded, create a pattern",
+        " *       // from the ImageElement.",
+        " *       CanvasPattern pattern = ctx.createPattern(img, 'repeat');",
+        " *       ctx.rect(0, 0, canvas.width, canvas.height);",
+        " *       ctx.fillStyle = pattern;",
+        " *       ctx.fill();",
+        " *     });",
+        " *     img.src = \"images/foo.jpg\";",
+        " *     document.body.children.add(canvas);",
+        " *",
+        " * See also:",
+        " * * [CanvasPattern](https://developer.mozilla.org/en-US/docs/DOM/CanvasPattern) from MDN.",
+        " * * [CanvasPattern](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspattern) from whatwg.",
+        " * * [CanvasPattern](http://www.w3.org/TR/2010/WD-2dcontext-20100304/#canvaspattern) from W3C.",
+        " */"
+      ]
+    },
+    "CanvasRenderingContext": {
+      "comment": [
+        "/**",
+        " * A rendering context for a canvas element.",
+        " *",
+        " * This context is extended by [CanvasRenderingContext2D] and",
+        " * [WebGLRenderingContext].",
+        " */"
+      ],
+      "members": {
+        "canvas": [
+          "/// Reference to the canvas element to which this context belongs."
+        ]
+      }
+    },
+    "Document": {
+      "members": {
+        "body": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "caretRangeFromPoint": [
+          "/// Use the [Range] constructor instead."
+        ],
+        "createElement": [
+          "/// Deprecated: use new Element.tag(tagName) instead."
+        ],
+        "createTouchList": [
+          "/// Use the [TouchList] constructor instead."
+        ],
+        "getCSSCanvasContext": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "getElementById": [
+          "/// Deprecated: use query(\"#$elementId\") instead."
+        ],
+        "head": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "lastModified": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "querySelector": [
+          "/// Deprecated: renamed to the shorter name [query]."
+        ],
+        "querySelectorAll": [
+          "/// Deprecated: use query(\"#$elementId\") instead."
+        ],
+        "referrer": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "styleSheets": [
+          "/// Moved to [HtmlDocument]"
+        ],
+        "title": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitCancelFullScreen": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitExitFullscreen": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitExitPointerLock": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitFullscreenElement": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitFullscreenEnabled": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitHidden": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitIsFullScreen": [
+          "/// Moved to [HtmlDocument]."
+        ],
+        "webkitPointerLockElement": [
+          "/// Moved to [HtmlDocument]."
+        ]
+      }
+    },
+    "HTMLCanvasElement": {
+      "members": {
+        "height": [
+          "/// The height of this canvas element in CSS pixels."
+        ],
+        "toDataURL": [
+          "/**",
+          "   * Returns a data URI containing a representation of the image in the",
+          "   * format specified by type (defaults to 'image/png').",
+          "   *",
+          "   * Data Uri format is as follow `data:[<MIME-type>][;charset=<encoding>][;base64],<data>`",
+          "   *",
+          "   * Optional parameter [quality] in the range of 0.0 and 1.0 can be used when requesting [type]",
+          "   * 'image/jpeg' or 'image/webp'. If [quality] is not passed the default",
+          "   * value is used. Note: the default value varies by browser.",
+          "   *",
+          "   * If the height or width of this canvas element is 0, then 'data:' is returned,",
+          "   * representing no data.",
+          "   *",
+          "   * If the type requested is not 'image/png', and the returned value is",
+          "   * 'data:image/png', then the requested type is not supported.",
+          "   *",
+          "   * Example usage:",
+          "   *",
+          "   *     CanvasElement canvas = new CanvasElement();",
+          "   *     var ctx = canvas.context2d",
+          "   *     ..fillStyle = \"rgb(200,0,0)\"",
+          "   *     ..fillRect(10, 10, 55, 50);",
+          "   *     var dataUrl = canvas.toDataURL(\"image/jpeg\", 0.95);",
+          "   *     // The Data Uri would look similar to",
+          "   *     // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA",
+          "   *     // AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO",
+          "   *     // 9TXL0Y4OHwAAAABJRU5ErkJggg=='",
+          "   *     //Create a new image element from the data URI.",
+          "   *     var img = new ImageElement();",
+          "   *     img.src = dataUrl;",
+          "   *     document.body.children.add(img);",
+          "   *",
+          "   * See also:",
+          "   *",
+          "   * * [Data URI Scheme](http://en.wikipedia.org/wiki/Data_URI_scheme) from Wikipedia.",
+          "   *",
+          "   * * [HTMLCanvasElement](https://developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElement) from MDN.",
+          "   *",
+          "   * * [toDataUrl](http://dev.w3.org/html5/spec/the-canvas-element.html#dom-canvas-todataurl) from W3C.",
+          "   */"
+        ],
+        "width": [
+          "/// The width of this canvas element in CSS pixels."
+        ]
+      }
+    },
+    "HTMLDivElement": {
+      "comment": [
+        "/**",
+        " * Represents an HTML <div> element.",
+        " *",
+        " * The [DivElement] is a generic container for content and does not have any",
+        " * special significance. It is functionally similar to [SpanElement].",
+        " *",
+        " * The [DivElement] is a block-level element, as opposed to [SpanElement],",
+        " * which is an inline-level element.",
+        " *",
+        " * Example usage:",
+        " *",
+        " *     DivElement div = new DivElement();",
+        " *     div.text = 'Here's my new DivElem",
+        " *     document.body.elements.add(elem);",
+        " *",
+        " * See also:",
+        " *",
+        " * * [HTML <div> element](http://www.w3.org/TR/html-markup/div.html) from W3C.",
+        " * * [Block-level element](http://www.w3.org/TR/CSS2/visuren.html#block-boxes) from W3C.",
+        " * * [Inline-level element](http://www.w3.org/TR/CSS2/visuren.html#inline-boxes) from W3C.",
+        " */"
+      ]
+    },
+    "XMLHttpRequest": {
+      "members": {
+        "abort": [
+          "/**",
+          "   * Stop the current request.",
+          "   *",
+          "   * The request can only be stopped if readyState is `HEADERS_RECIEVED` or",
+          "   * `LOADING`. If this method is not in the process of being sent, the method",
+          "   * has no effect.",
+          "   */"
+        ],
+        "getAllResponseHeaders": [
+          "/**",
+          "   * Retrieve all the response headers from a request.",
+          "   *",
+          "   * `null` if no headers have been received. For multipart requests,",
+          "   * `getAllResponseHeaders` will return the response headers for the current",
+          "   * part of the request.",
+          "   *",
+          "   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+          "   * for a list of common response headers.",
+          "   */"
+        ],
+        "getResponseHeader": [
+          "/**",
+          "   * Return the response header named `header`, or `null` if not found.",
+          "   *",
+          "   * See also [HTTP response headers](http://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Responses)",
+          "   * for a list of common response headers.",
+          "   */"
+        ],
+        "open": [
+          "/**",
+          "   * Specify the desired `url`, and `method` to use in making the request.",
+          "   *",
+          "   * By default the request is done asyncronously, with no user or password",
+          "   * authentication information. If `async` is false, the request will be send",
+          "   * synchronously.",
+          "   *",
+          "   * Calling `open` again on a currently active request is equivalent to",
+          "   * calling `abort`.",
+          "   */"
+        ],
+        "overrideMimeType": [
+          "/**",
+          "   * Specify a particular MIME type (such as `text/xml`) desired for the",
+          "   * response.",
+          "   *",
+          "   * This value must be set before the request has been sent. See also the list",
+          "   * of [common MIME types](http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types)",
+          "   */"
+        ],
+        "readyState": [
+          "/**",
+          "   * Indicator of the current state of the request:",
+          "   *",
+          "   * <table>",
+          "   *   <tr>",
+          "   *     <td>Value</td>",
+          "   *     <td>State</td>",
+          "   *     <td>Meaning</td>",
+          "   *   </tr>",
+          "   *   <tr>",
+          "   *     <td>0</td>",
+          "   *     <td>unsent</td>",
+          "   *     <td><code>open()</code> has not yet been called</td>",
+          "   *   </tr>",
+          "   *   <tr>",
+          "   *     <td>1</td>",
+          "   *     <td>opened</td>",
+          "   *     <td><code>send()</code> has not yet been called</td>",
+          "   *   </tr>",
+          "   *   <tr>",
+          "   *     <td>2</td>",
+          "   *     <td>headers received</td>",
+          "   *     <td><code>sent()</code> has been called; response headers and <code>status</code> are available</td>",
+          "   *   </tr>",
+          "   *   <tr>",
+          "   *     <td>3</td> <td>loading</td> <td><code>responseText</code> holds some data</td>",
+          "   *   </tr>",
+          "   *   <tr>",
+          "   *     <td>4</td> <td>done</td> <td>request is complete</td>",
+          "   *   </tr>",
+          "   * </table>",
+          "   */"
+        ],
+        "response": [
+          "/**",
+          "   * The data received as a reponse from the request.",
+          "   *",
+          "   * The data could be in the",
+          "   * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a",
+          "   * [String]). `null` indicates request failure.",
+          "   */"
+        ],
+        "responseText": [
+          "/**",
+          "   * The response in string form or `null on failure.",
+          "   */"
+        ],
+        "responseType": [
+          "/**",
+          "   * [String] telling the server the desired response format.",
+          "   *",
+          "   * Default is `String`.",
+          "   * Other options are one of 'arraybuffer', 'blob', 'document', 'json',",
+          "   * 'text'. Some newer browsers will throw NS_ERROR_DOM_INVALID_ACCESS_ERR if",
+          "   * `responseType` is set while performing a synchronous request.",
+          "   *",
+          "   * See also: [MDN responseType](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType)",
+          "   */"
+        ],
+        "responseXML": [
+          "/**",
+          "   * The request response, or null on failure.",
+          "   *",
+          "   * The response is processed as",
+          "   * `text/xml` stream, unless responseType = 'document' and the request is",
+          "   * synchronous.",
+          "   */"
+        ],
+        "send": [
+          "/**",
+          "   * Send the request with any given `data`.",
+          "   *",
+          "   * See also:",
+          "   * [send() docs](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#send())",
+          "   * from MDN.",
+          "   */"
+        ],
+        "status": [
+          "/**",
+          "   * The http result code from the request (200, 404, etc).",
+          "   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+          "   */"
+        ],
+        "statusText": [
+          "/**",
+          "   * The request response string (such as \\\"200 OK\\\").",
+          "   * See also: [Http Status Codes](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)",
+          "   */"
+        ],
+        "upload": [
+          "/**",
+          "   * [EventTarget] that can hold listeners to track the progress of the request.",
+          "   * The events fired will be members of [HttpRequestUploadEvents].",
+          "   */"
+        ],
+        "withCredentials": [
+          "/**",
+          "   * True if cross-site requests should use credentials such as cookies",
+          "   * or authorization headers; false otherwise.",
+          "   *",
+          "   * This value is ignored for same-site requests.",
+          "   */"
+        ],
+        "XMLHttpRequest": [
+          "/**",
+          "   * General constructor for any type of request (GET, POST, etc).",
+          "   *",
+          "   * This call is used in conjunction with [open]:",
+          "   *",
+          "   *     var request = new HttpRequest();",
+          "   *     request.open('GET', 'http://dartlang.org')",
+          "   *     request.on.load.add((event) => print('Request complete'));",
+          "   *",
+          "   * is the (more verbose) equivalent of",
+          "   *",
+          "   *     var request = new HttpRequest.get('http://dartlang.org',",
+          "   *         (event) => print('Request complete'));",
+          "   */"
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/tools/dom/docs/lib/docs.dart b/tools/dom/docs/lib/docs.dart
index 69d9854..74529c4 100644
--- a/tools/dom/docs/lib/docs.dart
+++ b/tools/dom/docs/lib/docs.dart
@@ -29,7 +29,9 @@
  *           comment: "$comment"
  *           members: {
  *             $member: [
- *               $comment1,
+ *               [$comment1line1,
+ *                $comment1line2,
+ *                ...],
  *               ...
  *             ],
  *             ...
@@ -85,7 +87,7 @@
 
     var libraryJson = {};
     var sortedClasses = _sortAndFilterMirrors(
-        libMirror.classes.values.toList());
+        libMirror.classes.values.toList(), ignoreDocsEditable: true);
 
     for (ClassMirror classMirror in sortedClasses) {
       var classJson = {};
@@ -95,7 +97,8 @@
       var membersJson = {};
       for (var memberMirror in sortedMembers) {
         var memberDomName = domNames(memberMirror)[0];
-        var memberComment = computeUntrimmedCommentAsList(memberMirror);
+        var memberComment = _splitCommentsByNewline(
+            computeUntrimmedCommentAsList(memberMirror));
 
         // Remove interface name from Dom Name.
         if (memberDomName.indexOf('.') >= 0) {
@@ -107,8 +110,11 @@
         }
       }
 
-      var classComment = computeUntrimmedCommentAsList(classMirror);
-      if (!classComment.isEmpty) {
+      // Only include the comment if DocsEditable is set.
+      var classComment = _splitCommentsByNewline(
+          computeUntrimmedCommentAsList(classMirror));
+      if (!classComment.isEmpty &&
+          findMetadata(classMirror.metadata, 'DocsEditable') != null) {
         classJson.putIfAbsent('comment', () => classComment);
       }
       if (!membersJson.isEmpty) {
@@ -131,13 +137,19 @@
   return convertedJson;
 }
 
-List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors) {
-  // Filter out mirrors that are private, or which are not part of this docs
-  // process. That is, ones without the DocsEditable annotation.
+/// Filter out mirrors that are private, or which are not part of this docs
+/// process. That is, ones without the DocsEditable annotation.
+/// If [ignoreDocsEditable] is true, relax the restriction on @DocsEditable.
+/// This is to account for classes that are defined in a template, but whose
+/// members are generated.
+List<DeclarationMirror> _sortAndFilterMirrors(List<DeclarationMirror> mirrors,
+    {ignoreDocsEditable: false}) {
+
   var filteredMirrors = mirrors.where((DeclarationMirror c) =>
       !domNames(c).isEmpty &&
       !c.displayName.startsWith('_') &&
-      (findMetadata(c.metadata, 'DocsEditable') != null))
+      (!ignoreDocsEditable ? (findMetadata(c.metadata, 'DocsEditable') != null)
+          : true))
       .toList();
 
   filteredMirrors.sort((x, y) =>
@@ -147,6 +159,16 @@
   return filteredMirrors;
 }
 
+List<String> _splitCommentsByNewline(List<String> comments) {
+  var out = [];
+
+  comments.forEach((c) {
+    out.addAll(c.split(new RegExp('\n')));
+  });
+
+  return out;
+}
+
 /// Given the class mirror, returns the names found or an empty list.
 List<String> domNames(DeclarationMirror mirror) {
   var domNameMetadata = findMetadata(mirror.metadata, 'DomName');
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index e823e52..d822bc0 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -26,10 +26,6 @@
 };
 Element implements ElementTraversal;
 
-// TODO(antonm): fix it
-[Supplemental, Constructor]
-interface MediaStream {};
-
 [Callback]
 interface TimeoutHandler {
   void handleEvent();
@@ -44,6 +40,9 @@
 interface HTMLCanvasElement {
   [Suppressed] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type) raises(DOMException);
   [Custom] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Optional=DefaultIsUndefined] in DOMString type, [Optional] in float quality) raises(DOMException);
+
+  [Suppressed] DOMObject getContext(in DOMString contextId);
+  [Custom] CanvasRenderingContext getContext(in DOMString contextId, [Optional] in Dictionary attrs);
 };
 
 [Supplemental]
@@ -231,7 +230,7 @@
 // TODO(vsm): Define new names for these (see b/4436830).
 [Supplemental]
 interface IDBCursor {
-  [DartName=continueFunction] void continue([Optional] in IDBKey key);
+  [DartName=continueFunction] void continue([Optional] in any key);
 };
 [Supplemental]
 interface IDBDatabase {
@@ -246,20 +245,20 @@
 };
 [Supplemental]
 interface IDBIndex {
-  [DartName=getObject] IDBRequest get(in IDBKey key);
+  [DartName=getObject] IDBRequest get(in any key);
 };
 [Supplemental]
 interface IDBObjectStore {
-  [DartName=getObject] IDBRequest get(in IDBKey key);
+  [DartName=getObject] IDBRequest get(in any key);
   [DartName=getObject] IDBRequest get(in IDBKeyRange key);
 };
 
 [Supplemental]
 interface IDBKeyRange {
-  [DartName=only_] static IDBKeyRange only(in IDBKey value) raises (IDBDatabaseException);
-  [DartName=lowerBound_] static IDBKeyRange lowerBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
-  [DartName=upperBound_] static IDBKeyRange upperBound(in IDBKey bound, [Optional] in boolean open) raises (IDBDatabaseException);
-  [DartName=bound_] static IDBKeyRange bound(in IDBKey lower, in IDBKey upper, [Optional] in boolean lowerOpen, [Optional] in boolean upperOpen) raises (IDBDatabaseException);
+  [DartName=only_] static IDBKeyRange only(in any value) raises (IDBDatabaseException);
+  [DartName=lowerBound_] static IDBKeyRange lowerBound(in any bound, [Optional] in boolean open) raises (IDBDatabaseException);
+  [DartName=upperBound_] static IDBKeyRange upperBound(in any bound, [Optional] in boolean open) raises (IDBDatabaseException);
+  [DartName=bound_] static IDBKeyRange bound(in any lower, in any upper, [Optional] in boolean lowerOpen, [Optional] in boolean upperOpen) raises (IDBDatabaseException);
 };
 
 interface EntrySync {
@@ -327,7 +326,7 @@
   [Custom] Dictionary item(in unsigned long index);
 };
 
-[Supplemental, CustomConstructor, Constructor(in DOMString url)]
+[Supplemental]
 interface WebSocket {
   // Suppress the default since it has non-standard return type and add
   // overrides.
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index bc65b11..d4622cd 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -31,7 +31,6 @@
     'SVGFitToViewBox',
     'SVGLangSpace',
     'SVGLocatable',
-    'SVGStylable',
     'SVGTests',
     'SVGTransformable',
     'SVGURIReference',
@@ -222,20 +221,15 @@
   """
   if 'Constructor' in interface.ext_attrs:
     name = None
-    func_value = interface.ext_attrs.get('Constructor')
-    if not func_value:
-      args = []
-      idl_args = []
+    overloads = interface.ext_attrs['Constructor']
+    idl_args = [[] if f is None else f.arguments for f in overloads]
   elif 'NamedConstructor' in interface.ext_attrs:
     func_value = interface.ext_attrs.get('NamedConstructor')
+    idl_args = [func_value.arguments]
     name = func_value.id
   else:
     return None
 
-  if func_value:
-    idl_args = func_value.arguments
-    args =_BuildArguments([idl_args], interface, True)
-
   info = OperationInfo()
   info.overloads = None
   info.idl_args = idl_args
@@ -244,7 +238,7 @@
   info.constructor_name = None
   info.js_name = name
   info.type_name = interface.id
-  info.param_infos = args
+  info.param_infos = _BuildArguments(idl_args, interface, constructor=True)
   info.requires_named_arguments = False
   info.pure_dart_constructor = False
   return info
@@ -704,6 +698,18 @@
   "@Experimental",
 ]
 
+_web_sql_annotations = [
+  "@SupportedBrowser(SupportedBrowser.CHROME)",
+  "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  "@Experimental",
+]
+
+_webgl_annotations = [
+  "@SupportedBrowser(SupportedBrowser.CHROME)",
+  "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+  "@Experimental",
+]
+
 # Annotations to be placed on generated members.
 # The table is indexed as:
 #   INTERFACE:     annotations to be added to the interface declaration
@@ -711,6 +717,8 @@
 dart_annotations = {
   'ArrayBuffer': _all_but_ie9_annotations,
   'ArrayBufferView': _all_but_ie9_annotations,
+  'Database': _web_sql_annotations,
+  'DatabaseSync': _web_sql_annotations,
   'DOMApplicationCache': [
     "@SupportedBrowser(SupportedBrowser.CHROME)",
     "@SupportedBrowser(SupportedBrowser.FIREFOX)",
@@ -718,7 +726,10 @@
     "@SupportedBrowser(SupportedBrowser.OPERA)",
     "@SupportedBrowser(SupportedBrowser.SAFARI)",
   ],
+  'DOMWindow.convertPointFromNodeToPage': _webkit_experimental_annotations,
+  'DOMWindow.convertPointFromPageToNode': _webkit_experimental_annotations,
   'DOMWindow.indexedDB': _indexed_db_annotations,
+  'DOMWindow.openDatabase': _web_sql_annotations,
   'DOMWindow.performance': _performance_annotations,
   'DOMWindow.webkitNotifications': _webkit_experimental_annotations,
   'DOMWindow.webkitRequestFileSystem': _file_system_annotations,
@@ -793,38 +804,54 @@
   'SpeechRecognitionError': _speech_recognition_annotations,
   'SpeechRecognitionEvent': _speech_recognition_annotations,
   'SpeechRecognitionResult': _speech_recognition_annotations,
+  'SQLTransaction': _web_sql_annotations,
+  'SQLTransactionSync': _web_sql_annotations,
+  'WebGLRenderingContext': _webgl_annotations,
+  'WebKitCSSMatrix': _webkit_experimental_annotations,
+  'WebKitPoint': _webkit_experimental_annotations,
   'WebSocket': _all_but_ie9_annotations,
   'WorkerContext.indexedDB': _indexed_db_annotations,
+  'WorkerContext.openDatabase': _web_sql_annotations,
+  'WorkerContext.openDatabaseSync': _web_sql_annotations,
   'WorkerContext.webkitRequestFileSystem': _file_system_annotations,
   'WorkerContext.webkitRequestFileSystemSync': _file_system_annotations,
   'WorkerContext.webkitResolveLocalFileSystemSyncURL': _file_system_annotations,
   'WorkerContext.webkitResolveLocalFileSystemURL': _file_system_annotations,
   'XMLHttpRequestProgressEvent': _webkit_experimental_annotations,
+  'XSLTProcessor': [
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+    "@SupportedBrowser(SupportedBrowser.SAFARI)",
+  ],
 }
 
-def GetComments(interface_name, member_name=None, library_name=None):
+def GetComments(library_name, interface_name, member_name=None):
   """ Finds all comments for the interface or member and returns a list. """
 
   # Add documentation from JSON.
   comments = []
-
+  library_name = 'dart.dom.%s' % library_name
   if library_name in _dom_json and interface_name in _dom_json[library_name]:
-    if member_name and (member_name in
-                        _dom_json[library_name][interface_name]['members']):
+    if (member_name and 'members' in _dom_json[library_name][interface_name] and
+        (member_name in _dom_json[library_name][interface_name]['members'])):
       comments = _dom_json[library_name][interface_name]['members'][member_name]
-    elif 'comment' in _dom_json[library_name][interface_name]:
+    elif (not member_name and 'comment' in
+          _dom_json[library_name][interface_name]):
       comments = _dom_json[library_name][interface_name]['comment']
 
+  if (len(comments)):
+    comments = ['\n'.join(comments)]
+
   return comments
 
-def GetAnnotationsAndComments(interface_name, member_name=None,
-                              library_name=None):
-  annotations = GetComments(interface_name, member_name, library_name)
-  annotations.extend(FindCommonAnnotations(interface_name, member_name,
-                                           library_name))
+def GetAnnotationsAndComments(library_name, interface_name, member_name=None):
+  annotations = GetComments(library_name, interface_name, member_name)
+  annotations = annotations + (FindCommonAnnotations(library_name, interface_name,
+                                                     member_name))
+
   return annotations
 
-def FindCommonAnnotations(interface_name, member_name=None, library_name=None):
+def FindCommonAnnotations(library_name, interface_name, member_name=None):
   """ Finds annotations common between dart2js and dartium.
   """
   if member_name:
@@ -844,13 +871,12 @@
 
   return annotations
 
-def FindDart2JSAnnotationsAndComments(idl_type, interface_name, member_name,
-                           library_name=None):
+def FindDart2JSAnnotationsAndComments(idl_type, library_name, interface_name,
+                                      member_name,):
   """ Finds all annotations for Dart2JS members- including annotations for
   both dart2js and dartium.
   """
-  annotations = GetAnnotationsAndComments(interface_name, member_name,
-                                          library_name)
+  annotations = GetAnnotationsAndComments(library_name, interface_name, member_name)
 
   ann2 = _FindDart2JSSpecificAnnotations(idl_type, interface_name, member_name)
   if ann2:
@@ -869,6 +895,7 @@
 
 def FormatAnnotationsAndComments(annotations, indentation):
   if annotations:
+
     newline = '\n%s' % indentation
     result = newline.join(annotations) + newline
     return result
@@ -938,7 +965,7 @@
     return 'Dart%s' % self.idl_type()
 
   def vector_to_dart_template_parameter(self):
-    return self.bindings_class()
+    return self.native_type()
 
   def to_native_info(self, idl_node, interface_name):
     cls = self.bindings_class()
@@ -1097,12 +1124,16 @@
 
   def to_native_info(self, idl_node, interface_name):
     item_native_type = self._item_info.vector_to_dart_template_parameter()
-    return '%s', 'Vector<%s>' % item_native_type, 'DartUtilities', 'toNativeVector<%s>' % item_native_type
+    if isinstance(self._item_info, PrimitiveIDLTypeInfo):
+      return '%s', 'Vector<%s>' % item_native_type, 'DartUtilities', 'toNativeVector<%s>' % item_native_type
+    return '%s', 'Vector< RefPtr<%s> >' % item_native_type, 'DartUtilities', 'toNativeVector< RefPtr<%s> >' % item_native_type
 
   def pass_native_by_ref(self): return True
 
   def to_dart_conversion(self, value, interface_name=None, attributes=None):
-    return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.vector_to_dart_template_parameter(), value)
+    if isinstance(self._item_info, PrimitiveIDLTypeInfo):
+      return 'DartDOMWrapper::vectorToDart(%s)' % value
+    return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.bindings_class(), value)
 
   def conversion_includes(self):
     return self._item_info.conversion_includes()
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 6ff883a..dccbf03 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -6,9 +6,11 @@
 """This module provides shared functionality for the system to generate
 dart:html APIs from the IDL database."""
 
+import emitter
 from generator import AnalyzeOperation, ConstantOutputOrder, \
     DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \
-    IsPureInterface, TypeOrNothing, FindCommonAnnotations
+    IsPureInterface, TypeOrNothing, GetAnnotationsAndComments, \
+    FormatAnnotationsAndComments
 
 # Types that are accessible cross-frame in a limited fashion.
 # In these cases, the base type (e.g., WindowBase) provides restricted access
@@ -28,6 +30,7 @@
     self._type_registry = options.type_registry
     self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
     self._renamer = options.renamer
+    self._library_name = self._renamer.GetLibraryName(self._interface)
 
   def EmitSupportCheck(self):
     if self.HasSupportCheck():
@@ -176,8 +179,9 @@
     else:
       self.EmitOperation(info, method_name)
 
-  def _GenerateDispatcherBody(self,
-      operations,
+  def _GenerateOverloadDispatcher(self,
+      signatures,
+      is_void,
       parameter_names,
       declaration,
       generate_call,
@@ -192,7 +196,7 @@
         DECLARATION=declaration)
 
     version = [0]
-    def GenerateCall(operation, argument_count, checks):
+    def GenerateCall(signature_index, argument_count, checks):
       if checks:
         (stmts_emitter, call_emitter) = body_emitter.Emit(
             '    if ($CHECKS) {\n$!STMTS$!CALL    }\n',
@@ -203,19 +207,19 @@
             '$!STMTS$!CALL',
             INDENT='    ');
 
-      if operation.type.id == 'void':
+      if is_void:
         call_emitter = call_emitter.Emit('$(INDENT)$!CALL;\n$(INDENT)return;\n')
       else:
         call_emitter = call_emitter.Emit('$(INDENT)return $!CALL;\n')
 
       version[0] += 1
-      generate_call(
-          stmts_emitter, call_emitter, version[0], operation, argument_count)
+      generate_call(stmts_emitter, call_emitter,
+          version[0], signature_index, argument_count)
 
-    def GenerateChecksAndCall(operation, argument_count):
+    def GenerateChecksAndCall(signature_index, argument_count):
       checks = []
       for i in range(0, argument_count):
-        argument = operation.arguments[i]
+        argument = signatures[signature_index][i]
         parameter_name = parameter_names[i]
         test_type = self._DartType(argument.type.id)
         if test_type in ['dynamic', 'Object']:
@@ -227,34 +231,60 @@
       # optional argument could have been passed by name, leaving 'holes'.
       checks.extend(['!?%s' % name for name in parameter_names[argument_count:]])
 
-      GenerateCall(operation, argument_count, checks)
+      GenerateCall(signature_index, argument_count, checks)
 
     # TODO: Optimize the dispatch to avoid repeated checks.
-    if len(operations) > 1:
-      for operation in operations:
-        for position, argument in enumerate(operation.arguments):
-          if is_optional(operation, argument):
-            GenerateChecksAndCall(operation, position)
-        GenerateChecksAndCall(operation, len(operation.arguments))
+    if len(signatures) > 1:
+      for signature_index, signature in enumerate(signatures):
+        for argument_position, argument in enumerate(signature):
+          if is_optional(signature_index, argument):
+            GenerateChecksAndCall(signature_index, argument_position)
+        GenerateChecksAndCall(signature_index, len(signature))
       body_emitter.Emit(
           '    throw new ArgumentError("Incorrect number or type of arguments");'
           '\n');
     else:
-      operation = operations[0]
-      argument_count = len(operation.arguments)
-      for position, argument in list(enumerate(operation.arguments))[::-1]:
-        if is_optional(operation, argument):
-          check = '?%s' % parameter_names[position]
-          # argument_count instead of position + 1 is used here to cover one
+      signature = signatures[0]
+      argument_count = len(signature)
+      for argument_position, argument in list(enumerate(signature))[::-1]:
+        if is_optional(0, argument):
+          check = '?%s' % parameter_names[argument_position]
+          # argument_count instead of argument_position + 1 is used here to cover one
           # complicated case with the effectively optional argument in the middle.
           # Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z)
           # (as of now it's modelled after HTMLMediaElement.webkitAddKey).
           # y is optional in WebCore, while z is not.
           # In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation,
           # not foo(x, y).
-          GenerateCall(operation, argument_count, [check])
-          argument_count = position
-      GenerateCall(operation, argument_count, [])
+          GenerateCall(0, argument_count, [check])
+          argument_count = argument_position
+      GenerateCall(0, argument_count, [])
+
+  def _GenerateDispatcherBody(self,
+      operations,
+      parameter_names,
+      declaration,
+      generate_call,
+      is_optional,
+      can_omit_type_check=lambda type, pos: False):
+
+    def GenerateCall(
+        stmts_emitter, call_emitter, version, signature_index, argument_count):
+      generate_call(
+          stmts_emitter, call_emitter,
+          version, operations[signature_index], argument_count)
+
+    def IsOptional(signature_index, argument):
+      return is_optional(operations[signature_index], argument)
+
+    self._GenerateOverloadDispatcher(
+        [operation.arguments for operation in operations],
+        operations[0].type.id == 'void',
+        parameter_names,
+        declaration,
+        GenerateCall,
+        IsOptional,
+        can_omit_type_check)
 
   def AdditionalImplementedInterfaces(self):
     # TODO: Include all implemented interfaces, including other Lists.
@@ -288,25 +318,43 @@
       if type_info.is_typed_array():
         typed_array_type = type_info.list_item_type()
         break
+
+    annotations = FormatAnnotationsAndComments(
+        GetAnnotationsAndComments(self._library_name, self._interface.id,
+                                  self._interface.id), '  ')
+
+    fromListAnnotations = FormatAnnotationsAndComments(
+        GetAnnotationsAndComments(self._library_name, self._interface.id,
+                                  'fromList'), '  ')
+
+    fromBufferAnnotations = FormatAnnotationsAndComments(
+        GetAnnotationsAndComments(self._library_name, self._interface.id,
+                                  'fromBuffer'), '  ')
+
     if typed_array_type:
       self._members_emitter.Emit(
-          '\n'
-          '  factory $CTOR(int length) =>\n'
+          '\n  $(ANNOTATIONS)factory $CTOR(int length) =>\n'
           '    $FACTORY.create$(CTOR)(length);\n'
-          '\n'
-          '  factory $CTOR.fromList(List<$TYPE> list) =>\n'
+          '\n  $(LIST_ANNOTATIONS)factory $CTOR.fromList(List<$TYPE> list) =>\n'
           '    $FACTORY.create$(CTOR)_fromList(list);\n'
-          '\n'
-          '  factory $CTOR.fromBuffer(ArrayBuffer buffer, '
+          '\n  $(BUFFER_ANNOTATIONS)factory $CTOR.fromBuffer(ArrayBuffer buffer, '
               '[int byteOffset, int length]) => \n'
           '    $FACTORY.create$(CTOR)_fromBuffer(buffer, byteOffset, length);\n',
         CTOR=self._interface.id,
+        ANNOTATIONS=annotations,
+        LIST_ANNOTATIONS=fromListAnnotations,
+        BUFFER_ANNOTATIONS=fromBufferAnnotations,
         TYPE=self._DartType(typed_array_type),
         FACTORY=factory_name)
 
   def _AddConstructor(self,
       constructor_info, factory_name, factory_constructor_name):
-    self._members_emitter.Emit('\n  @DocsEditable');
+    if self.GenerateCustomFactory(constructor_info):
+      return
+
+    annotations = FormatAnnotationsAndComments(
+        GetAnnotationsAndComments(self._library_name, self._interface.id,
+                                  self._interface.id), '  ')
 
     if not factory_constructor_name:
       factory_constructor_name = '_create'
@@ -316,61 +364,90 @@
       factory_parameters = ', '.join(constructor_info.factory_parameters)
       has_factory_provider = False
 
-    has_optional = any(param_info.is_optional
-        for param_info in constructor_info.param_infos)
+    if constructor_info.pure_dart_constructor:
+      # TODO(antonm): use common dispatcher generation for this case as well.
+      has_optional = any(param_info.is_optional
+          for param_info in constructor_info.param_infos)
 
-    if not has_optional:
-      self._members_emitter.Emit(
-          '\n'
-          '  factory $CTOR($PARAMS) => '
-          '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
-          CTOR=constructor_info._ConstructorFullName(self._DartType),
-          PARAMS=constructor_info.ParametersDeclaration(self._DartType),
-          FACTORY=factory_name,
-          CTOR_FACTORY_NAME=factory_constructor_name,
-          FACTORY_PARAMS=factory_parameters)
-    else:
-      if has_factory_provider:
-        dispatcher_emitter = self._members_emitter.Emit(
-            '\n'
-            '  factory $CTOR($PARAMS) {\n'
-            '$!DISPATCHER'
-            '    return $FACTORY._create($FACTORY_PARAMS);\n'
-            '  }\n',
+      if not has_optional:
+        self._members_emitter.Emit(
+            '\n  $(ANNOTATIONS)'
+            'factory $CTOR($PARAMS) => '
+            '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
             CTOR=constructor_info._ConstructorFullName(self._DartType),
             PARAMS=constructor_info.ParametersDeclaration(self._DartType),
             FACTORY=factory_name,
-            FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
-
-        for index, param_info in enumerate(constructor_info.param_infos):
-          if param_info.is_optional:
-            dispatcher_emitter.Emit(
-              '    if (!?$OPT_PARAM_NAME) {\n'
-              '      return $FACTORY._create($FACTORY_PARAMS);\n'
-              '    }\n',
-              OPT_PARAM_NAME=param_info.name,
-              FACTORY=factory_name,
-              FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
-      else:
-        inits = self._members_emitter.Emit(
-            '\n'
-            '  factory $CONSTRUCTOR($PARAMS) {\n'
-            '    var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
-            '$!INITS'
-            '    return e;\n'
-            '  }\n',
-            CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
-            FACTORY=factory_name,
+            ANNOTATIONS=annotations,
             CTOR_FACTORY_NAME=factory_constructor_name,
-            PARAMS=constructor_info.ParametersDeclaration(self._DartType),
             FACTORY_PARAMS=factory_parameters)
+      else:
+        if has_factory_provider:
+          dispatcher_emitter = self._members_emitter.Emit(
+              '\n  $(ANNOTATIONS)'
+              'factory $CTOR($PARAMS) {\n'
+              '$!DISPATCHER'
+              '    return $FACTORY._create($FACTORY_PARAMS);\n'
+              '  }\n',
+              CTOR=constructor_info._ConstructorFullName(self._DartType),
+              PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+              FACTORY=factory_name,
+              ANNOTATIONS=annotations,
+              FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
 
-        for index, param_info in enumerate(constructor_info.param_infos):
-          if param_info.is_optional:
-            inits.Emit('    if ($E != null) e.$E = $E;\n', E=param_info.name)
+          for index, param_info in enumerate(constructor_info.param_infos):
+            if param_info.is_optional:
+              dispatcher_emitter.Emit(
+                '    if (!?$OPT_PARAM_NAME) {\n'
+                '      return $FACTORY._create($FACTORY_PARAMS);\n'
+                '    }\n',
+                OPT_PARAM_NAME=param_info.name,
+                FACTORY=factory_name,
+                FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
+        else:
+          inits = self._members_emitter.Emit(
+              '\n  $(ANNOTATIONS)'
+              'factory $CONSTRUCTOR($PARAMS) {\n'
+              '    var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
+              '$!INITS'
+              '    return e;\n'
+              '  }\n',
+              CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
+              ANNOTATIONS=annotations,
+              FACTORY=factory_name,
+              CTOR_FACTORY_NAME=factory_constructor_name,
+              PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+              FACTORY_PARAMS=factory_parameters)
 
-    if not constructor_info.pure_dart_constructor:
-      self.EmitStaticFactory(constructor_info)
+          for index, param_info in enumerate(constructor_info.param_infos):
+            if param_info.is_optional:
+              inits.Emit('    if ($E != null) e.$E = $E;\n', E=param_info.name)
+    else:
+      def GenerateCall(
+          stmts_emitter, call_emitter,
+          version, signature_index, argument_count):
+        name = emitter.Format('_create_$VERSION', VERSION=version)
+        call_emitter.Emit('$FACTORY.$NAME($FACTORY_PARAMS)',
+            FACTORY=factory_name,
+            NAME=name,
+            FACTORY_PARAMS= \
+                constructor_info.ParametersAsArgumentList(argument_count))
+        self.EmitStaticFactoryOverload(
+            constructor_info, name,
+            constructor_info.idl_args[signature_index][:argument_count])
+
+      def IsOptional(signature_index, argument):
+        return self.IsConstructorArgumentOptional(argument)
+
+      self._GenerateOverloadDispatcher(
+          constructor_info.idl_args,
+          False,
+          [info.name for info in constructor_info.param_infos],
+          emitter.Format('$(ANNOTATIONS)factory $CTOR($PARAMS)',
+            CTOR=constructor_info._ConstructorFullName(self._DartType),
+            ANNOTATIONS=annotations,
+            PARAMS=constructor_info.ParametersDeclaration(self._DartType)),
+          GenerateCall,
+          IsOptional)
 
   def EmitHelpers(self, base_class):
     pass
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index fd180ec..8c351a4 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -396,7 +396,7 @@
         continue
 
       annotations = FormatAnnotationsAndComments(
-          GetAnnotationsAndComments(interface.id, dom_name, library_name), '  ')
+          GetAnnotationsAndComments(library_name, interface.id, dom_name), '  ')
 
       members_emitter.Emit(
           "\n"
@@ -425,7 +425,7 @@
         provider = html_name + 'Event'
 
       annotations = FormatAnnotationsAndComments(
-          GetAnnotationsAndComments(interface.id, dom_name, library_name), '  ')
+          GetAnnotationsAndComments(library_name, interface.id, dom_name), '  ')
 
       members_emitter.Emit(
           "\n"
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 8d49ed7..6fb4c86 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -8,6 +8,7 @@
 
 html_interface_renames = monitored.Dict('htmlrenamer.html_interface_renames', {
     'CDATASection': 'CDataSection',
+    'Clipboard': 'DataTransfer',
     'DOMApplicationCache': 'ApplicationCache',
     'DOMCoreException': 'DomException',
     'DOMFileSystem': 'FileSystem',
@@ -37,7 +38,7 @@
     'WebKitCSSKeyframesRule': 'CssKeyframesRule',
     'WebKitCSSMatrix': 'CssMatrix',
     'WebKitCSSTransformValue': 'CssTransformValue',
-    'WebKitPoint': 'Point',
+    'WebKitPoint': 'DomPoint',
     'WebKitTransitionEvent': 'TransitionEvent',
     'XMLHttpRequest': 'HttpRequest',
     'XMLHttpRequestException': 'HttpRequestException',
@@ -154,6 +155,8 @@
 _renamed_html_members = monitored.Dict('htmlrenamer._renamed_html_members', {
     'DOMURL.createObjectURL': 'createObjectUrl',
     'DOMURL.revokeObjectURL': 'revokeObjectUrl',
+    'DOMWindow.webkitConvertPointFromNodeToPage': 'convertPointFromNodeToPage',
+    'DOMWindow.webkitConvertPointFromPageToNode': 'convertPointFromPageToNode',
     'DOMWindow.webkitNotifications': 'notifications',
     'DOMWindow.webkitRequestFileSystem': 'requestFileSystem',
     'DOMWindow.webkitResolveLocalFileSystemURL': 'resolveLocalFileSystemUrl',
@@ -172,7 +175,6 @@
     'Node.previousSibling': 'previousNode',
     'Node.textContent': 'text',
     'SVGElement.className': '$dom_svgClassName',
-    'SVGStylable.className': '$dom_svgClassName',
     'WorkerContext.webkitRequestFileSystem': 'requestFileSystem',
     'WorkerContext.webkitRequestFileSystemSync': 'requestFileSystemSync',
     'WorkerContext.webkitResolveLocalFileSystemSyncURL':
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index 7c488a5..7442912 100755
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -216,6 +216,9 @@
   def get(self, key, default=None):
     return self.__map.get(key, default)
 
+  def setdefault(self, key, value=None):
+    return self.__map.setdefault(key, value)
+
   def items(self):
     return self.__map.items()
 
@@ -287,6 +290,18 @@
       name = self._find_first(ext_attr, 'Id')
       value = self._find_first(ext_attr, 'ExtAttrValue')
 
+      if name == 'Constructor':
+        # There might be multiple constructor attributes, collect them
+        # as a list.  Represent plain Constructor attribute
+        # (without any signature) as None.
+        assert value is None
+        func_value = None
+        ctor_args = self._find_first(ext_attr, 'ExtAttrArgList')
+        if ctor_args:
+          func_value = IDLExtAttrFunctionValue(None, ctor_args)
+        self.setdefault('Constructor', []).append(func_value)
+        continue
+
       func_value = self._find_first(value, 'ExtAttrFunctionValue')
       if func_value:
         # E.g. NamedConstructor=Audio(in [Optional] DOMString src)
@@ -295,12 +310,6 @@
             self._find_first(func_value, 'ExtAttrArgList'))
         continue
 
-      ctor_args = not value and self._find_first(ext_attr, 'ExtAttrArgList')
-      if ctor_args:
-        # E.g. Constructor(Element host)
-        self[name] = IDLExtAttrFunctionValue(None, ctor_args)
-        continue
-
       self[name] = value
 
   def _all_subnodes(self):
diff --git a/tools/dom/scripts/idlrenderer.py b/tools/dom/scripts/idlrenderer.py
index 6e3e4d5..c145ade 100755
--- a/tools/dom/scripts/idlrenderer.py
+++ b/tools/dom/scripts/idlrenderer.py
@@ -121,6 +121,11 @@
               if v.id:
                 w('=')
               w(v)
+            elif isinstance(v, list):
+              assert k == 'Constructor'
+              w(v[0])
+              for c in v[1:]:
+                w(', '); w(k); w(c)
             else:
               w('=%s' % v.__str__())
           i += 1
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 08156fa..78b1934c 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -46,7 +46,6 @@
     'Element.remove',
     'ElementEvents.mouseWheel',
     'DOMException.name',
-    'HTMLCanvasElement.getContext',
     'HTMLTableElement.createTBody',
     'IDBDatabase.transaction',
     'KeyboardEvent.initKeyboardEvent',
@@ -72,6 +71,7 @@
 
 js_support_checks = {
   'ArrayBuffer': "JS('bool', 'typeof window.ArrayBuffer != \"undefined\"')",
+  'Database': "JS('bool', '!!(window.openDatabase)')",
   'DOMApplicationCache': "JS('bool', '!!(window.applicationCache)')",
   'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
   'HashChangeEvent': "Event._isTypeSupported('HashChangeEvent')",
@@ -96,7 +96,11 @@
       "window.webkitSpeechRecognition)')",
   'XMLHttpRequestProgressEvent':
       "Event._isTypeSupported('XMLHttpRequestProgressEvent')",
+  'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
+  'WebKitCSSMatrix': "JS('bool', '!!(window.WebKitCSSMatrix)')",
+  'WebKitPoint': "JS('bool', '!!(window.WebKitPoint)')",
   'WebSocket': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
+  'XSLTProcessor': "JS('bool', '!!(window.XSLTProcessor)')",
 }
 
 # Classes that offer only static methods, and therefore we should suppress
@@ -331,6 +335,7 @@
 
     typedef_name = self._renamer.RenameInterface(self._interface)
     code.Emit('typedef void $NAME($PARAMS);\n',
+              LIBRARYNAME='dart.dom.%s' % self._library_name,
               NAME=typedef_name,
               PARAMS=info.ParametersDeclaration(self._DartType))
     self._backend.GenerateCallback(info)
@@ -402,12 +407,12 @@
       implements_str = ' implements ' + ', '.join(set(implements))
 
     annotations = FormatAnnotationsAndComments(
-        GetAnnotationsAndComments(self._interface.doc_js_name,
-                              library_name=self._library_name), '')
+        GetAnnotationsAndComments(self._library_name,
+                                  self._interface.doc_js_name), '')
 
     self._implementation_members_emitter = implementation_emitter.Emit(
         self._backend.ImplementationTemplate(),
-        LIBRARYNAME=self._library_name,
+        LIBRARYNAME='dart.dom.%s' % self._library_name,
         ANNOTATIONS=annotations,
         CLASSNAME=self._interface_type_info.implementation_name(),
         EXTENDS=' extends %s' % base_class if base_class else '',
@@ -518,56 +523,33 @@
   def GetSupportCheck(self):
     return js_support_checks.get(self._interface.doc_js_name)
 
-  def EmitStaticFactory(self, constructor_info):
-    WITH_CUSTOM_STATIC_FACTORY = [
+  def GenerateCustomFactory(self, constructor_info):
+    # Custom factory will be taken from the template.
+    return self._interface.doc_js_name in [
         'AudioContext',
         'Blob',
         'MutationObserver',
         'SpeechRecognition',
     ]
 
-    if self._interface.doc_js_name in WITH_CUSTOM_STATIC_FACTORY:
-      return
+  def IsConstructorArgumentOptional(self, argument):
+    return 'Optional' in argument.ext_attrs
 
-    has_optional = any(param_info.is_optional
-        for param_info in constructor_info.param_infos)
-
-    def FormatJS(index):
-      arguments = constructor_info.ParametersAsArgumentList(index)
-      if arguments:
-        arguments = ', ' + arguments
-      return "JS('%s', 'new %s(%s)'%s)" % (
-          self._interface_type_info.interface_name(),
-          constructor_info.name or self._interface.doc_js_name,
-          ','.join(['#'] * index),
-          arguments)
-
-    if not has_optional:
-      self._members_emitter.Emit(
-          "  static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) => $JS;\n",
-          INTERFACE_NAME=self._interface_type_info.interface_name(),
-          PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
-              self._DartType),
-          JS=FormatJS(len(constructor_info.param_infos)))
-    else:
-      dispatcher_emitter = self._members_emitter.Emit(
-          "  static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) {\n"
-          "$!DISPATCHER"
-          "    return $JS;\n"
-          "  }\n",
-          INTERFACE_NAME=self._interface_type_info.interface_name(),
-          PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
-              self._DartType),
-          JS=FormatJS(len(constructor_info.param_infos)))
-
-      for index, param_info in enumerate(constructor_info.param_infos):
-        if param_info.is_optional:
-          dispatcher_emitter.Emit(
-            "    if (!?$OPT_PARAM_NAME) {\n"
-            "      return $JS;\n"
-            "    }\n",
-            OPT_PARAM_NAME=constructor_info.param_infos[index].name,
-            JS=FormatJS(index))
+  def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
+    index = len(arguments)
+    arguments = constructor_info.ParametersAsArgumentList(index)
+    if arguments:
+      arguments = ', ' + arguments
+    self._members_emitter.Emit(
+        "  static $INTERFACE_NAME $NAME($PARAMETERS) => "
+          "JS('$INTERFACE_NAME', 'new $CTOR_NAME($PLACEHOLDERS)'$ARGUMENTS);\n",
+        INTERFACE_NAME=self._interface_type_info.interface_name(),
+        NAME=name,
+        # TODO(antonm): add types to parameters.
+        PARAMETERS=constructor_info.ParametersAsArgumentList(index),
+        CTOR_NAME=constructor_info.name or self._interface.doc_js_name,
+        PLACEHOLDERS=','.join(['#'] * index),
+        ARGUMENTS=arguments)
 
   def SecondaryContext(self, interface):
     if interface is not self._current_secondary_parent:
@@ -916,8 +898,9 @@
     return ''
 
   def _Annotations(self, idl_type, idl_member_name, indent='  '):
-    anns = FindDart2JSAnnotationsAndComments(idl_type, self._interface.id,
-        idl_member_name, self._library_name)
+    anns = FindDart2JSAnnotationsAndComments(idl_type, self._library_name,
+                                             self._interface.id,
+                                             idl_member_name)
 
     if not AnyConversionAnnotations(idl_type, self._interface.id,
                                   idl_member_name):
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 08d6708..df82ca7 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -160,44 +160,72 @@
         CLASSNAME=self._interface_type_info.implementation_name(),
         SUPERCONSTRUCTOR=super_constructor)
 
-  def EmitStaticFactory(self, constructor_info):
-    constructor_callback_id = self._interface.id + '_constructor_Callback'
+  def _EmitConstructorInfrastructure(self,
+      constructor_info, constructor_callback_cpp_name, factory_method_name,
+      argument_count=None):
+    constructor_callback_id = self._interface.id + '_' + constructor_callback_cpp_name
+    if argument_count is None:
+      argument_count = len(constructor_info.param_infos)
 
     self._members_emitter.Emit(
-        '  static $INTERFACE_NAME _create($PARAMETERS_DECLARATION) '
-          'native "$CONSTRUCTOR_CALLBACK_ID";\n',
+        '\n  @DocsEditable\n'
+        '  static $INTERFACE_NAME $FACTORY_METHOD_NAME($PARAMETERS) '
+            'native "$ID";\n',
         INTERFACE_NAME=self._interface_type_info.interface_name(),
-        PARAMETERS_DECLARATION=constructor_info.ParametersDeclaration(
-            self._DartType),
-        CONSTRUCTOR_CALLBACK_ID=constructor_callback_id)
+        FACTORY_METHOD_NAME=factory_method_name,
+        # TODO: add types to parameters.
+        PARAMETERS=constructor_info.ParametersAsArgumentList(argument_count),
+        ID=constructor_callback_id)
 
-    # TODO(antonm): currently we don't have information about number of arguments expected by
-    # the constructor, so name only dispatch.
     self._cpp_resolver_emitter.Emit(
-        '    if (name == "$CONSTRUCTOR_CALLBACK_ID")\n'
-        '        return Dart$(WEBKIT_INTERFACE_NAME)Internal::constructorCallback;\n',
-        CONSTRUCTOR_CALLBACK_ID=constructor_callback_id,
-        WEBKIT_INTERFACE_NAME=self._interface.id)
+        '    if (name == "$ID")\n'
+        '        return Dart$(WEBKIT_INTERFACE_NAME)Internal::$CPP_CALLBACK;\n',
+        ID=constructor_callback_id,
+        WEBKIT_INTERFACE_NAME=self._interface.id,
+        CPP_CALLBACK=constructor_callback_cpp_name)
+
+  def GenerateCustomFactory(self, constructor_info):
+    if 'CustomConstructor' not in self._interface.ext_attrs:
+        return False
+
+    self._members_emitter.Emit(
+        '  factory $CTOR($PARAMS) => _create($FACTORY_PARAMS);\n',
+        CTOR=constructor_info._ConstructorFullName(self._DartType),
+        PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+        FACTORY_PARAMS= \
+            constructor_info.ParametersAsArgumentList())
+
+    constructor_callback_cpp_name = 'constructorCallback'
+    self._EmitConstructorInfrastructure(
+        constructor_info, constructor_callback_cpp_name, '_create')
+
+    self._cpp_declarations_emitter.Emit(
+        '\n'
+        'void $CPP_CALLBACK(Dart_NativeArguments);\n',
+        CPP_CALLBACK=constructor_callback_cpp_name)
+
+    return True
+
+  def IsConstructorArgumentOptional(self, argument):
+    return False
+
+  def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
+    constructor_callback_cpp_name = name + 'constructorCallback'
+    self._EmitConstructorInfrastructure(
+        constructor_info, constructor_callback_cpp_name, name, len(arguments))
 
     ext_attrs = self._interface.ext_attrs
 
-    if 'CustomConstructor' in ext_attrs:
-      # We have a custom implementation for it.
-      self._cpp_declarations_emitter.Emit(
-          '\n'
-          'void constructorCallback(Dart_NativeArguments);\n')
-      return
-
     create_function = 'create'
     if 'NamedConstructor' in ext_attrs:
       create_function = 'createForJSConstructor'
     function_expression = '%s::%s' % (self._interface_type_info.native_type(), create_function)
     self._GenerateNativeCallback(
-        'constructorCallback',
+        constructor_callback_cpp_name,
         False,
         function_expression,
         self._interface,
-        constructor_info.idl_args,
+        arguments,
         self._interface.id,
         'ConstructorRaisesException' in ext_attrs)
 
@@ -674,7 +702,8 @@
           type_info.to_native_info(argument, self._interface.id)
 
       if ((IsOptional(argument) and not self._IsArgumentOptionalInWebCore(node, argument)) or
-          (argument.ext_attrs.get('Optional') == 'DefaultIsNullString')):
+          (argument.ext_attrs.get('Optional') == 'DefaultIsNullString') or
+          _IsOptionalStringArgumentInInitEventMethod(self._interface, node, argument)):
         function += 'WithNullCheck'
 
       argument_name = DartDomNameOfAttribute(argument)
@@ -734,7 +763,9 @@
   def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
       native_suffix, is_custom):
     annotations = FormatAnnotationsAndComments(
-        GetAnnotationsAndComments(self._interface.id, idl_name), '  ')
+        GetAnnotationsAndComments(self._renamer.GetLibraryName(self._interface),
+                                  self._interface.id, idl_name),
+                                  '  ')
 
     native_binding = '%s_%s_%s' % (self._interface.id, idl_name, native_suffix)
     self._members_emitter.Emit(
@@ -859,3 +890,10 @@
             '    if (Dart_NativeFunction func = $CLASS_NAME::resolver(name, argumentCount))\n'
             '        return func;\n',
             CLASS_NAME=os.path.splitext(os.path.basename(path))[0])
+
+def _IsOptionalStringArgumentInInitEventMethod(interface, operation, argument):
+  return (
+      interface.id.endswith('Event') and
+      operation.id.startswith('init') and
+      argument.ext_attrs.get('Optional') == 'DefaultIsUndefined' and
+      argument.type.id == 'DOMString')
diff --git a/tools/dom/src/CssClassSet.dart b/tools/dom/src/CssClassSet.dart
index 2c875b0..c688181 100644
--- a/tools/dom/src/CssClassSet.dart
+++ b/tools/dom/src/CssClassSet.dart
@@ -44,6 +44,8 @@
 
   String join([String separator]) => readClasses().join(separator);
 
+  Iterable map(f(String element)) => readClasses().map(f);
+
   Iterable mappedBy(f(String element)) => readClasses().mappedBy(f);
 
   Iterable<String> where(bool f(String element)) => readClasses().where(f);
@@ -141,7 +143,7 @@
    * Helper method used to modify the set of css classes on this element.
    *
    *   f - callback with:
-   *      s - a Set of all the css class name currently on this element.
+   *   s - a Set of all the css class name currently on this element.
    *
    *   After f returns, the modified set is written to the
    *       className property of this element.
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index 477359a..776d602 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -15,7 +15,7 @@
   _EventStream(this._target, this._eventType, this._useCapture);
 
   // DOM events are inherently multi-subscribers.
-  Stream<T> asMultiSubscriberStream() => this;
+  Stream<T> asBroadcastStream() => this;
 
   StreamSubscription<T> listen(void onData(T event),
       { void onError(AsyncError error),
diff --git a/tools/dom/src/KeyboardEventController.dart b/tools/dom/src/KeyboardEventController.dart
index 1e0f97a..73a7602 100644
--- a/tools/dom/src/KeyboardEventController.dart
+++ b/tools/dom/src/KeyboardEventController.dart
@@ -37,9 +37,8 @@
   // The distance to shift from upper case alphabet Roman letters to lower case.
   final int _ROMAN_ALPHABET_OFFSET = "a".charCodes[0] - "A".charCodes[0];
 
-  // Instance members referring to the internal event handlers because closures
-  // are not hashable.
-  var _keyUp, _keyDown, _keyPress;
+  StreamSubscription _keyUpSubscription, _keyDownSubscription,
+      _keyPressSubscription;
 
   /**
    * An enumeration of key identifiers currently part of the W3C draft for DOM3
@@ -95,9 +94,6 @@
     _callbacks = [];
     _type = type;
     _target = target;
-    _keyDown = processKeyDown;
-    _keyUp = processKeyUp;
-    _keyPress = processKeyPress;
   }
 
   /**
@@ -106,9 +102,14 @@
    */
   void _initializeAllEventListeners() {
     _keyDownList = [];
-    _target.on.keyDown.add(_keyDown, true);
-    _target.on.keyPress.add(_keyPress, true);
-    _target.on.keyUp.add(_keyUp, true);
+    if (_keyDownSubscription == null) {
+      _keyDownSubscription = Element.keyDownEvent.forTarget(
+          _target, useCapture: true).listen(processKeyDown);
+      _keyPressSubscription = Element.keyPressEvent.forTarget(
+          _target, useCapture: true).listen(processKeyUp);
+      _keyUpSubscription = Element.keyUpEvent.forTarget(
+          _target, useCapture: true).listen(processKeyPress);
+    }
   }
 
   /** Add a callback that wishes to be notified when a KeyEvent occurs. */
@@ -142,9 +143,12 @@
     }
     if (_callbacks.length == 0) {
       // If we have no listeners, don't bother keeping track of keypresses.
-      _target.on.keyDown.remove(_keyDown);
-      _target.on.keyPress.remove(_keyPress);
-      _target.on.keyUp.remove(_keyUp);
+      _keyDownSubscription.cancel();
+      _keyDownSubscription = null;
+      _keyPressSubscription.cancel();
+      _keyPressSubscription = null;
+      _keyUpSubscription.cancel();
+      _keyUpSubscription = null;
     }
   }
 
diff --git a/tools/dom/src/Measurement.dart b/tools/dom/src/Measurement.dart
deleted file mode 100644
index f664aac..0000000
--- a/tools/dom/src/Measurement.dart
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-typedef Object ComputeValue();
-
-class _MeasurementRequest<T> {
-  final ComputeValue computeValue;
-  final Completer<T> completer;
-  Object value;
-  bool exception = false;
-  _MeasurementRequest(this.computeValue, this.completer);
-}
-
-typedef void _MeasurementCallback();
-
-/**
- * This class attempts to invoke a callback as soon as the current event stack
- * unwinds, but before the browser repaints.
- */
-abstract class _MeasurementScheduler {
-  bool _nextMeasurementFrameScheduled = false;
-  _MeasurementCallback _callback;
-
-  _MeasurementScheduler(this._callback);
-
-  /**
-   * Creates the best possible measurement scheduler for the current platform.
-   */
-  factory _MeasurementScheduler.best(_MeasurementCallback callback) {
-    if (MutationObserver.supported) {
-      return new _MutationObserverScheduler(callback);
-    }
-    return new _PostMessageScheduler(callback);
-  }
-
-  /**
-   * Schedules a measurement callback if one has not been scheduled already.
-   */
-  void maybeSchedule() {
-    if (this._nextMeasurementFrameScheduled) {
-      return;
-    }
-    this._nextMeasurementFrameScheduled = true;
-    this._schedule();
-  }
-
-  /**
-   * Does the actual scheduling of the callback.
-   */
-  void _schedule();
-
-  /**
-   * Handles the measurement callback and forwards it if necessary.
-   */
-  void _onCallback() {
-    // Ignore spurious messages.
-    if (!_nextMeasurementFrameScheduled) {
-      return;
-    }
-    _nextMeasurementFrameScheduled = false;
-    this._callback();
-  }
-}
-
-/**
- * Scheduler which uses window.postMessage to schedule events.
- */
-class _PostMessageScheduler extends _MeasurementScheduler {
-  const _MEASUREMENT_MESSAGE = "DART-MEASURE";
-
-  _PostMessageScheduler(_MeasurementCallback callback): super(callback) {
-      // Messages from other windows do not cause a security risk as
-      // all we care about is that _handleMessage is called
-      // after the current event loop is unwound and calling the function is
-      // a noop when zero requests are pending.
-      window.on.message.add(this._handleMessage);
-  }
-
-  void _schedule() {
-    window.postMessage(_MEASUREMENT_MESSAGE, "*");
-  }
-
-  _handleMessage(e) {
-    this._onCallback();
-  }
-}
-
-/**
- * Scheduler which uses a MutationObserver to schedule events.
- */
-class _MutationObserverScheduler extends _MeasurementScheduler {
-  MutationObserver _observer;
-  Element _dummy;
-
-  _MutationObserverScheduler(_MeasurementCallback callback): super(callback) {
-    // Mutation events get fired as soon as the current event stack is unwound
-    // so we just make a dummy event and listen for that.
-    _observer = new MutationObserver(this._handleMutation);
-    _dummy = new DivElement();
-    _observer.observe(_dummy, attributes: true);
-  }
-
-  void _schedule() {
-    // Toggle it to trigger the mutation event.
-    _dummy.hidden = !_dummy.hidden;
-  }
-
-  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
-    this._onCallback();
-  }
-}
-
-
-List<_MeasurementRequest> _pendingRequests;
-List<TimeoutHandler> _pendingMeasurementFrameCallbacks;
-_MeasurementScheduler _measurementScheduler = null;
-
-void _maybeScheduleMeasurementFrame() {
-  if (_measurementScheduler == null) {
-    _measurementScheduler =
-      new _MeasurementScheduler.best(_completeMeasurementFutures);
-  }
-  _measurementScheduler.maybeSchedule();
-}
-
-/**
- * Registers a [callback] which is called after the next batch of measurements
- * completes. Even if no measurements completed, the callback is triggered
- * when they would have completed to avoid confusing bugs if it happened that
- * no measurements were actually requested.
- */
-void _addMeasurementFrameCallback(TimeoutHandler callback) {
-  if (_pendingMeasurementFrameCallbacks == null) {
-    _pendingMeasurementFrameCallbacks = <TimeoutHandler>[];
-    _maybeScheduleMeasurementFrame();
-  }
-  _pendingMeasurementFrameCallbacks.add(callback);
-}
-
-/**
- * Returns a [Future] whose value will be the result of evaluating
- * [computeValue] during the next safe measurement interval.
- * The next safe measurement interval is after the current event loop has
- * unwound but before the browser has rendered the page.
- * It is important that the [computeValue] function only queries the html
- * layout and html in any way.
- */
-Future _createMeasurementFuture(ComputeValue computeValue,
-                                Completer completer) {
-  if (_pendingRequests == null) {
-    _pendingRequests = <_MeasurementRequest>[];
-    _maybeScheduleMeasurementFrame();
-  }
-  _pendingRequests.add(new _MeasurementRequest(computeValue, completer));
-  return completer.future;
-}
-
-/**
- * Complete all pending measurement futures evaluating them in a single batch
- * so that the the browser is guaranteed to avoid multiple layouts.
- */
-void _completeMeasurementFutures() {
-  // We must compute all new values before fulfilling the futures as
-  // the onComplete callbacks for the futures could modify the DOM making
-  // subsequent measurement calculations expensive to compute.
-  if (_pendingRequests != null) {
-    for (_MeasurementRequest request in _pendingRequests) {
-      try {
-        request.value = request.computeValue();
-      } catch (e) {
-        request.value = e;
-        request.exception = true;
-      }
-    }
-  }
-
-  final completedRequests = _pendingRequests;
-  final readyMeasurementFrameCallbacks = _pendingMeasurementFrameCallbacks;
-  _pendingRequests = null;
-  _pendingMeasurementFrameCallbacks = null;
-  if (completedRequests != null) {
-    for (_MeasurementRequest request in completedRequests) {
-      if (request.exception) {
-        request.completer.completeError(request.value);
-      } else {
-        request.completer.complete(request.value);
-      }
-    }
-  }
-
-  if (readyMeasurementFrameCallbacks != null) {
-    for (TimeoutHandler handler in readyMeasurementFrameCallbacks) {
-      // TODO(jacobr): wrap each call to a handler in a try-catch block.
-      handler();
-    }
-  }
-}
diff --git a/tools/dom/src/Microtask.dart b/tools/dom/src/Microtask.dart
new file mode 100644
index 0000000..4b811e4
--- /dev/null
+++ b/tools/dom/src/Microtask.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of html;
+
+typedef void _MicrotaskCallback();
+
+/**
+ * This class attempts to invoke a callback as soon as the current event stack
+ * unwinds, but before the browser repaints.
+ */
+abstract class _MicrotaskScheduler {
+  bool _nextMicrotaskFrameScheduled = false;
+  _MicrotaskCallback _callback;
+
+  _MicrotaskScheduler(this._callback);
+
+  /**
+   * Creates the best possible microtask scheduler for the current platform.
+   */
+  factory _MicrotaskScheduler.best(_MicrotaskCallback callback) {
+    if (Window._supportsSetImmediate) {
+      return new _SetImmediateScheduler(callback);
+    } else if (MutationObserver.supported) {
+      return new _MutationObserverScheduler(callback);
+    }
+    return new _PostMessageScheduler(callback);
+  }
+
+  /**
+   * Schedules a microtask callback if one has not been scheduled already.
+   */
+  void maybeSchedule() {
+    if (this._nextMicrotaskFrameScheduled) {
+      return;
+    }
+    this._nextMicrotaskFrameScheduled = true;
+    this._schedule();
+  }
+
+  /**
+   * Does the actual scheduling of the callback.
+   */
+  void _schedule();
+
+  /**
+   * Handles the microtask callback and forwards it if necessary.
+   */
+  void _onCallback() {
+    // Ignore spurious messages.
+    if (!_nextMicrotaskFrameScheduled) {
+      return;
+    }
+    _nextMicrotaskFrameScheduled = false;
+    this._callback();
+  }
+}
+
+/**
+ * Scheduler which uses window.postMessage to schedule events.
+ */
+class _PostMessageScheduler extends _MicrotaskScheduler {
+  const _MICROTASK_MESSAGE = "DART-MICROTASK";
+
+  _PostMessageScheduler(_MicrotaskCallback callback): super(callback) {
+      // Messages from other windows do not cause a security risk as
+      // all we care about is that _handleMessage is called
+      // after the current event loop is unwound and calling the function is
+      // a noop when zero requests are pending.
+      window.onMessage.listen(this._handleMessage);
+  }
+
+  void _schedule() {
+    window.postMessage(_MICROTASK_MESSAGE, "*");
+  }
+
+  void _handleMessage(e) {
+    this._onCallback();
+  }
+}
+
+/**
+ * Scheduler which uses a MutationObserver to schedule events.
+ */
+class _MutationObserverScheduler extends _MicrotaskScheduler {
+  MutationObserver _observer;
+  Element _dummy;
+
+  _MutationObserverScheduler(_MicrotaskCallback callback): super(callback) {
+    // Mutation events get fired as soon as the current event stack is unwound
+    // so we just make a dummy event and listen for that.
+    _observer = new MutationObserver(this._handleMutation);
+    _dummy = new DivElement();
+    _observer.observe(_dummy, attributes: true);
+  }
+
+  void _schedule() {
+    // Toggle it to trigger the mutation event.
+    _dummy.hidden = !_dummy.hidden;
+  }
+
+  _handleMutation(List<MutationRecord> mutations, MutationObserver observer) {
+    this._onCallback();
+  }
+}
+
+/**
+ * Scheduler which uses window.setImmediate to schedule events.
+ */
+class _SetImmediateScheduler extends _MicrotaskScheduler {
+  _SetImmediateScheduler(_MicrotaskCallback callback): super(callback);
+
+  void _schedule() {
+    window._setImmediate(_handleImmediate);
+  }
+
+  void _handleImmediate() {
+    this._onCallback();
+  }
+}
+
+List<TimeoutHandler> _pendingMicrotasks;
+_MicrotaskScheduler _microtaskScheduler = null;
+
+void _maybeScheduleMicrotaskFrame() {
+  if (_microtaskScheduler == null) {
+    _microtaskScheduler =
+      new _MicrotaskScheduler.best(_completeMicrotasks);
+  }
+  _microtaskScheduler.maybeSchedule();
+}
+
+/**
+ * Registers a [callback] which is called after the current execution stack
+ * unwinds.
+ */
+void _addMicrotaskCallback(TimeoutHandler callback) {
+  if (_pendingMicrotasks == null) {
+    _pendingMicrotasks = <TimeoutHandler>[];
+    _maybeScheduleMicrotaskFrame();
+  }
+  _pendingMicrotasks.add(callback);
+}
+
+
+/**
+ * Complete all pending microtasks.
+ */
+void _completeMicrotasks() {
+  var callbacks = _pendingMicrotasks;
+  _pendingMicrotasks = null;
+  for (var callback in callbacks) {
+    callback();
+  }
+}
diff --git a/tools/dom/src/_HttpRequestUtils.dart b/tools/dom/src/_HttpRequestUtils.dart
index 7ebd01f..352ddfc 100644
--- a/tools/dom/src/_HttpRequestUtils.dart
+++ b/tools/dom/src/_HttpRequestUtils.dart
@@ -15,7 +15,7 @@
 
     request.withCredentials = withCredentials;
 
-    request.on.readyStateChange.add((e) {
+    request.onReadyStateChange.listen((e) {
       if (request.readyState == HttpRequest.DONE) {
         onComplete(request);
       }
diff --git a/tools/dom/src/_Testing.dart b/tools/dom/src/_Testing.dart
deleted file mode 100644
index 7b15688..0000000
--- a/tools/dom/src/_Testing.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of html;
-
-// TODO(rnystrom): add a way to supress public classes from DartDoc output.
-// TODO(jacobr): we can remove this class now that we are using the $dom_
-// convention for deprecated methods rather than truly private methods.
-/**
- * This class is intended for testing purposes only.
- */
-class Testing {
-  static void addEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
-    target.$dom_addEventListener(type, listener, useCapture);
-  }
-  static void removeEventListener(EventTarget target, String type, EventListener listener, bool useCapture) {
-    target.$dom_removeEventListener(type, listener, useCapture);
-  }
-
-}
diff --git a/tools/dom/src/chrome/app.runtime.dart b/tools/dom/src/chrome/app.runtime.dart
new file mode 100644
index 0000000..8b38aac
--- /dev/null
+++ b/tools/dom/src/chrome/app.runtime.dart
@@ -0,0 +1,257 @@
+// 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.
+
+// from app_runtime.idl
+part of chrome;
+
+/**
+ * Types
+ */
+
+/// A WebIntents intent object. Deprecated.
+class Intent extends ChromeObject {
+  /*
+   * Public (Dart) constructor
+   */
+  Intent({String action, String type, var data}) {
+    this.action = action;
+    this.type = type;
+    this.data = data;
+  }
+
+  /*
+   * Private (JS) constructor
+   */
+  Intent._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+
+  /// The WebIntent being invoked.
+  String get action => JS('String', '#.action', this._jsObject);
+
+  void set action(String action) {
+    JS('void', '#.action = #', this._jsObject, action);
+  }
+
+  /// The MIME type of the data.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+
+  /// Data associated with the intent.
+  // TODO(sashab): What is the best way to serialize/return generic JS objects?
+  Object get data => JS('Object', '#.data', this._jsObject);
+
+  void set data(Object data) {
+    JS('void', '#.data = #', this._jsObject, convertArgument(data));
+  }
+
+  /*
+   * TODO(sashab): What is a NullCallback() type?
+   * Add postResult and postFailure once understanding what this type is, and
+   * once there is a way to pass functions back from JS.
+   */
+}
+
+class LaunchItem extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  LaunchItem({FileEntry entry, String type}) {
+    this.entry = entry;
+    this.type = type;
+  }
+
+  /*
+   * Private constructor
+   */
+  LaunchItem._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+
+  /// FileEntry for the file.
+  FileEntry get entry => JS('FileEntry', '#.entry', this._jsObject);
+
+  void set entry(FileEntry entry) {
+    JS('void', '#.entry = #', this._jsObject, entry);
+  }
+
+  /// The MIME type of the file.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+}
+
+/// Optional data for the launch.
+class LaunchData extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  LaunchData({Intent intent, String id, List<LaunchItem> items}) {
+    this.intent = intent;
+    this.id = id;
+    this.items = items;
+  }
+
+  /*
+   * Private constructor
+   */
+  LaunchData._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  Intent get intent => new Intent._proxy(JS('', '#.intent', this._jsObject));
+
+  void set intent(Intent intent) {
+    JS('void', '#.intent = #', this._jsObject, convertArgument(intent));
+  }
+
+  /// The id of the file handler that the app is being invoked with.
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  List<LaunchItem> get items() {
+    List<LaunchItem> items_final = new List<LaunchItem>();
+    for (var o in JS('List', '#.items', this._jsObject)) {
+      items_final.add(new LaunchItem._proxy(o));
+    }
+    return items_final;
+  }
+
+  void set items(List<LaunchItem> items) {
+    JS('void', '#.items = #', this._jsObject, convertArgument(items));
+  }
+}
+
+class IntentResponse extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  IntentResponse({int intentId, bool success, Object data}) {
+    this.intentId = intentId;
+    this.success = success;
+    this.data = data;
+  }
+
+  /*
+   * Private constructor
+   */
+  IntentResponse._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+
+  /// Identifies the intent.
+  int get intentId => JS('int', '#.intentId', this._jsObject);
+
+  void set intentId(int intentId) {
+    JS('void', '#.intentId = #', this._jsObject, intentId);
+  }
+
+  /// Was this intent successful? (i.e., postSuccess vs postFailure).
+  bool get success => JS('bool', '#.success', this._jsObject);
+
+  void set success(bool success) {
+    JS('void', '#.success = #', this._jsObject, success);
+  }
+
+  /// Data associated with the intent response.
+  // TODO(sashab): What's the best way to serialize/return generic JS objects?
+  Object get data => JS('Object', '#.data', this._jsObject);
+
+  void set data(Object data) {
+    JS('void', '#.data = #', this._jsObject, convertArgument(data));
+  }
+}
+
+/**
+ * Events
+ */
+
+/// Fired at Chrome startup to apps that were running when Chrome last shut
+/// down.
+class Event_ChromeAppRuntimeOnRestarted extends Event {
+  /*
+   * Override callback type definitions
+   */
+  void addListener(void callback())
+      => super.addListener(callback);
+  void removeListener(void callback())
+      => super.removeListener(callback);
+  bool hasListener(void callback())
+      => super.hasListener(callback);
+
+  /*
+   * Constructor
+   */
+  Event_ChromeAppRuntimeOnRestarted(jsObject) : super._(jsObject, 0);
+}
+
+/// Fired when an app is launched from the launcher or in response to a web
+/// intent.
+class Event_ChromeAppRuntimeOnLaunched extends Event {
+  /*
+   * Override callback type definitions
+   */
+  void addListener(void callback(LaunchData launchData))
+      => super.addListener(callback);
+  void removeListener(void callback(LaunchData launchData))
+      => super.removeListener(callback);
+  bool hasListener(void callback(LaunchData launchData))
+      => super.hasListener(callback);
+
+  /*
+   * Constructor
+   */
+  Event_ChromeAppRuntimeOnLaunched(jsObject) : super._(jsObject, 1);
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppRuntime {
+  /*
+   * API connection
+   */
+  Object _jsObject;
+
+  /*
+   * Events
+   */
+  Event_ChromeAppRuntimeOnRestarted onRestarted;
+  Event_ChromeAppRuntimeOnLaunched onLaunched;
+
+  /*
+   * Functions
+   */
+  void postIntentResponse(IntentResponse intentResponse) =>
+    JS('void', '#.postIntentResponse(#)', this._jsObject,
+        convertArgument(intentResponse));
+
+  /*
+   * Constructor
+   */
+  API_ChromeAppRuntime(this._jsObject) {
+    onRestarted = new Event_ChromeAppRuntimeOnRestarted(JS('Object',
+                                                           '#.onRestarted',
+                                                           this._jsObject));
+    onLaunched = new Event_ChromeAppRuntimeOnLaunched(JS('Object',
+                                                         '#.onLaunched',
+                                                         this._jsObject));
+  }
+}
+
diff --git a/tools/dom/src/chrome/app.window.dart b/tools/dom/src/chrome/app.window.dart
new file mode 100644
index 0000000..24aad67
--- /dev/null
+++ b/tools/dom/src/chrome/app.window.dart
@@ -0,0 +1,359 @@
+// 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.
+
+// from app.window.idl
+part of chrome;
+
+/**
+ * Types
+ */
+class CreateWindowOptions extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  CreateWindowOptions({String id, int defaultWidth, int defaultHeight,
+      int defaultLeft, int defaultTop, int width, int height, int left, int top,
+      int minWidth, int minHeight, int maxWidth, int maxHeight, String type,
+      String frame, Bounds bounds, bool hidden}) {
+    this.id = id;
+    this.defaultWidth = defaultWidth;
+    this.defaultHeight = defaultHeight;
+    this.defaultLeft = defaultLeft;
+    this.defaultTop = defaultTop;
+    this.width = width;
+    this.height = height;
+    this.left = left;
+    this.top = top;
+    this.minWidth = minWidth;
+    this.minHeight = minHeight;
+    this.maxWidth = maxWidth;
+    this.maxHeight = maxHeight;
+    this.type = type;
+    this.frame = frame;
+    this.bounds = bounds;
+    this.hidden = hidden;
+  }
+
+  /*
+   * Private constructor
+   */
+  CreateWindowOptions._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// Id to identify the window. This will be used to remember the size
+  /// and position of the window and restore that geometry when a window
+  /// with the same id (and no explicit size or position) is later opened.
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  /// Default width of the window. (Deprecated; regular bounds act like this
+  /// now.)
+  int get defaultWidth => JS('int', '#.defaultWidth', this._jsObject);
+
+  void set defaultWidth(int defaultWidth) {
+    JS('void', '#.defaultWidth = #', this._jsObject, defaultWidth);
+  }
+
+  /// Default height of the window. (Deprecated; regular bounds act like this
+  /// now.)
+  int get defaultHeight => JS('int', '#.defaultHeight', this._jsObject);
+
+  void set defaultHeight(int defaultHeight) {
+    JS('void', '#.defaultHeight = #', this._jsObject, defaultHeight);
+  }
+
+  /// Default X coordinate of the window. (Deprecated; regular bounds act like
+  /// this now.)
+  int get defaultLeft => JS('int', '#.defaultLeft', this._jsObject);
+
+  void set defaultLeft(int defaultLeft) {
+    JS('void', '#.defaultLeft = #', this._jsObject, defaultLeft);
+  }
+
+  /// Default Y coordinate of the window. (Deprecated; regular bounds act like
+  /// this now.)
+  int get defaultTop => JS('int', '#.defaultTop', this._jsObject);
+
+  void set defaultTop(int defaultTop) {
+    JS('void', '#.defaultTop = #', this._jsObject, defaultTop);
+  }
+
+  /// Width of the window. (Deprecated; use 'bounds'.)
+  int get width => JS('int', '#.width', this._jsObject);
+
+  void set width(int width) {
+    JS('void', '#.width = #', this._jsObject, width);
+  }
+
+  /// Height of the window. (Deprecated; use 'bounds'.)
+  int get height => JS('int', '#.height', this._jsObject);
+
+  void set height(int height) {
+    JS('void', '#.height = #', this._jsObject, height);
+  }
+
+  /// X coordinate of the window. (Deprecated; use 'bounds'.)
+  int get left => JS('int', '#.left', this._jsObject);
+
+  void set left(int left) {
+    JS('void', '#.left = #', this._jsObject, left);
+  }
+
+  /// Y coordinate of the window. (Deprecated; use 'bounds'.)
+  int get top => JS('int', '#.top', this._jsObject);
+
+  void set top(int top) {
+    JS('void', '#.top = #', this._jsObject, top);
+  }
+
+  /// Minimium width of the window.
+  int get minWidth => JS('int', '#.minWidth', this._jsObject);
+
+  void set minWidth(int minWidth) {
+    JS('void', '#.minWidth = #', this._jsObject, minWidth);
+  }
+
+  /// Minimum height of the window.
+  int get minHeight => JS('int', '#.minHeight', this._jsObject);
+
+  void set minHeight(int minHeight) {
+    JS('void', '#.minHeight = #', this._jsObject, minHeight);
+  }
+
+  /// Maximum width of the window.
+  int get maxWidth => JS('int', '#.maxWidth', this._jsObject);
+
+  void set maxWidth(int maxWidth) {
+    JS('void', '#.maxWidth = #', this._jsObject, maxWidth);
+  }
+
+  /// Maximum height of the window.
+  int get maxHeight => JS('int', '#.maxHeight', this._jsObject);
+
+  void set maxHeight(int maxHeight) {
+    JS('void', '#.maxHeight = #', this._jsObject, maxHeight);
+  }
+
+  /// Window type: 'shell' (the default) is the only currently supported value.
+  String get type => JS('String', '#.type', this._jsObject);
+
+  void set type(String type) {
+    JS('void', '#.type = #', this._jsObject, type);
+  }
+
+  /// Frame type: 'none' or 'chrome' (defaults to 'chrome').
+  String get frame => JS('String', '#.frame', this._jsObject);
+
+  void set frame(String frame) {
+    JS('void', '#.frame = #', this._jsObject, frame);
+  }
+
+  /// Size of the content in the window (excluding the titlebar). If specified
+  /// in addition to any of the left/top/width/height parameters, this field
+  /// takes precedence. If a frameBounds is specified, the frameBounds take
+  /// precedence.
+  Bounds get bounds =>
+      new Bounds._proxy(JS('Bounds', '#.bounds', this._jsObject));
+
+  void set bounds(Bounds bounds) {
+    JS('void', '#.bounds = #', this._jsObject, convertArgument(bounds));
+  }
+
+  /// If true, the window will be created in a hidden state. Call show() on
+  /// the window to show it once it has been created. Defaults to false.
+  bool get hidden => JS('bool', '#.hidden', this._jsObject);
+
+  void set hidden(bool hidden) {
+    JS('void', '#.hidden = #', this._jsObject, hidden);
+  }
+}
+
+class Bounds extends ChromeObject {
+  /*
+   * Public constructor
+   */
+  Bounds({int left, int top, int width, int height}) {
+    this.left = left;
+    this.top = top;
+    this.width = width;
+    this.height = height;
+  }
+
+  /*
+   * Private constructor
+   */
+  Bounds._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  int get left => JS('int', '#.left', this._jsObject);
+
+  void set left(int left) {
+    JS('void', '#.left = #', this._jsObject, left);
+  }
+
+  int get top => JS('int', '#.top', this._jsObject);
+
+  void set top(int top) {
+    JS('void', '#.top = #', this._jsObject, top);
+  }
+
+  int get width => JS('int', '#.width', this._jsObject);
+
+  void set width(int width) {
+    JS('void', '#.width = #', this._jsObject, width);
+  }
+
+  int get height => JS('int', '#.height', this._jsObject);
+
+  void set height(int height) {
+    JS('void', '#.height = #', this._jsObject, height);
+  }
+}
+
+class AppWindow extends ChromeObject {
+  /*
+   * Public constructor
+   * TODO(sashab): Does it make sense to be able to create a new AppWindow this
+   * way?
+   */
+  //AppWindow();
+
+  /*
+   * Private constructor
+   */
+  AppWindow._proxy(jsObject) : super._proxy(jsObject);
+
+  /*
+   * Public accessors
+   */
+  /// The JavaScript 'window' object for the created child.
+  // TODO(sashab, sra): Detect whether this is the current window, or an
+  // external one, and return an appropriately-typed object
+  WindowBase get contentWindow =>
+      JS("Window", "#.contentWindow", this._jsObject);
+
+  /*
+   * Functions
+   */
+
+  /// Focus the window.
+  void focus() => JS("void", "#.focus()", this._jsObject);
+
+  /// Minimize the window.
+  void minimize() => JS("void", "#.minimize()", this._jsObject);
+
+  /// Is the window minimized?
+  bool isMinimized() => JS("bool", "#.isMinimized()", this._jsObject);
+
+  /// Maximize the window.
+  void maximize() => JS("void", "#.maximize()", this._jsObject);
+
+  /// Is the window maximized?
+  bool isMaximized() => JS("bool", "c#.isMaximized()", this._jsObject);
+
+  /// Restore the window.
+  void restore() => JS("void", "#.restore()", this._jsObject);
+
+  /// Move the window to the position (|left|, |top|).
+  void moveTo(int left, int top) =>
+      JS("void", "#.moveTo(#, #)", this._jsObject, left, top);
+
+  /// Resize the window to |width|x|height| pixels in size.
+  void resizeTo(int width, int height) =>
+      JS("void", "#.resizeTo(#, #)", this._jsObject, width, height);
+
+  /// Draw attention to the window.
+  void drawAttention() => JS("void", "#.drawAttention()", this._jsObject);
+
+  /// Clear attention to the window.
+  void clearAttention() => JS("void", "#.clearAttention()", this._jsObject);
+
+  /// Close the window.
+  void close() => JS("void", "#.close()", this._jsObject);
+
+  /// Show the window. Does nothing if the window is already visible.
+  void show() => JS("void", "#.show()", this._jsObject);
+
+  /// Hide the window. Does nothing if the window is already hidden.
+  void hide() => JS("void", "#.hide()", this._jsObject);
+
+  /// Set the window's bounds.
+  void setBounds(Bounds bounds) =>
+      JS("void", "#.setBounds(#)", this._jsObject, convertArgument(bounds));
+
+}
+
+/**
+ * Functions
+ */
+class API_ChromeAppWindow {
+  /**
+   * JS object
+   */
+  Object _jsObject;
+
+  /**
+   * Constructor
+   */
+  API_ChromeAppWindow(this._jsObject);
+
+  /**
+   * Functions
+   */
+
+  /// Returns an <a href="#type-AppWindow">AppWindow</a> object for the
+  /// current script context (ie JavaScript 'window' object). This can also be
+  /// called on a handle to a script context for another page, for example:
+  /// otherWindow.chrome.app.window.current().
+  AppWindow current() =>
+      new AppWindow._proxy(JS("Object", "#.current()", this._jsObject));
+
+  /// The size and position of a window can be specified in a number of
+  /// different ways. The most simple option is not specifying anything at
+  /// all, in which case a default size and platform dependent position will
+  /// be used.
+  ///
+  /// Another option is to use the top/left and width/height properties,
+  /// which will always put the window at the specified coordinates with the
+  /// specified size.
+  ///
+  /// Yet another option is to give the window a (unique) id. This id is then
+  /// used to remember the size and position of the window whenever it is
+  /// moved or resized. This size and position is then used instead of the
+  /// specified bounds on subsequent opening of a window with the same id. If
+  /// you need to open a window with an id at a location other than the
+  /// remembered default, you can create it hidden, move it to the desired
+  /// location, then show it.
+  ///
+  /// You can also combine these various options, explicitly specifying for
+  /// example the size while having the position be remembered or other
+  /// combinations like that. Size and position are dealt with seperately,
+  /// but individual coordinates are not. So if you specify a top (or left)
+  /// coordinate, you should also specify a left (or top) coordinate, and
+  /// similar for size.
+  ///
+  /// If you specify both a regular and a default value for the same option
+  /// the regular value is the only one that takes effect.
+  void create(String url, [CreateWindowOptions options,
+                           void callback(AppWindow created_window)]) {
+    void __proxy_callback(Object created_window) {
+      if (?callback)
+        callback(new AppWindow._proxy(created_window));
+    }
+
+    JS("void", "#.create(#, #, #)",
+       this._jsObject,
+       url,
+       convertArgument(options),
+       convertDartClosureToJS(__proxy_callback, 1)
+    );
+  }
+}
\ No newline at end of file
diff --git a/tools/dom/src/chrome/chrome.dart b/tools/dom/src/chrome/chrome.dart
new file mode 100644
index 0000000..97464a1
--- /dev/null
+++ b/tools/dom/src/chrome/chrome.dart
@@ -0,0 +1,64 @@
+// 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.
+
+part of chrome;
+
+// chrome.app
+class API_ChromeApp {
+  /*
+   * JS Variable
+   */
+  Object _jsObject;
+
+  /*
+   * Members
+   */
+  API_ChromeAppWindow window;
+  API_ChromeAppRuntime runtime;
+
+  /*
+   * Constructor
+   */
+  API_ChromeApp(this._jsObject) {
+    var window_object = JS('', '#.window', this._jsObject);
+    if (window_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    window = new API_ChromeAppWindow(window_object);
+
+    var runtime_object = JS('', '#.runtime', this._jsObject);
+    if (runtime_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    runtime = new API_ChromeAppRuntime(runtime_object);
+  }
+}
+
+// chrome
+class API_Chrome {
+  /*
+   * JS Variable
+   */
+  Object _jsObject;
+
+  /*
+   * Members
+   */
+  API_ChromeApp app;
+
+  /*
+   * Constructor
+   */
+  API_Chrome() {
+    this._jsObject = JS("Object", "chrome");
+    if (this._jsObject == null)
+      throw new UnsupportedError('Not supported by current browser.');
+
+    var app_object = JS('', '#.app', this._jsObject);
+    if (app_object == null)
+      throw new UnsupportedError('Not supported by current browser.');
+    app = new API_ChromeApp(app_object);
+  }
+}
+
+// The final chrome objects
+final API_Chrome chrome = new API_Chrome();
diff --git a/tools/dom/src/chrome/sample.dart b/tools/dom/src/chrome/sample.dart
deleted file mode 100644
index 4578b44..0000000
--- a/tools/dom/src/chrome/sample.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of chrome;
-
-// This is an example of exposing chrome APIs in Dart and will be replaced with
-// the proper implementation in the future.
-
-class AppModule {
-  AppModule._();
-
-  WindowModule get window => new WindowModule._();
-}
-
-class WindowModule {
-  WindowModule._();
-
-  void create(String url) {
-    var chrome = JS('', 'chrome');
-
-    if (chrome == null) {
-      throw new UnsupportedError('Not supported by current browser');
-    }
-    var app = JS('', '#.app', chrome);
-    if (app == null) {
-      throw new UnsupportedError('Not supported by current browser');
-    }
-    var window = JS('', '#.window', app);
-    if (app == null) {
-      throw new UnsupportedError('Not supported by current browser');
-    }
-    JS('void', '#.create(#)', window, url);
-  }
-}
-
-final app = new AppModule._();
diff --git a/tools/dom/src/chrome/utils.dart b/tools/dom/src/chrome/utils.dart
new file mode 100644
index 0000000..eddc6a4
--- /dev/null
+++ b/tools/dom/src/chrome/utils.dart
@@ -0,0 +1,295 @@
+// 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 set of utilities for use with the Chrome Extension APIs.
+ *
+ * Allows for easy access to required JS objects.
+ */
+part of chrome;
+
+/**
+ * A dart object, that is convertible to JS. Used for creating objects in dart,
+ * then passing them to JS.
+ *
+ * Objects that are passable to JS need to implement this interface.
+ */
+abstract class ChromeObject {
+  /*
+   * Default Constructor
+   *
+   * Called by child objects during their regular construction.
+   */
+  ChromeObject() : _jsObject = JS('var', '{}');
+
+  /*
+   * Internal proxy constructor
+   *
+   * Creates a new Dart object using this existing proxy.
+   */
+  ChromeObject._proxy(this._jsObject);
+
+  /*
+   * JS Object Representation
+   */
+  Object _jsObject;
+}
+
+/**
+ * Useful functions for converting arguments.
+ */
+
+/**
+ * Converts the given map-type argument to js-friendly format, recursively.
+ * Returns the new Map object.
+ */
+Object _convertMapArgument(Map argument) {
+  Map m = new Map();
+  for (Object key in argument.keys)
+    m[key] = convertArgument(argument[key]);
+  return convertDartToNative_Dictionary(m);
+}
+
+/**
+ * Converts the given list-type argument to js-friendly format, recursively.
+ * Returns the new List object.
+ */
+List _convertListArgument(List argument) {
+  List l = new List();
+  for (var i = 0; i < argument.length; i ++)
+    l.add(convertArgument(argument[i]));
+  return l;
+}
+
+/**
+ * Converts the given argument Object to js-friendly format, recursively.
+ *
+ * Flattens out all Chrome objects into their corresponding ._toMap()
+ * definitions, then converts them to JS objects.
+ *
+ * Returns the new argument.
+ *
+ * Cannot be used for functions.
+ */
+Object convertArgument(var argument) {
+  if (argument == null)
+    return argument;
+
+  if (argument is num || argument is String || argument is bool)
+    return argument;
+
+  if (argument is ChromeObject)
+    return argument._jsObject;
+
+  if (argument is List)
+    return _convertListArgument(argument);
+
+  if (argument is Map)
+    return _convertMapArgument(argument);
+
+  if (argument is Function)
+    throw new Exception("Cannot serialize Function argument ${argument}.");
+
+  // TODO(sashab): Try and detect whether the argument is already serialized.
+  return argument;
+}
+
+/// Description of a declarative rule for handling events.
+class Rule extends ChromeObject {
+  /*
+   * Public (Dart) constructor
+   */
+  Rule({String id, List conditions, List actions, int priority}) {
+    this.id = id;
+    this.conditions = conditions;
+    this.actions = actions;
+    this.priority = priority;
+  }
+
+  /*
+   * Private (JS) constructor
+   */
+  Rule._proxy(_jsObject) : super._proxy(_jsObject);
+
+  /*
+   * Public accessors
+   */
+  String get id => JS('String', '#.id', this._jsObject);
+
+  void set id(String id) {
+    JS('void', '#.id = #', this._jsObject, id);
+  }
+
+  // TODO(sashab): Wrap these generic Lists somehow.
+  List get conditions => JS('List', '#.conditions', this._jsObject);
+
+  void set conditions(List conditions) {
+    JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions));
+  }
+
+  // TODO(sashab): Wrap these generic Lists somehow.
+  List get actions => JS('List', '#.actions', this._jsObject);
+
+  void set actions(List actions) {
+    JS('void', '#.actions = #', this._jsObject, convertArgument(actions));
+  }
+
+  int get priority => JS('int', '#.priority', this._jsObject);
+
+  void set priority(int priority) {
+    JS('void', '#.priority = #', this._jsObject, priority);
+  }
+
+}
+
+/**
+ * The Event class.
+ *
+ * Chrome Event classes extend this interface.
+ *
+ * e.g.
+ *
+ *  // chrome.app.runtime.onLaunched
+ *  class Event_ChromeAppRuntimeOnLaunched extends Event {
+ *    // constructor, passing the arity of the callback
+ *    Event_ChromeAppRuntimeOnLaunched(jsObject) :
+ *     super._(jsObject, 1);
+ *
+ *    // methods, strengthening the Function parameter specificity
+ *    void addListener(void callback(LaunchData launchData))
+ *        => super.addListener(callback);
+ *    void removeListener(void callback(LaunchData launchData))
+ *        => super.removeListener(callback);
+ *    bool hasListener(void callback(LaunchData launchData))
+ *        => super.hasListener(callback);
+ *  }
+ *
+ */
+class Event {
+  /*
+   * JS Object Representation
+   */
+  Object _jsObject;
+
+  /*
+   * Number of arguments the callback takes.
+   */
+  int _callbackArity;
+
+  /*
+   * Private constructor
+   */
+  Event._(this._jsObject, this._callbackArity);
+
+  /*
+   * Methods
+   */
+
+  /// Registers an event listener <em>callback</em> to an event.
+  void addListener(Function callback) =>
+      JS('void',
+         '#.addListener(#)',
+         this._jsObject,
+         convertDartClosureToJS(callback, this._callbackArity)
+      );
+
+  /// Deregisters an event listener <em>callback</em> from an event.
+  void removeListener(Function callback) =>
+      JS('void',
+         '#.removeListener(#)',
+         this._jsObject,
+         convertDartClosureToJS(callback, this._callbackArity)
+      );
+
+  /// Returns True if <em>callback</em> is registered to the event.
+  bool hasListener(Function callback) =>
+      JS('bool',
+         '#.hasListener(#)',
+         this._jsObject,
+         convertDartClosureToJS(callback, this._callbackArity)
+      );
+
+  /// Returns true if any event listeners are registered to the event.
+  bool hasListeners() =>
+      JS('bool',
+         '#.hasListeners()',
+         this._jsObject
+      );
+
+  /// Registers rules to handle events.
+  ///
+  /// [eventName] is the name of the event this function affects and [rules] are
+  /// the rules to be registered. These do not replace previously registered
+  /// rules. [callback] is called with registered rules.
+  ///
+  void addRules(String eventName, List<Rule> rules,
+                [void callback(List<Rule> rules)]) {
+    // proxy the callback
+    void __proxy_callback(List rules) {
+      if (?callback) {
+        List<Rule> __proxy_rules = new List<Rule>();
+
+        for (Object o in rules)
+          __proxy_rules.add(new Rule._proxy(o));
+
+        callback(__proxy_rules);
+      }
+    }
+
+    JS('void',
+       '#.addRules(#, #, #)',
+       this._jsObject,
+       convertArgument(eventName),
+       convertArgument(rules),
+       convertDartClosureToJS(__proxy_callback, 1)
+    );
+  }
+
+  /// Returns currently registered rules.
+  ///
+  /// [eventName] is the name of the event this function affects and, if an array
+  /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+  /// this array are returned. [callback] is called with registered rules.
+  ///
+  void getRules(String eventName, [List<String> ruleIdentifiers,
+                                   void callback(List<Rule> rules)]) {
+    // proxy the callback
+    void __proxy_callback(List rules) {
+      if (?callback) {
+        List<Rule> __proxy_rules = new List<Rule>();
+
+        for (Object o in rules)
+          __proxy_rules.add(new Rule._proxy(o));
+
+        callback(__proxy_rules);
+      }
+    }
+
+    JS('void',
+       '#.getRules(#, #, #)',
+       this._jsObject,
+       convertArgument(eventName),
+       convertArgument(ruleIdentifiers),
+       convertDartClosureToJS(__proxy_callback, 1)
+    );
+  }
+
+  /// Unregisters currently registered rules.
+  ///
+  /// [eventName] is the name of the event this function affects and, if an array
+  /// is passed as [ruleIdentifiers], only rules with identifiers contained in
+  /// this array are unregistered. [callback] is called when the rules are
+  /// unregistered.
+  ///
+  void removeRules(String eventName, [List<String> ruleIdentifiers,
+                                      void callback()]) =>
+      JS('void',
+         '#.removeRules(#, #, #)',
+         this._jsObject,
+         convertArgument(eventName),
+         convertArgument(ruleIdentifiers),
+         convertDartClosureToJS(callback, 0)
+      );
+}
+
diff --git a/tools/dom/src/dart2js_KeyEvent.dart b/tools/dom/src/dart2js_KeyEvent.dart
index 332ce8d..17e0905 100644
--- a/tools/dom/src/dart2js_KeyEvent.dart
+++ b/tools/dom/src/dart2js_KeyEvent.dart
@@ -59,7 +59,7 @@
     _parent.cancelBubble = cancel;
   }
   /** Accessor to the clipboardData available for this event. */
-  Clipboard get clipboardData => _parent.clipboardData;
+  DataTransfer get clipboardData => _parent.clipboardData;
   /** True if the ctrl key is pressed during this event. */
   bool get ctrlKey => _parent.ctrlKey;
   /** Accessor to the target this event is listening to for changes. */
diff --git a/tools/dom/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
index c610b8e..a8eff57 100644
--- a/tools/dom/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -59,7 +59,7 @@
     _parent.cancelBubble = cancel;
   }
   /** Accessor to the clipboardData available for this event. */
-  Clipboard get clipboardData => _parent.clipboardData;
+  DataTransfer get clipboardData => _parent.clipboardData;
   /** True if the ctrl key is pressed during this event. */
   bool get ctrlKey => _parent.ctrlKey;
   /** Accessor to the target this event is listening to for changes. */
diff --git a/tools/dom/templates/callback.darttemplate b/tools/dom/templates/callback.darttemplate
index 9ffc669..5c891ce 100644
--- a/tools/dom/templates/callback.darttemplate
+++ b/tools/dom/templates/callback.darttemplate
@@ -4,6 +4,6 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 //$ Keep previous blank line when editor removes trailing empty lines.
diff --git a/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate b/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
index b41466f..56dec80 100644
--- a/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/chrome_dart2js.darttemplate
@@ -8,5 +8,11 @@
 library chrome;
 
 import 'dart:_foreign_helper' show JS;
+import 'dart:html_common';
+import 'dart:html';
 
-part '$AUXILIARY_DIR/chrome/sample.dart';
+part "$AUXILIARY_DIR/chrome/utils.dart";
+part "$AUXILIARY_DIR/chrome/chrome.dart";
+part "$AUXILIARY_DIR/chrome/app.runtime.dart";
+part "$AUXILIARY_DIR/chrome/app.window.dart";
+
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 1094cf7..f87c1b2 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -5,11 +5,10 @@
 // DO NOT EDIT
 // Auto-generated dart:html library.
 
-library html;
+library dart.dom.html;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -38,7 +37,7 @@
 part '$AUXILIARY_DIR/Timer.dart';
 part '$AUXILIARY_DIR/_HttpRequestUtils.dart';
 part '$AUXILIARY_DIR/Isolates.dart';
-part '$AUXILIARY_DIR/Measurement.dart';
+part '$AUXILIARY_DIR/Microtask.dart';
 part '$AUXILIARY_DIR/Serialization.dart';
 part '$AUXILIARY_DIR/shared_FactoryProviders.dart';
 part '$AUXILIARY_DIR/dart2js_Conversions.dart';
@@ -47,7 +46,6 @@
 part '$AUXILIARY_DIR/dart2js_FactoryProviders.dart';
 part '$AUXILIARY_DIR/dart2js_LocationWrapper.dart';
 part '$AUXILIARY_DIR/dart2js_TypedArrayFactoryProvider.dart';
-part '$AUXILIARY_DIR/_Testing.dart';
 part '$AUXILIARY_DIR/_ListIterators.dart';
 
 
diff --git a/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate b/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
index e67365c..36529bb 100644
--- a/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_AudioBufferSourceNode.darttemplate
@@ -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 web_audio;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
diff --git a/tools/dom/templates/html/dart2js/impl_Console.darttemplate b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
index eb4f5e5..dbd7bc3 100644
--- a/tools/dom/templates/html/dart2js/impl_Console.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_Console.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class Console {
 
diff --git a/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate b/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
index dd355c6..3e82f58 100644
--- a/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_ElementEvents.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 @deprecated
 class $CLASSNAME extends $SUPER {
diff --git a/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
index 261fffd..52f7436 100644
--- a/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_HTMLTableElement.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
diff --git a/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate b/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
index e2b870c..cc7154d 100644
--- a/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_IDBDatabase.darttemplate
@@ -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 indexed_db;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
diff --git a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
index ed29b0f..7ca2b26 100644
--- a/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_MouseEvent.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate b/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate
index 599b50c..139f6c5 100644
--- a/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_SpeechRecognition.darttemplate
@@ -6,7 +6,7 @@
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
-  static SpeechRecognition _create() {
+  factory SpeechRecognition() {
     return JS('SpeechRecognition',
         'new (window.SpeechRecognition || window.webkitSpeechRecognition)()');
   }
diff --git a/tools/dom/templates/html/dart2js/impl_URL.darttemplate b/tools/dom/templates/html/dart2js/impl_URL.darttemplate
index 8188c31..1a02aa1 100644
--- a/tools/dom/templates/html/dart2js/impl_URL.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_URL.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
diff --git a/tools/dom/templates/html/dart2js/impl_Window.darttemplate b/tools/dom/templates/html/dart2js/impl_Window.darttemplate
index 037ef2d..1f74f22 100644
--- a/tools/dom/templates/html/dart2js/impl_Window.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_Window.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS native "@*DOMWindow" {
 
@@ -71,12 +71,13 @@
   }
 
   /**
-   * Executes a [callback] after the next batch of browser layout measurements
-   * has completed or would have completed if any browser layout measurements
-   * had been scheduled.
+   * Executes a [callback] after the immediate execution stack has completed.
+   *
+   * This will cause the callback to be executed after all processing has
+   * completed for the current event, but before any subsequent events.
    */
-  void requestLayoutFrame(TimeoutHandler callback) {
-    _addMeasurementFrameCallback(callback);
+  void setImmediate(TimeoutHandler callback) {
+    _addMicrotaskCallback(callback);
   }
 
   @DomName('DOMWindow.requestAnimationFrame')
@@ -159,5 +160,14 @@
   @DomName('Window.console')
   Console get console => Console.safeConsole;
 
+  /// Checks if _setImmediate is supported.
+  static bool get _supportsSetImmediate =>
+      JS('bool', '!!(window.setImmediate)');
+
+  // Set immediate implementation for IE
+  void _setImmediate(void callback()) {
+    JS('void', '#.setImmediate(#)', this, convertDartClosureToJS(callback, 0));
+  }
+
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate b/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
index 4461917..27275bf 100644
--- a/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_WorkerContext.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
diff --git a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
index 8dc5ad5..cf7542f 100644
--- a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
@@ -5,7 +5,7 @@
 // DO NOT EDIT
 // Auto-generated dart:svg library.
 
-library indexed_db;
+library dart.dom.indexed_db;
 
 import 'dart:async';
 import 'dart:html';
diff --git a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
index bb5a01d..d907998 100644
--- a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
@@ -1,11 +1,10 @@
 // DO NOT EDIT
 // Auto-generated dart:svg library.
 
-library svg;
+library dart.dom.svg;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, Returns, JavaScriptIndexingBehavior, JSName;
diff --git a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
index 4812b82..17c774a 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -1,11 +1,10 @@
 // DO NOT EDIT
 // Auto-generated dart:audio library.
 
-library web_audio;
+library dart.dom.web_audio;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_foreign_helper' show JS;
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index a10a44a..3445f6b 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -5,11 +5,10 @@
 // DO NOT EDIT
 // Auto-generated dart:html library.
 
-library html;
+library dart.dom.html;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -38,9 +37,8 @@
 part '$AUXILIARY_DIR/dartium_FactoryProviders.dart';
 part '$AUXILIARY_DIR/Device.dart';
 part '$AUXILIARY_DIR/Isolates.dart';
-part '$AUXILIARY_DIR/Measurement.dart';
+part '$AUXILIARY_DIR/Microtask.dart';
 part '$AUXILIARY_DIR/Serialization.dart';
-part '$AUXILIARY_DIR/_Testing.dart';
 part '$AUXILIARY_DIR/_ListIterators.dart';
 
 part '$AUXILIARY_DIR/native_DOMPublic.dart';
diff --git a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
index d3de585..bb1be2c 100644
--- a/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_MouseEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/dartium/impl_Window.darttemplate b/tools/dom/templates/html/dartium/impl_Window.darttemplate
index 381e58b..3c4125b 100644
--- a/tools/dom/templates/html/dartium/impl_Window.darttemplate
+++ b/tools/dom/templates/html/dartium/impl_Window.darttemplate
@@ -2,17 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
   /**
-   * Executes a [callback] after the next batch of browser layout measurements
-   * has completed or would have completed if any browser layout measurements
-   * had been scheduled.
+   * Executes a [callback] after the immediate execution stack has completed.
+   *
+   * This will cause the callback to be executed after all processing has
+   * completed for the current event, but before any subsequent events.
    */
-  void requestLayoutFrame(TimeoutHandler callback) {
-    _addMeasurementFrameCallback(callback);
+  void setImmediate(TimeoutHandler callback) {
+    _addMicrotaskCallback(callback);
   }
 
   /**
@@ -34,5 +35,13 @@
     document.documentElement.attributes['dart-port:$name'] = json.stringify(serialized);
   }
 
+  /// Checks if _setImmediate is supported.
+  static bool get _supportsSetImmediate => false;
+
+  /// Dartium stub for IE's setImmediate.
+  void _setImmediate(void callback()) {
+    throw new UnsupportedError('setImmediate is not supported');
+  }
+
 $!MEMBERS
 }
diff --git a/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate b/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
index 47a3433..34e1d23 100644
--- a/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/indexed_db_dartium.darttemplate
@@ -5,7 +5,7 @@
 // DO NOT EDIT
 // Auto-generated dart:indexed_db library.
 
-library indexed_db;
+library dart.dom.indexed_db;
 
 import 'dart:async';
 import 'dart:html';
diff --git a/tools/dom/templates/html/dartium/svg_dartium.darttemplate b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
index 70af41e..13f2891 100644
--- a/tools/dom/templates/html/dartium/svg_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
@@ -1,11 +1,10 @@
 // DO NOT EDIT
 // Auto-generated dart:svg library.
 
-library svg;
+library dart.dom.svg;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
index f4526bb..b6319de 100644
--- a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
@@ -1,11 +1,10 @@
 // DO NOT EDIT
 // Auto-generated dart:audio library.
 
-library web_audio;
+library dart.dom.web_audio;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/tools/dom/templates/html/impl/impl_AudioContext.darttemplate b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
index 9c30422..1ef4069 100644
--- a/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
+++ b/tools/dom/templates/html/impl/impl_AudioContext.darttemplate
@@ -7,7 +7,7 @@
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
 $if DART2JS
-  static AudioContext _create() => JS('AudioContext',
+  factory AudioContext() => JS('AudioContext',
       'new (window.AudioContext || window.webkitAudioContext)()');
 
   GainNode createGain() {
diff --git a/tools/dom/templates/html/impl/impl_Blob.darttemplate b/tools/dom/templates/html/impl/impl_Blob.darttemplate
index 12554be..022b6de 100644
--- a/tools/dom/templates/html/impl/impl_Blob.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Blob.darttemplate
@@ -2,12 +2,12 @@
 // for 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;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
 $if DART2JS
-  static Blob _create([List blobParts = null, String type, String endings]) {
+  factory Blob(List blobParts, [String type, String endings]) {
     // TODO: validate that blobParts is a JS Array and convert if not.
     // TODO: any coercions on the elements of blobParts, e.g. coerce a typed
     // array to ArrayBuffer if it is a total view.
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index 0212570..67152b1 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 String _cachedBrowserPrefix;
 
diff --git a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
index fb76557..e26e050 100644
--- a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate b/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
index 64b5298..c190a86 100644
--- a/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CompositionEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
index 2d2b6c0..e568a09 100644
--- a/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CustomEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_DOMException.darttemplate b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
index 07aacbb..593fd4c 100644
--- a/tools/dom/templates/html/impl/impl_DOMException.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 /// @domName $DOMNAME
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
diff --git a/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate b/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
index 221c014..e613959 100644
--- a/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DeviceOrientationEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 $ANNOTATIONS
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_Document.darttemplate b/tools/dom/templates/html/impl/impl_Document.darttemplate
index f707aac..ad71764 100644
--- a/tools/dom/templates/html/impl/impl_Document.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Document.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 /**
  * The base class for all documents.
diff --git a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
index d9af150..13edffb 100644
--- a/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DocumentFragment.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createDocumentFragment();
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index b554609..340774c 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 // TODO(jacobr): use _Lists.dart to remove some of the duplicated
 // functionality.
@@ -61,6 +61,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Element element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Element element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -73,7 +77,7 @@
     return _element.$dom_firstElementChild == null;
   }
 
-  List<Element> take(int n) {
+  Iterable<Element> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -81,7 +85,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Element> skip(int n) {
+  Iterable<Element> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -137,8 +141,9 @@
     }
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(this, 0, null);
+  List<Element> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('TODO(jacobr): should we impl?');
@@ -156,7 +161,7 @@
   void remove(Object object) {
     if (object is Element) {
       Element element = object;
-      if (identical(element.parentNode, this)) {
+      if (identical(element.parentNode, _element)) {
         _element.$dom_removeChild(element);
       }
     }
@@ -273,6 +278,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Element element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Element element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -302,7 +311,7 @@
   List<Element> toList() => new List<Element>.from(this);
   Set<Element> toSet() => new Set<Element>.from(this);
 
-  List<Element> take(int n) {
+  Iterable<Element> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -310,7 +319,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Element> skip(int n) {
+  Iterable<Element> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -362,8 +371,9 @@
     throw new UnsupportedError('');
   }
 
-  List<Element> get reversed =>
-      new ReversedListView<Element>(this, 0, null);
+  List<Element> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare(Element a, Element b)]) {
     throw new UnsupportedError('');
@@ -707,27 +717,20 @@
    * [style] property, which contains only the values specified directly on this
    * element.
    *
+   * PseudoElement can be values such as `::after`, `::before`, `::marker`,
+   * `::line-marker`.
+   *
    * See also:
    *
    * * [CSS Inheritance and Cascade](http://docs.webplatform.org/wiki/tutorials/inheritance_and_cascade)
-   */
-  Future<CssStyleDeclaration> get computedStyle {
-     // TODO(jacobr): last param should be null, see b/5045788
-     return getComputedStyle('');
-  }
-
-  /**
-   * Returns the computed styles for pseudo-elements such as `::after`,
-   * `::before`, `::marker`, `::line-marker`.
-   *
-   * See also:
-   *
    * * [Pseudo-elements](http://docs.webplatform.org/wiki/css/selectors/pseudo-elements)
    */
-  Future<CssStyleDeclaration> getComputedStyle(String pseudoElement) {
-    return _createMeasurementFuture(
-        () => window.$dom_getComputedStyle(this, pseudoElement),
-        new Completer<CssStyleDeclaration>());
+  CssStyleDeclaration getComputedStyle([String pseudoElement]) {
+    if (pseudoElement == null) {
+      pseudoElement = '';
+    }
+    // TODO(jacobr): last param should be null, see b/5045788
+    return window.$dom_getComputedStyle(this, pseudoElement);
   }
 
   /**
@@ -907,6 +910,7 @@
     } else if (JS('bool', '!!#.msMatchesSelector', this)) {
       return JS('bool', '#.msMatchesSelector(#)', this, selectors);
     }
+    throw new UnsupportedError("Not supported on this platform");
   }
 $else
 $endif
diff --git a/tools/dom/templates/html/impl/impl_Event.darttemplate b/tools/dom/templates/html/impl/impl_Event.darttemplate
index b9b7b4c..70c340a 100644
--- a/tools/dom/templates/html/impl/impl_Event.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Event.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   // In JS, canBubble and cancelable are technically required parameters to
diff --git a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
index f0bf5ce..e0ff57e 100644
--- a/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
+++ b/tools/dom/templates/html/impl/impl_EventTarget.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 /**
  * Base class that supports listening for and dispatching browser events.
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index 50c46d1..699a328 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -2,13 +2,30 @@
 // for 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;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
-
-$if DART2JS
-  CanvasRenderingContext getContext(String contextId) native;
-$endif
   CanvasRenderingContext2D get context2d => getContext('2d');
+
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.FIREFOX)
+  @Experimental
+  WebGLRenderingContext getContext3d({alpha: true, depth: true, stencil: false,
+    antialias: true, premultipliedAlpha: true, preserveDrawingBuffer: false}) {
+
+    var options = {
+      'alpha': alpha,
+      'depth': depth,
+      'stencil': stencil,
+      'antialias': antialias,
+      'premultipliedAlpha': premultipliedAlpha,
+      'preserveDrawingBuffer': preserveDrawingBuffer,
+    };
+    var context = getContext('webgl', options);
+    if (context == null) {
+      context = getContext('experimental-webgl', options);
+    }
+    return context;
+  }
 }
diff --git a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
index 422278a..c64f11a 100644
--- a/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLDocument.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
index e215391..0f378ab 100644
--- a/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLSelectElement.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
index 515dd4a..dd908aa 100644
--- a/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HashChangeEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 $ANNOTATIONS
 class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate b/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
index 0c24dd9..7599fa9 100644
--- a/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBKeyRange.darttemplate
@@ -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 indexed_db;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   @DomName('IDBKeyRange.only')
diff --git a/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate b/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
index 8aae717..da137de 100644
--- a/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MessageEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate b/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
index bcef767..0f7c316 100644
--- a/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationEvent.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
index 5c70356..abab691 100644
--- a/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
+++ b/tools/dom/templates/html/impl/impl_MutationObserver.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
@@ -91,7 +91,7 @@
   @JSName('observe')
   void _call(target, options) native;
 
-  static MutationObserver _create(MutationCallback callback) {
+  factory MutationObserver(MutationCallback callback) {
     // Dummy statement to mark types as instantiated.
     JS('MutationObserver|MutationRecord', '0');
 
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index e23c5d8..473f94a 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 /**
  * Lazy implementation of the child nodes of an element that does not request
@@ -138,6 +138,10 @@
     return IterableMixinWorkaround.joinList(this, separator);
   }
 
+  Iterable map(f(Node element)) {
+    return IterableMixinWorkaround.map(this, f);
+  }
+
   List mappedBy(f(Node element)) {
     return IterableMixinWorkaround.mappedByList(this, f);
   }
@@ -157,7 +161,7 @@
 
   // From List<Node>:
 
-  List<Node> take(int n) {
+  Iterable<Node> take(int n) {
     return IterableMixinWorkaround.takeList(this, n);
   }
 
@@ -165,7 +169,7 @@
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<Node> skip(int n) {
+  Iterable<Node> skip(int n) {
     return IterableMixinWorkaround.skipList(this, n);
   }
 
@@ -189,8 +193,9 @@
     return this[index];
   }
 
-  List<Node> get reversed =>
-      new ReversedListView<Node>(this, 0, null);
+  List<Node> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   // TODO(jacobr): this could be implemented for child node lists.
   // The exception we throw here is misleading.
diff --git a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
index 0fbdacb..42ad450 100644
--- a/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGElement.darttemplate
@@ -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 svg;
+part of $LIBRARYNAME;
 
 class _AttributeClassSet extends CssClassSet {
   final Element _element;
diff --git a/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
index bc77c46..cc21d77 100644
--- a/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_SVGSVGElement.darttemplate
@@ -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 svg;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME() => _$(CLASSNAME)FactoryProvider.createSvgSvgElement();
diff --git a/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate b/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
index 30752ce..cb2e479 100644
--- a/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
+++ b/tools/dom/templates/html/impl/impl_ShadowRoot.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
index 273adfd..7cde516 100644
--- a/tools/dom/templates/html/impl/impl_Storage.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Storage.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS implements Map<String, String>
     $NATIVESPEC {
diff --git a/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate b/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
index 72b640d..686dc1c 100644
--- a/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_StorageEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_Text.darttemplate b/tools/dom/templates/html/impl/impl_Text.darttemplate
index b558e60..e5bbf5d 100644
--- a/tools/dom/templates/html/impl/impl_Text.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Text.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String data) => _$(CLASSNAME)FactoryProvider.create$CLASSNAME(data);
diff --git a/tools/dom/templates/html/impl/impl_TextEvent.darttemplate b/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
index 7249ce2..c877d70 100644
--- a/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TextEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(String type,
diff --git a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
index ea0bef9..7223959 100644
--- a/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_TouchEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   factory $CLASSNAME(TouchList touches, TouchList targetTouches,
@@ -21,4 +21,24 @@
     return e;
   }
 $!MEMBERS
+
+  /**
+   * Checks if touch events supported on the current platform.
+   *
+   * Note that touch events are only supported if the user is using a touch
+   * device.
+   */
+  static bool get supported {
+$if DART2JS
+    if (JS('bool', '"ontouchstart" in window')) {
+      return Event._isTypeSupported('TouchEvent');
+    }
+    return false;
+$else
+    // Bug #8186 add equivalent 'ontouchstart' check for Dartium.
+    // Basically, this is a fairly common check and it'd be great if it did not
+    // throw exceptions.
+    return Event._isTypeSupported('TouchEvent');
+$endif
+  }
 }
diff --git a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
index 939ce85..a4d2830 100644
--- a/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_UIEvent.darttemplate
@@ -4,7 +4,7 @@
 
 // WARNING: Do not edit - generated code.
 
-part of html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
   // In JS, canBubble and cancelable are technically required parameters to
diff --git a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
index a49a979..a3cf320 100644
--- a/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
+++ b/tools/dom/templates/html/impl/impl_WheelEvent.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 11efa77..078d873 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -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 html;
+part of $LIBRARYNAME;
 
 /**
  * A utility for retrieving data from a URL.
@@ -30,25 +30,39 @@
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
  */
 $(ANNOTATIONS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
-  /**
-   * Creates a URL get request for the specified `url`.
-   *
-   * After completing the request, the object will call the user-provided
-   * [onComplete] callback.
-   */
-  factory $CLASSNAME.get(String url, onComplete($CLASSNAME request)) =>
-      _HttpRequestUtils.get(url, onComplete, false);
 
-  // 80 char issue for comments in lists: dartbug.com/7588.
   /**
-   * Creates a URL GET request for the specified `url` with
-   * credentials such a cookie (already) set in the header or
-   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2).
+   * Creates a URL get request for the specified [url].
    *
-   * After completing the request, the object will call the user-provided
-   * [onComplete] callback.
+   * The server response must be a `text/` mime type for this request to
+   * succeed.
    *
-   * A few other details to keep in mind when using credentials:
+   * This is similar to [request] but specialized for HTTP GET requests which
+   * return text content.
+   *
+   * See also:
+   *
+   * * [request]
+   */
+  static Future<String> getString(String url,
+      {bool withCredentials, void onProgress(ProgressEvent e)}) {
+    return request(url, withCredentials: withCredentials,
+        onProgress: onProgress).then((xhr) => xhr.responseText);
+  }
+
+  /**
+   * Creates a URL request for the specified [url].
+   *
+   * By default this will do an HTTP GET request, this can be overridden with
+   * [method].
+   *
+   * The Future is completed when the response is available.
+   *
+   * The [withCredentials] parameter specified that credentials such as a cookie
+   * (already) set in the header or
+   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
+   * should be specified for the request. Details to keep in mind when using
+   * credentials:
    *
    * * Using credentials is only useful for cross-origin requests.
    * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
@@ -57,9 +71,50 @@
    *
    * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
    */
-  factory $CLASSNAME.getWithCredentials(String url,
-      onComplete($CLASSNAME request)) =>
-      _HttpRequestUtils.get(url, onComplete, true);
+  static Future<HttpRequest> request(String url,
+      {String method, bool withCredentials, String responseType, sendData,
+      void onProgress(ProgressEvent e)}) {
+    var completer = new Completer<HttpRequest>();
+
+    var xhr = new HttpRequest();
+    if (method == null) {
+      method = 'GET';
+    }
+    xhr.open(method, url, true);
+
+    if (withCredentials != null) {
+      xhr.withCredentials = withCredentials;
+    }
+
+    if (responseType != null) {
+      xhr.responseType = responseType;
+    }
+
+    if (onProgress != null) {
+      xhr.onProgress.listen(onProgress);
+    }
+
+    xhr.onLoad.listen((e) {
+      if (xhr.status >= 200 && xhr.status < 300 ||
+          xhr.status == 304 ) {
+        completer.complete(xhr);
+      } else {
+        completer.completeError(e);
+      }
+    });
+
+    xhr.onError.listen((e) {
+      completer.completeError(e);
+    });
+
+    if (sendData != null) {
+      xhr.send(sendData);
+    } else {
+      xhr.send();
+    }
+
+    return completer.future;
+  }
 
 $!MEMBERS
 }
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 3a09ac5..58cf40c 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -29,7 +29,11 @@
   String join([String separator]) =>
       IterableMixinWorkaround.joinList(this, separator);
 
-  List mappedBy(f($E element)) => IterableMixinWorkaround.mappedByList(this, f);
+  Iterable map(f($E element)) =>
+      IterableMixinWorkaround.map(this, f);
+
+  List mappedBy(f($E element)) =>
+      IterableMixinWorkaround.mappedByList(this, f);
 
   Iterable<$E> where(bool f($E element)) =>
       IterableMixinWorkaround.where(this, f);
@@ -43,13 +47,13 @@
 
   bool get isEmpty => this.length == 0;
 
-  List<$E> take(int n) => IterableMixinWorkaround.takeList(this, n);
+  Iterable<$E> take(int n) => IterableMixinWorkaround.takeList(this, n);
 
   Iterable<$E> takeWhile(bool test($E value)) {
     return IterableMixinWorkaround.takeWhile(this, test);
   }
 
-  List<$E> skip(int n) => IterableMixinWorkaround.skipList(this, n);
+  Iterable<$E> skip(int n) => IterableMixinWorkaround.skipList(this, n);
 
   Iterable<$E> skipWhile(bool test($E value)) {
     return IterableMixinWorkaround.skipWhile(this, test);
@@ -100,8 +104,9 @@
   // clear() defined by IDL.
 $endif
 
-  List<$E> get reversed =>
-      new ReversedListView<$E>(this, 0, null);
+  List<$E> get reversed {
+    return IterableMixinWorkaround.reversedList(this);
+  }
 
   void sort([int compare($E a, $E b)]) {
     throw new UnsupportedError("Cannot sort immutable List.");
diff --git a/tools/publish_all_pkgs.py b/tools/publish_all_pkgs.py
new file mode 100644
index 0000000..c20ed29
--- /dev/null
+++ b/tools/publish_all_pkgs.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Upload all packages in pkg/ (other than a few that should be explicitly 
+# excluded), plus sdk/lib/_internal/compiler .
+#
+# Usage: publish_all_pkgs.py
+#
+# "pub" must be in PATH.
+
+
+import os
+import os.path
+import subprocess
+import sys
+
+def Main(argv):
+  pkgs_to_publish = []
+  for name in os.listdir('pkg'):
+    if os.path.isdir(os.path.join('pkg', name)):
+      if (name != '.svn' and name != 'fixnum' and
+          not name.endswith('-experimental')):
+        pkgs_to_publish.append(os.path.join('pkg', name))
+
+  # Publish dart2js as an "unsupported" package.
+  pkgs_to_publish.append(
+    os.path.join('sdk', 'lib', '_internal', 'compiler'))
+
+  for pkg in pkgs_to_publish: 
+    print "Publishing " + pkg
+    subprocess.call(['python', 'tools/publish_pkg.py', pkg])
+
+if __name__ == '__main__':
+  sys.exit(Main(sys.argv))
diff --git a/tools/test-runtime.dart b/tools/test-runtime.dart
index a959f23..036c861 100755
--- a/tools/test-runtime.dart
+++ b/tools/test-runtime.dart
@@ -102,9 +102,12 @@
     if (runningBrowserTests) startHttpServer('127.0.0.1', 9876);
   }
 
+  var maxBrowserProcesses = maxProcesses;
+
   // Start process queue.
   new ProcessQueue(
       maxProcesses,
+      maxBrowserProcesses,
       progressIndicator,
       startTime,
       printTiming,
diff --git a/tools/test.dart b/tools/test.dart
index 3077ac6..12cff10 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -126,7 +126,14 @@
   }
 
   var testSuites = new List<TestSuite>();
+  var maxBrowserProcesses = maxProcesses;
   for (var conf in configurations) {
+    // There should not be more than one InternetExplorerDriver instance
+    // running at a time. For details, see
+    // http://code.google.com/p/selenium/wiki/InternetExplorerDriver.
+    if (conf['runtime'].startsWith('ie')) {
+      maxBrowserProcesses = 1;
+    }
     TestingServerRunner.setPackageRootDir(conf);
     for (String key in selectors.keys) {
       if (key == 'co19') {
@@ -158,6 +165,7 @@
 
   // Start process queue.
   new ProcessQueue(maxProcesses,
+                   maxBrowserProcesses,
                    progressIndicator,
                    startTime,
                    printTiming,
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index dcc37a6..84a5b77 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -27,6 +27,7 @@
       defaultsTo: 'ia32');
   parser.addFlag('help', abbr: 'h', negatable: false,
       help: 'Print this usage information.');
+  parser.addOption('package-root', help: 'The package root to use.');
   var args = parser.parse(new Options().arguments);
   if (args['help']) {
     print(parser.getUsage());
@@ -39,10 +40,7 @@
         .join(new Path('../../test.dart'))
         .canonicalize()
         .toNativePath();
-    TestingServerRunner.setPackageRootDir({'mode': args['mode'],
-        'arch': args['arch'], 'system': Platform.operatingSystem,
-        'build_directory': ''});
-
+    TestingServerRunner._packageRootDir = new Path(args['package-root']);
     TestingServerRunner.startHttpServer('127.0.0.1',
         port: int.parse(args['port']));
     print('Server listening on port '
@@ -125,7 +123,6 @@
           }
         }
       });
-
     };
 
     // Echos back the contents of the request as the response data.
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 7a45a41..3de6e2f 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -208,7 +208,8 @@
           'http_server.dart -m ${test.configuration["mode"]} '
           '-a ${test.configuration["arch"]} '
           '-p ${http_server.TestingServerRunner.serverList[0].port} '
-          '-c ${http_server.TestingServerRunner.serverList[1].port}');
+          '-c ${http_server.TestingServerRunner.serverList[1].port} '
+          '--package-root=${http_server.TestingServerRunner.packageRootDir}');
     }
     for (Command c in test.commands) {
       output.add('');
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index a3e72c9..356b664 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -27,6 +27,8 @@
 const int NO_TIMEOUT = 0;
 const int SLOW_TIMEOUT_MULTIPLIER = 4;
 
+const int CRASHING_BROWSER_EXITCODE = -10;
+
 typedef void TestCaseEvent(TestCase testCase);
 typedef void ExitCodeEvent(int exitCode);
 typedef void EnqueueMoreWork(ProcessQueue queue);
@@ -566,6 +568,11 @@
       if (exitCode == 3) {
         return !timedOut;
       }
+      // TODO(ricow): Remove this dirty hack ones we have a selenium
+      // replacement.
+      if (exitCode == CRASHING_BROWSER_EXITCODE) {
+        return !timedOut;
+      }
       // If a program receives an uncaught system exception, the program
       // terminates with the exception code as exit code.
       // The 0x3FFFFF00 mask here tries to determine if an exception indicates
@@ -925,124 +932,69 @@
  * be garbage collected as soon as it is done.
  */
 class RunningProcess {
-  ProcessQueue processQueue;
-  io.Process process;
   TestCase testCase;
+  Command command;
   bool timedOut = false;
   Date startTime;
   Timer timeoutTimer;
-  List<int> stdout;
-  List<int> stderr;
-  List<String> notifications;
-  bool compilationSkipped;
-  bool allowRetries;
+  List<int> stdout = <int>[];
+  List<int> stderr = <int>[];
+  bool compilationSkipped = false;
+  Completer<CommandOutput> completer;
 
-  /** Which command of [testCase.commands] is currently being executed. */
-  int currentStep;
+  RunningProcess(TestCase this.testCase, Command this.command);
 
-  RunningProcess(TestCase this.testCase,
-      [this.allowRetries = false, this.processQueue]);
+  Future<CommandOutput> start() {
+    Expect.isFalse(testCase.expectedOutcomes.contains(SKIP));
 
-  /**
-   * Called when all commands are executed.
-   */
-  void testComplete(CommandOutput lastCommandOutput) {
-    var command = lastCommandOutput.command;
+    completer = new Completer<CommandOutput>();
+    startTime = new Date.now();
+    _runCommand();
+    return completer.future;
+  }
 
+  void _runCommand() {
+    command.outputIsUpToDate.then((bool isUpToDate) {
+      if (isUpToDate) {
+        compilationSkipped = true;
+        _commandComplete(0);
+      } else {
+        var processOptions = _createProcessOptions();
+        Future processFuture = io.Process.start(command.executable,
+                                                command.arguments,
+                                                processOptions);
+        processFuture.then((io.Process process) {
+          void timeoutHandler(_) {
+            timedOut = true;
+            if (process != null) {
+              process.kill();
+            }
+          }
+          process.onExit = _commandComplete;
+          _drainStream(process.stdout, stdout);
+          _drainStream(process.stderr, stderr);
+          timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
+        }).catchError((e) {
+          print("Process error:");
+          print("  Command: $command");
+          print("  Error: $e");
+          _commandComplete(-1);
+          return true;
+        });
+      }
+    });
+  }
+
+  void _commandComplete(int exitCode) {
     if (timeoutTimer != null) {
       timeoutTimer.cancel();
     }
-    if (lastCommandOutput.unexpectedOutput
-        && testCase.configuration['verbose'] != null
-        && testCase.configuration['verbose']) {
-      print(testCase.displayName);
-
-      print(decodeUtf8(lastCommandOutput.stderr));
-      if (!lastCommandOutput.command.isPixelTest) {
-        print(decodeUtf8(lastCommandOutput.stdout));
-      } else {
-        print("DRT pixel test failed! stdout is not printed because it "
-              "contains binary data!");
-      }
-      print('');
-      if (notifications.length > 0) {
-        print("Notifications:");
-        for (var line in notifications) {
-          print(notifications);
-        }
-        print('');
-      }
-    }
-    if (allowRetries && testCase.usesWebDriver
-        && lastCommandOutput.unexpectedOutput
-        && (testCase as BrowserTestCase).numRetries > 0) {
-      // Selenium tests can be flaky. Try rerunning.
-      lastCommandOutput.requestRetry = true;
-    }
-    if (lastCommandOutput.requestRetry) {
-      lastCommandOutput.requestRetry = false;
-      this.timedOut = false;
-      (testCase as BrowserTestCase).numRetries--;
-      print("Potential flake. Re-running ${testCase.displayName} "
-          "(${(testCase as BrowserTestCase).numRetries} attempt(s) remains)");
-      // When retrying we need to reset the timeout as well.
-      // Otherwise there will be no timeout handling for the retry.
-      timeoutTimer = null;
-      this.start();
-    } else {
-      testCase.completed();
-    }
+    var commandOutput = _createCommandOutput(command, exitCode);
+    completer.complete(commandOutput);
   }
 
-  /**
-   * Process exit handler called at the end of every command. It internally
-   * treats all but the last command as compilation steps. The last command is
-   * the actual test and its output is analyzed in [testComplete].
-   */
-  void commandComplete(Command command, int exitCode) {
-    process = null;
-    int totalSteps = testCase.commands.length;
-    String suffix =' (step $currentStep of $totalSteps)';
-    if (timedOut) {
-      // Non-webdriver test timed out before it could complete. Webdriver tests
-      // run their own timeouts by timing from the launch of the browser (which
-      // could be delayed).
-      testComplete(createCommandOutput(command, 0, true));
-    } else if (currentStep == totalSteps) {
-      // Done with all test commands.
-      testComplete(createCommandOutput(command, exitCode, false));
-    } else if (exitCode != 0) {
-      // One of the steps failed.
-      notifications.add('test.dart: Compilation failed$suffix, '
-                        'exit code $exitCode\n');
-      testComplete(createCommandOutput(command, exitCode, true));
-    } else {
-      createCommandOutput(command, exitCode, true);
-      // One compilation step successfully completed, move on to the
-      // next step.
-      notifications.add('test.dart: Compilation finished $suffix\n\n');
-      if (currentStep == totalSteps - 1 && testCase.usesWebDriver &&
-          !testCase.configuration['noBatch']) {
-        // Note: processQueue will always be non-null for runtime == ie9, ie10,
-        // ff, safari, chrome, opera. (It is only null for runtime == vm)
-        // This RunningProcess object is done, and hands over control to
-        // BatchRunner.startTest(), which handles reporting, etc.
-        if (timeoutTimer != null) {
-          timeoutTimer.cancel();
-        }
-        processQueue._getBatchRunner(testCase).startTest(testCase);
-      } else {
-        runCommand(testCase.commands[currentStep++], commandComplete);
-      }
-    }
-  }
-
-  /**
-   * Called for all executed commands.
-   */
-  CommandOutput createCommandOutput(Command command,
-                                    int exitCode,
-                                    bool incomplete) {
+  CommandOutput _createCommandOutput(Command command, int exitCode) {
+    var incomplete = command != testCase.commands.last;
     var commandOutput = new CommandOutput.fromCase(
         testCase,
         command,
@@ -1053,18 +1005,10 @@
         stderr,
         new Date.now().difference(startTime),
         compilationSkipped);
-    resetLocalOutputInformation();
     return commandOutput;
   }
 
-  void resetLocalOutputInformation() {
-    stdout = new List<int>();
-    stderr = new List<int>();
-    notifications = new List<String>();
-    compilationSkipped = false;
-  }
-
-  void drainStream(io.InputStream source, List<int> destination) {
+  void _drainStream(io.InputStream source, List<int> destination) {
     void onDataHandler () {
       if (source.closed) {
         return;  // TODO(whesse): Remove when bug is fixed.
@@ -1079,77 +1023,14 @@
     source.onClosed = onDataHandler;
   }
 
-  void start() {
-    Expect.isFalse(testCase.expectedOutcomes.contains(SKIP));
-    resetLocalOutputInformation();
-    currentStep = 0;
-    startTime = new Date.now();
-    runCommand(testCase.commands[currentStep++], commandComplete);
-  }
-
-  void runCommand(Command command, void commandCompleteHandler(Command, int)) {
-    void processExitHandler(int returnCode) {
-      commandCompleteHandler(command, returnCode);
-    }
-
-    command.outputIsUpToDate.then((bool isUpToDate) {
-      if (isUpToDate) {
-        notifications.add("Skipped compilation because the old output is "
-                          "still up to date!");
-        compilationSkipped = true;
-        commandComplete(command, 0);
-      } else {
-        io.ProcessOptions options = new io.ProcessOptions();
-        if (command.environment != null) {
-          options.environment =
-              new Map<String, String>.from(command.environment);
-        } else {
-          options.environment =
-              new Map<String, String>.from(io.Platform.environment);
-        }
-
-        options.environment['DART_CONFIGURATION'] =
-            TestUtils.configurationDir(testCase.configuration);
-        Future processFuture = io.Process.start(command.executable,
-                                             command.arguments,
-                                             options);
-        processFuture.then((io.Process p) {
-          process = p;
-          process.onExit = processExitHandler;
-          drainStream(process.stdout, stdout);
-          drainStream(process.stderr, stderr);
-          if (timeoutTimer == null) {
-            // Create one timeout timer when starting test case, remove it at
-            // the end.
-            timeoutTimer = new Timer(1000 * testCase.timeout, timeoutHandler);
-          }
-          // If the timeout fired in between two commands, kill the just
-          // started process immediately.
-          if (timedOut) safeKill(process);
-        }).catchError((e) {
-          print("Process error:");
-          print("  Command: $command");
-          print("  Error: $e");
-          testComplete(createCommandOutput(command, -1, false));
-          return true;
-        });
-      }
-    });
-  }
-
-  void timeoutHandler(Timer unusedTimer) {
-    timedOut = true;
-    safeKill(process);
-  }
-
-  void safeKill(io.Process p) {
-    if (p != null) {
-      try {
-        p.kill();
-      } on io.ProcessException {
-        // Hopefully, this means that the process died on its own.
-      }
-    }
+  io.ProcessOptions _createProcessOptions() {
+    var baseEnvironment = command.environment != null ?
+        command.environment : io.Platform.environment;
+    io.ProcessOptions options = new io.ProcessOptions();
+    options.environment = new Map<String, String>.from(baseEnvironment);
+    options.environment['DART_CONFIGURATION'] =
+        TestUtils.configurationDir(testCase.configuration);
+    return options;
   }
 }
 
@@ -1280,7 +1161,7 @@
 
     var outcome = _status.split(" ")[2];
     var exitCode = 0;
-    if (outcome == "CRASH") exitCode = -10;
+    if (outcome == "CRASH") exitCode = CRASHING_BROWSER_EXITCODE;
     if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1;
     new CommandOutput.fromCase(_currentTest,
                                _command,
@@ -1434,6 +1315,8 @@
 class ProcessQueue {
   int _numProcesses = 0;
   int _maxProcesses;
+  int _numBrowserProcesses = 0;
+  int _maxBrowserProcesses;
   bool _allTestsWereEnqueued = false;
 
   /** The number of tests we allow to actually fail before we stop retrying. */
@@ -1470,7 +1353,8 @@
   /** True if we find that there is already a selenium jar running. */
   bool _seleniumAlreadyRunning = false;
 
-  ProcessQueue(int this._maxProcesses,
+  ProcessQueue(this._maxProcesses,
+               this._maxBrowserProcesses,
                String progress,
                Date startTime,
                bool printTiming,
@@ -1707,7 +1591,7 @@
         // The test is not yet ready to run. Put the test back in
         // the queue.  Avoid spin-polling by using a timeout.
         _tests.add(test);
-        new Timer(100, (timer) {_tryRunTest();});  // Don't lose a process.
+        new Timer(100, (_) => _tryRunTest());  // Don't lose a process.
         return;
       }
       if (_verbose) {
@@ -1715,11 +1599,13 @@
         if (test is BrowserTestCase) {
           // Additional command for rerunning the steps locally after the fact.
           print('$i. ${TestUtils.dartTestExecutable.toNativePath()} '
-              '${TestUtils.dartDir().toNativePath()}/tools/testing/dart/'
-              'http_server.dart -m ${test.configuration["mode"]} '
-              '-a ${test.configuration["arch"]} '
-              '-p ${http_server.TestingServerRunner.serverList[0].port} '
-              '-c ${http_server.TestingServerRunner.serverList[1].port}');
+                '${TestUtils.dartDir().toNativePath()}/tools/testing/dart/'
+                'http_server.dart -m ${test.configuration["mode"]} '
+                '-a ${test.configuration["arch"]} '
+                '-p ${http_server.TestingServerRunner.serverList[0].port} '
+                '-c ${http_server.TestingServerRunner.serverList[1].port} '
+                '--package-root='
+                '${http_server.TestingServerRunner.packageRootDir}');
           i++;
         }
         for (Command command in test.commands) {
@@ -1727,23 +1613,40 @@
           i++;
         }
       }
-      _progress.start(test);
-      TestCaseEvent oldCallback = test.completedHandler;
-      void wrapper(TestCase test_arg) {
-        _numProcesses--;
-        _progress.done(test_arg);
-        if (test_arg is BrowserTestCase) test_arg.notifyObservers();
-        _tryRunTest();
-        oldCallback(test_arg);
-      };
-      test.completedHandler = wrapper;
 
-      if ((test.configuration['compiler'] == 'dartc' &&
-           test.displayName != 'dartc/junit_tests') ||
-          (test.commands.length == 1 && test.usesWebDriver &&
-           !test.configuration['noBatch'])) {
-        // Dartc and browser test cases that do not require a precompilation
-        // step, start with the batch runner right away.
+      var isLastCommand =
+          ((test.commands.length-1) == test.commandOutputs.length);
+      var isBrowserCommand = isLastCommand && (test is BrowserTestCase);
+      if (isBrowserCommand && _numBrowserProcesses == _maxBrowserProcesses) {
+        // If there is no free browser runner, put it back into the queue.
+        _tests.add(test);
+        new Timer(100, (_) => _tryRunTest());  // Don't lose a process.
+        return;
+      }
+
+      _progress.start(test);
+
+      // Dartc and browser test commands can be run by a [BatchRunnerProcess]
+      var nextCommandIndex = test.commandOutputs.keys.length;
+      var numberOfCommands = test.commands.length;
+      var useBatchRunnerForDartc = test.configuration['compiler'] == 'dartc' &&
+                                   test.displayName != 'dartc/junit_tests';
+      var isWebdriverCommand = nextCommandIndex == (numberOfCommands - 1) &&
+                               test.usesWebDriver &&
+                               !test.configuration['noBatch'];
+      if (useBatchRunnerForDartc || isWebdriverCommand) {
+        TestCaseEvent oldCallback = test.completedHandler;
+        void testCompleted(TestCase test_arg) {
+          _numProcesses--;
+          if (isBrowserCommand) {
+            _numBrowserProcesses--;
+          }
+          _progress.done(test_arg);
+          if (test_arg is BrowserTestCase) test_arg.notifyObservers();
+          oldCallback(test_arg);
+          _tryRunTest();
+        };
+        test.completedHandler = testCompleted;
         _getBatchRunner(test).startTest(test);
       } else {
         // Once we've actually failed a test, technically, we wouldn't need to
@@ -1754,9 +1657,104 @@
         // tests that appear to be broken but were actually just flakes that
         // didn't get retried because there had already been one failure.
         bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests;
-        new RunningProcess(test, allowRetry, this).start();
+        runNextCommandWithRetries(test, allowRetry).then((TestCase testCase) {
+          _numProcesses--;
+          if (isBrowserCommand) {
+            _numBrowserProcesses--;
+          }
+          if (isTestCaseFinished(testCase)) {
+            testCase.completed();
+            _progress.done(testCase);
+            if (testCase is BrowserTestCase) testCase.notifyObservers();
+          } else {
+            _tests.addFirst(testCase);
+          }
+          _tryRunTest();
+        });
       }
+
       _numProcesses++;
+      if (isBrowserCommand) {
+        _numBrowserProcesses++;
+      }
     }
   }
+
+  bool isTestCaseFinished(TestCase testCase) {
+    var numberOfCommandOutputs = testCase.commandOutputs.keys.length;
+    var numberOfCommands = testCase.commands.length;
+
+    var lastCommandCompleted = (numberOfCommandOutputs == numberOfCommands);
+    var lastCommandOutput = testCase.lastCommandOutput;
+    var lastCommand = lastCommandOutput.command;
+    var timedOut = lastCommandOutput.hasTimedOut;
+    var nonZeroExitCode = lastCommandOutput.exitCode != 0;
+    // NOTE: If this was the last command or there was unexpected output
+    // we're done with the test.
+    // Otherwise we need to enqueue it again into the test queue.
+    if (lastCommandCompleted || timedOut || nonZeroExitCode) {
+      var verbose = testCase.configuration['verbose'];
+      if (lastCommandOutput.unexpectedOutput && verbose != null && verbose) {
+        print(testCase.displayName);
+        print("stderr:");
+        print(decodeUtf8(lastCommandOutput.stderr));
+        if (!lastCommand.isPixelTest) {
+          print("stdout:");
+          print(decodeUtf8(lastCommandOutput.stdout));
+        } else {
+          print("");
+          print("DRT pixel test failed! stdout is not printed because it "
+                "contains binary data!");
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  Future runNextCommandWithRetries(TestCase testCase, bool allowRetry) {
+    var completer = new Completer();
+
+    var nextCommandIndex = testCase.commandOutputs.keys.length;
+    var numberOfCommands = testCase.commands.length;
+    Expect.isTrue(nextCommandIndex < numberOfCommands);
+    var command = testCase.commands[nextCommandIndex];
+    var isLastCommand = nextCommandIndex == (numberOfCommands - 1);
+
+    void runCommand() {
+      var runningProcess = new RunningProcess(testCase, command);
+      runningProcess.start().then((CommandOutput commandOutput) {
+        if (isLastCommand) {
+          // NOTE: We need to call commandOutput.unexpectedOutput here.
+          // Calling this getter may result in the side-effect, that
+          // commandOutput.requestRetry is set to true.
+          // (BrowserCommandOutputImpl._failedBecauseOfMissingXDisplay
+          // does that for example)
+          // TODO(ricow/kustermann): Issue 8206
+          var unexpectedOutput = commandOutput.unexpectedOutput;
+          if (allowRetry && testCase.usesWebDriver
+              && unexpectedOutput
+              && (testCase as BrowserTestCase).numRetries > 0) {
+            // Selenium tests can be flaky. Try rerunning.
+            commandOutput.requestRetry = true;
+          }
+        }
+        if (commandOutput.requestRetry) {
+          commandOutput.requestRetry = false;
+          (testCase as BrowserTestCase).numRetries--;
+          DebugLogger.warning("Rerunning Test: ${testCase.displayName} "
+                              "(${(testCase as BrowserTestCase).numRetries} "
+                              "attempt(s) remains) [cmd:$command]");
+          runCommand();
+        } else {
+          completer.complete(testCase);
+        }
+      });
+    }
+    runCommand();
+
+    return completer.future;
+  }
 }
+
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 9a1f7b9..349a8a6 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -970,13 +970,25 @@
         htmlPath = htmlPath.startsWith(basePath) ?
             htmlPath.substring(basePath.length) : htmlPath;
         String fullHtmlPath = htmlPath;
+        var searchStr = '?';
         if (!htmlPath.startsWith('http')) {
-          fullHtmlPath = 'http://127.0.0.1:${serverList[0].port}$htmlPath?'
-              'crossOriginPort=${serverList[1].port}';
+          // Note: If we run test.py with the "--list" option, no http servers
+          // will be started. Therefore serverList is an empty list in this
+          // case. So we use PORT/CROSS_ORIGIN_PORT instead of real ports.
+          var serverPort = "PORT";
+          var crossOriginPort = "CROSS_ORIGIN_PORT";
+          if (!configuration['list']) {
+            serverPort = serverList[0].port.toString();
+            crossOriginPort = serverList[1].port.toString();
+          }
+          fullHtmlPath = 'http://127.0.0.1:$serverPort$htmlPath${searchStr}'
+              'crossOriginPort=$crossOriginPort';
+          searchStr = '&';
         }
         if (info.optionsFromFile['isMultiHtmlTest']
             && subtestNames.length > 0) {
-          fullHtmlPath = '${fullHtmlPath}#${subtestNames[subtestIndex]}';
+          fullHtmlPath = '${fullHtmlPath}${searchStr}group='
+              '${subtestNames[subtestIndex]}';
         }
 
         if (TestUtils.usesWebDriver(runtime)) {
diff --git a/tools/testing/run_selenium.py b/tools/testing/run_selenium.py
index 18f7798..ba4cc6d 100755
--- a/tools/testing/run_selenium.py
+++ b/tools/testing/run_selenium.py
@@ -43,6 +43,7 @@
 import threading
 
 TIMEOUT_ERROR_MSG = 'FAIL (timeout)'
+CRASH_ERROR_MSG = 'CRASH'
 
 def correctness_test_done(source):
   """Checks if test has completed."""
@@ -84,12 +85,28 @@
   if refresh:
     browser.refresh()
   try:
+    def pythonTimeout():
+      # The builtin quit call for chrome will call close on the RemoteDriver
+      # which may hang. Explicitly call browser.service.stop()
+      if (type(browser) is selenium.webdriver.chrome.webdriver.WebDriver):
+        # Browser may be dead
+        try:
+          browser.service.stop()
+        except:
+          print("Trying to close browser that has already been closed")
+    # If the browser is crashing selenium may not time out.
+    # Explicitly catch this case with a python timer.
+    t = threading.Timer(timeout, pythonTimeout)
+    t.start()
     test_done = CONFIGURATIONS[mode]
     element = WebDriverWait(browser, float(timeout)).until(
         lambda driver: test_done(driver.page_source))
+    t.cancel()
     return browser.page_source
   except selenium.common.exceptions.TimeoutException:
     return TIMEOUT_ERROR_MSG
+  except:
+    return CRASH_ERROR_MSG
 
 def run_test_in_browser_selenium_rc(sel, html_out, timeout, mode, refresh):
   """ Run the desired test in the browser using Selenium 1.0 syntax, and wait
@@ -226,6 +243,7 @@
   if (type(browser) is not selenium.webdriver.chrome.webdriver.WebDriver and
       type(browser) is not selenium.webdriver.ie.webdriver.WebDriver):
     browser.close()
+
   browser.quit()
 
 def report_results(mode, source, browser):
@@ -321,6 +339,11 @@
           print '>>> TEST PASS'
         elif source == TIMEOUT_ERROR_MSG:
           print '>>> TEST TIMEOUT'
+        elif source == CRASH_ERROR_MSG:
+          print '>>> TEST CRASH'
+          # The browser crashed, set the browser to None so that we will
+          # create a new instance on next iteration.
+          browser = None
         else:
           print '>>> TEST FAIL'
         sys.stdout.flush()
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index bba8136..bf6324f 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -63,7 +63,7 @@
         } else if (arg.startsWith('--out=')) {
           outputDir = new Path(arg.substring('--out='.length));
         } else if (arg.startsWith('--pkg=')) {
-          pkgPath = arg.substring('--pkg='.length);
+          pkgPath = new Path(arg.substring('--pkg='.length));
         } else {
           print('Unknown option: $arg');
           return;
diff --git a/utils/apidoc/apidoc.gyp b/utils/apidoc/apidoc.gyp
index 81a0330..b27cceb 100644
--- a/utils/apidoc/apidoc.gyp
+++ b/utils/apidoc/apidoc.gyp
@@ -53,6 +53,7 @@
             '--exclude-lib=oauth2',
             '--exclude-lib=path',
             '--exclude-lib=webdriver',
+            '--exclude-lib=yaml',
             '--include-lib=matcher',
             '--include-lib=mock',
           ],
diff --git a/utils/apidoc/html_diff.dart b/utils/apidoc/html_diff.dart
index e251745..c9aaf84 100644
--- a/utils/apidoc/html_diff.dart
+++ b/utils/apidoc/html_diff.dart
@@ -26,9 +26,9 @@
     'dart:svg',
     'dart:web_audio'];
 const List<String> HTML_DECLARED_NAMES = const [
-    'html',
-    'svg',
-    'web_audio'];
+    'dart.dom.html',
+    'dart.dom.svg',
+    'dart.dom.web_audio'];
 
 /**
  * A class for computing a many-to-many mapping between the types and
@@ -234,4 +234,4 @@
     }
     return new Set.from([name]);
   }
-}
\ No newline at end of file
+}
diff --git a/utils/compiler/compiler.gyp b/utils/compiler/compiler.gyp
index 4226483..784a75b 100644
--- a/utils/compiler/compiler.gyp
+++ b/utils/compiler/compiler.gyp
@@ -17,7 +17,6 @@
         {
           'action_name': 'generate_dart2js_snapshot',
           'inputs': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)',
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '../../sdk/lib/_internal/libraries.dart',
             '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../sdk/lib/_internal/compiler", "../../runtime/lib"])',
@@ -26,13 +25,13 @@
             '<(PRODUCT_DIR)/dart2js.snapshot',
           ],
           'action': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)gen_snapshot<(EXECUTABLE_SUFFIX)',
+            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             # Note: we don't store the snapshot in the location where
             # the dart2js script is looking for it.  The motivation
             # for that is to support an incremental development model
             # for dart2js compiler engineers.  However, we install the
             # snapshot in the proper location when building the SDK.
-            '--script_snapshot=<(PRODUCT_DIR)/dart2js.snapshot',
+            '--generate-script-snapshot=<(PRODUCT_DIR)/dart2js.snapshot',
             '../../sdk/lib/_internal/compiler/implementation/dart2js.dart',
           ],
         },
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 59bfbbf..536a3aa 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -87,20 +87,21 @@
 
   Future onRun() {
     var files;
-    return _filesToPublish.then((f) {
+    var packageBytesFuture = _filesToPublish.then((f) {
       files = f;
       log.fine('Archiving and publishing ${entrypoint.root}.');
       return createTarGz(files, baseDir: entrypoint.root.dir);
-    }).then(consumeInputStream).then((packageBytes) {
-      // Show the package contents so the user can verify they look OK.
-      var package = entrypoint.root;
-      log.message(
-          'Publishing "${package.name}" ${package.version}:\n'
-          '${generateTree(files)}');
+    }).then(consumeInputStream);
+
+    // Show the package contents so the user can verify they look OK.
+    var package = entrypoint.root;
+    log.message(
+        'Publishing "${package.name}" ${package.version}:\n'
+        '${generateTree(files)}');
 
       // Validate the package.
-      return _validate().then((_) => _publish(packageBytes));
-    });
+    return _validate(packageBytesFuture.then((bytes) => bytes.length))
+        .then((_) => packageBytesFuture).then(_publish);
   }
 
   /// The basenames of files that are automatically excluded from archives.
@@ -128,7 +129,7 @@
       }
 
       return listDir(rootDir, recursive: true).then((entries) {
-        return Future.wait(entries.mappedBy((entry) {
+        return Future.wait(entries.map((entry) {
           return fileExists(entry).then((isFile) {
             // Skip directories.
             if (!isFile) return null;
@@ -159,8 +160,8 @@
   }
 
   /// Validates the package. Throws an exception if it's invalid.
-  Future _validate() {
-    return Validator.runAll(entrypoint).then((pair) {
+  Future _validate(Future<int> packageSize) {
+    return Validator.runAll(entrypoint, packageSize).then((pair) {
       var errors = pair.first;
       var warnings = pair.last;
 
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index 30bfeb1..d562997 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -130,7 +130,7 @@
   /// [packageVersions], and writes a [LockFile].
   Future _installDependencies(List<PackageId> packageVersions) {
     return cleanDir(path).then((_) {
-      return Future.wait(packageVersions.mappedBy((id) {
+      return Future.wait(packageVersions.map((id) {
         if (id.isRoot) return new Future.immediate(id);
         return install(id);
       }));
@@ -207,7 +207,7 @@
       return _linkSecondaryPackageDir(dir)
         .then((_) => _listDirWithoutPackages(dir))
         .then((files) {
-        return Future.wait(files.mappedBy((file) {
+        return Future.wait(files.map((file) {
           return dirExists(file).then((isDir) {
             if (!isDir) return;
             return _linkSecondaryPackageDir(file);
@@ -222,7 +222,7 @@
   /// files and `package` files.
   Future<List<String>> _listDirWithoutPackages(dir) {
     return listDir(dir).then((files) {
-      return Future.wait(files.mappedBy((file) {
+      return Future.wait(files.map((file) {
         if (basename(file) == 'packages') return new Future.immediate([]);
         return dirExists(file).then((isDir) {
           if (!isDir) return [];
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index 81a8057..b774bc0 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -39,7 +39,7 @@
     return httpClient.read(fullUrl).then((body) {
       var doc = json.parse(body);
       return doc['versions']
-          .mappedBy((version) => new Version.parse(version))
+          .map((version) => new Version.parse(version))
           .toList();
     }).catchError((ex) {
       _throwFriendlyError(ex, parsed.first, parsed.last);
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 79f0a06..8243a28 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -22,7 +22,7 @@
 /// [File] objects.
 String join(part1, [part2, part3, part4, part5, part6, part7, part8]) {
   var parts = [part1, part2, part3, part4, part5, part6, part7, part8]
-      .mappedBy((part) => part == null ? null : _getPath(part)).toList();
+      .map((part) => part == null ? null : _getPath(part)).toList();
 
   return path.join(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5],
       parts[6], parts[7]);
@@ -85,6 +85,16 @@
       });
 }
 
+/// Reads the contents of the binary file [file], which can either be a [String]
+/// or a [File].
+List<int> readBinaryFile(file) {
+  var path = _getPath(file);
+  log.io("Reading binary file $path.");
+  var contents = new File(path).readAsBytesSync();
+  log.io("Read ${contents.length} bytes from $path.");
+  return contents;
+}
+
 /// Creates [file] (which can either be a [String] or a [File]), and writes
 /// [contents] to it. Completes when the file is written and closed.
 ///
@@ -109,6 +119,20 @@
   });
 }
 
+/// Creates [file] (which can either be a [String] or a [File]), and writes
+/// [contents] to it.
+File writeBinaryFile(file, List<int> contents) {
+  var path = _getPath(file);
+  file = new File(path);
+
+  log.io("Writing ${contents.length} bytes to binary file $path.");
+  file.openSync(FileMode.WRITE)
+      ..writeListSync(contents, 0, contents.length)
+      ..closeSync();
+  log.fine("Wrote text file $path.");
+  return file;
+}
+
 /// Asynchronously deletes [file], which can be a [String] or a [File]. Returns
 /// a [Future] that completes when the deletion is done.
 Future<File> deleteFile(file) {
@@ -873,7 +897,7 @@
 
   if (baseDir == null) baseDir = path.current;
   baseDir = getFullPath(baseDir);
-  contents = contents.mappedBy((entry) {
+  contents = contents.map((entry) {
     entry = getFullPath(entry);
     if (!isBeneath(entry, baseDir)) {
       throw 'Entry $entry is not inside $baseDir.';
@@ -883,7 +907,7 @@
 
   if (Platform.operatingSystem != "windows") {
     var args = ["--create", "--gzip", "--directory", baseDir];
-    args.addAll(contents.mappedBy(_getPath));
+    args.addAll(contents.map(_getPath));
     // TODO(nweiz): It's possible that enough command-line arguments will make
     // the process choke, so at some point we should save the arguments to a
     // file and pass them in via --files-from for tar and -i@filename for 7zip.
@@ -903,7 +927,7 @@
     // Create the tar file.
     var tarFile = join(tempDir, "intermediate.tar");
     var args = ["a", "-w$baseDir", tarFile];
-    args.addAll(contents.mappedBy((entry) => '-i!"$entry"'));
+    args.addAll(contents.map((entry) => '-i!"$entry"'));
 
     // Note: This line of code gets munged by create_sdk.py to be the correct
     // relative path to 7zip in the SDK.
diff --git a/utils/pub/lock_file.dart b/utils/pub/lock_file.dart
index 1e97585..23e7099 100644
--- a/utils/pub/lock_file.dart
+++ b/utils/pub/lock_file.dart
@@ -9,7 +9,7 @@
 import 'source_registry.dart';
 import 'utils.dart';
 import 'version.dart';
-import 'yaml/yaml.dart';
+import '../../pkg/yaml/lib/yaml.dart';
 
 /// A parsed and validated `pubspec.lock` file.
 class LockFile {
@@ -26,7 +26,6 @@
     var packages = <String, PackageId>{};
 
     if (contents.trim() == '') return new LockFile.empty();
-
     var parsed = loadYaml(contents);
 
     if (parsed.containsKey('packages')) {
@@ -85,6 +84,9 @@
 
     // TODO(nweiz): Serialize using the YAML library once it supports
     // serialization. For now, we use JSON, since it's a subset of YAML anyway.
-    return json.stringify({'packages': packagesObj});
+    return '''
+        # Generated by pub. See: http://pub.dartlang.org/doc/glossary.html#lockfile
+         ${json.stringify({'packages': packagesObj})}
+        ''';
   }
 }
diff --git a/utils/pub/package.dart b/utils/pub/package.dart
index f62e2be..15fcb97 100644
--- a/utils/pub/package.dart
+++ b/utils/pub/package.dart
@@ -11,6 +11,8 @@
 import 'source_registry.dart';
 import 'version.dart';
 
+final _README_REGEXP = new RegExp(r"^README($|\.)", caseSensitive: false);
+
 /// A named, versioned, unit of code and resource reuse.
 class Package {
   /// Loads the package whose root directory is [packageDir]. [name] is the
@@ -58,6 +60,26 @@
   /// specified in the pubspec when this package depends on another.
   Collection<PackageRef> get dependencies => pubspec.dependencies;
 
+  /// Returns the path to the README file at the root of the entrypoint, or null
+  /// if no README file is found. If multiple READMEs are found, this uses the
+  /// same conventions as pub.dartlang.org for choosing the primary one: the
+  /// README with the fewest extensions that is lexically ordered first is
+  /// chosen.
+  Future<String> get readmePath {
+    return listDir(dir).then((entries) {
+      var readmes = entries.where((entry) => entry.contains(_README_REGEXP));
+      if (readmes.isEmpty) return;
+
+      return readmes.min((readme1, readme2) {
+        var extensions1 = ".".allMatches(readme1).length;
+        var extensions2 = ".".allMatches(readme2).length;
+        var comparison = extensions1.compareTo(extensions2);
+        if (comparison != 0) return comparison;
+        return readme1.compareTo(readme2);
+      });
+    });
+  }
+
   /// Constructs a package with the given pubspec. The package will have no
   /// directory associated with it.
   Package.inMemory(this.pubspec)
diff --git a/utils/pub/pubspec.dart b/utils/pub/pubspec.dart
index aaabdd1..11b840e 100644
--- a/utils/pub/pubspec.dart
+++ b/utils/pub/pubspec.dart
@@ -9,7 +9,7 @@
 import 'source_registry.dart';
 import 'utils.dart';
 import 'version.dart';
-import 'yaml/yaml.dart';
+import '../../pkg/yaml/lib/yaml.dart';
 
 /// The parsed and validated contents of a pubspec file.
 class Pubspec {
diff --git a/utils/pub/sdk.dart b/utils/pub/sdk.dart
index 0e47acd..98007b5 100644
--- a/utils/pub/sdk.dart
+++ b/utils/pub/sdk.dart
@@ -14,7 +14,7 @@
 /// Matches an Eclipse-style SDK version number. This is four dotted numbers
 /// (major, minor, patch, build) with an optional suffix attached to the build
 /// number.
-final _versionPattern = new RegExp(r'^(\d+)\.(\d+)\.(\d+)\.(\d+)(.*)$');
+final _versionPattern = new RegExp(r'^(\d+)\.(\d+)\.(\d+)\.(\d+.*)$');
 
 /// Gets the path to the root directory of the SDK.
 String get rootDirectory {
@@ -41,15 +41,15 @@
   var version = new File(revisionPath).readAsStringSync().trim();
 
   // Given a version file like: 0.1.2.0_r17495
-  // We create a semver like:   0.1.2+0._r17495
+  // We create a semver like:   0.1.2+0.r17495
   var match = _versionPattern.firstMatch(version);
   if (match == null) {
     throw new FormatException("The Dart SDK's 'version' file was not in a "
         "format pub could recognize. Found: $version");
   }
 
-  var build = match[4];
-  if (match[5].length > 0) build = '$build.${match[5]}';
+  // Semantic versions cannot use "_".
+  var build = match[4].replaceAll('_', '.');
 
   return new Version(
       int.parse(match[1]), int.parse(match[2]), int.parse(match[3]),
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 7710ac1..4311c09 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -118,6 +118,18 @@
       onError: (e) => completer.completeError(e.error, e.stackTrace));
 }
 
+/// Like [Iterable.where], but allows [test] to return [Future]s and uses the
+/// results of those [Future]s as the test.
+Future<Iterable> futureWhere(Iterable iter, test(value)) {
+  return Future.wait(iter.mappedBy((e) {
+    var result = test(e);
+    if (result is! Future) result = new Future.immediate(result);
+    return result.then((result) => new Pair(e, result));
+  }))
+      .then((pairs) => pairs.where((pair) => pair.last))
+      .then((pairs) => pairs.mappedBy((pair) => pair.first));
+}
+
 // TODO(nweiz): unify the following functions with the utility functions in
 // pkg/http.
 
@@ -162,7 +174,7 @@
     value = (value == null || value.isEmpty) ? null : encodeUriComponent(value);
     pairs.add([key, value]);
   });
-  return Strings.join(pairs.mappedBy((pair) {
+  return Strings.join(pairs.map((pair) {
     if (pair[1] == null) return pair[0];
     return "${pair[0]}=${pair[1]}";
   }), "&");
diff --git a/utils/pub/validator.dart b/utils/pub/validator.dart
index 5ec0f23..72f65d1 100644
--- a/utils/pub/validator.dart
+++ b/utils/pub/validator.dart
@@ -11,12 +11,15 @@
 import 'io.dart';
 import 'system_cache.dart';
 import 'utils.dart';
+import 'validator/compiled_dartdoc.dart';
 import 'validator/dependency.dart';
 import 'validator/directory.dart';
 import 'validator/lib.dart';
 import 'validator/license.dart';
 import 'validator/name.dart';
 import 'validator/pubspec_field.dart';
+import 'validator/size.dart';
+import 'validator/utf8_readme.dart';
 
 /// The base class for validators that check whether a package is fit for
 /// uploading. Each validator should override [errors], [warnings], or both to
@@ -42,23 +45,32 @@
   /// Run all validators on the [entrypoint] package and print their results.
   /// The future will complete with the error and warning messages,
   /// respectively.
+  ///
+  /// [packageSize], if passed, should complete to the size of the tarred
+  /// package, in bytes. This is used to validate that it's not too big to
+  /// upload to the server.
   static Future<Pair<List<String>, List<String>>> runAll(
-      Entrypoint entrypoint) {
+      Entrypoint entrypoint, [Future<int> packageSize]) {
     var validators = [
       new LibValidator(entrypoint),
       new LicenseValidator(entrypoint),
       new NameValidator(entrypoint),
       new PubspecFieldValidator(entrypoint),
       new DependencyValidator(entrypoint),
-      new DirectoryValidator(entrypoint)
+      new DirectoryValidator(entrypoint),
+      new CompiledDartdocValidator(entrypoint),
+      new Utf8ReadmeValidator(entrypoint)
     ];
+    if (packageSize != null) {
+      validators.add(new SizeValidator(entrypoint, packageSize));
+    }
 
-    return Future.wait(validators.mappedBy((validator) => validator.validate()))
+    return Future.wait(validators.map((validator) => validator.validate()))
       .then((_) {
       var errors =
-          flatten(validators.mappedBy((validator) => validator.errors));
+          flatten(validators.map((validator) => validator.errors));
       var warnings =
-          flatten(validators.mappedBy((validator) => validator.warnings));
+          flatten(validators.map((validator) => validator.warnings));
 
       if (!errors.isEmpty) {
         log.error("Missing requirements:");
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
new file mode 100644
index 0000000..c2c93f3
--- /dev/null
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library compiled_dartdoc_validator;
+
+import 'dart:async';
+
+import '../../../pkg/path/lib/path.dart' as path;
+
+import '../entrypoint.dart';
+import '../io.dart';
+import '../utils.dart';
+import '../validator.dart';
+
+/// Validates that a package doesn't contain compiled Dartdoc
+/// output.
+class CompiledDartdocValidator extends Validator {
+  CompiledDartdocValidator(Entrypoint entrypoint)
+    : super(entrypoint);
+
+  Future validate() {
+    return listDir(entrypoint.root.dir, recursive: true).then((entries) {
+      return futureWhere(entries, (entry) {
+        if (basename(entry) != "nav.json") return false;
+        var dir = dirname(entry);
+
+        // Look for tell-tale Dartdoc output files all in the same directory.
+        return Future.wait([
+          fileExists(entry),
+          fileExists(join(dir, "index.html")),
+          fileExists(join(dir, "styles.css")),
+          fileExists(join(dir, "dart-logo-small.png")),
+          fileExists(join(dir, "client-live-nav.js"))
+        ]).then((results) => results.every((val) => val));
+      }).then((files) {
+        for (var dartdocDir in files.mappedBy(dirname)) {
+          var relativePath = path.relative(dartdocDir);
+          warnings.add("Avoid putting generated documentation in "
+                  "$relativePath.\n"
+              "Generated documentation bloats the package with redundant "
+                  "data.");
+        }
+      });
+    });
+  }
+}
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
index 132bdd7..09a6c7e 100644
--- a/utils/pub/validator/directory.dart
+++ b/utils/pub/validator/directory.dart
@@ -19,7 +19,7 @@
 
   Future validate() {
     return listDir(entrypoint.root.dir).then((dirs) {
-      return Future.wait(dirs.mappedBy((dir) {
+      return Future.wait(dirs.map((dir) {
         return dirExists(dir).then((exists) {
           if (!exists) return;
 
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index e679847..faee7290 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -31,7 +31,7 @@
       }
 
       return listDir(libDir).then((files) {
-        files = files.mappedBy((file) => relativeTo(file, libDir)).toList();
+        files = files.map((file) => relativeTo(file, libDir)).toList();
         if (files.isEmpty) {
           errors.add('You must have a non-empty "lib" directory.\n'
               "Without that, users cannot import any code from your package.");
diff --git a/utils/pub/validator/license.dart b/utils/pub/validator/license.dart
index 25556f8..8c32548 100644
--- a/utils/pub/validator/license.dart
+++ b/utils/pub/validator/license.dart
@@ -20,7 +20,7 @@
     return listDir(entrypoint.root.dir).then((files) {
       var licenseLike = new RegExp(
           r"^([a-zA-Z0-9]+[-_])?(LICENSE|COPYING)(\..*)?$");
-      if (files.mappedBy(basename).any(licenseLike.hasMatch)) return;
+      if (files.map(basename).any(licenseLike.hasMatch)) return;
 
       errors.add(
           "You must have a COPYING or LICENSE file in the root directory.\n"
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index eb1bc85..7c4778c 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -52,7 +52,7 @@
       return listDir(libDir, recursive: true);
     }).then((files) {
       return files
-          .mappedBy((file) => relativeTo(file, dirname(libDir)))
+          .map((file) => relativeTo(file, dirname(libDir)))
           .where((file) => !splitPath(file).contains("src") &&
                            path.extension(file) == '.dart')
           .toList();
diff --git a/utils/pub/validator/size.dart b/utils/pub/validator/size.dart
new file mode 100644
index 0000000..8014b29
--- /dev/null
+++ b/utils/pub/validator/size.dart
@@ -0,0 +1,32 @@
+// 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 size_validator;
+
+import 'dart:async';
+import 'dart:math' as math;
+
+import '../entrypoint.dart';
+import '../validator.dart';
+
+/// The maximum size of the package to upload (10 MB).
+const _MAX_SIZE = 10 * 1024 * 1024;
+
+/// A validator that validates that a package isn't too big.
+class SizeValidator extends Validator {
+  final Future<int> packageSize;
+
+  SizeValidator(Entrypoint entrypoint, this.packageSize)
+    : super(entrypoint);
+
+  Future validate() {
+    return packageSize.then((size) {
+      if (size <= _MAX_SIZE) return;
+      var sizeInMb = (size / math.pow(2, 20)).toStringAsPrecision(4);
+      errors.add("Your package is $sizeInMb MB. Hosted packages must be "
+          "smaller than 10 MB.");
+    });
+  }
+}
+
diff --git a/utils/pub/validator/utf8_readme.dart b/utils/pub/validator/utf8_readme.dart
new file mode 100644
index 0000000..e586230
--- /dev/null
+++ b/utils/pub/validator/utf8_readme.dart
@@ -0,0 +1,39 @@
+// 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 utf8_readme_validator;
+
+import 'dart:async';
+import 'dart:utf';
+
+import '../../../pkg/path/lib/path.dart' as path;
+
+import '../entrypoint.dart';
+import '../io.dart';
+import '../utils.dart';
+import '../validator.dart';
+
+/// Validates that a package's README is valid utf-8.
+class Utf8ReadmeValidator extends Validator {
+  Utf8ReadmeValidator(Entrypoint entrypoint)
+    : super(entrypoint);
+
+  Future validate() {
+    return entrypoint.root.readmePath.then((readme) {
+      if (readme == null) return;
+      var bytes = readBinaryFile(readme);
+      try {
+        // The second and third arguments here are the default values. The
+        // fourth tells [decodeUtf8] to throw an ArgumentError if `bytes` isn't
+        // valid utf-8.
+        decodeUtf8(bytes, 0, null, null);
+      } on ArgumentError catch (_) {
+        warnings.add("$readme contains invalid UTF-8.\n"
+            "This will cause it to be displayed incorrectly on "
+                "pub.dartlang.org.");
+      }
+    });
+  }
+}
+
diff --git a/utils/pub/version.dart b/utils/pub/version.dart
index 18e15a5..06c14fd 100644
--- a/utils/pub/version.dart
+++ b/utils/pub/version.dart
@@ -192,7 +192,7 @@
   /// Splits a string of dot-delimited identifiers into their component parts.
   /// Identifiers that are numeric are converted to numbers.
   List _splitParts(String text) {
-    return text.split('.').mappedBy((part) {
+    return text.split('.').map((part) {
       try {
         return int.parse(part);
       } on FormatException catch (ex) {
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 21f8cad..a45af91 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -189,12 +189,12 @@
       }
     }
 
-    return dependency.dependers.mappedBy(getDependency).any((subdependency) =>
+    return dependency.dependers.map(getDependency).any((subdependency) =>
         tryUnlockDepender(subdependency, seen));
   }
 
   List<PackageId> buildResults() {
-    return _packages.values.where((dep) => dep.isDependedOn).mappedBy((dep) {
+    return _packages.values.where((dep) => dep.isDependedOn).map((dep) {
       var description = dep.description;
 
       // If the lockfile contains a fully-resolved description for the package,
@@ -507,7 +507,7 @@
   VersionConstraint get constraint {
     if (_refs.isEmpty) return null;
     return new VersionConstraint.intersection(
-        _refs.values.mappedBy((ref) => ref.constraint));
+        _refs.values.map((ref) => ref.constraint));
   }
 
   /// The source of this dependency's package.
diff --git a/utils/tests/archive/reader_test.dart b/utils/tests/archive/reader_test.dart
index 0feac52..e95d5dd 100644
--- a/utils/tests/archive/reader_test.dart
+++ b/utils/tests/archive/reader_test.dart
@@ -58,7 +58,7 @@
       .then((input) => input.readAll())
       .then((entries) {
       entries = entries
-          .mappedBy((entry) => [entry.pathname, entry.contents.trim()])
+          .map((entry) => [entry.pathname, entry.contents.trim()])
           .toList();
       expect(entries[0], orderedEquals(["filename1", "contents 1"]));
       expect(entries[1], orderedEquals(["filename2", "contents 2"]));
diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
index 1d4f7bf..71df35e 100644
--- a/utils/tests/pub/command_line_config.dart
+++ b/utils/tests/pub/command_line_config.dart
@@ -6,6 +6,7 @@
 
 import 'dart:io';
 
+import '../../../pkg/path/lib/path.dart' as path;
 import '../../../pkg/unittest/lib/unittest.dart';
 import '../../pub/utils.dart';
 
@@ -70,6 +71,8 @@
   void _printStackTrace(String stackTrace) {
     if (stackTrace == null || stackTrace == '') return;
 
+    print('');
+
     // Parse out each stack entry.
     var stack = [];
     for (var line in stackTrace.split('\n')) {
@@ -79,35 +82,8 @@
 
     if (stack.length == 0) return;
 
-    // Find the common prefixes of the paths.
-    var common = 0;
-    while (true) {
-      var matching = true;
-      var c;
-      for (var frame in stack) {
-        if (frame.isCore) continue;
-        if (c == null) c = frame.library[common];
-
-        if (frame.library.length <= common || frame.library[common] != c) {
-          matching = false;
-          break;
-        }
-      }
-
-      if (!matching) break;
-      common++;
-    }
-
-    // Remove them.
-    if (common > 0) {
-      for (var frame in stack) {
-        if (frame.isCore) continue;
-        frame.library = frame.library.substring(common);
-      }
-    }
-
     // Figure out the longest path so we know how much to pad.
-    int longest = stack.mappedBy((frame) => frame.location.length).max();
+    int longest = stack.map((frame) => frame.location.length).max();
 
     // Print out the stack trace nicely formatted.
     for (var frame in stack) {
@@ -132,13 +108,13 @@
   String _indent(String str) {
     // TODO(nweiz): Use this simpler code once issue 2980 is fixed.
     // return str.replaceAll(new RegExp("^", multiLine: true), "  ");
-    return Strings.join(str.split("\n").mappedBy((line) => "  $line"), "\n");
+    return Strings.join(str.split("\n").map((line) => "  $line"), "\n");
   }
 }
 
 class _StackFrame {
   static final fileRegExp = new RegExp(
-      r'#\d+\s+(.*) \((file:///.+):(\d+):(\d+)\)');
+      r'#\d+\s+(.*) \(file://(/.+):(\d+):(\d+)\)');
   static final coreRegExp = new RegExp(r'#\d+\s+(.*) \((.+):(\d+):(\d+)\)');
 
   /// If `true`, then this stack frame is for a library built into Dart and
@@ -172,7 +148,13 @@
       isCore = true;
     }
 
+    var library = match[2];
+    if (!isCore) {
+      // Make the library path relative to the entrypoint.
+      library = path.relative(library);
+    }
+
     var member = match[1].replaceAll("<anonymous closure>", _LAMBDA);
-    return new _StackFrame._(isCore, match[2], match[3], match[4], member);
+    return new _StackFrame._(isCore, library, match[3], match[4], member);
   }
 }
\ No newline at end of file
diff --git a/utils/tests/pub/curl_client_test.dart b/utils/tests/pub/curl_client_test.dart
index ba57e21..924e994 100644
--- a/utils/tests/pub/curl_client_test.dart
+++ b/utils/tests/pub/curl_client_test.dart
@@ -168,19 +168,6 @@
   }
 }
 
-// TODO(nweiz): remove this once it's built in to unittest (issue 7922).
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
-    const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
-  const _StateError() : super("StateError");
-  bool matches(item, MatchState matchState) => item is StateError;
-}
-
 /// A matcher for HttpExceptions.
 const isHttpException = const _HttpException();
 
diff --git a/utils/tests/pub/error_group_test.dart b/utils/tests/pub/error_group_test.dart
index 9d2d59e0..c2f10fe 100644
--- a/utils/tests/pub/error_group_test.dart
+++ b/utils/tests/pub/error_group_test.dart
@@ -451,16 +451,3 @@
     });
   });
 }
-
-// TODO(nweiz): remove this once it's built in to unittest (issue 7922).
-/// A matcher for StateErrors.
-const isStateError = const _StateError();
-
-/// A matcher for functions that throw StateError.
-const Matcher throwsStateError =
-    const Throws(isStateError);
-
-class _StateError extends TypeMatcher {
-  const _StateError() : super("StateError");
-  bool matches(item, MatchState matchState) => item is StateError;
-}
diff --git a/utils/tests/pub/lock_file_test.dart b/utils/tests/pub/lock_file_test.dart
index d1aeb00..eeef7bf 100644
--- a/utils/tests/pub/lock_file_test.dart
+++ b/utils/tests/pub/lock_file_test.dart
@@ -5,13 +5,13 @@
 library lock_file_test;
 
 import '../../../pkg/unittest/lib/unittest.dart';
+import '../../../pkg/yaml/lib/yaml.dart';
 import '../../pub/lock_file.dart';
 import '../../pub/package.dart';
 import '../../pub/source.dart';
 import '../../pub/source_registry.dart';
 import '../../pub/utils.dart';
 import '../../pub/version.dart';
-import '../../pub/yaml/yaml.dart';
 
 class MockSource extends Source {
   final String name = 'mock';
diff --git a/utils/tests/pub/pub.status b/utils/tests/pub/pub.status
index 09fcf6d..ab958ef 100644
--- a/utils/tests/pub/pub.status
+++ b/utils/tests/pub/pub.status
@@ -4,7 +4,7 @@
 
 pub_uploader_test: Pass, Fail # Issue 7905
 pub_lish_test: Pass, Fail # Issue 7905
-oauth2_test: Pass, Fail # Issue 7905, 7920
+oauth2_test: Pass, Fail, Timeout # Issue 7905, 7920
 curl_client_test: Pass, Fail # Issue 7920
 
 # Pub only runs on the VM, so just rule out all compilers.
diff --git a/utils/tests/pub/pub_test.dart b/utils/tests/pub/pub_test.dart
index 13426f1..6de4dbc 100644
--- a/utils/tests/pub/pub_test.dart
+++ b/utils/tests/pub/pub_test.dart
@@ -123,11 +123,31 @@
 
   });
 
-  integration('displays the current version', () {
-    dir(sdkPath, [
-      file('version', '0.1.2.3'),
-    ]).scheduleCreate();
+  group('version', () {
+    integration('displays the current version', () {
+      dir(sdkPath, [
+        file('version', '0.1.2.3'),
+      ]).scheduleCreate();
 
-    schedulePub(args: ['version'], output: VERSION_STRING);
+      schedulePub(args: ['version'], output: VERSION_STRING);
+    });
+
+    integration('parses a release-style version', () {
+      dir(sdkPath, [
+        file('version', '0.1.2.0_r17645'),
+      ]).scheduleCreate();
+
+      schedulePub(args: ['version'], output: "Pub 0.1.2+0.r17645\n");
+    });
+
+    integration('parses a dev-only style version', () {
+      // The "version" file generated on developer builds is a little funky and
+      // we need to make sure we don't choke on it.
+      dir(sdkPath, [
+        file('version', '0.1.2.0_r16279_bobross'),
+      ]).scheduleCreate();
+
+      schedulePub(args: ['version'], output: "Pub 0.1.2+0.r16279.bobross\n");
+    });
   });
 }
diff --git a/utils/tests/pub/real_version_test.dart b/utils/tests/pub/real_version_test.dart
index 1688fa7..b0329a6 100644
--- a/utils/tests/pub/real_version_test.dart
+++ b/utils/tests/pub/real_version_test.dart
@@ -25,7 +25,7 @@
   // Note that this test expects to be invoked from a Dart executable that is
   // in the built SDK's "bin" directory. Note also that this invokes pub from
   // the built SDK directory, and not the live pub code directly in the repo.
-  test('Pub can parse the real SDK "version" file', () {
+  test('parse the real SDK "version" file', () {
     // Get the path to the pub binary in the SDK.
     var dartPath = new Options().executable;
     var pubPath = path.join(path.dirname(dartPath), "pub");
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 2ef2689..27708ff 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -14,11 +14,13 @@
 import 'dart:json' as json;
 import 'dart:math';
 import 'dart:uri';
+import 'dart:utf';
 
+import '../../../pkg/http/lib/testing.dart';
 import '../../../pkg/oauth2/lib/oauth2.dart' as oauth2;
 import '../../../pkg/path/lib/path.dart' as path;
 import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/http/lib/testing.dart';
+import '../../../pkg/yaml/lib/yaml.dart';
 import '../../lib/file_system.dart' as fs;
 import '../../pub/entrypoint.dart';
 // TODO(rnystrom): Using "gitlib" as the prefix here is ugly, but "git" collides
@@ -33,7 +35,6 @@
 import '../../pub/system_cache.dart';
 import '../../pub/utils.dart';
 import '../../pub/validator.dart';
-import '../../pub/yaml/yaml.dart';
 import 'command_line_config.dart';
 
 /// This should be called at the top of a test file to set up an appropriate
@@ -49,6 +50,10 @@
 FileDescriptor file(Pattern name, String contents) =>
     new FileDescriptor(name, contents);
 
+/// Creates a new [FileDescriptor] with [name] and [contents].
+FileDescriptor binaryFile(Pattern name, List<int> contents) =>
+    new FileDescriptor.bytes(name, contents);
+
 /// Creates a new [DirectoryDescriptor] with [name] and [contents].
 DirectoryDescriptor dir(Pattern name, [List<Descriptor> contents]) =>
     new DirectoryDescriptor(name, contents);
@@ -190,7 +195,7 @@
           file('$name.json',
               json.stringify({'versions': versions})),
           dir(name, [
-            dir('versions', flatten(versions.mappedBy((version) {
+            dir('versions', flatten(versions.map((version) {
               return [
                 file('$version.yaml', _servedPackages[name][version]),
                 tar('$version.tar.gz', [
@@ -462,42 +467,42 @@
 /// operations which will be run asynchronously.
 void integration(String description, void body()) {
   test(description, () {
+    // Schedule the test.
     body();
-    _run();
-  });
-}
 
-/// Runs all the scheduled events for a test case. This should only be called
-/// once per test case.
-void _run() {
-  var createdSandboxDir;
-  var asyncDone = expectAsync0(() {});
-
-  Future cleanup() {
-    return _runScheduled(createdSandboxDir, _scheduledCleanup).then((_) {
-      _scheduled = null;
-      _scheduledCleanup = null;
-      _scheduledOnException = null;
-      if (createdSandboxDir != null) return deleteDir(createdSandboxDir);
-    });
-  }
-
-  timeout(_setUpSandbox().then((sandboxDir) {
-    createdSandboxDir = sandboxDir;
-    return _runScheduled(sandboxDir, _scheduled);
-  }).catchError((e) {
-    // If an error occurs during testing, delete the sandbox, throw the error so
-    // that the test framework sees it, then finally call asyncDone so that the
-    // test framework knows we're done doing asynchronous stuff.
-    return _runScheduled(createdSandboxDir, _scheduledOnException)
-        .then((_) => registerException(e.error, e.stackTrace)).catchError((e) {
-      print("Exception while cleaning up: ${e.error}");
-      print(e.stackTrace);
+    // Run all of the scheduled tasks. If an error occurs, it will propagate
+    // through the futures back up to here where we can hand it off to unittest.
+    var asyncDone = expectAsync0(() {});
+    var createdSandboxDir;
+    _setUpSandbox().then((sandboxDir) {
+      createdSandboxDir = sandboxDir;
+      return timeout(_runScheduled(sandboxDir, _scheduled),
+          _TIMEOUT, 'waiting for a test to complete');
+    }).catchError((e) {
+      return _runScheduled(createdSandboxDir, _scheduledOnException).then((_) {
+        // Rethrow the original error so it keeps propagating.
+        throw e;
+      });
+    }).whenComplete(() {
+      // Clean up after ourselves. Do this first before reporting back to
+      // unittest because it will advance to the next test immediately.
+      return _runScheduled(createdSandboxDir, _scheduledCleanup).then((_) {
+        _scheduled = null;
+        _scheduledCleanup = null;
+        _scheduledOnException = null;
+        if (createdSandboxDir != null) return deleteDir(createdSandboxDir);
+      });
+    }).then((_) {
+      // If we got here, the test completed successfully so tell unittest so.
+      asyncDone();
+    }).catchError((e) {
+      // If we got here, an error occurred. We will register it with unittest
+      // directly so that the error message isn't wrapped in any matcher stuff.
+      // We do this call last because it will cause unittest to *synchronously*
+      // advance to the next test and run it.
       registerException(e.error, e.stackTrace);
     });
-  }), _TIMEOUT, 'waiting for a test to complete')
-      .then((_) => cleanup())
-      .then((_) => asyncDone());
+  });
 }
 
 /// Get the path to the root "util/test/pub" directory containing the pub
@@ -514,8 +519,7 @@
 void schedulePub({List args, Pattern output, Pattern error,
     Future<Uri> tokenEndpoint, int exitCode: 0}) {
   _schedule((sandboxDir) {
-    return _doPub(runProcess, sandboxDir, args, tokenEndpoint)
-        .then((result) {
+    return _doPub(runProcess, sandboxDir, args, tokenEndpoint).then((result) {
       var failures = [];
 
       _validateOutput(failures, 'stdout', output, result.stdout);
@@ -530,7 +534,7 @@
         if (error == null) {
           // If we aren't validating the error, still show it on failure.
           failures.add('Pub stderr:');
-          failures.addAll(result.stderr.mappedBy((line) => '| $line'));
+          failures.addAll(result.stderr.map((line) => '| $line'));
         }
 
         throw new ExpectException(Strings.join(failures, '\n'));
@@ -702,7 +706,7 @@
     failures.add('Expected $pipe to match "${expected.pattern}" but got none.');
   } else {
     failures.add('Expected $pipe to match "${expected.pattern}" but got:');
-    failures.addAll(actual.mappedBy((line) => '| $line'));
+    failures.addAll(actual.map((line) => '| $line'));
   }
 }
 
@@ -747,7 +751,7 @@
   // If any lines mismatched, show the expected and actual.
   if (failed) {
     failures.add('Expected $pipe:');
-    failures.addAll(expected.mappedBy((line) => '| $line'));
+    failures.addAll(expected.map((line) => '| $line'));
     failures.add('Got:');
     failures.addAll(results);
   }
@@ -808,7 +812,9 @@
     if (name is String) {
       var path = join(dir, name);
       return exists(path).then((exists) {
-        if (!exists) Expect.fail('File $name in $dir not found.');
+        if (!exists) {
+          throw new ExpectException('File $name in $dir not found.');
+        }
         return validate(path);
       });
     }
@@ -824,7 +830,7 @@
     return listDir(dir).then((files) {
       var matches = files.where((file) => endsWithPattern(file, name)).toList();
       if (matches.isEmpty) {
-        Expect.fail('No files in $dir match pattern $name.');
+        throw new ExpectException('No files in $dir match pattern $name.');
       }
       if (matches.length == 1) return validate(matches[0]);
 
@@ -865,16 +871,20 @@
 /// tree before running a test, and for validating that the file system matches
 /// some expectations after running it.
 class FileDescriptor extends Descriptor {
-  /// The text contents of the file.
-  final String contents;
+  /// The contents of the file, in bytes.
+  final List<int> contents;
 
-  FileDescriptor(Pattern name, this.contents) : super(name);
+  String get textContents => new String.fromCharCodes(contents);
+
+  FileDescriptor.bytes(Pattern name, this.contents) : super(name);
+
+  FileDescriptor(Pattern name, String contents) :
+      this.bytes(name, encodeUtf8(contents));
 
   /// Creates the file within [dir]. Returns a [Future] that is completed after
   /// the creation is done.
-  Future<File> create(dir) {
-    return writeTextFile(join(dir, _stringName), contents);
-  }
+  Future<File> create(dir) => new Future.immediate(null).then((_) =>
+      writeBinaryFile(join(dir, _stringName), contents));
 
   /// Deletes the file within [dir]. Returns a [Future] that is completed after
   /// the deletion is done.
@@ -886,10 +896,11 @@
   Future validate(String path) {
     return _validateOneMatch(path, (file) {
       return readTextFile(file).then((text) {
-        if (text == contents) return null;
+        if (text == textContents) return null;
 
-        Expect.fail('File $file should contain:\n\n$contents\n\n'
-                    'but contained:\n\n$text');
+        throw new ExpectException(
+            'File $file should contain:\n\n$textContents\n\n'
+            'but contained:\n\n$text');
       });
     });
   }
@@ -902,7 +913,7 @@
     }
 
     var stream = new ListInputStream();
-    stream.write(contents.charCodes);
+    stream.write(contents);
     stream.markEndOfStream();
     return stream;
   }
@@ -928,7 +939,7 @@
 
       // Recursively create all of its children.
       final childFutures =
-          contents.mappedBy((child) => child.create(dir)).toList();
+          contents.map((child) => child.create(dir)).toList();
       // Only complete once all of the children have been created too.
       return Future.wait(childFutures).then((_) => dir);
     });
@@ -948,7 +959,7 @@
     return _validateOneMatch(path, (dir) {
       // Validate each of the items in this directory.
       final entryFutures =
-          contents.mappedBy((entry) => entry.validate(dir)).toList();
+          contents.map((entry) => entry.validate(dir)).toList();
 
       // If they are all valid, the directory is valid.
       return Future.wait(entryFutures).then((entries) => null);
@@ -1080,7 +1091,7 @@
     var tempDir;
     return createTempDir().then((_tempDir) {
       tempDir = _tempDir;
-      return Future.wait(contents.mappedBy((child) => child.create(tempDir)));
+      return Future.wait(contents.map((child) => child.create(tempDir)));
     }).then((createdContents) {
       return consumeInputStream(createTarGz(createdContents, baseDir: tempDir));
     }).then((bytes) {
@@ -1133,7 +1144,9 @@
 
   Future validate(String dir) {
     return exists(join(dir, name)).then((exists) {
-      if (exists) Expect.fail('File $name in $dir should not exist.');
+      if (exists) {
+        throw new ExpectException('File $name in $dir should not exist.');
+      }
     });
   }
 
@@ -1489,7 +1502,7 @@
   // Unroll nested futures.
   if (object is Future) return object.then(_awaitObject);
   if (object is Collection) {
-    return Future.wait(object.mappedBy(_awaitObject).toList());
+    return Future.wait(object.map(_awaitObject).toList());
   }
   if (object is! Map) return new Future.immediate(object);
 
diff --git a/utils/tests/pub/validator_test.dart b/utils/tests/pub/validator_test.dart
index 75b51ff..b9eb6b7 100644
--- a/utils/tests/pub/validator_test.dart
+++ b/utils/tests/pub/validator_test.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:io';
 import 'dart:json' as json;
+import 'dart:math' as math;
 
 import 'test_pub.dart';
 import '../../../pkg/unittest/lib/unittest.dart';
@@ -15,12 +16,15 @@
 import '../../pub/entrypoint.dart';
 import '../../pub/io.dart';
 import '../../pub/validator.dart';
+import '../../pub/validator/compiled_dartdoc.dart';
 import '../../pub/validator/dependency.dart';
 import '../../pub/validator/directory.dart';
 import '../../pub/validator/lib.dart';
 import '../../pub/validator/license.dart';
 import '../../pub/validator/name.dart';
 import '../../pub/validator/pubspec_field.dart';
+import '../../pub/validator/size.dart';
+import '../../pub/validator/utf8_readme.dart';
 
 void expectNoValidationError(ValidatorCreator fn) {
   expectLater(schedulePackageValidation(fn), pairOf(isEmpty, isEmpty));
@@ -34,6 +38,9 @@
   expectLater(schedulePackageValidation(fn), pairOf(isEmpty, isNot(isEmpty)));
 }
 
+Validator compiledDartdoc(Entrypoint entrypoint) =>
+  new CompiledDartdocValidator(entrypoint);
+
 Validator dependency(Entrypoint entrypoint) =>
   new DependencyValidator(entrypoint);
 
@@ -49,6 +56,14 @@
 Validator pubspecField(Entrypoint entrypoint) =>
   new PubspecFieldValidator(entrypoint);
 
+Function size(int size) {
+  return (entrypoint) =>
+      new SizeValidator(entrypoint, new Future.immediate(size));
+}
+
+Validator utf8Readme(Entrypoint entrypoint) =>
+  new Utf8ReadmeValidator(entrypoint);
+
 void scheduleNormalPackage() => normalPackage.scheduleCreate();
 
 main() {
@@ -125,6 +140,31 @@
       ]).scheduleCreate();
       expectNoValidationError(directory);
     });
+
+    integration('is <= 10 MB', () {
+      expectNoValidationError(size(100));
+      expectNoValidationError(size(10 * math.pow(2, 20)));
+    });
+
+    integration('has most but not all files from compiling dartdoc', () {
+      dir(appPath, [
+        dir("doc-out", [
+          file("nav.json", ""),
+          file("index.html", ""),
+          file("styles.css", ""),
+          file("dart-logo-small.png", "")
+        ])
+      ]).scheduleCreate();
+      expectNoValidationError(compiledDartdoc);
+    });
+
+    integration('has a non-primary readme with invalid utf-8', () {
+      dir(appPath, [
+        file("README", "Valid utf-8"),
+        binaryFile("README.invalid", [192])
+      ]).scheduleCreate();
+      expectNoValidationError(utf8Readme);
+    });
   });
 
   group('should consider a package invalid if it', () {
@@ -520,5 +560,30 @@
         });
       }
     });
+
+    integration('is more than 10 MB', () {
+      expectValidationError(size(10 * math.pow(2, 20) + 1));
+    });
+
+    test('contains compiled dartdoc', () {
+      dir(appPath, [
+        dir('doc-out', [
+          file('nav.json', ''),
+          file('index.html', ''),
+          file('styles.css', ''),
+          file('dart-logo-small.png', ''),
+          file('client-live-nav.js', '')
+        ])
+      ]).scheduleCreate();
+
+      expectValidationWarning(compiledDartdoc);
+    });
+
+    test('has a README with invalid utf-8', () {
+      dir(appPath, [
+        binaryFile("README", [192])
+      ]).scheduleCreate();
+      expectValidationWarning(utf8Readme);
+    });
   });
 }