Version 0.4.7.0 .

svn merge -r 21386:21520 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@21522 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/README.dart-sdk b/README.dart-sdk
index 9a967c0..8a5c750 100644
--- a/README.dart-sdk
+++ b/README.dart-sdk
@@ -7,14 +7,15 @@
 bin/             Binaries/scripts to compile, run, and manage Dart applications.
   dart           Dart virtual machine
   dart2js        Dart-to-JavaScript compiler
-  dart_analyzer  Dart static analyzer
+  dartanalyzer   Dart static analyzer
+  dart_analyzer  The older, deprecated Dart static analyzer
   dartdoc        Dart documentation generator
   pub            Pub, the Dart package manager
 
 lib/             Libraries that are shipped with the Dart runtime. More 
                  information is available at api.dartlang.org.
 
-pkg/             Additional packages that are shipped outside of the Dart 
+packages/        Additional packages that are shipped outside of the Dart 
                  runtime. More information is available at api.dartlang.org.
 
 version          The version number of the SDK (ex. 0.1.2.0_r1234).
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
index 2d614f39..f016f2a 100644
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
@@ -672,7 +672,7 @@
           analyzeLibrary(
               "class A {",
               "  void foo();",
-              "  noSuchMethod(InvocationMirror m) {}",
+              "  noSuchMethod(Invocation m) {}",
               "}",
               "main() {",
               "  new A();",
@@ -693,7 +693,7 @@
           analyzeLibrary(
               "class A {",
               "  void foo();",
-              "  noSuchMethod(InvocationMirror m) {}",
+              "  noSuchMethod(Invocation m) {}",
               "}",
               "main() {",
               "  new A();",
@@ -5354,7 +5354,7 @@
     String[] lines = {
         "// filler filler filler filler filler filler filler filler filler filler",
         "class A {",
-        "  noSuchMethod(InvocationMirror invocation) {}",
+        "  noSuchMethod(Invocation invocation) {}",
         "}",
         "class B extends A {}",
         "class C {}",
@@ -5396,7 +5396,7 @@
     String[] lines = {
         "// filler filler filler filler filler filler filler filler filler filler",
         "class A {",
-        "  noSuchMethod(InvocationMirror invocation) {}",
+        "  noSuchMethod(Invocation invocation) {}",
         "}",
         "class B extends A {}",
         "class C {}",
@@ -5436,7 +5436,7 @@
     String[] lines = {
         "// filler filler filler filler filler filler filler filler filler filler",
         "class A {",
-        "  noSuchMethod(InvocationMirror invocation) {}",
+        "  noSuchMethod(Invocation invocation) {}",
         "}",
         "class B extends A {}",
         "class C {}",
diff --git a/dart.gyp b/dart.gyp
index b4f7aa4..6eea60b 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -50,6 +50,7 @@
       'dependencies': [
         'runtime/dart-runtime.gyp:dart',
         'utils/compiler/compiler.gyp:dart2js',
+        'analyzer',
         'compiler',
       ],
       'actions': [
@@ -62,6 +63,7 @@
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot',
             '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer',
+            '<(PRODUCT_DIR)/dartanalyzer/dartanalyzer.jar',
           ],
           'outputs': [
             '<(PRODUCT_DIR)/dart-sdk/README',
diff --git a/pkg/analyzer_experimental/bin/analyzer.dart b/pkg/analyzer_experimental/bin/analyzer.dart
index cb730cd..f4806ac 100644
--- a/pkg/analyzer_experimental/bin/analyzer.dart
+++ b/pkg/analyzer_experimental/bin/analyzer.dart
@@ -38,7 +38,7 @@
 
   var options = new CommandLineOptions.parse(args);
   if (options == null) {
-    return new Future.immediate(new AnalysisResult.forFailure());
+    return new Future.value(new AnalysisResult.forFailure());
   }
 
   //TODO(pquitslund): call out to analyzer...
diff --git a/pkg/analyzer_experimental/lib/src/generated/element.dart b/pkg/analyzer_experimental/lib/src/generated/element.dart
index 3d7e2a4..e3e9d02 100644
--- a/pkg/analyzer_experimental/lib/src/generated/element.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/element.dart
@@ -2133,7 +2133,7 @@
     List<String> components = new List<String>();
     Element ancestor = element;
     while (ancestor != null) {
-      components.insertRange(0, 1, ((ancestor as ElementImpl)).identifier);
+      components.insert(0, ((ancestor as ElementImpl)).identifier);
       ancestor = ancestor.enclosingElement;
     }
     this._components = new List.from(components);
diff --git a/pkg/analyzer_experimental/lib/src/generated/java_core.dart b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
index 995fa42..d90e510 100644
--- a/pkg/analyzer_experimental/lib/src/generated/java_core.dart
+++ b/pkg/analyzer_experimental/lib/src/generated/java_core.dart
@@ -311,7 +311,7 @@
     elements.clear();
   }
 
-  void remove(Object element) {
+  bool remove(Object element) {
     return elements.remove(element);
   }
 
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index 25b0022..26b8d0f 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -164,7 +164,7 @@
 }
 
 /// Returns a [Future] that asynchronously completes to `null`.
-Future get async => new Future.immediate(null);
+Future get async => new Future.value();
 
 /// Returns a closed [Stream] with no elements.
 Stream get emptyStream => streamFromIterable([]);
@@ -218,8 +218,8 @@
 /// Configures [future] so that its result (success or exception) is passed on
 /// to [completer].
 void chainToCompleter(Future future, Completer completer) {
-  future.then((v) => completer.complete(v)).catchError((e) {
-    completer.completeError(e.error, e.stackTrace);
+  future.then((v) => completer.complete(v)).catchError((error) {
+    completer.completeError(error);
   });
 }
 
@@ -234,7 +234,7 @@
 Future forEachFuture(Iterable input, Future fn(element)) {
   var iterator = input.iterator;
   Future nextElement(_) {
-    if (!iterator.moveNext()) return new Future.immediate(null);
+    if (!iterator.moveNext()) return new Future.value();
     return fn(iterator.current).then(nextElement);
   }
   return nextElement(null);
diff --git a/pkg/http/test/mock_client_test.dart b/pkg/http/test/mock_client_test.dart
index f1f75bf..a77d965 100644
--- a/pkg/http/test/mock_client_test.dart
+++ b/pkg/http/test/mock_client_test.dart
@@ -19,7 +19,7 @@
 void main() {
   test('handles a request', () {
     var client = new MockClient((request) {
-      return new Future.immediate(new http.Response(
+      return new Future.value(new http.Response(
           json.stringify(request.bodyFields), 200,
           request: request, headers: {'content-type': 'application/json'}));
     });
@@ -57,7 +57,7 @@
 
   test('handles a request with no body', () {
     var client = new MockClient((request) {
-      return new Future.immediate(new http.Response('you did it', 200));
+      return new Future.value(new http.Response('you did it', 200));
     });
 
     expect(client.read("http://example.com/foo"),
diff --git a/pkg/http/test/multipart_test.dart b/pkg/http/test/multipart_test.dart
index e7ea1e5..288a445 100644
--- a/pkg/http/test/multipart_test.dart
+++ b/pkg/http/test/multipart_test.dart
@@ -213,7 +213,7 @@
     tearDown(() => tempDir.deleteSync(recursive: true));
 
     test('with a file from disk', () {
-      expect(new Future.of(() {
+      expect(new Future.sync(() {
         var filePath = path.join(tempDir.path, 'test-file');
         new File(filePath).writeAsStringSync('hello');
         return http.MultipartFile.fromPath('file', filePath);
diff --git a/pkg/http/test/request_test.dart b/pkg/http/test/request_test.dart
index e17589c..2e4c570 100644
--- a/pkg/http/test/request_test.dart
+++ b/pkg/http/test/request_test.dart
@@ -215,10 +215,10 @@
 
       var request = new http.Request('POST', serverUrl.resolve('/loop?1'))
         ..maxRedirects = 2;
-      var future = request.send().catchError((e) {
+      var future = request.send().catchError((error) {
         print("#maxRedirects test exception received");
-        expect(e.error, isRedirectLimitExceededException);
-        expect(e.error.redirects.length, equals(2));
+        expect(error, isRedirectLimitExceededException);
+        expect(error.redirects.length, equals(2));
       });
       expect(future.catchError((_) {}).then((_) {
         print("#maxRedirects test stopping server...");
diff --git a/pkg/http/test/safe_http_server.dart b/pkg/http/test/safe_http_server.dart
index 2b388dd..7019df1 100644
--- a/pkg/http/test/safe_http_server.dart
+++ b/pkg/http/test/safe_http_server.dart
@@ -42,23 +42,22 @@
   HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
 
   StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
-      {void onError(AsyncError error), void onDone(),
-      bool unsubscribeOnError: false}) {
+      {void onError(error), void onDone(),
+      bool cancelOnError: false}) {
     var subscription;
     subscription = super.listen((request) {
       onData(new _HttpRequestWrapper(request));
-    }, onError: (e) {
-      var error = e.error;
+    }, onError: (error) {
       // Ignore socket error 104, which is caused by a request being cancelled
       // before it writes any headers. There's no reason to care about such
       // requests.
       if (error is SocketIOException && error.osError.errorCode == 104) return;
       // Ignore any parsing errors, which come from malformed requests.
       if (error is HttpParserException) return;
-      // Manually handle unsubscribeOnError so the above (ignored) errors don't
+      // Manually handle cancelOnError so the above (ignored) errors don't
       // cause unsubscription.
-      if (unsubscribeOnError) subscription.cancel();
-      if (onError != null) onError(e);
+      if (cancelOnError) subscription.cancel();
+      if (onError != null) onError(error);
     }, onDone: onDone);
     return subscription;
   }
@@ -132,10 +131,8 @@
   Future<Socket> detachSocket() => _inner.detachSocket();
   HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
   void add(List<int> data) => _inner.add(data);
-  Future<HttpResponse> consume(Stream<List<int>> stream) =>
-    _inner.consume(stream);
-  Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
-    _inner.writeStream(stream);
+  Future<HttpResponse> addStream(Stream<List<int>> stream) =>
+    _inner.addStream(stream);
   Future close() => _inner.close();
   void write(Object obj) => _inner.write(obj);
   void writeAll(Iterable objects, [String separator = ""]) =>
diff --git a/pkg/intl/example/basic/messages_all.dart b/pkg/intl/example/basic/messages_all.dart
index e722f6c..78cb5f0 100644
--- a/pkg/intl/example/basic/messages_all.dart
+++ b/pkg/intl/example/basic/messages_all.dart
@@ -28,7 +28,7 @@
 initializeMessages(localeName) {
   initializeInternalMessageLookup(() => new CompositeMessageLookup());
   messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
-  return new Future.immediate(null);
+  return new Future.value();
 }
 
 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
diff --git a/pkg/intl/lib/date_symbol_data_local.dart b/pkg/intl/lib/date_symbol_data_local.dart
index 939bb3d..a8ce2b8 100644
--- a/pkg/intl/lib/date_symbol_data_local.dart
+++ b/pkg/intl/lib/date_symbol_data_local.dart
@@ -31,7 +31,7 @@
 Future initializeDateFormatting(String locale, String ignored) {
   initializeDateSymbols(dateTimeSymbolMap);
   initializeDatePatterns(dateTimePatternMap);
-  return new Future.immediate(null);
+  return new Future.value();
 }
 
 /**
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index 0961d38..26fb304 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -183,7 +183,7 @@
 initializeMessages(localeName) {
   initializeInternalMessageLookup(() => new CompositeMessageLookup());
   messageLookup.addLocale(localeName, _findGeneratedMessagesFor);
-  return new Future.immediate(null);
+  return new Future.value();
 }
 
 MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
diff --git a/pkg/intl/lib/intl_browser.dart b/pkg/intl/lib/intl_browser.dart
index 76e8d50..995b2c1 100644
--- a/pkg/intl/lib/intl_browser.dart
+++ b/pkg/intl/lib/intl_browser.dart
@@ -27,5 +27,5 @@
  */
 Future<String> findSystemLocale() {
   Intl.systemLocale = Intl.canonicalizedLocale(window.navigator.language);
-  return new Future.immediate(Intl.systemLocale);
+  return new Future.value(Intl.systemLocale);
 }
diff --git a/pkg/intl/lib/intl_standalone.dart b/pkg/intl/lib/intl_standalone.dart
index e40126f..fe70ccf 100644
--- a/pkg/intl/lib/intl_standalone.dart
+++ b/pkg/intl/lib/intl_standalone.dart
@@ -43,7 +43,7 @@
     return _getAppleDefaults();
   }
   // We can't find anything, don't set the system locale and return null.
-  return new Future.immediate(null);
+  return new Future.value();
 }
 
 /**
@@ -83,12 +83,12 @@
  * then don't set the variable and return a future that completes with null.
  */
 Future<String> _checkResult(ProcessResult result, RegExp regex) {
-  if (result.exitCode != 0) return new Future.immediate(null);
+  if (result.exitCode != 0) return new Future.value();
   var match = regex.firstMatch(result.stdout);
-  if (match == null) return new Future.immediate(null);
+  if (match == null) return new Future.value();
   var locale = match.group(1);
   _setLocale(locale);
-  return new Future.immediate(locale);
+  return new Future.value(locale);
 }
 
 /**
@@ -96,5 +96,5 @@
  */
 Future<String> _setLocale(aLocale) {
   Intl.systemLocale = Intl.canonicalizedLocale(aLocale);
-  return new Future.immediate(Intl.systemLocale);
+  return new Future.value(Intl.systemLocale);
 }
diff --git a/pkg/logging/lib/logging.dart b/pkg/logging/lib/logging.dart
index d2610b1..222ff1e 100644
--- a/pkg/logging/lib/logging.dart
+++ b/pkg/logging/lib/logging.dart
@@ -48,6 +48,9 @@
   /** Controller used to notify when log entries are added to this logger. */
   StreamController<LogRecord> _controller;
 
+  /** The broadcast stream associated with the controller. */
+  Stream _stream;
+
   /**
    * Singleton constructor. Calling `new Logger(name)` will return the same
    * actual instance whenever it is called with the same string name.
@@ -177,9 +180,10 @@
   Stream<LogRecord> _getStream() {
     if (hierarchicalLoggingEnabled || parent == null) {
       if (_controller == null) {
-        _controller = new StreamController<LogRecord>.broadcast();
+        _controller = new StreamController<LogRecord>();
+        _stream = _controller.stream.asBroadcastStream();
       }
-      return _controller.stream;
+      return _stream;
     } else {
       return root._getStream();
     }
diff --git a/pkg/oauth2/lib/src/client.dart b/pkg/oauth2/lib/src/client.dart
index 0d422af..ec8dda5 100644
--- a/pkg/oauth2/lib/src/client.dart
+++ b/pkg/oauth2/lib/src/client.dart
@@ -83,7 +83,7 @@
   /// the request if necessary.
   Future<http.StreamedResponse> send(http.BaseRequest request) {
     return async.then((_) {
-      if (!credentials.isExpired) return new Future.immediate(null);
+      if (!credentials.isExpired) return new Future.value();
       if (!credentials.canRefresh) throw new ExpirationException(credentials);
       return refreshCredentials();
     }).then((_) {
diff --git a/pkg/oauth2/test/authorization_code_grant_test.dart b/pkg/oauth2/test/authorization_code_grant_test.dart
index 85c055b..22be3cfa7 100644
--- a/pkg/oauth2/test/authorization_code_grant_test.dart
+++ b/pkg/oauth2/test/authorization_code_grant_test.dart
@@ -33,8 +33,8 @@
 }
 
 void expectFutureThrows(future, predicate) {
-  future.catchError(expectAsync1((AsyncError e) {
-    expect(predicate(e.error), isTrue);
+  future.catchError(expectAsync1((error) {
+    expect(predicate(error), isTrue);
   }));
 }
 
@@ -154,7 +154,7 @@
           'client_secret': 'secret'
         }));
 
-        return new Future.immediate(new http.Response(JSON.stringify({
+        return new Future.value(new http.Response(JSON.stringify({
           'access_token': 'access token',
           'token_type': 'bearer',
         }), 200, headers: {'content-type': 'application/json'}));
@@ -198,7 +198,7 @@
           'client_secret': 'secret'
         }));
 
-        return new Future.immediate(new http.Response(JSON.stringify({
+        return new Future.value(new http.Response(JSON.stringify({
           'access_token': 'access token',
           'token_type': 'bearer',
         }), 200, headers: {'content-type': 'application/json'}));
diff --git a/pkg/oauth2/test/client_test.dart b/pkg/oauth2/test/client_test.dart
index 7049122..bac0548 100644
--- a/pkg/oauth2/test/client_test.dart
+++ b/pkg/oauth2/test/client_test.dart
@@ -26,8 +26,8 @@
 }
 
 void expectFutureThrows(future, predicate) {
-  future.catchError(expectAsync1((AsyncError e) {
-    expect(predicate(e.error), isTrue);
+  future.catchError(expectAsync1((error) {
+    expect(predicate(error), isTrue);
   }));
 }
 
@@ -57,7 +57,7 @@
       httpClient.expectRequest((request) {
         expect(request.method, equals('POST'));
         expect(request.url.toString(), equals(tokenEndpoint.toString()));
-        return new Future.immediate(new http.Response(JSON.stringify({
+        return new Future.value(new http.Response(JSON.stringify({
           'access_token': 'new access token',
           'token_type': 'bearer'
         }), 200, headers: {'content-type': 'application/json'}));
@@ -69,7 +69,7 @@
         expect(request.headers['authorization'],
             equals('Bearer new access token'));
 
-        return new Future.immediate(new http.Response('good job', 200));
+        return new Future.value(new http.Response('good job', 200));
       });
 
       expect(client.read(requestUri).then((_) {
@@ -92,7 +92,7 @@
         expect(request.headers['authorization'],
             equals('Bearer access token'));
 
-        return new Future.immediate(new http.Response('good job', 200));
+        return new Future.value(new http.Response('good job', 200));
       });
 
       expect(client.read(requestUri), completion(equals('good job')));
@@ -107,7 +107,7 @@
       httpClient.expectRequest((request) {
         expect(request.method, equals('POST'));
         expect(request.url.toString(), equals(tokenEndpoint.toString()));
-        return new Future.immediate(new http.Response(JSON.stringify({
+        return new Future.value(new http.Response(JSON.stringify({
           'access_token': 'new access token',
           'token_type': 'bearer'
         }), 200, headers: {'content-type': 'application/json'}));
@@ -144,7 +144,7 @@
 
         var authenticate = 'Bearer error="invalid_token", error_description='
             '"Something is terribly wrong."';
-        return new Future.immediate(new http.Response('bad job', 401,
+        return new Future.value(new http.Response('bad job', 401,
                 headers: {'www-authenticate': authenticate}));
       });
 
@@ -163,7 +163,7 @@
         expect(request.headers['authorization'],
             equals('Bearer access token'));
 
-        return new Future.immediate(new http.Response('bad job', 401));
+        return new Future.value(new http.Response('bad job', 401));
       });
 
       expect(
@@ -184,7 +184,7 @@
 
         var authenticate = 'Bearer error="invalid_token", error_description='
           '"Something is terribly wrong.", ';
-        return new Future.immediate(new http.Response('bad job', 401,
+        return new Future.value(new http.Response('bad job', 401,
                 headers: {'www-authenticate': authenticate}));
       });
 
@@ -204,7 +204,7 @@
         expect(request.headers['authorization'],
             equals('Bearer access token'));
 
-        return new Future.immediate(new http.Response('bad job', 401,
+        return new Future.value(new http.Response('bad job', 401,
                 headers: {'www-authenticate': 'Digest'}));
       });
 
@@ -224,7 +224,7 @@
         expect(request.headers['authorization'],
             equals('Bearer access token'));
 
-        return new Future.immediate(new http.Response('bad job', 401,
+        return new Future.value(new http.Response('bad job', 401,
                 headers: {'www-authenticate': 'Bearer'}));
       });
 
diff --git a/pkg/oauth2/test/credentials_test.dart b/pkg/oauth2/test/credentials_test.dart
index 8e40a4a..652d394 100644
--- a/pkg/oauth2/test/credentials_test.dart
+++ b/pkg/oauth2/test/credentials_test.dart
@@ -46,8 +46,8 @@
         'access token', null, tokenEndpoint);
     expect(credentials.canRefresh, false);
     credentials.refresh('identifier', 'secret', httpClient: httpClient)
-        .catchError(expectAsync1((e) {
-          expect(e.error is StateError, isTrue);
+        .catchError(expectAsync1((error) {
+          expect(error is StateError, isTrue);
         }));
   });
 
@@ -55,8 +55,8 @@
     var credentials = new oauth2.Credentials('access token', 'refresh token');
     expect(credentials.canRefresh, false);
     credentials.refresh('identifier', 'secret', httpClient: httpClient)
-        .catchError(expectAsync1((e) {
-          expect(e.error is StateError, isTrue);
+        .catchError(expectAsync1((error) {
+          expect(error is StateError, isTrue);
         }));
   });
 
@@ -76,7 +76,7 @@
         "client_secret": "secret"
       }));
 
-      return new Future.immediate(new http.Response(JSON.stringify({
+      return new Future.value(new http.Response(JSON.stringify({
         'access_token': 'new access token',
         'token_type': 'bearer',
         'refresh_token': 'new refresh token'
@@ -106,7 +106,7 @@
         "client_secret": "secret"
       }));
 
-      return new Future.immediate(new http.Response(JSON.stringify({
+      return new Future.value(new http.Response(JSON.stringify({
         'access_token': 'new access token',
         'token_type': 'bearer'
       }), 200, headers: {'content-type': 'application/json'}));
diff --git a/pkg/oauth2/test/utils.dart b/pkg/oauth2/test/utils.dart
index b874cc4..9198c80 100644
--- a/pkg/oauth2/test/utils.dart
+++ b/pkg/oauth2/test/utils.dart
@@ -38,7 +38,7 @@
 
   Future<http.Response> _handleRequest(http.Request request) {
     if (_handlers.isEmpty) {
-      return new Future.immediate(new http.Response('not found', 404));
+      return new Future.value(new http.Response('not found', 404));
     } else {
       return _handlers.removeFirst()(request);
     }
diff --git a/pkg/pathos/lib/path.dart b/pkg/pathos/lib/path.dart
index 0fe031d..5136871 100644
--- a/pkg/pathos/lib/path.dart
+++ b/pkg/pathos/lib/path.dart
@@ -11,6 +11,18 @@
 /// functional interface and not require users to create one.
 final _builder = new Builder();
 
+/**
+ * Inserts [length] elements in front of the [list] and fills them with the
+ * [fillValue].
+ */
+void _growListFront(List list, int length, fillValue) {
+  list.length += length;
+  list.setRange(length, list.length, list);
+  for (var i = 0; i < length; i++) {
+    list[i] = fillValue;
+  }
+}
+
 /// Gets the path to the current working directory.
 String get current => new io.Directory.current().path;
 
@@ -408,7 +420,7 @@
     // Filter out empty parts that exist due to multiple separators in a row.
     parsed.parts = parsed.parts.where((part) => !part.isEmpty)
                                .toList();
-    if (parsed.root != null) parsed.parts.insertRange(0, 1, parsed.root);
+    if (parsed.root != null) parsed.parts.insert(0, parsed.root);
     return parsed.parts;
   }
 
@@ -503,9 +515,9 @@
 
     // If there are any directories left in the root path, we need to walk up
     // out of them.
-    pathParsed.parts.insertRange(0, fromParsed.parts.length, '..');
-    pathParsed.separators.insertRange(0, fromParsed.parts.length,
-        style.separator);
+    _growListFront(pathParsed.parts, fromParsed.parts.length, '..');
+    _growListFront(
+        pathParsed.separators, fromParsed.parts.length, style.separator);
 
     // Corner case: the paths completely collapsed.
     if (pathParsed.parts.length == 0) return '.';
@@ -678,7 +690,7 @@
 
     // A relative path can back out from the start directory.
     if (!isAbsolute) {
-      newParts.insertRange(0, leadingDoubles, '..');
+      _growListFront(newParts, leadingDoubles, '..');
     }
 
     // If we collapsed down to nothing, do ".".
@@ -688,7 +700,7 @@
 
     // Canonicalize separators.
     var newSeparators = [];
-    newSeparators.insertRange(0, newParts.length, style.separator);
+    _growListFront(newSeparators, newParts.length, style.separator);
 
     parts = newParts;
     separators = newSeparators;
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 959a310..195a42f 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -2,6 +2,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+serialization/test/*: Skip # http://dartbug.com/9894
+
+
 # Run this test manually to verify that the fixnum library produces
 # the same results as native ints on a set of directed and random inputs.
 # Skip it when running automated tests because it times out.  This
@@ -120,7 +123,8 @@
 
 [ $compiler == dart2js && $minified ]
 # The unittest package relies on getting the original (non-minified) method
-# names in InvocationMirrors.  You can't get that when minifying.
+# names in Invocation.  You can't get that when minifying.
+# TODO(ahe/erikcorry): But soon you can, now that we use Symbol.
 unittest/test/mock_test: Fail
 unittest/test/mock_regexp_negative_test: Fail
 
diff --git a/pkg/scheduled_test/lib/scheduled_process.dart b/pkg/scheduled_test/lib/scheduled_process.dart
index cf37211..45e5061 100644
--- a/pkg/scheduled_test/lib/scheduled_process.dart
+++ b/pkg/scheduled_test/lib/scheduled_process.dart
@@ -134,9 +134,9 @@
       _handleExit(exitCodeCompleter);
 
       return Future.wait([
-        new Future.of(() => executable),
+        new Future.sync(() => executable),
         awaitObject(arguments),
-        new Future.of(() => options)
+        new Future.sync(() => options)
       ]).then((results) {
         executable = results[0];
         arguments = results[1];
diff --git a/pkg/scheduled_test/lib/scheduled_server.dart b/pkg/scheduled_test/lib/scheduled_server.dart
index 1ad8ac2..cb17268 100644
--- a/pkg/scheduled_test/lib/scheduled_server.dart
+++ b/pkg/scheduled_test/lib/scheduled_server.dart
@@ -91,7 +91,7 @@
   /// responsibility to check that the method/path are correct and that it's
   /// being run at the correct time.
   void _handleRequest(HttpRequest request) {
-    wrapFuture(new Future.of(() {
+    wrapFuture(new Future.sync(() {
       if (_handlers.isEmpty) {
         throw "'$description' received ${request.method} ${request.uri.path} "
             "when no more requests were expected.";
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index b46dc45..6e7b754 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -228,8 +228,6 @@
         assert(e.schedule.errors.contains(e));
         assert(e.schedule == currentSchedule);
         unittest.registerException(e.schedule.errorString());
-      } else if (e is AsyncError) {
-        unittest.registerException(e.error, e.stackTrace);
       } else {
         unittest.registerException(e);
       }
diff --git a/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
index d07b5bc..97f8c92 100644
--- a/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/directory_descriptor.dart
@@ -46,9 +46,9 @@
     }
 
     return Future.wait(contents.map((entry) {
-      return new Future.of(() => entry.validateNow(fullPath))
+      return new Future.sync(() => entry.validateNow(fullPath))
           .then((_) => null)
-          .catchError((e) => e.error);
+          .catchError((e) => e);
     })).then((results) {
       var errors = results.where((e) => e != null);
       if (errors.isEmpty) return;
@@ -57,7 +57,7 @@
   }
 
   Stream<List<int>> load(String pathToLoad) {
-    return futureStream(new Future.immediate(null).then((_) {
+    return futureStream(new Future.value().then((_) {
       if (_path.isAbsolute(pathToLoad)) {
         throw "Can't load absolute path '$pathToLoad'.";
       }
diff --git a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
index 75327d1..f56f720 100644
--- a/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/file_descriptor.dart
@@ -63,7 +63,7 @@
     });
   }
 
-  Stream<List<int>> read() => new Future.immediate(contents).asStream();
+  Stream<List<int>> read() => new Future.value(contents).asStream();
 
   String describe() => name;
 
diff --git a/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
index e56db2a..1cc47f5 100644
--- a/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/nothing_descriptor.dart
@@ -19,12 +19,12 @@
   NothingDescriptor(String name)
       : super(name);
 
-  Future create([String parent]) => new Future.immediate(null);
+  Future create([String parent]) => new Future.value();
 
   Future validate([String parent]) => schedule(() => validateNow(parent),
       "validating '$name' doesn't exist");
 
-  Future validateNow([String parent]) => new Future.of(() {
+  Future validateNow([String parent]) => new Future.sync(() {
     if (parent == null) parent = defaultRoot;
     var fullPath = path.join(parent, name);
     if (new File(fullPath).existsSync()) {
diff --git a/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart b/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
index 3735f82..7eb0c61 100644
--- a/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
+++ b/pkg/scheduled_test/lib/src/descriptor/pattern_descriptor.dart
@@ -62,8 +62,8 @@
       var descriptor = _fn(path.basename(entry));
       return descriptor.validateNow(parent).then((_) {
         return new Pair(null, descriptor.describe());
-      }).catchError((e) {
-        return new Pair(e.error.toString(), descriptor.describe());
+      }).catchError((error) {
+        return new Pair(error.toString(), descriptor.describe());
       });
     })).then((results) {
       var matches = results.where((result) => result.first == null).toList();
@@ -110,7 +110,7 @@
     return '/${regExp.pattern}/$flags';
   }
 
-  Future create([String parent]) => new Future.immediateError(
+  Future create([String parent]) => new Future.error(
       new UnsupportedError("Pattern descriptors don't support create()."));
 
   Stream<List<int>> load(String pathToLoad) => errorStream(
diff --git a/pkg/scheduled_test/lib/src/future_group.dart b/pkg/scheduled_test/lib/src/future_group.dart
index 213f0fc..f1f64db 100644
--- a/pkg/scheduled_test/lib/src/future_group.dart
+++ b/pkg/scheduled_test/lib/src/future_group.dart
@@ -34,11 +34,11 @@
         completed = true;
         _completer.complete(_values);
       }
-    }).catchError((e) {
+    }).catchError((error) {
       if (completed) return;
 
       completed = true;
-      _completer.completeError(e.error, e.stackTrace);
+      _completer.completeError(error);
     }));
 
     return task;
diff --git a/pkg/scheduled_test/lib/src/mock_clock.dart b/pkg/scheduled_test/lib/src/mock_clock.dart
index a4bbdee..6abe81f 100644
--- a/pkg/scheduled_test/lib/src/mock_clock.dart
+++ b/pkg/scheduled_test/lib/src/mock_clock.dart
@@ -45,8 +45,15 @@
   int _time = 0;
 
   /// The stream of millisecond ticks of the clock.
-  Stream<int> get onTick => _onTickController.stream;
-  final _onTickController = new StreamController<int>.broadcast();
+  Stream<int> get onTick {
+    if (_onTickControllerStream == null) {
+      _onTickControllerStream = _onTickController.stream.asBroadcastStream();
+    }
+    return _onTickControllerStream;
+  }
+
+  final _onTickController = new StreamController<int>();
+  Stream<int> _onTickControllerStream;
 
   Clock._();
 
@@ -57,7 +64,7 @@
   void tick([int milliseconds=1]) {
     for (var i = 0; i < milliseconds; i++) {
       var tickTime = ++_time;
-      new Future.immediate(null).then((_) => _onTickController.add(tickTime));
+      new Future.value().then((_) => _onTickController.add(tickTime));
     }
   }
 
diff --git a/pkg/scheduled_test/lib/src/schedule.dart b/pkg/scheduled_test/lib/src/schedule.dart
index 2569b4b..ecdf4dd 100644
--- a/pkg/scheduled_test/lib/src/schedule.dart
+++ b/pkg/scheduled_test/lib/src/schedule.dart
@@ -131,7 +131,7 @@
   /// Sets up this schedule by running [setUp], then runs all the task queues in
   /// order. Any errors in [setUp] will cause [onException] to run.
   Future run(void setUp()) {
-    return new Future.immediate(null).then((_) {
+    return new Future.value().then((_) {
       try {
         setUp();
       } catch (e, stackTrace) {
@@ -188,7 +188,7 @@
   /// Signals that an out-of-band error has occurred. Using [wrapAsync] along
   /// with `throw` is usually preferable to calling this directly.
   ///
-  /// The metadata in [AsyncError]s and [ScheduleError]s will be preserved.
+  /// The metadata in [ScheduleError]s will be preserved.
   void signalError(error, [stackTrace]) {
     heartbeat();
 
@@ -432,13 +432,13 @@
     if (isRunning) {
       var task = _schedule.currentTask;
       var wrappedFn = () => _schedule.wrapFuture(
-          new Future.immediate(null).then((_) => fn()));
+          new Future.value().then((_) => fn()));
       if (task == null) return wrappedFn();
       return task.runChild(wrappedFn, description);
     }
 
     var task = new Task(() {
-      return new Future.of(fn).catchError((e) {
+      return new Future.sync(fn).catchError((e) {
         throw new ScheduleError.from(_schedule, e);
       });
     }, description, this);
@@ -557,7 +557,7 @@
     } else if (_taskFuture != null) {
       // Catch errors coming off the old task future, in case it completes after
       // timing out.
-      _taskFuture.substitute(new Future.immediateError(error)).catchError((e) {
+      _taskFuture.substitute(new Future.error(error)).catchError((e) {
         _schedule._signalPostTimeoutError(e);
       });
     } else {
diff --git a/pkg/scheduled_test/lib/src/schedule_error.dart b/pkg/scheduled_test/lib/src/schedule_error.dart
index 7b66391..09bb350 100644
--- a/pkg/scheduled_test/lib/src/schedule_error.dart
+++ b/pkg/scheduled_test/lib/src/schedule_error.dart
@@ -13,7 +13,13 @@
 import 'utils.dart';
 
 /// A wrapper for errors that occur during a scheduled test.
-class ScheduleError extends AsyncError {
+class ScheduleError {
+  /// The wrapped error.
+  final error;
+
+  /// The stack trace that was attached to the error. Can be `null`.
+  final stackTrace;
+
   /// The schedule during which this error occurred.
   final Schedule schedule;
 
@@ -33,33 +39,33 @@
   final ScheduleState _stateWhenDetected;
 
   int get hashCode => schedule.hashCode ^ task.hashCode ^ queue.hashCode ^
-      _stateWhenDetected.hashCode ^ error.hashCode ^ stackTrace.hashCode ^
-      cause.hashCode;
+      _stateWhenDetected.hashCode ^ error.hashCode ^ stackTrace.hashCode;
 
   /// Creates a new [ScheduleError] wrapping [error]. The metadata in
-  /// [AsyncError]s and [ScheduleError]s will be preserved.
-  factory ScheduleError.from(Schedule schedule, error, {StackTrace stackTrace,
-      AsyncError cause}) {
+  /// [ScheduleError]s will be preserved.
+  factory ScheduleError.from(Schedule schedule, error,
+                             {StackTrace stackTrace}) {
     if (error is ScheduleError) return error;
 
-    if (error is AsyncError) {
+    var attachedTrace = getAttachedStackTrace(error);
+    if (attachedTrace != null) {
       // Overwrite the explicit stack trace, because it probably came from a
       // rethrow in the first place.
-      stackTrace = error.stackTrace;
-      if (cause == null) cause = error.cause;
-      error = error.error;
+      stackTrace = attachedTrace;
     }
 
     if (schedule.captureStackTraces && stackTrace == null) {
       stackTrace = new Trace.current();
     }
 
-    return new ScheduleError(schedule, error, stackTrace, cause);
+    return new ScheduleError(schedule, error, stackTrace);
   }
 
-  ScheduleError(Schedule schedule, error, StackTrace stackTrace,
-      AsyncError cause)
-      : super.withCause(error, stackTrace, cause),
+  // TODO(floitsch): restore StackTrace type when it has been integrated into
+  // the core libraries.
+  ScheduleError(Schedule schedule, error, var stackTrace)
+      : error = error,
+        stackTrace = stackTrace,
         schedule = schedule,
         task = schedule.currentTask,
         queue = schedule.currentQueue,
@@ -69,8 +75,7 @@
 
   bool operator ==(other) => other is ScheduleError && task == other.task &&
       queue == other.queue && _stateWhenDetected == other._stateWhenDetected &&
-      error == other.error && stackTrace == other.stackTrace &&
-      cause == other.cause;
+      error == other.error && stackTrace == other.stackTrace;
 
   String toString() {
     var result = new StringBuffer();
diff --git a/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart b/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
index 83609f5..599613d 100644
--- a/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_future_matchers.dart
@@ -66,11 +66,10 @@
     currentSchedule.wrapFuture(item.then((value) {
       if (_matcher == null) return;
 
-      try {
-        expect(value, _matcher);
-      } catch (e, stackTrace) {
-        throw new AsyncError(e, outerTrace);
-      }
+      // TODO(floitsch): we cannot switch traces anymore.
+      // If expect throws we might want to be able to switch to the outer trace
+      // instead.
+      expect(value, _matcher);
     }), description);
 
     return true;
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
index 6be6b1c..4d6c6b8 100644
--- a/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_server/handler.dart
@@ -54,7 +54,7 @@
         // between a test failing while waiting for a handler and a test failing
         // while executing a handler.
         chainToCompleter(schedule(() {
-          return new Future.of(() {
+          return new Future.sync(() {
             if (request.method != method || request.uri.path != path) {
               throw "'${server.description}' expected $method $path, "
                   "but got ${request.method} ${request.uri.path}.";
diff --git a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
index 7e4e4cc..2e5b9cc 100644
--- a/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
+++ b/pkg/scheduled_test/lib/src/scheduled_server/safe_http_server.dart
@@ -42,22 +42,21 @@
   HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
 
   StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
-      {void onError(AsyncError error), void onDone(),
-      bool unsubscribeOnError: false}) {
+      {void onError(error), void onDone(),
+      bool cancelOnError: false}) {
     var subscription;
     subscription = super.listen((request) {
       onData(new _HttpRequestWrapper(request));
-    }, onError: (e) {
-      var error = e.error;
+    }, onError: (error) {
       // Ignore socket error 104, which is caused by a request being cancelled
       // before it writes any headers. There's no reason to care about such
       // requests.
       if (error is SocketIOException && error.osError.errorCode == 104) return;
       // Ignore any parsing errors, which come from malformed requests.
       if (error is HttpParserException) return;
-      // Manually handle unsubscribeOnError so the above (ignored) errors don't
+      // Manually handle cancelOnError so the above (ignored) errors don't
       // cause unsubscription.
-      if (unsubscribeOnError) subscription.cancel();
+      if (cancelOnError) subscription.cancel();
       if (onError != null) onError(e);
     }, onDone: onDone);
     return subscription;
@@ -132,12 +131,8 @@
   Future<Socket> detachSocket() => _inner.detachSocket();
   HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
   void add(List<int> data) => _inner.add(data);
-  Future<HttpResponse> consume(Stream<List<int>> stream) =>
-    _inner.consume(stream);
   Future<HttpResponse> addStream(Stream<List<int>> stream) =>
-    _inner.writeStream(stream);
-  Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
-    _inner.writeStream(stream);
+    _inner.addStream(stream);
   Future close() => _inner.close();
   void write(Object obj) => _inner.write(obj);
   void writeAll(Iterable objects, [String separator = ""]) =>
diff --git a/pkg/scheduled_test/lib/src/substitute_future.dart b/pkg/scheduled_test/lib/src/substitute_future.dart
index 4122a3d..abbb5d4 100644
--- a/pkg/scheduled_test/lib/src/substitute_future.dart
+++ b/pkg/scheduled_test/lib/src/substitute_future.dart
@@ -24,9 +24,9 @@
   }
 
   Stream<T> asStream() => _completer.future.asStream();
-  Future catchError(onError(AsyncError asyncError), {bool test(error)}) =>
+  Future catchError(onError(asyncError), {bool test(error)}) =>
     _completer.future.catchError(onError, test: test);
-  Future then(onValue(T value), {onError(AsyncError asyncError)}) =>
+  Future then(onValue(T value), {onError(error)}) =>
     _completer.future.then(onValue, onError: onError);
   Future<T> whenComplete(action()) => _completer.future.whenComplete(action);
 
diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
index aabdbba..e77f531 100644
--- a/pkg/scheduled_test/lib/src/task.dart
+++ b/pkg/scheduled_test/lib/src/task.dart
@@ -79,7 +79,7 @@
       }
 
       _state = TaskState.RUNNING;
-      var future = new Future.immediate(null).then((_) => fn())
+      var future = new Future.value().then((_) => fn())
           .whenComplete(() {
         if (_childGroup == null || _childGroup.completed) return;
         return _childGroup.future;
diff --git a/pkg/scheduled_test/lib/src/utils.dart b/pkg/scheduled_test/lib/src/utils.dart
index 419e47e..6e4c636 100644
--- a/pkg/scheduled_test/lib/src/utils.dart
+++ b/pkg/scheduled_test/lib/src/utils.dart
@@ -50,8 +50,8 @@
 /// times. By default, this should pump the event queue enough times to allow
 /// any code to run, as long as it's not waiting on some external event.
 Future pumpEventQueue([int times=20]) {
-  if (times == 0) return new Future.immediate(null);
-  return new Future.immediate(null).then((_) => pumpEventQueue(times - 1));
+  if (times == 0) return new Future.value();
+  return new Future.value().then((_) => pumpEventQueue(times - 1));
 }
 
 /// Returns whether [iterable1] has the same elements in the same order as
@@ -71,7 +71,7 @@
 
 // TODO(nweiz): remove this when issue 8731 is fixed.
 /// Returns a [Stream] that will immediately emit [error] and then close.
-Stream errorStream(error) => new Future.immediateError(error).asStream();
+Stream errorStream(error) => new Future.error(error).asStream();
 
 /// Returns a buffered stream that will emit the same values as the stream
 /// returned by [future] once [future] completes. If [future] completes to an
@@ -107,10 +107,10 @@
     subscription.cancel();
     completer.complete(value);
   }, onError: (e) {
-    completer.completeError(e.error, e.stackTrace);
+    completer.completeError(e);
   }, onDone: () {
     completer.completeError(new StateError("No elements"), stackTrace);
-  }, unsubscribeOnError: true);
+  }, cancelOnError: true);
   return completer.future;
 }
 
@@ -122,15 +122,16 @@
 /// the wrapped stream. Unlike [StreamSubscription], this canceller will send a
 /// "done" message to the wrapped stream.
 Pair<Stream, StreamCanceller> streamWithCanceller(Stream stream) {
-  var controller = stream.isBroadcast ?
-      new StreamController.broadcast() :
-      new StreamController();
+  var controller = new StreamController();
+  var controllerStream = stream.isBroadcast ?
+      controller.stream.asBroadcastStream() :
+      controller.stream;
   var subscription = stream.listen((value) {
     if (!controller.isClosed) controller.add(value);
   }, onError: (error) {
     if (!controller.isClosed) controller.signalError(error);
   }, onDone: controller.close);
-  return new Pair<Stream, StreamCanceller>(controller.stream, controller.close);
+  return new Pair<Stream, StreamCanceller>(controllerStream, controller.close);
 }
 
 // TODO(nweiz): remove this when issue 7787 is fixed.
@@ -162,7 +163,7 @@
   if (object is Iterable) {
     return Future.wait(object.map(awaitObject).toList());
   }
-  if (object is! Map) return new Future.immediate(object);
+  if (object is! Map) return new Future.value(object);
 
   var pairs = <Future<Pair>>[];
   object.forEach((key, value) {
diff --git a/pkg/scheduled_test/lib/src/value_future.dart b/pkg/scheduled_test/lib/src/value_future.dart
index 41ffcc0..8aa2c62 100644
--- a/pkg/scheduled_test/lib/src/value_future.dart
+++ b/pkg/scheduled_test/lib/src/value_future.dart
@@ -30,9 +30,9 @@
   }
 
   Stream<T> asStream() => _future.asStream();
-  Future catchError(onError(AsyncError asyncError), {bool test(error)}) =>
+  Future catchError(onError(Object error), {bool test(error)}) =>
     _future.catchError(onError, test: test);
-  Future then(onValue(T value), {onError(AsyncError asyncError)}) =>
+  Future then(onValue(T value), {onError(Object error)}) =>
     _future.then(onValue, onError: onError);
   Future<T> whenComplete(action()) => _future.whenComplete(action);
 }
diff --git a/pkg/scheduled_test/test/descriptor/async_test.dart b/pkg/scheduled_test/test/descriptor/async_test.dart
index b35718f..1726345 100644
--- a/pkg/scheduled_test/test/descriptor/async_test.dart
+++ b/pkg/scheduled_test/test/descriptor/async_test.dart
@@ -126,7 +126,7 @@
     test('test', () {
       scheduleSandbox();
 
-      expect(d.async(new Future.immediate(d.file('name.txt')))
+      expect(d.async(new Future.value(d.file('name.txt')))
               .load('path').toList(),
           throwsA(equals("AsyncDescriptors don't support load().")));
     });
@@ -136,7 +136,7 @@
     test('test', () {
       scheduleSandbox();
 
-      expect(d.async(new Future.immediate(d.file('name.txt'))).read().toList(),
+      expect(d.async(new Future.value(d.file('name.txt'))).read().toList(),
           throwsA(equals("AsyncDescriptors don't support read().")));
     });
   });
diff --git a/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart b/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart
index 6ea9e59..25bba20 100644
--- a/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/capture_stack_traces_test.dart
@@ -32,6 +32,7 @@
   }, passing: ['test 2']);
 
   expectTestsPass('does not capture a stack trace if set to false', () {
+    var errorThrown = new Object();
     var error;
     test('test 1', () {
       currentSchedule.captureStackTraces = false;
@@ -39,7 +40,7 @@
         error = currentSchedule.errors.first;
       });
 
-      schedule(() => throw 'error');
+      schedule(() => throw errorThrown);
     });
 
     test('test 2', () {
diff --git a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
index 2e7a10b..047cd3b 100644
--- a/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/nested_task_test.dart
@@ -89,6 +89,7 @@
 
   expectTestsPass("nested scheduled blocks whose return values are passed to "
       "wrapFuture should report exceptions once", () {
+    var error = new Object();
     var errors;
     test('test 1', () {
       currentSchedule.onException.schedule(() {
@@ -97,7 +98,7 @@
 
       schedule(() {
         wrapFuture(schedule(() {
-          throw 'error';
+          throw error;
         }));
 
         return pumpEventQueue();
@@ -106,7 +107,7 @@
 
     test('test 2', () {
       expect(errors, everyElement(new isInstanceOf<ScheduleError>()));
-      expect(errors.map((e) => e.error), equals(['error']));
+      expect(errors.map((e) => e.error), equals([error]));
     });
   }, passing: ['test 2']);
 
diff --git a/pkg/scheduled_test/test/scheduled_test/simple_test.dart b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
index ea51921..8c67bf3 100644
--- a/pkg/scheduled_test/test/scheduled_test/simple_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/simple_test.dart
@@ -30,14 +30,14 @@
   expectTestsPass('a scheduled test with a correct asynchronous expectation '
       'should pass', () {
     test('test', () {
-      expect(new Future.immediate('foo'), completion(equals('foo')));
+      expect(new Future.value('foo'), completion(equals('foo')));
     });
   });
 
   expectTestsFail('a scheduled test with an incorrect asynchronous expectation '
       'should fail', () {
     test('test', () {
-      expect(new Future.immediate('foo'), completion(equals('bar')));
+      expect(new Future.value('foo'), completion(equals('bar')));
     });
   });
 
@@ -57,7 +57,7 @@
       'register', () {
     test('test', () {
       schedule(() =>
-          expect(new Future.immediate('foo'), completion(equals('foo'))));
+          expect(new Future.value('foo'), completion(equals('foo'))));
     });
   });
 
@@ -65,7 +65,7 @@
       'register', () {
     test('test', () {
       schedule(() =>
-          expect(new Future.immediate('foo'), completion(equals('bar'))));
+          expect(new Future.value('foo'), completion(equals('bar'))));
     });
   });
 
@@ -88,7 +88,7 @@
     });
 
     test('asynchronous value', () {
-      var future = schedule(() => new Future.immediate('value'));
+      var future = schedule(() => new Future.value('value'));
       expect(future, completion(equals('value')));
     });
   });
@@ -107,7 +107,7 @@
   expectTestsFail('a test failure in a chained future in a scheduled block '
       'should be registered', () {
     test('test', () {
-      schedule(() => new Future.immediate('foo')
+      schedule(() => new Future.value('foo')
           .then((v) => expect(v, equals('bar'))));
     });
   });
@@ -115,7 +115,7 @@
   expectTestsFail('an error in a chained future in a scheduled block should be '
       'registered', () {
     test('test', () {
-      schedule(() => new Future.immediate(null).then((_) {
+      schedule(() => new Future.value().then((_) {
         throw 'error';
       }));
     });
diff --git a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
index fd8e003..2a44cc5 100644
--- a/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/wrap_future_test.dart
@@ -53,7 +53,7 @@
         wrapFuture(pumpEventQueue().then((_) {
           throw 'error';
         })).catchError(wrapAsync((e) {
-          error = e.error;
+          error = e;
         }));
       });
     });
diff --git a/pkg/scheduled_test/test/substitute_future_test.dart b/pkg/scheduled_test/test/substitute_future_test.dart
index f9c8b32..7202c86 100644
--- a/pkg/scheduled_test/test/substitute_future_test.dart
+++ b/pkg/scheduled_test/test/substitute_future_test.dart
@@ -31,28 +31,28 @@
 
     test('.then and .catchError on success', () {
       expect(future.then((v) => "transformed $v")
-              .catchError((e) => "caught ${e.error}"),
+              .catchError((error) => "caught ${error}"),
           completion(equals('transformed success')));
       completer.complete('success');
     });
 
     test('.then and .catchError on error', () {
       expect(future.then((v) => "transformed $v")
-              .catchError((e) => "caught ${e.error}"),
+              .catchError((error) => "caught ${error}"),
           completion(equals('caught error')));
       completer.completeError('error');
     });
 
     test('.then with onError on success', () {
       expect(future.then((v) => "transformed $v",
-              onError: (e) => "caught ${e.error}"),
+              onError: (error) => "caught ${error}"),
           completion(equals('transformed success')));
       completer.complete('success');
     });
 
     test('.then with onError on error', () {
       expect(future.then((v) => "transformed $v",
-              onError: (e) => "caught ${e.error}"),
+              onError: (error) => "caught ${error}"),
           completion(equals('caught error')));
       completer.completeError('error');
     });
@@ -148,7 +148,7 @@
     var completer = new Completer();
     var future = new SubstituteFuture(completer.future);
     completer.complete('success');
-    expect(() => future.substitute(new Future.immediate(null)),
+    expect(() => future.substitute(new Future.value()),
         throwsStateError);
   });
 }
diff --git a/pkg/scheduled_test/test/utils.dart b/pkg/scheduled_test/test/utils.dart
index 4dd7ef9..a52b137 100644
--- a/pkg/scheduled_test/test/utils.dart
+++ b/pkg/scheduled_test/test/utils.dart
@@ -26,16 +26,16 @@
 Future timeout(Future input, int milliseconds, onTimeout()) {
   var completer = new Completer();
   var timer = new Timer(new Duration(milliseconds: milliseconds), () {
-    chainToCompleter(new Future.of(onTimeout), completer);
+    chainToCompleter(new Future.sync(onTimeout), completer);
   });
   input.then((value) {
     if (completer.isCompleted) return;
     timer.cancel();
     completer.complete(value);
-  }).catchError((e) {
+  }).catchError((error) {
     if (completer.isCompleted) return;
     timer.cancel();
-    completer.completeError(e.error, e.stackTrace);
+    completer.completeError(error);
   });
   return completer.future;
 }
diff --git a/pkg/scheduled_test/test/value_future_test.dart b/pkg/scheduled_test/test/value_future_test.dart
index a5777b3..61ab436 100644
--- a/pkg/scheduled_test/test/value_future_test.dart
+++ b/pkg/scheduled_test/test/value_future_test.dart
@@ -31,28 +31,28 @@
 
     test('.then and .catchError on success', () {
       expect(future.then((v) => "transformed $v")
-              .catchError((e) => "caught ${e.error}"),
+              .catchError((error) => "caught ${error}"),
           completion(equals('transformed success')));
       completer.complete('success');
     });
 
     test('.then and .catchError on error', () {
       expect(future.then((v) => "transformed $v")
-              .catchError((e) => "caught ${e.error}"),
+              .catchError((error) => "caught ${error}"),
           completion(equals('caught error')));
       completer.completeError('error');
     });
 
     test('.then with onError on success', () {
       expect(future.then((v) => "transformed $v",
-              onError: (e) => "caught ${e.error}"),
+              onError: (error) => "caught ${error}"),
           completion(equals('transformed success')));
       completer.complete('success');
     });
 
     test('.then with onError on error', () {
       expect(future.then((v) => "transformed $v",
-              onError: (e) => "caught ${e.error}"),
+              onError: (error) => "caught ${error}"),
           completion(equals('caught error')));
       completer.completeError('error');
     });
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index c640ba6..b3e3a95 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -419,7 +419,7 @@
  * are kept in a separate object, which also has the ability to compute the
  * default fields to use reflectively.
  */
-class _FieldList extends Iterable {
+class _FieldList extends IterableBase {
   /**
    * All of our fields, indexed by name. Note that the names are not
    * necessarily strings.
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index e83e804..d63f07a 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -521,7 +521,7 @@
  * looks like it's just a list of objects to a [CustomRule] without needing
  * to inflate all the references in advance.
  */
-class _LazyList extends Iterable implements List {
+class _LazyList extends IterableBase implements List {
   _LazyList(this._raw, this._reader);
 
   final List _raw;
@@ -566,7 +566,6 @@
   getRange(x, y) => _throw();
   setRange(x, y, z, [a]) => _throw();
   removeRange(x, y) => _throw();
-  insertRange(x, y, [z]) => _throw();
   get reversed => _throw();
   void set length(x) => _throw();
 }
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index bed1d5d..fa0c313 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -5,7 +5,7 @@
 library trace;
 
 import 'dart:uri';
-import 'dart:math';
+import 'dart:math' as math;
 
 import 'frame.dart';
 
@@ -52,7 +52,7 @@
   /// a [Trace], it will be returned as-is.
   factory Trace.from(StackTrace trace) {
     if (trace is Trace) return trace;
-    return new Trace.parse(trace.fullStackTrace);
+    return new Trace.parse(trace.toString());
   }
 
   /// Parses a string representation of a stack trace.
@@ -117,7 +117,7 @@
     if (frames.length == '') return '';
 
     // Figure out the longest path so we know how much to pad.
-    var longest = frames.map((frame) => frame.location.length).reduce(max);
+    var longest = frames.map((frame) => frame.location.length).reduce(math.max);
 
     // Print out the stack trace nicely formatted.
     return frames.map((frame) {
diff --git a/pkg/unittest/lib/mock.dart b/pkg/unittest/lib/mock.dart
index db243db..8bdb115 100644
--- a/pkg/unittest/lib/mock.dart
+++ b/pkg/unittest/lib/mock.dart
@@ -513,7 +513,8 @@
             actionMatcher.matches(entry, matchState)) {
           rtn.add(entry);
           if (destructive) {
-            logs.removeRange(i--, 1);
+            int startIndex = i--;
+            logs.removeRange(startIndex, startIndex + 1);
           }
         }
       }
@@ -621,7 +622,7 @@
     int pos = findLogEntry(logFilter, 0, defaultPosition);
     if (inPlace) {
       if (pos < logs.length) {
-        logs.removeRange(pos, logs.length - pos);
+        logs.removeRange(pos, logs.length);
       }
       filter = description;
       return this;
@@ -1291,7 +1292,7 @@
    * return value. If we find no [Behavior] to apply an exception is
    * thrown.
    */
-  noSuchMethod(InvocationMirror invocation) {
+  noSuchMethod(Invocation invocation) {
     var method = invocation.memberName;
     var args = invocation.positionalArguments;
     if (invocation.isGetter) {
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index 1a8143c..e8606aa 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -326,16 +326,17 @@
       // completes.
       item.then((value) {
         done(() => fail("Expected future to fail, but succeeded with '$value'."));
-      }, onError: (e) {
+      }, onError: (error) {
         done(() {
           if (_matcher == null) return;
           var reason;
-          if (e.stackTrace != null) {
-            var stackTrace = e.stackTrace.toString();
+          var trace = getAttachedStackTrace(error);
+          if (trace != null) {
+            var stackTrace = trace.toString();
             stackTrace = "  ${stackTrace.replaceAll("\n", "\n  ")}";
             reason = "Actual exception trace:\n$stackTrace";
           }
-          expect(e.error, _matcher, reason: reason);
+          expect(error, _matcher, reason: reason);
         });
       });
       // It hasn't failed yet.
diff --git a/pkg/unittest/lib/src/future_matchers.dart b/pkg/unittest/lib/src/future_matchers.dart
index cfc0518..6067451 100644
--- a/pkg/unittest/lib/src/future_matchers.dart
+++ b/pkg/unittest/lib/src/future_matchers.dart
@@ -42,12 +42,13 @@
 
     item.then((value) {
       done(() { if (_matcher != null) expect(value, _matcher); });
-    }, onError: (e) {
+    }, onError: (error) {
       var id = _id == '' ? '' : '${_id} ';
       var reason = 'Expected future ${id}to complete successfully, '
-                   'but it failed with ${e.error}';
-      if (e.stackTrace != null) {
-        var stackTrace = e.stackTrace.toString();
+                   'but it failed with ${error}';
+      var trace = getAttachedStackTrace(error);
+      if (trace != null) {
+        var stackTrace = trace.toString();
         stackTrace = '  ${stackTrace.replaceAll('\n', '\n  ')}';
         reason = '$reason\nStack trace:\n$stackTrace';
       }
diff --git a/pkg/unittest/lib/src/test_case.dart b/pkg/unittest/lib/src/test_case.dart
index 23d04de..13d59f5 100644
--- a/pkg/unittest/lib/src/test_case.dart
+++ b/pkg/unittest/lib/src/test_case.dart
@@ -83,7 +83,7 @@
     --_callbackFunctionsOutstanding;
     if (f is Future) {
       return f.then((_) => _finishTest())
-       .catchError((e) => fail("${e.error}"));
+       .catchError((error) => fail("${error}"));
     } else {
       _finishTest();
       return null;
@@ -118,7 +118,7 @@
           // a failed setUp. There is no right answer, but doing it
           // seems to be the more conservative approach, because
           // unittest will not stop at a test failure.
-          error("$description: Test setup failed: ${e.error}");
+          error("$description: Test setup failed: $e");
         });
     } else {
       var f = _runTest();
@@ -175,11 +175,12 @@
           rtn.then((_) {
             _notifyComplete();
           })
-          .catchError((e) {
+          .catchError((error) {
+            var trace = getAttachedStackTrace(error);
             // We don't call fail() as that will potentially result in
             // spurious messages like 'test failed more than once'.
-            _setResult(ERROR, "$description: Test teardown failed: ${e.error}",
-                e.stackTrace.toString());
+            _setResult(ERROR, "$description: Test teardown failed: ${error}",
+                trace == null ? "" : trace.toString());
             _notifyComplete();
           });
           return;
diff --git a/pkg/unittest/lib/unittest.dart b/pkg/unittest/lib/unittest.dart
index efe6f8d..ec79288 100644
--- a/pkg/unittest/lib/unittest.dart
+++ b/pkg/unittest/lib/unittest.dart
@@ -668,7 +668,7 @@
  * (as we do in unitttest_test.dart).
  */
 _defer(void callback()) {
-  (new Future.immediate(null)).then((_) => callback());
+  (new Future.value()).then((_) => callback());
 }
 
 void rerunTests() {
diff --git a/pkg/unittest/test/matchers_test.dart b/pkg/unittest/test/matchers_test.dart
index 7e97b38..be286ea 100644
--- a/pkg/unittest/test/matchers_test.dart
+++ b/pkg/unittest/test/matchers_test.dart
@@ -35,19 +35,19 @@
   featureValueOf(actual) => actual.price;
 }
 
-class SimpleIterable extends Iterable {
+class SimpleIterable extends IterableBase {
   int count;
   SimpleIterable(this.count);
-  
+
   bool contains(int val) => count < val ? false : true;
-  
+
   bool any(bool f(element)) {
     for(var i = 0; i <= count; i++) {
       if(f(i)) return true;
     }
     return false;
   }
-  
+
   String toString() => "<[$count]>";
 
   Iterator get iterator {
@@ -197,7 +197,7 @@
         "but:  exception <Exception> does not match "
             "UnsupportedError.");
     });
-    
+
     test('throwsStateError', () {
       shouldPass(() { throw new StateError(''); },
           throwsStateError);
@@ -453,14 +453,14 @@
       shouldPass(d, isEmpty);
       shouldFail(e, isEmpty, "Expected: empty but: was <[1]>.");
     });
-    
+
     test('contains', () {
       var d = new SimpleIterable(3);
       shouldPass(d, contains(2));
       shouldFail(d, contains(5), "Expected: contains <5> but: was <[3]>.");
     });
   });
-  
+
   group('Iterable Matchers', () {
 
     test('isEmpty', () {
diff --git a/pkg/unittest/test/unittest_test.dart b/pkg/unittest/test/unittest_test.dart
index 8a641a4..f6a2f5d 100644
--- a/pkg/unittest/test/unittest_test.dart
+++ b/pkg/unittest/test/unittest_test.dart
@@ -15,7 +15,7 @@
 import 'package:unittest/unittest.dart';
 
 Future _defer(void fn()) {
-  return new Future.of(fn);
+  return new Future.sync(fn);
 }
 
 String buildStatusString(int passed, int failed, int errors,
@@ -154,37 +154,37 @@
     } else if (testName == 'async setup/teardown test') {
       group('good setup/good teardown', () {
         setUp(() {
-          return new Future.immediate(0);
+          return new Future.value(0);
         });
         tearDown(() {
-          return new Future.immediate(0);
+          return new Future.value(0);
         });
         test('foo1', (){});
       });
       group('good setup/bad teardown', () {
         setUp(() {
-          return new Future.immediate(0);
+          return new Future.value(0);
         });
         tearDown(() {
-          return new Future.immediateError("Failed to complete tearDown");
+          return new Future.error("Failed to complete tearDown");
         });
         test('foo2', (){});
       });
       group('bad setup/good teardown', () {
         setUp(() {
-          return new Future.immediateError("Failed to complete setUp");
+          return new Future.error("Failed to complete setUp");
         });
         tearDown(() {
-          return new Future.immediate(0);
+          return new Future.value(0);
         });
         test('foo3', (){});
       });
       group('bad setup/bad teardown', () {
         setUp(() {
-          return new Future.immediateError("Failed to complete setUp");
+          return new Future.error("Failed to complete setUp");
         });
         tearDown(() {
-          return new Future.immediateError("Failed to complete tearDown");
+          return new Future.error("Failed to complete tearDown");
         });
         test('foo4', (){});
       });
diff --git a/pkg/webdriver/lib/webdriver.dart b/pkg/webdriver/lib/webdriver.dart
index 9fed8d7..cc6b7d3 100644
--- a/pkg/webdriver/lib/webdriver.dart
+++ b/pkg/webdriver/lib/webdriver.dart
@@ -215,9 +215,10 @@
     _url = 'http://$_host:$_port$_path';
   }
 
-  void _failRequest(Completer completer, error, StackTrace stackTrace) {
+  void _failRequest(Completer completer, error, [stackTrace]) {
     if (completer != null) {
-      completer.completeError(new WebDriverError(-1, error), stackTrace);
+      var trace = stackTrace != null ? stackTrace, getAttachedStackTrace(error);
+      completer.completeError(new WebDriverError(-1, error), trace);
     }
   }
 
@@ -273,7 +274,7 @@
             results = new String.fromCharCodes(body).trim();
             if (!successCodes.contains(rsp.statusCode)) {
               _failRequest(completer, 
-                  'Unexpected response ${rsp.statusCode}; $results', null);
+                  'Unexpected response ${rsp.statusCode}; $results');
               completer = null;
               return;
             }
@@ -297,18 +298,18 @@
                 completer.complete(value);
               }
             }
-          }, onError: (e) {
-            _failRequest(completer, e.error, e.stackTrace);
+          }, onError: (error) {
+            _failRequest(completer, error);
             completer = null;
           });
         })
-        .catchError((e) {
-          _failRequest(completer, e.error, e.stackTrace);
+        .catchError((error) {
+          _failRequest(completer, error);
           completer = null;
         });
       })
-      .catchError((e) {
-        _failRequest(completer, e.error, e.stackTrace);
+      .catchError((error) {
+        _failRequest(completer, error);
         completer = null;
       });
     } catch (e, s) {
diff --git a/pkg/webdriver/test/webdriver_test.dart b/pkg/webdriver/test/webdriver_test.dart
index 213917f..3c4d500 100644
--- a/pkg/webdriver/test/webdriver_test.dart
+++ b/pkg/webdriver/test/webdriver_test.dart
@@ -1,4 +1,5 @@
 library webdriver_test;
+import 'dart:async' show getAttachedStackTrace;
 import 'package:webdriver/webdriver.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/vm_config.dart';
@@ -15,12 +16,13 @@
   var web_driver = new WebDriver('localhost', 4444, '/wd/hub');
   var session = null;
 
-  var exceptionHandler = (e) {
-    if (e.error is TestFailure) {
-      currentTestCase.fail(e.error.message, e.stackTrace.toString());
+  var exceptionHandler = (error) {
+    var trace = getAttachedStackTrace(error);
+    String traceString = trace == null ? "" : trace.toString();
+    if (error is TestFailure) {
+      currentTestCase.fail(error.message, traceString);
     } else {
-      currentTestCase.error("Unexpected error: ${e.error}",
-          e.stackTrace.toString());
+      currentTestCase.error("Unexpected error: ${error}", traceString);
     }
     if (session != null) {
       var s = session;
diff --git a/pkg/yaml/lib/model.dart b/pkg/yaml/lib/model.dart
index 5c09aa5..ac237a0 100644
--- a/pkg/yaml/lib/model.dart
+++ b/pkg/yaml/lib/model.dart
@@ -190,8 +190,7 @@
   /// long.
   String zeroPad(String str, int length) {
     assert(length >= str.length);
-    var prefix = [];
-    prefix.insertRange(0, length - str.length, '0');
+    var prefix = new List.filled(length - str.length, '0');
     return '${prefix.join()}$str';
   }
 
diff --git a/pkg/yaml/lib/parser.dart b/pkg/yaml/lib/parser.dart
index 9621b13..b923fe3 100644
--- a/pkg/yaml/lib/parser.dart
+++ b/pkg/yaml/lib/parser.dart
@@ -1637,7 +1637,7 @@
         if (!truth(s_indent(indent))) return null;
         return c_l_blockSeqEntry(indent);
       }));
-    content.insertRange(0, 1, first);
+    content.insert(0, first);
 
     return new _SequenceNode("?", content);
   });
@@ -1720,7 +1720,7 @@
         if (!truth(s_indent(indent))) return null;
         return ns_l_blockMapEntry(indent);
       }));
-    pairs.insertRange(0, 1, first);
+    pairs.insert(0, first);
 
     return map(pairs);
   });
diff --git a/pkg/yaml/test/yaml_test.dart b/pkg/yaml/test/yaml_test.dart
index 6013dc9..047c273 100644
--- a/pkg/yaml/test/yaml_test.dart
+++ b/pkg/yaml/test/yaml_test.dart
@@ -1350,8 +1350,7 @@
          bar: invalid ]""")));
 
       // TODO(nweiz): enable this when we throw an error for long keys
-      // var dotList = [];
-      // dotList.insertRange(0, 1024, ' ');
+      // var dotList = new List.filled(1024, ' ');
       // var dots = dotList.join();
       // Expect.throws(() => loadYaml('[ "foo...$dots...bar": invalid ]'));
     });
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index b4b44d0..555dfe5 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -31,8 +31,8 @@
   V(File_ReadByte, 1)                                                          \
   V(File_WriteByte, 2)                                                         \
   V(File_Read, 2)                                                              \
-  V(File_ReadList, 4)                                                          \
-  V(File_WriteList, 4)                                                         \
+  V(File_ReadInto, 4)                                                          \
+  V(File_WriteFrom, 4)                                                         \
   V(File_Position, 1)                                                          \
   V(File_SetPosition, 2)                                                       \
   V(File_Truncate, 2)                                                          \
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 7dd8534..37cf816 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -678,9 +678,10 @@
 
 
 Dart_CObject* CObject::NewUint8Array(int length) {
-  Dart_CObject* cobject = New(Dart_CObject::kUint8Array, length);
-  cobject->value.as_byte_array.length = length;
-  cobject->value.as_byte_array.values = reinterpret_cast<uint8_t*>(cobject + 1);
+  Dart_CObject* cobject = New(Dart_CObject::kTypedData, length);
+  cobject->value.as_typed_data.type = Dart_CObject::kUint8Array;
+  cobject->value.as_typed_data.length = length;
+  cobject->value.as_typed_data.values = reinterpret_cast<uint8_t*>(cobject + 1);
   return cobject;
 }
 
@@ -688,11 +689,12 @@
 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;
-  cobject->value.as_external_byte_array.peer = peer;
-  cobject->value.as_external_byte_array.callback = callback;
+  Dart_CObject* cobject = New(Dart_CObject::kExternalTypedData);
+  cobject->value.as_external_typed_data.type = Dart_CObject::kUint8Array;
+  cobject->value.as_external_typed_data.length = length;
+  cobject->value.as_external_typed_data.data = data;
+  cobject->value.as_external_typed_data.peer = peer;
+  cobject->value.as_external_typed_data.callback = callback;
   return cobject;
 }
 
@@ -704,10 +706,10 @@
 
 
 void CObject::FreeIOBufferData(Dart_CObject* cobject) {
-  ASSERT(cobject->type == Dart_CObject::kExternalUint8Array);
-  cobject->value.as_external_byte_array.callback(
-      NULL, cobject->value.as_external_byte_array.peer);
-  cobject->value.as_external_byte_array.data = NULL;
+  ASSERT(cobject->type == Dart_CObject::kExternalTypedData);
+  cobject->value.as_external_typed_data.callback(
+      NULL, cobject->value.as_external_typed_data.peer);
+  cobject->value.as_external_typed_data.data = NULL;
 }
 
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index da7653e..83457dc 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -205,6 +205,11 @@
  public:
   explicit CObject(Dart_CObject *cobject) : cobject_(cobject) {}
   Dart_CObject::Type type() { return cobject_->type; }
+  Dart_CObject::TypedDataType byte_array_type() {
+    ASSERT(type() == Dart_CObject::kTypedData ||
+           type() == Dart_CObject::kExternalTypedData);
+    return cobject_->value.as_typed_data.type;
+  }
 
   bool IsNull() { return type() == Dart_CObject::kNull; }
   bool IsBool() { return type() == Dart_CObject::kBool; }
@@ -216,7 +221,11 @@
   bool IsDouble() { return type() == Dart_CObject::kDouble; }
   bool IsString() { return type() == Dart_CObject::kString; }
   bool IsArray() { return type() == Dart_CObject::kArray; }
-  bool IsUint8Array() { return type() == Dart_CObject::kUint8Array; }
+  bool IsTypedData() { return type() == Dart_CObject::kTypedData; }
+  bool IsUint8Array() {
+    return type() == Dart_CObject::kTypedData &&
+           byte_array_type() == Dart_CObject::kUint8Array;
+  }
 
   bool IsTrue() {
     return type() == Dart_CObject::kBool && cobject_->value.as_bool;
@@ -288,7 +297,35 @@
     ASSERT(cobject != NULL);                                                   \
     ASSERT(cobject->type() == Dart_CObject::k##t);                             \
     cobject_ = cobject->AsApiCObject();                                        \
-  }
+  }                                                                            \
+
+
+#define DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(t)                             \
+  explicit CObject##t(Dart_CObject *cobject) : CObject(cobject) {              \
+    ASSERT(type() == Dart_CObject::kTypedData);                                \
+    ASSERT(byte_array_type() == Dart_CObject::k##t);                           \
+    cobject_ = cobject;                                                        \
+  }                                                                            \
+  explicit CObject##t(CObject* cobject) : CObject() {                          \
+    ASSERT(cobject != NULL);                                                   \
+    ASSERT(cobject->type() == Dart_CObject::kTypedData);                       \
+    ASSERT(cobject->byte_array_type() == Dart_CObject::k##t);                  \
+    cobject_ = cobject->AsApiCObject();                                        \
+  }                                                                            \
+
+
+#define DECLARE_COBJECT_EXTERNAL_TYPED_DATA_CONSTRUCTORS(t)                    \
+  explicit CObjectExternal##t(Dart_CObject *cobject) : CObject(cobject) {      \
+    ASSERT(type() == Dart_CObject::kExternalTypedData);                        \
+    ASSERT(byte_array_type() == Dart_CObject::k##t);                           \
+    cobject_ = cobject;                                                        \
+  }                                                                            \
+  explicit CObjectExternal##t(CObject* cobject) : CObject() {                  \
+    ASSERT(cobject != NULL);                                                   \
+    ASSERT(cobject->type() == Dart_CObject::kExternalTypedData);               \
+    ASSERT(cobject->byte_array_type() == Dart_CObject::k##t);                  \
+    cobject_ = cobject->AsApiCObject();                                        \
+  }                                                                            \
 
 
 class CObjectBool : public CObject {
@@ -404,12 +441,35 @@
 };
 
 
+class CObjectTypedData : public CObject {
+ public:
+  explicit CObjectTypedData(Dart_CObject *cobject) : CObject(cobject) {
+    ASSERT(type() == Dart_CObject::kTypedData);
+    cobject_ = cobject;
+  }
+  explicit CObjectTypedData(CObject* cobject) : CObject() {
+    ASSERT(cobject != NULL);
+    ASSERT(cobject->type() == Dart_CObject::kTypedData);
+    cobject_ = cobject->AsApiCObject();
+  }
+
+  Dart_CObject::TypedDataType Type() const {
+    return cobject_->value.as_typed_data.type;
+  }
+  int Length() const { return cobject_->value.as_typed_data.length; }
+  uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CObjectTypedData);
+};
+
+
 class CObjectUint8Array : public CObject {
  public:
-  DECLARE_COBJECT_CONSTRUCTORS(Uint8Array)
+  DECLARE_COBJECT_TYPED_DATA_CONSTRUCTORS(Uint8Array)
 
-  int Length() const { return cobject_->value.as_byte_array.length; }
-  uint8_t* Buffer() const { return cobject_->value.as_byte_array.values; }
+  int Length() const { return cobject_->value.as_typed_data.length; }
+  uint8_t* Buffer() const { return cobject_->value.as_typed_data.values; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CObjectUint8Array);
@@ -418,16 +478,16 @@
 
 class CObjectExternalUint8Array : public CObject {
  public:
-  DECLARE_COBJECT_CONSTRUCTORS(ExternalUint8Array)
+  DECLARE_COBJECT_EXTERNAL_TYPED_DATA_CONSTRUCTORS(Uint8Array)
 
-  int Length() const { return cobject_->value.as_external_byte_array.length; }
+  int Length() const { return cobject_->value.as_external_typed_data.length; }
   void SetLength(uint64_t length) {
-    cobject_->value.as_external_byte_array.length = length;
+    cobject_->value.as_external_typed_data.length = length;
   }
-  uint8_t* Data() const { return cobject_->value.as_external_byte_array.data; }
-  void* Peer() const { return cobject_->value.as_external_byte_array.peer; }
+  uint8_t* Data() const { return cobject_->value.as_external_typed_data.data; }
+  void* Peer() const { return cobject_->value.as_external_typed_data.peer; }
   Dart_WeakPersistentHandleFinalizer Callback() const {
-    return cobject_->value.as_external_byte_array.callback;
+    return cobject_->value.as_external_typed_data.callback;
   }
 
  private:
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 931d2bc..a1ac5e5 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -398,24 +398,15 @@
   Dart_ActivationFrame frame;
   res = Dart_GetActivationFrame(trace, 0, &frame);
   ASSERT_NOT_ERROR(res);
-  Dart_Handle script_url;
-  intptr_t token_number = 0;
-  intptr_t line_number = 0;
-  intptr_t library_id = 0;
-  // TODO(hausner): Remove this call and line_number once Editor no
-  // longer depends on line number info.
-  res = Dart_ActivationFrameInfo(frame, NULL, NULL, &line_number, NULL);
+  Dart_CodeLocation location;
+  res = Dart_ActivationFrameGetLocation(frame, NULL, &location);
   ASSERT_NOT_ERROR(res);
-  res = Dart_ActivationFrameGetLocation(
-      frame, &script_url, &library_id, &token_number);
-  ASSERT_NOT_ERROR(res);
-  if (!Dart_IsNull(script_url)) {
-    ASSERT(Dart_IsString(script_url));
+  if (!Dart_IsNull(location.script_url)) {
+    ASSERT(Dart_IsString(location.script_url));
     msg->Printf("%s\"location\": { \"url\":", prefix);
-    FormatEncodedString(msg, script_url);
-    msg->Printf(",\"libraryId\":%"Pd",", library_id);
-    msg->Printf("\"tokenOffset\":%"Pd",", token_number);
-    msg->Printf("\"lineNumber\":%"Pd"}", line_number);
+    FormatEncodedString(msg, location.script_url);
+    msg->Printf(",\"libraryId\":%d,", location.library_id);
+    msg->Printf("\"tokenOffset\":%d}", location.token_pos);
   }
 }
 
@@ -430,36 +421,22 @@
     res = Dart_GetActivationFrame(trace, i, &frame);
     ASSERT_NOT_ERROR(res);
     Dart_Handle func_name;
-    Dart_Handle script_url;
-    intptr_t line_number = 0;
-    intptr_t token_number = 0;
-    intptr_t library_id = 0;
-    res = Dart_ActivationFrameInfo(
-        frame, &func_name, NULL, &line_number, &library_id);
+    Dart_CodeLocation location;
+    res = Dart_ActivationFrameGetLocation(frame, &func_name, &location);
     ASSERT_NOT_ERROR(res);
-
     ASSERT(Dart_IsString(func_name));
     msg->Printf("%s{\"functionName\":", (i > 0) ? "," : "");
     FormatEncodedString(msg, func_name);
-    // TODO(hausner): Remove this libraryId field when Editor
-    // no longer depends on it.
-    msg->Printf(",\"libraryId\": %"Pd",", library_id);
-
-    res = Dart_ActivationFrameGetLocation(
-        frame, &script_url, NULL, &token_number);
-    ASSERT_NOT_ERROR(res);
-    if (!Dart_IsNull(script_url)) {
-      ASSERT(Dart_IsString(script_url));
-      msg->Printf("\"location\": { \"url\":");
-      FormatEncodedString(msg, script_url);
-      msg->Printf(",\"libraryId\": %"Pd",", library_id);
-      msg->Printf("\"tokenOffset\":%"Pd",", token_number);
-      msg->Printf("\"lineNumber\":%"Pd"},", line_number);
+    if (!Dart_IsNull(location.script_url)) {
+      ASSERT(Dart_IsString(location.script_url));
+      msg->Printf(",\"location\": { \"url\":");
+      FormatEncodedString(msg, location.script_url);
+      msg->Printf(",\"libraryId\":%d,", location.library_id);
+      msg->Printf("\"tokenOffset\":%d}", location.token_pos);
     }
-
     Dart_Handle locals = Dart_GetLocalVariables(frame);
     ASSERT_NOT_ERROR(locals);
-    msg->Printf("\"locals\":");
+    msg->Printf(",\"locals\":");
     FormatNamedValueList(msg, locals);
     msg->Printf("}");
   }
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index f04a367..c9fc1b2 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -210,28 +210,29 @@
 }
 
 
-void FUNCTION_NAME(File_ReadList)(Dart_NativeArguments args) {
+void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) {
   Dart_EnterScope();
   File* file = GetFilePointer(Dart_GetNativeArgument(args, 0));
   ASSERT(file != NULL);
   Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
   ASSERT(Dart_IsList(buffer_obj));
-  // Offset and length arguments are checked in Dart code to be
-  // integers and have the property that (offset + length) <=
+  // start and end arguments are checked in Dart code to be
+  // integers and have the property that end <=
   // list.length. Therefore, it is safe to extract their value as
   // intptr_t.
-  intptr_t offset =
+  intptr_t start =
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
-  intptr_t length =
+  intptr_t end =
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+  intptr_t length = end - start;
   intptr_t array_len = 0;
   Dart_Handle result = Dart_ListLength(buffer_obj, &array_len);
   if (Dart_IsError(result)) Dart_PropagateError(result);
-  ASSERT((offset + length) <= array_len);
+  ASSERT(end <= array_len);
   uint8_t* buffer = new uint8_t[length];
   int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
   if (bytes_read >= 0) {
-    result = Dart_ListSetAsBytes(buffer_obj, offset, buffer, bytes_read);
+    result = Dart_ListSetAsBytes(buffer_obj, start, buffer, bytes_read);
     if (Dart_IsError(result)) {
       delete[] buffer;
       Dart_PropagateError(result);
@@ -247,7 +248,7 @@
 }
 
 
-void FUNCTION_NAME(File_WriteList)(Dart_NativeArguments args) {
+void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) {
   Dart_EnterScope();
   File* file = GetFilePointer(Dart_GetNativeArgument(args, 0));
   ASSERT(file != NULL);
@@ -257,24 +258,23 @@
   // integers and have the property that (offset + length) <=
   // list.length. Therefore, it is safe to extract their value as
   // intptr_t.
-  intptr_t offset =
+  intptr_t start =
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
-  intptr_t length =
+  intptr_t end =
       DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+  intptr_t length = end - start;
   intptr_t buffer_len = 0;
   Dart_Handle result = Dart_ListLength(buffer_obj, &buffer_len);
   if (Dart_IsError(result)) Dart_PropagateError(result);
-  ASSERT((offset + length) <= buffer_len);
+  ASSERT(end <= buffer_len);
   uint8_t* buffer = new uint8_t[length];
-  result = Dart_ListGetAsBytes(buffer_obj, offset, buffer, length);
+  result = Dart_ListGetAsBytes(buffer_obj, start, buffer, length);
   if (Dart_IsError(result)) {
     delete[] buffer;
     Dart_PropagateError(result);
   }
   int64_t bytes_written = file->Write(reinterpret_cast<void*>(buffer), length);
-  if (bytes_written >= 0) {
-    Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
-  } else {
+  if (bytes_written != length) {
     Dart_Handle err = DartUtils::NewDartOSError();
     if (Dart_IsError(err)) Dart_PropagateError(err);
     Dart_SetReturnValue(args, err);
@@ -911,7 +911,7 @@
     if (!file->IsClosed()) {
       int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
       Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
-      uint8_t* data = io_buffer->value.as_external_byte_array.data;
+      uint8_t* data = io_buffer->value.as_external_typed_data.data;
       int64_t bytes_read = file->Read(data, length);
       if (bytes_read >= 0) {
         CObjectExternalUint8Array* external_array =
@@ -933,7 +933,7 @@
 }
 
 
-static CObject* FileReadListRequest(const CObjectArray& request) {
+static CObject* FileReadIntoRequest(const CObjectArray& request) {
   if (request.Length() == 3 &&
       request[1]->IsIntptr() &&
       request[2]->IsInt32OrInt64()) {
@@ -942,7 +942,7 @@
     if (!file->IsClosed()) {
       int64_t length = CObjectInt32OrInt64ToInt64(request[2]);
       Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
-      uint8_t* data = io_buffer->value.as_external_byte_array.data;
+      uint8_t* data = io_buffer->value.as_external_typed_data.data;
       int64_t bytes_read = file->Read(data, length);
       if (bytes_read >= 0) {
         CObjectExternalUint8Array* external_array =
@@ -965,27 +965,55 @@
 }
 
 
-static CObject* FileWriteListRequest(const CObjectArray& request) {
+static int SizeInBytes(Dart_CObject::TypedDataType type) {
+  switch (type) {
+    case Dart_CObject::kInt8Array:
+    case Dart_CObject::kUint8Array:
+    case Dart_CObject::kUint8ClampedArray:
+      return 1;
+    case Dart_CObject::kInt16Array:
+    case Dart_CObject::kUint16Array:
+      return 2;
+    case Dart_CObject::kInt32Array:
+    case Dart_CObject::kUint32Array:
+    case Dart_CObject::kFloat32Array:
+      return 4;
+    case Dart_CObject::kInt64Array:
+    case Dart_CObject::kUint64Array:
+    case Dart_CObject::kFloat64Array:
+      return 8;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+
+static CObject* FileWriteFromRequest(const CObjectArray& request) {
   if (request.Length() == 5 &&
       request[1]->IsIntptr() &&
-      (request[2]->IsUint8Array() || request[2]->IsArray()) &&
+      (request[2]->IsTypedData() || request[2]->IsArray()) &&
       request[3]->IsInt32OrInt64() &&
       request[4]->IsInt32OrInt64()) {
     File* file = CObjectToFilePointer(request[1]);
     ASSERT(file != NULL);
     if (!file->IsClosed()) {
-      int64_t offset = CObjectInt32OrInt64ToInt64(request[3]);
-      int64_t length = CObjectInt32OrInt64ToInt64(request[4]);
+      int64_t start = CObjectInt32OrInt64ToInt64(request[3]);
+      int64_t end = CObjectInt32OrInt64ToInt64(request[4]);
+      int64_t length = end - start;
       uint8_t* buffer_start;
-      if (request[2]->IsUint8Array()) {
-        CObjectUint8Array byte_array(request[2]);
-        buffer_start = byte_array.Buffer() + offset;
+      if (request[2]->IsTypedData()) {
+        CObjectTypedData typed_data(request[2]);
+        start = start * SizeInBytes(typed_data.Type());
+        length = length * SizeInBytes(typed_data.Type());
+        buffer_start = typed_data.Buffer() + start;
       } else {
         CObjectArray array(request[2]);
         buffer_start = new uint8_t[length];
         for (int i = 0; i < length; i++) {
-          if (array[i + offset]->IsInt32OrInt64()) {
-            int64_t value = CObjectInt32OrInt64ToInt64(array[i + offset]);
+          if (array[i + start]->IsInt32OrInt64()) {
+            int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]);
             buffer_start[i] = static_cast<uint8_t>(value & 0xFF);
           } else {
             // Unsupported type.
@@ -993,11 +1021,11 @@
             return CObject::IllegalArgumentError();
           }
         }
-        offset = 0;
+        start = 0;
       }
       int64_t bytes_written =
           file->Write(reinterpret_cast<void*>(buffer_start), length);
-      if (!request[2]->IsUint8Array()) {
+      if (!request[2]->IsTypedData()) {
         delete[] buffer_start;
       }
       if (bytes_written >= 0) {
@@ -1103,11 +1131,11 @@
         case File::kReadRequest:
           response = FileReadRequest(request);
           break;
-        case File::kReadListRequest:
-          response = FileReadListRequest(request);
+        case File::kReadIntoRequest:
+          response = FileReadIntoRequest(request);
           break;
-        case File::kWriteListRequest:
-          response = FileWriteListRequest(request);
+        case File::kWriteFromRequest:
+          response = FileWriteFromRequest(request);
           break;
         case File::kDeleteLinkRequest:
           response = FileDeleteLinkRequest(request);
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index b4c5c50..944fd6a 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -75,8 +75,8 @@
     kReadByteRequest = 14,
     kWriteByteRequest = 15,
     kReadRequest = 16,
-    kReadListRequest = 17,
-    kWriteListRequest = 18,
+    kReadIntoRequest = 17,
+    kWriteFromRequest = 18,
     kCreateLinkRequest = 19,
     kDeleteLinkRequest = 20
   };
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index c246002..65ac0a4 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -26,11 +26,11 @@
   /* patch */ static int _close(int id) native "File_Close";
   /* patch */ static _readByte(int id) native "File_ReadByte";
   /* patch */ static _read(int id, int bytes) native "File_Read";
-  /* patch */ static _readList(int id, List<int> buffer, int offset, int bytes)
-      native "File_ReadList";
+  /* patch */ static _readInto(int id, List<int> buffer, int start, int end)
+      native "File_ReadInto";
   /* patch */ static _writeByte(int id, int value) native "File_WriteByte";
-  /* patch */ static _writeList(int id, List<int> buffer, int offset, int bytes)
-      native "File_WriteList";
+  /* patch */ static _writeFrom(int id, List<int> buffer, int start, int end)
+      native "File_WriteFrom";
   /* patch */ static _position(int id) native "File_Position";
   /* patch */ static _setPosition(int id, int position)
       native "File_SetPosition";
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 64828f5..ae87f4e 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -199,7 +199,7 @@
           _stdin._sink.destroy();
         }
 
-        exitDataBuffer.setRange(exitDataRead, data.length, data);
+        exitDataBuffer.setRange(exitDataRead, exitDataRead + data.length, data);
         exitDataRead += data.length;
         if (exitDataRead == EXIT_DATA_SIZE) {
           handleExit();
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 81e8ab3..bb71cc2 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -115,11 +115,11 @@
     var socket = new _NativeSocket.listen();
     var result = socket.nativeCreateBindListen(address, port, backlog);
     if (result is OSError) {
-      return new Future.immediateError(
+      return new Future.error(
           new SocketIOException("Failed to create server socket", result));
     }
     if (port != 0) socket.localPort = port;
-    return new Future.immediate(socket);
+    return new Future.value(socket);
   }
 
   _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET {
@@ -175,10 +175,10 @@
     }
     if (isClosed) return 0;
     if (bytes == 0) return 0;
-    _BufferAndOffset bufferAndOffset =
-        _ensureFastAndSerializableBuffer(buffer, offset, bytes);
+    _BufferAndStart bufferAndStart =
+        _ensureFastAndSerializableBuffer(buffer, offset, offset + bytes);
     var result =
-        nativeWrite(bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
+        nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
     if (result is OSError) {
       reportError(result, "Write failed");
       result = 0;
@@ -432,8 +432,10 @@
 
   _RawServerSocket(this._socket) {
     _controller = new StreamController(
-        onSubscriptionStateChange: _onSubscriptionStateChange,
-        onPauseStateChange: _onPauseStateChange);
+        onListen: _onSubscriptionStateChange,
+        onCancel: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange);
     _socket.closeFuture.then((_) => _controller.close());
     _socket.setHandlers(
       read: () {
@@ -441,21 +443,21 @@
         if (socket != null) _controller.add(new _RawSocket(socket));
       },
       error: (e) {
-        _controller.addError(new AsyncError(e));
+        _controller.addError(e);
         _controller.close();
       }
     );
   }
 
   StreamSubscription<RawSocket> listen(void onData(RawSocket event),
-                                       {void onError(AsyncError error),
+                                       {void onError(Object error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _controller.stream.listen(
         onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: unsubscribeOnError);
+        cancelOnError: cancelOnError);
   }
 
   int get port => _socket.port;
@@ -501,8 +503,10 @@
 
   _RawSocket(this._socket) {
     _controller = new StreamController(
-        onSubscriptionStateChange: _onSubscriptionStateChange,
-        onPauseStateChange: _onPauseStateChange);
+        onListen: _onSubscriptionStateChange,
+        onCancel: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange);
     _socket.closeFuture.then((_) => _controller.close());
     _socket.setHandlers(
       read: () => _controller.add(RawSocketEvent.READ),
@@ -514,7 +518,7 @@
       },
       closed: () => _controller.add(RawSocketEvent.READ_CLOSED),
       error: (e) {
-        _controller.addError(new AsyncError(e));
+        _controller.addError(e);
         close();
       }
     );
@@ -535,14 +539,14 @@
   }
 
   StreamSubscription<RawSocketEvent> listen(void onData(RawSocketEvent event),
-                                            {void onError(AsyncError error),
+                                            {void onError(Object error),
                                              void onDone(),
-                                             bool unsubscribeOnError}) {
+                                             bool cancelOnError}) {
     return _controller.stream.listen(
         onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: unsubscribeOnError);
+        cancelOnError: cancelOnError);
   }
 
   int available() => _socket.available();
@@ -629,14 +633,14 @@
   _ServerSocket(this._socket);
 
   StreamSubscription<Socket> listen(void onData(Socket event),
-                                    {void onError(AsyncError error),
+                                    {void onError(error),
                                      void onDone(),
-                                     bool unsubscribeOnError}) {
+                                     bool cancelOnError}) {
     return _socket.map((rawSocket) => new _Socket(rawSocket)).listen(
         onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: unsubscribeOnError);
+        cancelOnError: cancelOnError);
   }
 
   int get port => _socket.port;
@@ -665,32 +669,13 @@
   int offset;
   List<int> buffer;
   bool paused = false;
+  Completer streamCompleter;
 
   _SocketStreamConsumer(this.socket);
 
-  Future<Socket> consume(Stream<List<int>> stream) {
-    if (socket._raw != null) {
-      subscription = stream.listen(
-          (data) {
-            assert(!paused);
-            assert(buffer == null);
-            buffer = data;
-            offset = 0;
-            write();
-          },
-          onError: (error) {
-            socket._consumerDone(error);
-          },
-          onDone: () {
-            socket._consumerDone();
-          },
-          unsubscribeOnError: true);
-    }
-    return socket._doneFuture;
-  }
-
   Future<Socket> addStream(Stream<List<int>> stream) {
-    Completer completer = new Completer<Socket>();
+    socket._ensureRawSocketSubscription();
+    streamCompleter = new Completer<Socket>();
     if (socket._raw != null) {
       subscription = stream.listen(
           (data) {
@@ -701,20 +686,20 @@
             write();
           },
           onError: (error) {
-            socket._consumerDone(error);
-            completer.completeError(error.error, error.stackTrace);
+            socket._consumerDone();
+            done(error);
           },
           onDone: () {
-            completer.complete(socket);
+            done();
           },
-          unsubscribeOnError: true);
+          cancelOnError: true);
     }
-    return completer.future;
+    return streamCompleter.future;
   }
 
   Future<Socket> close() {
     socket._consumerDone();
-    return completer.future;
+    return new Future.value(socket);
   }
 
   void write() {
@@ -743,7 +728,20 @@
       }
     } catch (e) {
       stop();
-      socket._consumerDone(e);
+      socket._consumerDone();
+      done(e);
+    }
+  }
+
+  void done([error]) {
+    if (streamCompleter != null) {
+      var tmp = streamCompleter;
+      streamCompleter = null;
+      if (error != null) {
+        tmp.completeError(error);
+      } else {
+        tmp.complete(socket);
+      }
     }
   }
 
@@ -762,14 +760,15 @@
   StreamController _controller;
   bool _controllerClosed = false;
   _SocketStreamConsumer _consumer;
-  IOSink<Socket> _sink;
-  Completer _doneCompleter;
+  IOSink _sink;
   var _subscription;
 
   _Socket(RawSocket this._raw) {
     _controller = new StreamController<List<int>>(
-        onSubscriptionStateChange: _onSubscriptionStateChange,
-        onPauseStateChange: _onPauseStateChange);
+        onListen: _onSubscriptionStateChange,
+        onCancel: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange);
     _consumer = new _SocketStreamConsumer(this);
     _sink = new IOSink(_consumer);
 
@@ -791,14 +790,14 @@
   _NativeSocket get _nativeSocket => _raw._socket;
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _controller.stream.listen(
         onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: unsubscribeOnError);
+        cancelOnError: cancelOnError);
   }
 
   Encoding get encoding => _sink.encoding;
@@ -817,15 +816,11 @@
 
   void add(List<int> bytes) => _sink.add(bytes);
 
-  Future<Socket> consume(Stream<List<int>> stream) {
-    return _sink.consume(stream);
+  Future<Socket> addStream(Stream<List<int>> stream) {
+    return _sink.addStream(stream);
   }
 
-  Future<Socket> writeStream(Stream<List<int>> stream) {
-    return _sink.writeStream(stream);
-  }
-
-  close() => _sink.close();
+  Future<Socket> close() => _sink.close();
 
   Future<Socket> get done => _sink.done;
 
@@ -851,11 +846,11 @@
   // consumer needs a subscription as they share the error and done
   // events from the raw socket.
   void _ensureRawSocketSubscription() {
-    if (_subscription == null) {
+    if (_subscription == null && _raw != null) {
       _subscription = _raw.listen(_onData,
                                   onError: _onError,
                                   onDone: _onDone,
-                                  unsubscribeOnError: true);
+                                  cancelOnError: true);
     }
   }
 
@@ -908,7 +903,7 @@
       _controllerClosed = true;
       _controller.close();
     }
-    _done();
+    _consumer.done();
   }
 
   void _onError(error) {
@@ -917,27 +912,7 @@
       _controller.addError(error);
       _controller.close();
     }
-    _done(error);
-  }
-
-  get _doneFuture {
-    if (_doneCompleter == null) {
-      _ensureRawSocketSubscription();
-      _doneCompleter = new Completer();
-    }
-    return _doneCompleter.future;
-  }
-
-  void _done([error]) {
-    if (_doneCompleter != null) {
-      var tmp = _doneCompleter;
-      _doneCompleter = null;
-      if (error != null) {
-        tmp.completeError(error);
-      } else {
-        tmp.complete(this);
-      }
-    }
+    _consumer.done(error);
   }
 
   int _write(List<int> data, int offset, int length) =>
@@ -953,8 +928,7 @@
     }
   }
 
-  void _consumerDone([error]) {
-    _done(error);
+  void _consumerDone() {
     if (_raw != null) {
       _raw.shutdown(SocketDirection.SEND);
       _disableWriteEvent();
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
index f709000..c37c80b 100644
--- a/runtime/embedders/openglui/common/gl.dart
+++ b/runtime/embedders/openglui/common/gl.dart
@@ -214,7 +214,7 @@
   }
 
   /// Has no effect.
-  void onError(void handleError(AsyncError error)) {}
+  void onError(void handleError(Object error)) {}
 
   /// Has no effect.
   void onDone(void handleDone()) {}
@@ -255,6 +255,12 @@
       _target.removeListener(_eventType, _onData);
     }
   }
+
+  Future asFuture([var futureValue]) {
+    // We just need a future that will never succeed or fail.
+    Completer completer = new Completer();
+    return completer.future;
+  }
 }
 
 class _EventStream<T extends Event> extends Stream<T> {
@@ -268,9 +274,9 @@
   bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
-      { void onError(AsyncError error),
+      { void onError(Object error),
       void onDone(),
-      bool unsubscribeOnError}) {
+      bool cancelOnError}) {
 
     return new _EventStreamSubscription<T>(
         this._target, this._eventType, onData);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 2ac024a..121e49d 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -942,6 +942,11 @@
  * representation as a Dart_CObject.
  *
  * The string encoding in the 'value.as_string' is UTF-8.
+ *
+ * All the different types from dart:typeddata are exposed as type
+ * kTypedData. The specific type from dart:typeddata is in the type
+ * field of the as_typed_data structure. The length in the
+ * as_typed_data structure is always in bytes.
  */
 typedef struct _Dart_CObject {
   enum Type {
@@ -953,11 +958,27 @@
     kDouble,
     kString,
     kArray,
-    kUint8Array,
-    kExternalUint8Array,
+    kTypedData,
+    kExternalTypedData,
     kUnsupported,
     kNumberOfTypes
   } type;
+
+  enum TypedDataType {
+    kInt8Array = 0,
+    kUint8Array,
+    kUint8ClampedArray,
+    kInt16Array,
+    kUint16Array,
+    kInt32Array,
+    kUint32Array,
+    kInt64Array,
+    kUint64Array,
+    kFloat32Array,
+    kFloat64Array,
+    kNumberOfTypedDataTypes
+  };
+
   union {
     bool as_bool;
     int32_t as_int32;
@@ -970,15 +991,17 @@
       struct _Dart_CObject** values;
     } as_array;
     struct {
+      TypedDataType type;
       int length;
       uint8_t* values;
-    } as_byte_array;
+    } as_typed_data;
     struct {
+      TypedDataType type;
       int length;
       uint8_t* data;
       void* peer;
       Dart_WeakPersistentHandleFinalizer callback;
-    } as_external_byte_array;
+    } as_external_typed_data;
   } value;
 } Dart_CObject;
 
@@ -1665,6 +1688,7 @@
   kUint64,
   kFloat32,
   kFloat64,
+  kFloat32x4,
   kInvalid
 } Dart_TypedData_Type;
 
diff --git a/runtime/include/dart_debugger_api.h b/runtime/include/dart_debugger_api.h
index 1fa5f2d..5694f8e 100755
--- a/runtime/include/dart_debugger_api.h
+++ b/runtime/include/dart_debugger_api.h
@@ -44,6 +44,17 @@
   kShutdown,
 } Dart_IsolateEvent;
 
+
+/**
+ * Represents a location in Dart code.
+ */
+typedef struct {
+  Dart_Handle script_url;  // Url (string) of the script.
+  int32_t library_id;      // Library in which the script is loaded.
+  int32_t token_pos;       // Code address.
+} Dart_CodeLocation;
+
+
 typedef void Dart_IsolateEventHandler(Dart_IsolateId isolate_id,
                                       Dart_IsolateEvent kind);
 
@@ -362,6 +373,8 @@
 
 
 /**
+ * DEPRECATED -- Use Dart_ActivationframeGetLocation instead.
+ *
  * Returns information about the given activation frame.
  * \function_name receives a string handle with the qualified
  *    function name.
@@ -386,15 +399,20 @@
 
 
 /**
- * Returns text location of the given activation frame.
- * \script_url receives a string handle with the url of the
- *    source script that contains the frame's function.
+ * Returns code location of the given activation frame.
+ *
+ * \function_name receives a string handle with the qualified
+ *    function name.
+ * \location.script_url receives a string handle with the url of
+ *    the source script that contains the frame's function.
  *    Receives a null handle if there is no textual location
  *    that corresponds to the frame, e.g. for implicitly
  *    generated constructors.
- * \token_number receives the line number in the script.
+ * \location.library_id receives the id of the library in which the
+ *    function in this frame is defined.
+ * \location.token_pos receives the token position in the script.
  *
- * Any or all of the out parameters above may be NULL.
+ * Any of the out parameters above may be NULL.
  *
  * Requires there to be a current isolate.
  *
@@ -404,9 +422,8 @@
  */
 DART_EXPORT Dart_Handle Dart_ActivationFrameGetLocation(
                             Dart_ActivationFrame activation_frame,
-                            Dart_Handle* script_url,
-                            intptr_t* library_id,
-                            intptr_t* token_number);
+                            Dart_Handle* function_name,
+                            Dart_CodeLocation* location);
 
 
 /**
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 0ee4d08..1ebc5b7 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -29,6 +29,15 @@
         "Cannot add to a non-extendable array");
   }
 
+  void insertAll(int index, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot add to a non-extendable array");
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    IterableMixinWorkaround.setAllList(this, index, iterable);
+  }
+
   E removeAt(int index) {
     throw new UnsupportedError(
         "Cannot remove element of a non-extendable array");
@@ -54,27 +63,46 @@
   }
 
   // List interface.
-  void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
-    if (length < 0) {
-      throw new ArgumentError("negative length $length");
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    if (start < 0 || start > this.length) {
+      throw new RangeError.range(start, 0, this.length);
     }
-    if (from is _ObjectArray) {
-      _copyFromObjectArray(from, startFrom, start, length);
+    if (end < 0 || end > this.length) {
+      throw new RangeError.range(end, start, this.length);
+    }
+    int length = end - start;
+    if (length == 0) return;
+
+    if (iterable is _ObjectArray) {
+      _copyFromObjectArray(iterable, skipCount, start, length);
     } else {
-      Arrays.copy(from, startFrom, this, start, length);
+      List otherList;
+      int otherStart;
+      if (iterable is List) {
+        otherList = iterable;
+        otherStart = skipCount;
+      } else {
+        otherList =
+            iterable.skip(skipCount).take(length).toList(growable: false);
+        otherStart = 0;
+      }
+      Arrays.copy(otherList, otherStart, this, start, length);
     }
   }
 
-  void removeRange(int start, int length) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot remove range of a non-extendable array");
   }
 
-  void insertRange(int start, int length, [E initialValue = null]) {
+  void replaceRange(int start, int end, Iterable<E> iterable) {
     throw new UnsupportedError(
-        "Cannot insert range in a non-extendable array");
+        "Cannot remove range of a non-extendable array");
   }
 
+  void fillRange(int start, int end, [E fillValue]) {
+    IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+  }
 
   List<E> sublist(int start, [int end]) {
     Arrays.indicesCheck(this, start, end);
@@ -267,6 +295,16 @@
         "Cannot add to an immutable array");
   }
 
+  void insertAll(int index, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot add to an immutable array");
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot modify an immutable array");
+  }
+
   E removeAt(int index) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
@@ -292,19 +330,24 @@
         "Cannot modify an immutable array");
   }
 
-  void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
   }
 
-  void removeRange(int start, int length) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot remove range of an immutable array");
   }
 
-  void insertRange(int start, int length, [E initialValue = null]) {
+  void fillRange(int start, int end, [E fillValue]) {
     throw new UnsupportedError(
-        "Cannot insert range in an immutable array");
+        "Cannot modify an immutable array");
+  }
+
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot modify an immutable array");
   }
 
   List<E> sublist(int start, [int end]) {
diff --git a/runtime/lib/collection_dev_patch.dart b/runtime/lib/collection_dev_patch.dart
new file mode 100644
index 0000000..c4618bc
--- /dev/null
+++ b/runtime/lib/collection_dev_patch.dart
@@ -0,0 +1,3 @@
+// 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.
diff --git a/runtime/lib/collection_dev_sources.gypi b/runtime/lib/collection_dev_sources.gypi
new file mode 100644
index 0000000..76121f5
--- /dev/null
+++ b/runtime/lib/collection_dev_sources.gypi
@@ -0,0 +1,13 @@
+# 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.
+
+# Sources that patch the library "dart:_collection-dev".
+
+{
+  'sources': [
+    'collection_dev_patch.dart',
+    # The above file needs to be first as it imports required libraries.
+    'symbol_patch.dart',
+  ],
+}
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index 8ed2abc..1ddd5d9 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -700,7 +700,7 @@
 /**
  * Generic iterable based on a [_HashTable].
  */
-abstract class _HashTableIterable<E> extends Iterable<E> {
+abstract class _HashTableIterable<E> extends IterableBase<E> {
   final _HashTable _hashTable;
   _HashTableIterable(this._hashTable);
 
@@ -924,7 +924,7 @@
   }
 }
 
-class _LinkedHashTableKeyIterable<K> extends Iterable<K> {
+class _LinkedHashTableKeyIterable<K> extends IterableBase<K> {
   final _LinkedHashTable<K> _table;
   _LinkedHashTableKeyIterable(this._table);
   Iterator<K> get iterator => new _LinkedHashTableKeyIterator<K>(_table);
@@ -940,7 +940,7 @@
   K _getCurrent(int offset) => _hashTable._key(offset);
 }
 
-class _LinkedHashTableValueIterable<V> extends Iterable<V> {
+class _LinkedHashTableValueIterable<V> extends IterableBase<V> {
   final _LinkedHashTable _hashTable;
   final int _valueIndex;
   _LinkedHashTableValueIterable(this._hashTable, this._valueIndex);
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 8e6d905..0a27429 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -4,3 +4,5 @@
 
 import "dart:math";
 import "dart:typeddata";
+
+import "dart:_collection-dev" as _symbol_dev;
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index c1336c4..b1f2f8d 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -76,7 +76,7 @@
         _flooredDivision(_localDateInUtcMs, Duration.MILLISECONDS_PER_DAY);
     // 1970-1-1 was a Thursday.
     return ((daysSince1970 + DateTime.THURSDAY - DateTime.MONDAY)
-            % DateTime.DAYS_IN_WEEK) +
+            % DateTime.DAYS_PER_WEEK) +
         DateTime.MONDAY;
   }
 
diff --git a/runtime/lib/deferred_load_patch.dart b/runtime/lib/deferred_load_patch.dart
index 8d0a9ff..2bd0027 100644
--- a/runtime/lib/deferred_load_patch.dart
+++ b/runtime/lib/deferred_load_patch.dart
@@ -9,7 +9,7 @@
     // Dummy implementation that should eventually be replaced by real
     // implementation.
     Future future =
-        new Future<bool>.immediate(!_loadedLibraries.contains(libraryName));
+        new Future<bool>.value(!_loadedLibraries.contains(libraryName));
     _loadedLibraries.add(libraryName);
     return future;
   }
diff --git a/runtime/lib/function_patch.dart b/runtime/lib/function_patch.dart
index 56b817d..f0f016c 100644
--- a/runtime/lib/function_patch.dart
+++ b/runtime/lib/function_patch.dart
@@ -8,21 +8,21 @@
 
   /* patch */ static apply(Function function,
                            List positionalArguments,
-                           [Map<String,dynamic> namedArguments]) {
+                           [Map<Symbol, dynamic> namedArguments]) {
     int numPositionalArguments = 1 +  // Function is first implicit argument.
         (positionalArguments != null ? positionalArguments.length : 0);
     int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
     int numArguments = numPositionalArguments + numNamedArguments;
     List arguments = new List(numArguments);
     arguments[0] = function;
-    arguments.setRange(1, numPositionalArguments - 1, positionalArguments);
+    arguments.setRange(1, numPositionalArguments, positionalArguments);
     List names = new List(numNamedArguments);
     int argumentIndex = numPositionalArguments;
     int nameIndex = 0;
     if (numNamedArguments > 0) {
       namedArguments.forEach((name, value) {
         arguments[argumentIndex++] = value;
-        names[nameIndex++] = name;
+        names[nameIndex++] = _symbol_dev.Symbol.getName(name);
       });
     }
     return _apply(arguments, names);
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 76cacb4..f24da18 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -52,6 +52,33 @@
     }
   }
 
+  void insertAll(int index, Iterable<T> iterable) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    // TODO(floitsch): we can probably detect more cases.
+    if (iterable is! List && iterable is! Set && iterable is! SubListIterable) {
+      iterable = iterable.toList();
+    }
+    int insertionLength = iterable.length;
+    // There might be errors after the length change, in which case the list
+    // will end up being modified but the operation not complete. Unless we
+    // always go through a "toList" we can't really avoid that.
+    this.length += insertionLength;
+    setRange(index + insertionLength, this.length, this, index);
+    setAll(index, iterable);
+  }
+
+  void setAll(int index, Iterable<T> iterable) {
+    if (iterable is List) {
+      setRange(index, index + iterable.length, iterable);
+    } else {
+      for (T element in iterable) {
+        this[index++] = element;
+      }
+    }
+  }
+
   void removeWhere(bool test(T element)) {
     IterableMixinWorkaround.removeWhereList(this, test);
   }
@@ -65,43 +92,26 @@
     return IterableMixinWorkaround.getRangeList(this, start, end);
   }
 
-  void setRange(int start, int length, List<T> from, [int startFrom = 0]) {
-    IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
+  void setRange(int start, int end, Iterable<T> iterable, [int skipCount = 0]) {
+    IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
   }
 
-  void removeRange(int start, int length) {
-    if (length == 0) {
-      return;
-    }
-    Arrays.rangeCheck(this, start, length);
+  void removeRange(int start, int end) {
+    Arrays.indicesCheck(this, start, end);
     Arrays.copy(this,
-                start + length,
+                end,
                 this,
                 start,
-                this.length - length - start);
-    this.length = this.length - length;
+                this.length - end);
+    this.length = this.length - (end - start);
   }
 
-  void insertRange(int start, int length, [T initialValue = null]) {
-    if (length == 0) {
-      return;
-    }
-    if ((length < 0) || (length is! int)) {
-      throw new ArgumentError("invalid length specified $length");
-    }
-    if (start < 0 || start > this.length) {
-      throw new RangeError.value(start);
-    }
-    var old_length = this.length;
-    this.length = old_length + length;  // Will expand if needed.
-    Arrays.copy(this,
-                start,
-                this,
-                start + length,
-                old_length - start);
-    for (int i = start; i < start + length; i++) {
-      this[i] = initialValue;
-    }
+  void replaceRange(int start, int end, Iterable<T> iterable) {
+    IterableMixinWorkaround.replaceRangeList(this, start, end, iterable);
+  }
+
+  void fillRange(int start, int end, [T fillValue]) {
+    IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
   }
 
   List<T> sublist(int start, [int end]) {
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 82f5458..3ca9ed5 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -82,7 +82,7 @@
   }
 }
 
-class _ImmutableMapKeyIterable<E> extends Iterable<E> {
+class _ImmutableMapKeyIterable<E> extends IterableBase<E> {
   final ImmutableMap _map;
   _ImmutableMapKeyIterable(this._map);
 
@@ -91,7 +91,7 @@
   }
 }
 
-class _ImmutableMapValueIterable<E> extends Iterable<E> {
+class _ImmutableMapValueIterable<E> extends IterableBase<E> {
   final ImmutableMap _map;
   _ImmutableMapValueIterable(this._map);
 
diff --git a/runtime/lib/invocation_mirror_patch.dart b/runtime/lib/invocation_mirror_patch.dart
index c498eac..0b438c7 100644
--- a/runtime/lib/invocation_mirror_patch.dart
+++ b/runtime/lib/invocation_mirror_patch.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.
 
-class _InvocationMirror implements InvocationMirror {
+class _InvocationMirror implements Invocation {
   // Constants describing the invocation type.
   // _FIELD cannot be generated by regular invocation mirrors.
   static const int _METHOD = 0;
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 144e9c9..a4daac2 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -34,8 +34,8 @@
     _port.send(message);
   }
 
-  void addError(AsyncError errorEvent) {
-    throw new UnimplementedError("signalError on isolate streams");
+  void addError(Object errorEvent) {
+    throw new UnimplementedError("addError on isolate streams");
   }
 
   void close() {
diff --git a/runtime/lib/lib_sources.gypi b/runtime/lib/lib_sources.gypi
index 7f1c37a..d3efd48 100644
--- a/runtime/lib/lib_sources.gypi
+++ b/runtime/lib/lib_sources.gypi
@@ -50,7 +50,6 @@
     'string.cc',
     'string_patch.dart',
     'string_buffer_patch.dart',
-    'symbol_patch.dart',
     'type_patch.dart',
     'weak_property.dart',
     'weak_property.cc',
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 6588649..8aa5abd 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -9,20 +9,39 @@
   return (value == null || value is num || value is String || value is bool);
 }
 
-Map _filterMap(Map old_map, bool filter(key, value)) {
-  Map new_map = new Map();
+Map _filterMap(Map<Symbol, dynamic> old_map, bool filter(Symbol key, value)) {
+  Map new_map = new Map<Symbol, dynamic>();
   old_map.forEach((key, value) {
-      if (filter(key, value)) {
-        new_map[key] = value;
-      }
-    });
+    if (filter(key, value)) {
+      new_map[key] = value;
+    }
+  });
   return new_map;
 }
 
+String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
+
+Symbol _s(String name) {
+  if (name == null) return null;
+  return new _symbol_dev.Symbol.unvalidated(name);
+}
+
+Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
+  if (owner == null) return simpleName;
+  return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}');
+}
+
+Map<Symbol, dynamic> _convertStringToSymbolMap(Map<String, dynamic> map) {
+  if (map == null) return null;
+  Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
+  map.forEach((name, value) => result[_s(name)] = value);
+  return result;
+}
+
 String _makeSignatureString(TypeMirror returnType,
                             List<ParameterMirror> parameters) {
   StringBuffer buf = new StringBuffer();
-  buf.write(returnType.qualifiedName);
+  buf.write(_n(returnType.qualifiedName));
   buf.write(' (');
   bool found_optional_param = false;
   for (int i = 0; i < parameters.length; i++) {
@@ -31,7 +50,7 @@
       buf.write('[');
       found_optional_param = true;
     }
-    buf.write(param.type.qualifiedName);
+    buf.write(_n(param.type.qualifiedName));
     if (i < (parameters.length - 1)) {
       buf.write(', ');
     }
@@ -44,10 +63,13 @@
 }
 
 class _LocalMirrorSystemImpl implements MirrorSystem {
-  _LocalMirrorSystemImpl(this.libraries, this.isolate)
-      : _functionTypes = new Map<String, FunctionTypeMirror>() {}
+  // TODO(ahe): [libraries] should be Map<Uri, LibraryMirror>.
+  // Change parameter back to "this.libraries" when native code is changed.
+  _LocalMirrorSystemImpl(Map<String, LibraryMirror> libraries, this.isolate)
+      : _functionTypes = new Map<String, FunctionTypeMirror>(),
+        this.libraries = _convertStringToSymbolMap(libraries);
 
-  final Map<String, LibraryMirror> libraries;
+  final Map<Symbol, LibraryMirror> libraries;
   final IsolateMirror isolate;
 
   TypeMirror _dynamicType = null;
@@ -139,10 +161,10 @@
 abstract class _LocalObjectMirrorImpl extends _LocalVMObjectMirrorImpl
     implements ObjectMirror {
   _LocalObjectMirrorImpl(ref) : super(ref) {}
-  
-Future<InstanceMirror> invokeAsync(String memberName,
-                                   List positionalArguments,
-                                   [Map<String,dynamic> namedArguments]) {
+
+  Future<InstanceMirror> invokeAsync(Symbol memberName,
+                                     List positionalArguments,
+                                     [Map<Symbol, dynamic> namedArguments]) {
     if (namedArguments != null) {
       throw new UnimplementedError(
           'named argument support is not implemented');
@@ -155,29 +177,29 @@
     Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
     try {
       completer.complete(
-          _invoke(this, memberName, positionalArguments));
+          _invoke(this, _n(memberName), positionalArguments));
     } catch (exception, s) {
       completer.completeError(exception, s);
     }
     return completer.future;
   }
 
-  Future<InstanceMirror> getFieldAsync(String fieldName) {
+  Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
     Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
     try {
-      completer.complete(_getField(this, fieldName));
+      completer.complete(_getField(this, _n(fieldName)));
     } catch (exception, s) {
       completer.completeError(exception, s);
     }
     return completer.future;
   }
 
-  Future<InstanceMirror> setFieldAsync(String fieldName, Object arg) {
+  Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object arg) {
     _validateArgument(0, arg);
 
     Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
     try {
-      completer.complete(_setField(this, fieldName, arg));
+      completer.complete(_setField(this, _n(fieldName), arg));
     } catch (exception, s) {
       completer.completeError(exception, s);
     }
@@ -304,7 +326,7 @@
   }
 
   Future<InstanceMirror> applyAsync(List<Object> positionalArguments,
-                                    [Map<String,Object> namedArguments]) {
+                                    [Map<Symbol, Object> namedArguments]) {
     if (namedArguments != null) {
       throw new UnimplementedError(
           'named argument support is not implemented');
@@ -324,7 +346,7 @@
     return completer.future;
   }
 
-  Future<InstanceMirror> findInContext(String name) {
+  Future<InstanceMirror> findInContext(Symbol name) {
     throw new UnimplementedError(
         'ClosureMirror.findInContext() is not implemented');
   }
@@ -334,13 +356,15 @@
 }
 
 class _LazyTypeMirror {
-  _LazyTypeMirror(this.libraryName, this.typeName) {}
+  _LazyTypeMirror(String libraryName, String typeName)
+      : this.libraryName = _s(libraryName),
+        this.typeName = _s(typeName);
 
   TypeMirror resolve(MirrorSystem mirrors) {
     if (libraryName == null) {
-      if (typeName == 'dynamic') {
+      if (typeName == const Symbol('dynamic')) {
         return mirrors.dynamicType;
-      } else if (typeName == 'void') {
+      } else if (typeName == const Symbol('void')) {
         return mirrors.voidType;
       } else {
         throw new UnimplementedError(
@@ -355,35 +379,34 @@
     return resolved;
   }
 
-  final String libraryName;
-  final String typeName;
+  final Symbol libraryName;
+  final Symbol typeName;
 }
 
 class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
     implements ClassMirror {
   _LocalClassMirrorImpl(ref,
-                        this.simpleName,
+                        String simpleName,
                         this.isClass,
                         this._owner,
                         this._superclass,
                         this._superinterfaces,
                         this._defaultFactory,
-                        this.members,
-                        this.constructors,
-                        this.typeVariables) : super(ref) {}
+                        Map<String, Mirror> members,
+                        Map<String, Mirror> constructors,
+                        Map<String, Mirror> typeVariables)
+      : this.simpleName = _s(simpleName),
+        this.members = _convertStringToSymbolMap(members),
+        this.constructors = _convertStringToSymbolMap(constructors),
+        this.typeVariables = _convertStringToSymbolMap(typeVariables),
+        super(ref);
 
-  final String simpleName;
+  final Symbol simpleName;
 
-  String _qualifiedName = null;
-  String get qualifiedName {
-    if (_owner != null) {
-      if (_qualifiedName == null) {
-        _qualifiedName = '${owner.qualifiedName}.${simpleName}';
-      }
-    } else {
-      // The owner of a ClassMirror is null in certain odd cases, like
-      // 'void', 'dynamic' and function type mirrors.
-      _qualifiedName = simpleName;
+  Symbol _qualifiedName = null;
+  Symbol get qualifiedName {
+    if (_qualifiedName == null) {
+      _qualifiedName = _computeQualifiedName(owner, simpleName);
     }
     return _qualifiedName;
   }
@@ -396,7 +419,7 @@
     return _owner;
   }
 
-  bool get isPrivate => simpleName.startsWith('_');
+  bool get isPrivate => _n(simpleName).startsWith('_');
 
   final bool isTopLevel = true;
 
@@ -436,14 +459,14 @@
     return _defaultFactory;
   }
 
-  final Map<String, Mirror> members;
+  final Map<Symbol, Mirror> members;
 
-  Map<String, MethodMirror> _methods = null;
-  Map<String, MethodMirror> _getters = null;
-  Map<String, MethodMirror> _setters = null;
-  Map<String, VariableMirror> _variables = null;
+  Map<Symbol, MethodMirror> _methods = null;
+  Map<Symbol, MethodMirror> _getters = null;
+  Map<Symbol, MethodMirror> _setters = null;
+  Map<Symbol, VariableMirror> _variables = null;
 
-  Map<String, MethodMirror> get methods {
+  Map<Symbol, MethodMirror> get methods {
     if (_methods == null) {
       _methods = _filterMap(
           members,
@@ -452,7 +475,7 @@
     return _methods;
   }
 
-  Map<String, MethodMirror> get getters {
+  Map<Symbol, MethodMirror> get getters {
     if (_getters == null) {
       _getters = _filterMap(
           members,
@@ -461,7 +484,7 @@
     return _getters;
   }
 
-  Map<String, MethodMirror> get setters {
+  Map<Symbol, MethodMirror> get setters {
     if (_setters == null) {
       _setters = _filterMap(
           members,
@@ -470,7 +493,7 @@
     return _setters;
   }
 
-  Map<String, VariableMirror> get variables {
+  Map<Symbol, VariableMirror> get variables {
     if (_variables == null) {
       _variables = _filterMap(
           members,
@@ -479,10 +502,10 @@
     return _variables;
   }
 
-  Map<String, MethodMirror> constructors;
-  Map<String, TypeVariableMirror> typeVariables;
+  Map<Symbol, MethodMirror> constructors;
+  Map<Symbol, TypeVariableMirror> typeVariables;
 
-  Map<String, TypeMirror> get typeArguments {
+  Map<Symbol, TypeMirror> get typeArguments {
     throw new UnimplementedError(
         'ClassMirror.typeArguments is not implemented');
   }
@@ -499,9 +522,9 @@
 
   String toString() => "ClassMirror on '$simpleName'";
 
-  Future<InstanceMirror> newInstanceAsync(String constructorName,
+  Future<InstanceMirror> newInstanceAsync(Symbol constructorName,
                                           List positionalArguments,
-                                          [Map<String,dynamic> namedArguments]) {
+                                          [Map<Symbol, dynamic> namedArguments]) {
     if (namedArguments != null) {
       throw new UnimplementedError(
           'named argument support is not implemented');
@@ -514,7 +537,7 @@
     Completer<InstanceMirror> completer = new Completer<InstanceMirror>();
     try {
       completer.complete(
-          _invokeConstructor(this, constructorName, positionalArguments));
+          _invokeConstructor(this, _n(constructorName), positionalArguments));
     } catch (exception) {
       completer.completeError(exception);
     }
@@ -569,28 +592,31 @@
 
 
 class _LazyTypeVariableMirror {
-  _LazyTypeVariableMirror(this._variableName, this._owner) {}
+  _LazyTypeVariableMirror(String variableName, this._owner)
+      : this._variableName = _s(variableName);
 
   TypeVariableMirror resolve(MirrorSystem mirrors) {
     ClassMirror owner = _owner.resolve(mirrors);
     return owner.typeVariables[_variableName];
   }
 
-  final String _variableName;
+  final Symbol _variableName;
   final _LazyTypeMirror _owner;
 }
 
 class _LocalTypeVariableMirrorImpl extends _LocalMirrorImpl
     implements TypeVariableMirror {
-  _LocalTypeVariableMirrorImpl(this.simpleName,
+  _LocalTypeVariableMirrorImpl(String simpleName,
                                this._owner,
-                               this._upperBound) {}
-  final String simpleName;
+                               this._upperBound)
+      : this.simpleName = _s(simpleName);
 
-  String _qualifiedName = null;
-  String get qualifiedName {
+  final Symbol simpleName;
+
+  Symbol _qualifiedName = null;
+  Symbol get qualifiedName {
     if (_qualifiedName == null) {
-      _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+      _qualifiedName = _computeQualifiedName(owner, simpleName);
     }
     return _qualifiedName;
   }
@@ -626,15 +652,17 @@
 
 class _LocalTypedefMirrorImpl extends _LocalMirrorImpl
     implements TypedefMirror {
-  _LocalTypedefMirrorImpl(this.simpleName,
+  _LocalTypedefMirrorImpl(String simpleName,
                           this._owner,
-                          this._referent) {}
-  final String simpleName;
+                          this._referent)
+      : this.simpleName = _s(simpleName);
 
-  String _qualifiedName = null;
-  String get qualifiedName {
+  final Symbol simpleName;
+
+  Symbol _qualifiedName = null;
+  Symbol get qualifiedName {
     if (_qualifiedName == null) {
-      _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+      _qualifiedName = _computeQualifiedName(owner, simpleName);
     }
     return _qualifiedName;
   }
@@ -669,26 +697,30 @@
 
 
 class _LazyLibraryMirror {
-  _LazyLibraryMirror(this.libraryName) {}
+  _LazyLibraryMirror(String libraryName)
+      : this.libraryName = _s(libraryName);
 
   LibraryMirror resolve(MirrorSystem mirrors) {
     return mirrors.libraries[libraryName];
   }
 
-  final String libraryName;
+  final Symbol libraryName;
 }
 
 class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl
     implements LibraryMirror {
   _LocalLibraryMirrorImpl(ref,
-                          this.simpleName,
+                          String simpleName,
                           this.url,
-                          this.members) : super(ref) {}
+                          Map<String, Mirror> members)
+      : this.simpleName = _s(simpleName),
+        this.members = _convertStringToSymbolMap(members),
+        super(ref);
 
-  final String simpleName;
+  final Symbol simpleName;
 
   // The simple name and the qualified name are the same for a library.
-  String get qualifiedName => simpleName;
+  Symbol get qualifiedName => simpleName;
 
   // Always null for libraries.
   final DeclarationMirror owner = null;
@@ -705,15 +737,15 @@
   }
 
   final String url;
-  final Map<String, Mirror> members;
+  final Map<Symbol, Mirror> members;
 
-  Map<String, ClassMirror> _classes = null;
-  Map<String, MethodMirror> _functions = null;
-  Map<String, MethodMirror> _getters = null;
-  Map<String, MethodMirror> _setters = null;
-  Map<String, VariableMirror> _variables = null;
+  Map<Symbol, ClassMirror> _classes = null;
+  Map<Symbol, MethodMirror> _functions = null;
+  Map<Symbol, MethodMirror> _getters = null;
+  Map<Symbol, MethodMirror> _setters = null;
+  Map<Symbol, VariableMirror> _variables = null;
 
-  Map<String, ClassMirror> get classes {
+  Map<Symbol, ClassMirror> get classes {
     if (_classes == null) {
       _classes = _filterMap(members,
                             (key, value) => (value is ClassMirror));
@@ -721,7 +753,7 @@
     return _classes;
   }
 
-  Map<String, MethodMirror> get functions {
+  Map<Symbol, MethodMirror> get functions {
     if (_functions == null) {
       _functions = _filterMap(members,
                               (key, value) => (value is MethodMirror));
@@ -729,7 +761,7 @@
     return _functions;
   }
 
-  Map<String, MethodMirror> get getters {
+  Map<Symbol, MethodMirror> get getters {
     if (_getters == null) {
       _getters = _filterMap(functions,
                             (key, value) => (value.isGetter));
@@ -737,7 +769,7 @@
     return _getters;
   }
 
-  Map<String, MethodMirror> get setters {
+  Map<Symbol, MethodMirror> get setters {
     if (_setters == null) {
       _setters = _filterMap(functions,
                             (key, value) => (value.isSetter));
@@ -745,7 +777,7 @@
     return _setters;
   }
 
-  Map<String, VariableMirror> get variables {
+  Map<Symbol, VariableMirror> get variables {
     if (_variables == null) {
       _variables = _filterMap(members,
                               (key, value) => (value is VariableMirror));
@@ -758,7 +790,7 @@
 
 class _LocalMethodMirrorImpl extends _LocalMirrorImpl
     implements MethodMirror {
-  _LocalMethodMirrorImpl(this.simpleName,
+  _LocalMethodMirrorImpl(String simpleName,
                          this._owner,
                          this.parameters,
                          this._returnType,
@@ -770,14 +802,15 @@
                          this.isConstConstructor,
                          this.isGenerativeConstructor,
                          this.isRedirectingConstructor,
-                         this.isFactoryConstructor) {}
+                         this.isFactoryConstructor)
+      : this.simpleName = _s(simpleName);
 
-  final String simpleName;
+  final Symbol simpleName;
 
-  String _qualifiedName = null;
-  String get qualifiedName {
+  Symbol _qualifiedName = null;
+  Symbol get qualifiedName {
     if (_qualifiedName == null) {
-      _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+      _qualifiedName = _computeQualifiedName(owner, simpleName);
     }
     return _qualifiedName;
   }
@@ -791,7 +824,8 @@
   }
 
   bool get isPrivate {
-    return simpleName.startsWith('_') || constructorName.startsWith('_');
+    return _n(simpleName).startsWith('_') ||
+        _n(constructorName).startsWith('_');
   }
 
   bool get isTopLevel =>  owner is LibraryMirror;
@@ -825,21 +859,21 @@
   final bool isSetter;
   final bool isConstructor;
 
-  var _constructorName = null;
-  String get constructorName {
+  Symbol _constructorName = null;
+  Symbol get constructorName {
     if (_constructorName == null) {
       if (!isConstructor) {
-        _constructorName = '';
+        _constructorName = _s('');
       } else {
-        var parts = simpleName.split('.');
+        var parts = _n(simpleName).split('.');
         if (parts.length > 2) {
           throw new MirrorException(
               'Internal error in MethodMirror.constructorName: '
               'malformed name <$simpleName>');
         } else if (parts.length == 2) {
-          _constructorName = parts[1];
+          _constructorName = _s(parts[1]);
         } else {
-          _constructorName = '';
+          _constructorName = _s('');
         }
       }
     }
@@ -856,18 +890,19 @@
 
 class _LocalVariableMirrorImpl extends _LocalMirrorImpl
     implements VariableMirror {
-  _LocalVariableMirrorImpl(this.simpleName,
+  _LocalVariableMirrorImpl(String simpleName,
                            this._owner,
                            this._type,
                            this.isStatic,
-                           this.isFinal) {}
+                           this.isFinal)
+      : this.simpleName = _s(simpleName);
 
-  final String simpleName;
+  final Symbol simpleName;
 
-  String _qualifiedName = null;
-  String get qualifiedName {
+  Symbol _qualifiedName = null;
+  Symbol get qualifiedName {
     if (_qualifiedName == null) {
-      _qualifiedName = '${owner.qualifiedName}.${simpleName}';
+      _qualifiedName = _computeQualifiedName(owner, simpleName);
     }
     return _qualifiedName;
   }
@@ -881,7 +916,7 @@
   }
 
   bool get isPrivate {
-    return simpleName.startsWith('_');
+    return _n(simpleName).startsWith('_');
   }
 
   bool get isTopLevel {
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
index 78bbbd6..1c2e015 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/runtime/lib/mirrors_patch.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:nativewrappers";
+// TODO(ahe): Move _symbol_dev.Symbol to its own "private" library?
+import "dart:_collection-dev" as _symbol_dev;
 
 /**
  * Returns a [MirrorSystem] for the current isolate.
@@ -28,3 +30,9 @@
 patch InstanceMirror reflect(Object reflectee) {
   return _Mirrors.reflect(reflectee);
 }
+
+patch class MirrorSystem {
+  /* patch */ static String getName(Symbol symbol) {
+    return _symbol_dev.Symbol.getName(symbol);
+  }
+}
diff --git a/runtime/lib/object_patch.dart b/runtime/lib/object_patch.dart
index f6c6439..6c14f3e 100644
--- a/runtime/lib/object_patch.dart
+++ b/runtime/lib/object_patch.dart
@@ -33,7 +33,7 @@
                 Map<String, dynamic> namedArguments)
       native "Object_noSuchMethod";
 
-  /* patch */ noSuchMethod(InvocationMirror invocation) {
+  /* patch */ noSuchMethod(Invocation invocation) {
     return _noSuchMethod(invocation.isMethod,
                          invocation.memberName,
                          invocation._type,
diff --git a/runtime/lib/stacktrace_patch.dart b/runtime/lib/stacktrace_patch.dart
index 2d5fdc5..a545a9c 100644
--- a/runtime/lib/stacktrace_patch.dart
+++ b/runtime/lib/stacktrace_patch.dart
@@ -3,9 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class StackTrace {
-  /* patch */ String get fullStackTrace native "Stacktrace_getFullStacktrace";
+  /* patch */ String get _fullStackTrace native "Stacktrace_getFullStacktrace";
 
-  /* patch */ String get stackTrace native "Stacktrace_getStacktrace";
+  /* patch */ String get _stackTrace native "Stacktrace_getStacktrace";
 
   /* patch */ void _setupFullStackTrace()
       native "Stacktrace_setupFullStacktrace";
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 43101b0..2d148ec 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -157,41 +157,6 @@
     return _substringUnchecked(startIndex, endIndex);
   }
 
-  String slice([int startIndex, int endIndex]) {
-    int start, end;
-    if (startIndex == null) {
-      start = 0;
-    } else if (startIndex is! int) {
-      throw new ArgumentError("startIndex is not int");
-    } else if (startIndex >= 0) {
-      start = startIndex;
-    } else {
-      start = this.length + startIndex;
-    }
-    if (start < 0 || start > this.length) {
-      throw new RangeError(
-          "startIndex out of range: $startIndex (length: $length)");
-    }
-    if (endIndex == null) {
-      end = this.length;
-    } else if (endIndex is! int) {
-      throw new ArgumentError("endIndex is not int");
-    } else if (endIndex >= 0) {
-      end = endIndex;
-    } else {
-      end = this.length + endIndex;
-    }
-    if (end < 0 || end > this.length) {
-      throw new RangeError(
-          "endIndex out of range: $endIndex (length: $length)");
-    }
-    if (end < start) {
-      throw new ArgumentError(
-          "End before start: $endIndex < $startIndex (length: $length)");
-    }
-    return _substringUnchecked(start, end);
-  }
-
   String _substringUnchecked(int startIndex, int endIndex) {
     assert(endIndex != null);
     assert((startIndex >= 0) && (startIndex <= this.length));
diff --git a/runtime/lib/symbol_patch.dart b/runtime/lib/symbol_patch.dart
index 6771348..4359019 100644
--- a/runtime/lib/symbol_patch.dart
+++ b/runtime/lib/symbol_patch.dart
@@ -2,34 +2,44 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-patch  class Symbol {
-  final String _name;
+patch class Symbol {
   /* patch */ const Symbol(String name)
-    : this._name = _validate(name);
-
+      : this._name = _validate(name);
 
   static final RegExp _validationPattern =
-      new RegExp(r'^[a-zA-Z$][a-zA-Z$0-9_]*=?');
+      new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|'
+                 r'-|'
+                 r'unary-|'
+                 r'\[\]=|'
+                 r'~|'
+                 r'==|'
+                 r'\[\]|'
+                 r'\*|'
+                 r'/|'
+                 r'%|'
+                 r'~/|'
+                 r'\+|'
+                 r'<<|'
+                 r'>>|'
+                 r'>=|'
+                 r'>|'
+                 r'<=|'
+                 r'<|'
+                 r'&|'
+                 r'\^|'
+                 r'\|'
+                 r')$');
 
   static _validate(String name) {
     if (name is! String) throw new ArgumentError('name must be a String');
-    if (name.isEmpty) return;
+    if (name.isEmpty) return name;
     if (name.startsWith('_')) {
       throw new ArgumentError('"$name" is a private identifier');
     }
     if (!_validationPattern.hasMatch(name)) {
       throw new ArgumentError(
-	  '"$name" is not an identifier or an empty String');
+          '"$name" is not an identifier or an empty String');
     }
     return name;
   }
-
-  /* patch */ bool operator ==(other) {
-    return other is Symbol && _name == other._name;
-  }
-
-  /* patch */ int get hashCode {
-    const arbitraryPrime = 664597;
-    return 0x1fffffff & (arbitraryPrime * _name.hashCode);
-  }
 }
diff --git a/runtime/lib/typeddata.dart b/runtime/lib/typeddata.dart
index 75f81a7..2cf2873 100644
--- a/runtime/lib/typeddata.dart
+++ b/runtime/lib/typeddata.dart
@@ -15,7 +15,9 @@
 
   /* patch */ factory Int8List.fromList(List<int> elements) {
     var result = new _Int8Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -41,7 +43,9 @@
 
   /* patch */ factory Uint8List.fromList(List<int> elements) {
     var result = new _Uint8Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -67,7 +71,9 @@
 
   /* patch */ factory Uint8ClampedList.fromList(List<int> elements) {
     var result = new _Uint8ClampedArray(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -94,7 +100,9 @@
 
   /* patch */ factory Int16List.fromList(List<int> elements) {
     var result = new _Int16Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -120,7 +128,9 @@
 
   /* patch */ factory Uint16List.fromList(List<int> elements) {
     var result = new _Uint16Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -146,7 +156,9 @@
 
   /* patch */ factory Int32List.fromList(List<int> elements) {
     var result = new _Int32Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -172,7 +184,9 @@
 
   /* patch */ factory Uint32List.fromList(List<int> elements) {
     var result = new _Uint32Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -198,7 +212,9 @@
 
   /* patch */ factory Int64List.fromList(List<int> elements) {
     var result = new _Int64Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -224,7 +240,9 @@
 
   /* patch */ factory Uint64List.fromList(List<int> elements) {
     var result = new _Uint64Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -250,7 +268,9 @@
 
   /* patch */ factory Float32List.fromList(List<double> elements) {
     var result = new _Float32Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -276,7 +296,9 @@
 
   /* patch */ factory Float64List.fromList(List<double> elements) {
     var result = new _Float64Array(elements.length);
-    for (int i = 0; i < elements.length; i++) result[i] = elements[i];
+    for (int i = 0; i < elements.length; i++) {
+      result[i] = elements[i];
+    }
     return result;
   }
 
@@ -515,14 +537,14 @@
     throw new StateError("More than one element");
   }
 
-  void removeRange(int start, int length) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
   }
 
-  void insertRange(int start, int length, [initialValue]) {
+  void replaceRange(int start, int end, Iterable iterable) {
     throw new UnsupportedError(
-        "Cannot add to a non-extendable array");
+        "Cannot remove from a non-extendable array");
   }
 
   List toList() {
@@ -546,13 +568,21 @@
     return IterableMixinWorkaround.getRangeList(this, start, end);
   }
 
-  void setRange(int start, int length, List from, [int startFrom = 0]) {
-    if (!_setRange(start, length, from, startFrom)) {
+  void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
+    if (!_setRange(start, end - start, iterable, skipCount)) {
       IterableMixinWorkaround.setRangeList(this, start,
-                                           length, from, startFrom);
+                                           end, iterable, skipCount);
     }
   }
 
+  void setAll(int index, Iterable iterable) {
+    IterableMixinWorkaround.setAllList(this, index, iterable);
+  }
+
+  void fillRange(int start, int end, [fillValue]) {
+    IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+  }
+
 
   // Method(s) implementing Object interface.
 
@@ -563,7 +593,7 @@
 
   // Internal utility methods.
 
-  bool _setRange(int start, int length, List from, startFrom)
+  bool _setRange(int start, int length, Iterable from, int startFrom)
       native "TypedData_setRange";
 }
 
diff --git a/runtime/tests/vm/dart/byte_array_optimized_test.dart b/runtime/tests/vm/dart/byte_array_optimized_test.dart
index ca3f9e5..45604fde3 100644
--- a/runtime/tests/vm/dart/byte_array_optimized_test.dart
+++ b/runtime/tests/vm/dart/byte_array_optimized_test.dart
@@ -33,8 +33,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -85,7 +83,7 @@
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-128, 0, 1, 127]);
+    array.setRange(3, 7, [-128, 0, 1, 127]);
     Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
                       array);
   }
@@ -118,8 +116,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -158,7 +154,7 @@
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [257, 0, 1, 255]);
+    array.setRange(3, 7, [257, 0, 1, 255]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
                       array);
   }
@@ -192,8 +188,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -244,7 +238,7 @@
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-32768, 0, 1, 32767]);
+    array.setRange(3, 7, [-32768, 0, 1, 32767]);
     Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
                       array);
   }
@@ -278,8 +272,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -318,7 +310,7 @@
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+    array.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
                       array);
   }
@@ -352,8 +344,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -410,7 +400,7 @@
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+    array.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
                       array);
   }
@@ -444,8 +434,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -487,7 +475,7 @@
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+    array.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
                       array);
   }
@@ -524,8 +512,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -582,7 +568,7 @@
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+    array.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
                        1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
                       array);
@@ -617,8 +603,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -660,7 +644,7 @@
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+    array.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
                       array);
   }
@@ -694,8 +678,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -723,7 +705,7 @@
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       array);
@@ -758,8 +740,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -787,7 +767,7 @@
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       array);
@@ -852,8 +832,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -917,7 +895,7 @@
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-128, 0, 1, 127]);
+    view.setRange(3, 7, [-128, 0, 1, 127]);
     Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
                       view);
     Expect.listEquals([0xFF, 0, 1, 2, 128, 0, 1, 127, 7, 8, 9, 0xFF],
@@ -981,8 +959,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1028,7 +1004,7 @@
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [257, 0, 1, 255]);
+    view.setRange(3, 7, [257, 0, 1, 255]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
                       view);
   }
@@ -1090,8 +1066,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1160,7 +1134,7 @@
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-32768, 0, 1, 32767]);
+    view.setRange(3, 7, [-32768, 0, 1, 32767]);
     Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
                       view);
     Expect.listEquals([0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
@@ -1227,8 +1201,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1275,7 +1247,7 @@
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+    view.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([-1, -1, 0, 0, 1, 0, 2, 0,
@@ -1342,8 +1314,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1433,7 +1403,7 @@
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+    view.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
@@ -1498,8 +1468,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1560,7 +1528,7 @@
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+    view.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([-1, -1, -1, -1, 0, 0, 0, 0,
@@ -1629,8 +1597,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1750,7 +1716,7 @@
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+    view.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
                        1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
                       view);
@@ -1830,8 +1796,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1910,7 +1874,7 @@
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+    view.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([-1, -1, -1, -1, -1, -1, -1, -1,
@@ -1986,8 +1950,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -2020,7 +1982,7 @@
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       view);
@@ -2091,8 +2053,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -2125,7 +2085,7 @@
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       view);
diff --git a/runtime/tests/vm/dart/byte_array_test.dart b/runtime/tests/vm/dart/byte_array_test.dart
index 388e1bb..876642a 100644
--- a/runtime/tests/vm/dart/byte_array_test.dart
+++ b/runtime/tests/vm/dart/byte_array_test.dart
@@ -31,8 +31,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -86,7 +84,7 @@
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-128, 0, 1, 127]);
+    array.setRange(3, 7, [-128, 0, 1, 127]);
     Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
                       array);
   }
@@ -123,8 +121,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -166,7 +162,7 @@
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [257, 0, 1, 255]);
+    array.setRange(3, 7, [257, 0, 1, 255]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
                       array);
   }
@@ -204,8 +200,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -244,7 +238,7 @@
     Expect.isTrue(copy is Uint8ClampedList);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [257, 0, 1, 255]);
+    array.setRange(3, 7, [257, 0, 1, 255]);
     Expect.listEquals([0, 1, 2, 255, 0, 1, 255, 7, 8, 9], array);
   }
 
@@ -281,8 +275,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -336,7 +328,7 @@
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-32768, 0, 1, 32767]);
+    array.setRange(3, 7, [-32768, 0, 1, 32767]);
     Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
                       array);
   }
@@ -374,8 +366,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -417,7 +407,7 @@
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+    array.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
                       array);
   }
@@ -455,8 +445,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -516,7 +504,7 @@
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+    array.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
                       array);
   }
@@ -554,8 +542,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -600,7 +586,7 @@
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+    array.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
                       array);
   }
@@ -639,8 +625,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -700,7 +684,7 @@
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+    array.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
                        1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
                       array);
@@ -739,8 +723,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -785,7 +767,7 @@
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    array.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+    array.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
                       array);
   }
@@ -823,8 +805,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -855,7 +835,7 @@
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       array);
@@ -894,8 +874,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -926,7 +904,7 @@
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    array.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    array.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       array);
@@ -1138,8 +1116,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1203,7 +1179,7 @@
     Expect.isTrue(copy is Int8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-128, 0, 1, 127]);
+    view.setRange(3, 7, [-128, 0, 1, 127]);
     Expect.listEquals([0, 1, 2, -128, 0, 1, 127, 7, 8, 9],
                       view);
     Expect.listEquals([0xFF, 0, 1, 2, 128, 0, 1, 127, 7, 8, 9, 0xFF],
@@ -1269,8 +1245,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1316,7 +1290,7 @@
     Expect.isTrue(copy is Uint8List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [257, 0, 1, 255]);
+    view.setRange(3, 7, [257, 0, 1, 255]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 255, 7, 8, 9],
                       view);
   }
@@ -1380,8 +1354,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1450,7 +1422,7 @@
     Expect.isTrue(copy is Int16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-32768, 0, 1, 32767]);
+    view.setRange(3, 7, [-32768, 0, 1, 32767]);
     Expect.listEquals([0, 1, 2, -32768, 0, 1, 32767, 7, 8, 9],
                       view);
     Expect.listEquals([0xFF, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
@@ -1519,8 +1491,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1567,7 +1537,7 @@
     Expect.isTrue(copy is Uint16List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [0x10001, 0, 1, 0xFFFF]);
+    view.setRange(3, 7, [0x10001, 0, 1, 0xFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([-1, -1, 0, 0, 1, 0, 2, 0,
@@ -1636,8 +1606,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1727,7 +1695,7 @@
     Expect.isTrue(copy is Int32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-0x80000000, 0, 1, 0x7FFFFFFF]);
+    view.setRange(3, 7, [-0x80000000, 0, 1, 0x7FFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x80000000, 0, 1, 0x7FFFFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
@@ -1792,8 +1760,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -1854,7 +1820,7 @@
     Expect.isTrue(copy is Uint32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [0x100000001, 0, 1, 0xFFFFFFFF]);
+    view.setRange(3, 7, [0x100000001, 0, 1, 0xFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([-1, -1, -1, -1, 0, 0, 0, 0,
@@ -1925,8 +1891,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -2046,7 +2010,7 @@
     Expect.isTrue(copy is Int64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
+    view.setRange(3, 7, [-0x8000000000000000, 0, 1, 0x7FFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, -0x8000000000000000, 0,
                        1, 0x7FFFFFFFFFFFFFFF, 7, 8, 9],
                       view);
@@ -2128,8 +2092,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { view.insertRange(0, view.length, 0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { view.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { view.removeLast(); },
@@ -2208,7 +2170,7 @@
     Expect.isTrue(copy is Uint64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3, 4, 5, 6], region);
-    view.setRange(3, 4, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
+    view.setRange(3, 7, [0x10000000000000001, 0, 1, 0xFFFFFFFFFFFFFFFF]);
     Expect.listEquals([0, 1, 2, 1, 0, 1, 0xFFFFFFFFFFFFFFFF, 7, 8, 9],
                       view);
     Expect.listEquals([-1, -1, -1, -1, -1, -1, -1, -1,
@@ -2286,8 +2248,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -2320,7 +2280,7 @@
     Expect.isTrue(copy is Float32List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       view);
@@ -2393,8 +2353,6 @@
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.clear(); },
                   (e) { return e is UnsupportedError; });
-    Expect.throws(() { array.insertRange(0, array.length, 0.0); },
-                  (e) { return e is UnsupportedError; });
     Expect.throws(() { array.length = 0; },
                   (e) { return e is UnsupportedError; });
     Expect.throws(() { array.removeLast(); },
@@ -2427,7 +2385,7 @@
     Expect.isTrue(copy is Float64List);
     Expect.equals(4, region.length);
     Expect.listEquals([3.0, 4.0, 5.0, 6.0], region);
-    view.setRange(3, 4, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
+    view.setRange(3, 7, [double.NEGATIVE_INFINITY, 0.0, 1.0, double.INFINITY]);
     Expect.listEquals([0.0, 1.0, 2.0, double.NEGATIVE_INFINITY, 0.0,
                        1.0, double.INFINITY, 7.0, 8.0, 9.0],
                       view);
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
index e72f5a1..772ce66 100644
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
@@ -49,7 +49,8 @@
 sort(list) => list.sort(_stringCompare);
 
 String buildMethodString(MethodMirror func) {
-  var result = '${func.simpleName} return(${func.returnType.simpleName})';
+  var result = '${MirrorSystem.getName(func.simpleName)} '
+      'return(${MirrorSystem.getName(func.returnType.simpleName)})';
   if (func.isPrivate) {
     result = '$result private';
   }
@@ -90,7 +91,8 @@
 }
 
 String buildVariableString(VariableMirror variable) {
-  var result = '${variable.simpleName} type(${variable.type.simpleName})';
+  var result = '${MirrorSystem.getName(variable.simpleName)} '
+      'type(${MirrorSystem.getName(variable.type.simpleName)})';
   if (variable.isPrivate) {
     result = '$result private';
   }
@@ -107,27 +109,30 @@
 }
 
 void testRootLibraryMirror(LibraryMirror lib_mirror) {
-  Expect.equals('isolate_mirror_local_test', lib_mirror.simpleName);
-  Expect.equals('isolate_mirror_local_test', lib_mirror.qualifiedName);
+  Expect.equals(const Symbol('isolate_mirror_local_test'),
+                lib_mirror.simpleName);
+  Expect.equals(const Symbol('isolate_mirror_local_test'),
+                lib_mirror.qualifiedName);
   Expect.equals(null, lib_mirror.owner);
   Expect.isFalse(lib_mirror.isPrivate);
   Expect.isTrue(lib_mirror.url.contains('isolate_mirror_local_test.dart'));
-  Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
-                lib_mirror.toString());
+  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+  // Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
+  //               lib_mirror.toString());
 
   // Test library invocation by calling function(123).
   Expect.equals(0, global_var);
-  lib_mirror.invokeAsync('function', [123]).then(
+  lib_mirror.invokeAsync(const Symbol('function'), [123]).then(
       (InstanceMirror retval) {
         Expect.equals(123, global_var);
-        Expect.equals('int', retval.type.simpleName);
+        Expect.equals(const Symbol('int'), retval.type.simpleName);
         Expect.isTrue(retval.hasReflectee);
         Expect.equals(124, retval.reflectee);
         testDone('testRootLibraryMirror');
       });
 
   // Check that the members map is complete.
-  List keys = lib_mirror.members.keys.toList();
+  List keys = lib_mirror.members.keys.map(MirrorSystem.getName).toList();
   sort(keys);
   Expect.equals('['
                 'FuncType, '
@@ -164,7 +169,7 @@
                 '$keys');
 
   // Check that the classes map is complete.
-  keys = lib_mirror.classes.keys.toList();
+  keys = lib_mirror.classes.keys.map(MirrorSystem.getName).toList();
   sort(keys);
   Expect.equals('['
                 'FuncType, '
@@ -176,7 +181,7 @@
                 '$keys');
 
   // Check that the functions map is complete.
-  keys = lib_mirror.functions.keys.toList();
+  keys = lib_mirror.functions.keys.map(MirrorSystem.getName).toList();
   sort(keys);
   Expect.equals('['
                 '_stringCompare, '
@@ -202,17 +207,17 @@
                 '$keys');
 
   // Check that the getters map is complete.
-  keys = lib_mirror.getters.keys.toList();
+  keys = lib_mirror.getters.keys.map(MirrorSystem.getName).toList();
   sort(keys);
   Expect.equals('[myVar]', '$keys');
 
   // Check that the setters map is complete.
-  keys = lib_mirror.setters.keys.toList();
+  keys = lib_mirror.setters.keys.map(MirrorSystem.getName).toList();
   sort(keys);
   Expect.equals('[myVar=]', '$keys');
 
   // Check that the variables map is complete.
-  keys = lib_mirror.variables.keys.toList();
+  keys = lib_mirror.variables.keys.map(MirrorSystem.getName).toList();
   sort(keys);
   Expect.equals('['
                 'exit_port, '
@@ -222,108 +227,114 @@
                 'myFunc]',
                 '$keys');
 
-  ClassMirror cls_mirror = lib_mirror.members['MyClass'];
-  ClassMirror generic_cls_mirror = lib_mirror.members['GenericClass'];
+  ClassMirror cls_mirror = lib_mirror.members[const Symbol('MyClass')];
+  ClassMirror generic_cls_mirror =
+      lib_mirror.members[const Symbol('GenericClass')];
 
   // Test function mirrors.
-  MethodMirror func = lib_mirror.members['function'];
+  MethodMirror func = lib_mirror.members[const Symbol('function')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('function return(int) toplevel static method',
                 buildMethodString(func));
 
-  func = lib_mirror.members['myVar'];
+  func = lib_mirror.members[const Symbol('myVar')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('myVar return(int) toplevel static getter',
                 buildMethodString(func));
 
-  func = lib_mirror.members['myVar='];
+  func = lib_mirror.members[const Symbol('myVar=')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('myVar= return(void) toplevel static setter',
                 buildMethodString(func));
 
-  func = cls_mirror.members['method'];
+  func = cls_mirror.members[const Symbol('method')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('method return(int) method', buildMethodString(func));
 
-  func = cls_mirror.constructors['MyClass'];
+  func = cls_mirror.constructors[const Symbol('MyClass')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('MyClass return(MyClass) constructor', buildMethodString(func));
 
-  func = cls_mirror.constructors['MyClass.named'];
+  func = cls_mirror.constructors[const Symbol('MyClass.named')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('MyClass.named return(MyClass) constructor',
                 buildMethodString(func));
 
-  func = generic_cls_mirror.members['method'];
+  func = generic_cls_mirror.members[const Symbol('method')];
   Expect.isTrue(func is MethodMirror);
   Expect.equals('method return(T) method', buildMethodString(func));
 
   // Test variable mirrors.
-  VariableMirror variable = lib_mirror.members['global_var'];
+  VariableMirror variable = lib_mirror.members[const Symbol('global_var')];
   Expect.isTrue(variable is VariableMirror);
   Expect.equals('global_var type(int) toplevel static',
                 buildVariableString(variable));
 
-  variable = lib_mirror.members['final_global_var'];
+  variable = lib_mirror.members[const Symbol('final_global_var')];
   Expect.isTrue(variable is VariableMirror);
   Expect.equals('final_global_var type(int) toplevel static final',
                 buildVariableString(variable));
 
-  variable = cls_mirror.members['value'];
+  variable = cls_mirror.members[const Symbol('value')];
   Expect.isTrue(variable is VariableMirror);
   Expect.equals('value type(dynamic) final', buildVariableString(variable));
 
   // Test type variable mirrors.
-  var type_var = generic_cls_mirror.members['method'].returnType;
+  var type_var = generic_cls_mirror.members[const Symbol('method')].returnType;
   Expect.isTrue(type_var is TypeVariableMirror);
-  Expect.equals('GenericClass', type_var.owner.simpleName);
-  Expect.equals('Object', type_var.upperBound.simpleName);
+  Expect.equals(const Symbol('GenericClass'), type_var.owner.simpleName);
+  Expect.equals(const Symbol('Object'), type_var.upperBound.simpleName);
 
   // Test typedef mirrors.
-  var typedef_mirror = lib_mirror.members['myFunc'].type;
+  var typedef_mirror = lib_mirror.members[const Symbol('myFunc')].type;
   Expect.isTrue(typedef_mirror is TypedefMirror);
-  Expect.equals('isolate_mirror_local_test', typedef_mirror.owner.simpleName);
+  Expect.equals(const Symbol('isolate_mirror_local_test'),
+                typedef_mirror.owner.simpleName);
 
   // Test function type mirrors.
   var func_cls_mirror = typedef_mirror.referent;
   Expect.isTrue(func_cls_mirror is FunctionTypeMirror);
-  Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
-  Expect.equals('void', func_cls_mirror.returnType.simpleName);
+  // Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
+  Expect.equals(const Symbol('void'), func_cls_mirror.returnType.simpleName);
 }
 
 void testLibrariesMap(Map libraries) {
   // Just look for a couple of well-known libs.
-  LibraryMirror core_lib = libraries['dart.core'];
+  LibraryMirror core_lib = libraries[const Symbol('dart.core')];
   Expect.isTrue(core_lib is LibraryMirror);
 
-  LibraryMirror mirror_lib = libraries['dart.mirrors'];
+  LibraryMirror mirror_lib = libraries[const Symbol('dart.mirrors')];
   Expect.isTrue(mirror_lib is LibraryMirror);
 
   // Lookup an interface from a library and make sure it is sane.
-  ClassMirror list_intf = core_lib.members['List'];
+  ClassMirror list_intf = core_lib.members[const Symbol('List')];
   Expect.isTrue(list_intf is ClassMirror);
-  Expect.equals('List', list_intf.simpleName);
-  Expect.equals('dart.core.List', list_intf.qualifiedName);
+  Expect.equals(const Symbol('List'), list_intf.simpleName);
+  Expect.equals(const Symbol('dart.core.List'), list_intf.qualifiedName);
   Expect.isFalse(list_intf.isPrivate);
-  Expect.equals('Object', list_intf.superclass.simpleName);
-  Expect.equals('dart.core', list_intf.owner.simpleName);
+  Expect.equals(const Symbol('Object'), list_intf.superclass.simpleName);
+  Expect.equals(const Symbol('dart.core'), list_intf.owner.simpleName);
   Expect.isTrue(list_intf.isClass);
-  Expect.equals('Iterable', list_intf.superinterfaces[0].simpleName);
-  Expect.equals("ClassMirror on 'List'", list_intf.toString());
+  Expect.equals(const Symbol('Iterable'),
+                list_intf.superinterfaces[0].simpleName);
+  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+  // Expect.equals("ClassMirror on 'List'", list_intf.toString());
 
   // Lookup a class from a library and make sure it is sane.
-  ClassMirror oom_cls = core_lib.members['OutOfMemoryError'];
+  ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')];
   Expect.isTrue(oom_cls is ClassMirror);
-  Expect.equals('OutOfMemoryError', oom_cls.simpleName);
-  Expect.equals('dart.core.OutOfMemoryError', oom_cls.qualifiedName);
+  Expect.equals(const Symbol('OutOfMemoryError'), oom_cls.simpleName);
+  Expect.equals(const Symbol('dart.core.OutOfMemoryError'),
+                oom_cls.qualifiedName);
   Expect.isFalse(oom_cls.isPrivate);
-  Expect.equals('Object', oom_cls.superclass.simpleName);
+  Expect.equals(const Symbol('Object'), oom_cls.superclass.simpleName);
   Expect.isTrue(oom_cls.defaultFactory == null);
-  Expect.equals('dart.core', oom_cls.owner.simpleName);
+  Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName);
   Expect.isTrue(oom_cls.isClass);
-  Expect.equals('Error', oom_cls.superinterfaces[0].simpleName);
-  Expect.equals("ClassMirror on 'OutOfMemoryError'",
-                oom_cls.toString());
+  Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName);
+  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+  // Expect.equals("ClassMirror on 'OutOfMemoryError'",
+  //               oom_cls.toString());
   testDone('testLibrariesMap');
 }
 
@@ -331,21 +342,21 @@
   Expect.isTrue(mirrors.isolate.debugName.contains('main'));
   testRootLibraryMirror(mirrors.isolate.rootLibrary);
   testLibrariesMap(mirrors.libraries);
-  Expect.equals('void', mirrors.voidType.simpleName);
-  Expect.equals('dynamic', mirrors.dynamicType.simpleName);
+  Expect.equals(const Symbol('void'), mirrors.voidType.simpleName);
+  Expect.equals(const Symbol('dynamic'), mirrors.dynamicType.simpleName);
   testDone('testMirrorSystem');
 }
 
 void testIntegerInstanceMirror(InstanceMirror mirror) {
-  Expect.equals('int', mirror.type.simpleName);
+  Expect.equals(const Symbol('int'), mirror.type.simpleName);
   Expect.isTrue(mirror.hasReflectee);
   Expect.equals(1001, mirror.reflectee);
   Expect.equals("InstanceMirror on <1001>", mirror.toString());
 
   // Invoke (mirror + mirror).
-  mirror.invokeAsync('+', [ mirror ]).then(
+  mirror.invokeAsync(const Symbol('+'), [ mirror ]).then(
       (InstanceMirror retval) {
-        Expect.equals('int', retval.type.simpleName);
+        Expect.equals(const Symbol('int'), retval.type.simpleName);
         Expect.isTrue(retval.hasReflectee);
         Expect.equals(2002, retval.reflectee);
         testDone('testIntegerInstanceMirror');
@@ -353,16 +364,16 @@
 }
 
 void testStringInstanceMirror(InstanceMirror mirror) {
-  Expect.equals('String', mirror.type.simpleName);
+  Expect.equals(const Symbol('String'), mirror.type.simpleName);
   Expect.isTrue(mirror.hasReflectee);
   Expect.equals('This\nis\na\nString', mirror.reflectee);
   Expect.equals("InstanceMirror on <'This\\nis\\na\\nString'>",
                 mirror.toString());
 
   // Invoke mirror[0].
-  mirror.invokeAsync('[]', [ 0 ]).then(
+  mirror.invokeAsync(const Symbol('[]'), [ 0 ]).then(
       (InstanceMirror retval) {
-        Expect.equals('String', retval.type.simpleName);
+        Expect.equals(const Symbol('String'), retval.type.simpleName);
         Expect.isTrue(retval.hasReflectee);
         Expect.equals('T', retval.reflectee);
         testDone('testStringInstanceMirror');
@@ -370,7 +381,7 @@
 }
 
 void testBoolInstanceMirror(InstanceMirror mirror) {
-  Expect.equals('bool', mirror.type.simpleName);
+  Expect.equals(const Symbol('bool'), mirror.type.simpleName);
   Expect.isTrue(mirror.hasReflectee);
   Expect.equals(true, mirror.reflectee);
   Expect.equals("InstanceMirror on <true>", mirror.toString());
@@ -379,7 +390,7 @@
 
 void testNullInstanceMirror(InstanceMirror mirror) {
   // TODO(turnidge): This is returning the wrong class.  Fix it.
-  Expect.equals('Object', mirror.type.simpleName);
+  Expect.equals(const Symbol('Object'), mirror.type.simpleName);
   Expect.isTrue(mirror.hasReflectee);
   Expect.equals(null, mirror.reflectee);
   Expect.equals("InstanceMirror on <null>", mirror.toString());
@@ -418,23 +429,25 @@
     saw_exception = true;
   }
   Expect.isFalse(saw_exception);
-  Expect.equals("InstanceMirror on instance of 'MyClass'", mirror.toString());
+  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+  // Expect.equals("InstanceMirror on instance of 'MyClass'",
+  //               mirror.toString());
 
   ClassMirror cls = mirror.type;
   Expect.isTrue(cls is ClassMirror);
-  Expect.equals('MyClass', cls.simpleName);
-  Expect.equals('MySuperClass', cls.superclass.simpleName);
+  Expect.equals(const Symbol('MyClass'), cls.simpleName);
+  Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName);
   Expect.isTrue(cls.defaultFactory == null);
-  Expect.equals('isolate_mirror_local_test', cls.owner.simpleName);
+  Expect.equals(const Symbol('isolate_mirror_local_test'), cls.owner.simpleName);
   Expect.isTrue(cls.isClass);
-  Expect.equals('MyInterface', cls.superinterfaces[0].simpleName);
-  Expect.equals("ClassMirror on 'MyClass'",
-                cls.toString());
+  Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName);
+  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
+  // Expect.equals("ClassMirror on 'MyClass'", cls.toString());
 
   // Invoke mirror.method(1000).
-  mirror.invokeAsync('method', [ 1000 ]).then(
+  mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then(
       (InstanceMirror retval) {
-        Expect.equals('int', retval.type.simpleName);
+        Expect.equals(const Symbol('int'), retval.type.simpleName);
         Expect.isTrue(retval.hasReflectee);
         Expect.equals(1017, retval.reflectee);
         testDone('testCustomInstanceMirror');
@@ -460,44 +473,44 @@
 void testMirrorErrors(MirrorSystem mirrors) {
   LibraryMirror lib_mirror = mirrors.isolate.rootLibrary;
 
-  lib_mirror.invokeAsync('methodWithException', [])
+  lib_mirror.invokeAsync(const Symbol('methodWithException'), [])
     .then((InstanceMirror retval) {
       // Should not reach here.
       Expect.isTrue(false);
     })
-    .catchError((exc) {
-        Expect.isTrue(exc.error is MirroredUncaughtExceptionError);
-        Expect.equals('MyException',
-                      exc.error.exception_mirror.type.simpleName);
+    .catchError((error) {
+        Expect.isTrue(error is MirroredUncaughtExceptionError);
+        Expect.equals(const Symbol('MyException'),
+                      error.exception_mirror.type.simpleName);
         Expect.equals('MyException: from methodWithException',
-                      exc.error.exception_string);
-        Expect.isTrue(exc.error.stacktrace.toString().contains(
+                      error.exception_string);
+        Expect.isTrue(error.stacktrace.toString().contains(
             'isolate_mirror_local_test.dart'));
         testDone('testMirrorErrors1');
       });
 
-  lib_mirror.invokeAsync('methodWithError', [])
+  lib_mirror.invokeAsync(const Symbol('methodWithError'), [])
     .then((InstanceMirror retval) {
       // Should not reach here.
       Expect.isTrue(false);
     })
-    .catchError((exc) {
-      Expect.isTrue(exc.error is MirroredCompilationError);
-      Expect.isTrue(exc.error.message.contains('unexpected token'));
+    .catchError((error) {
+      Expect.isTrue(error is MirroredCompilationError);
+      Expect.isTrue(error.message.contains('unexpected token'));
       testDone('testMirrorErrors2');
     });
 
   // TODO(turnidge): When we call a method that doesn't exist, we
   // should probably call noSuchMethod().  I'm adding this test to
   // document the current behavior in the meantime.
-  lib_mirror.invokeAsync('methodNotFound', [])
+  lib_mirror.invokeAsync(const Symbol('methodNotFound'), [])
     .then((InstanceMirror retval) {
       // Should not reach here.
       Expect.isTrue(false);
     })
-    .catchError((exc) {
-      Expect.isTrue(exc.error is MirroredCompilationError);
-      Expect.isTrue(exc.error.message.contains(
+    .catchError((error) {
+      Expect.isTrue(error is MirroredCompilationError);
+      Expect.isTrue(error.message.contains(
           "did not find top-level function 'methodNotFound'"));
       testDone('testMirrorErrors3');
     });
diff --git a/runtime/tests/vm/dart/optimized_stacktrace_test.dart b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
index 40413c5..d002a2e 100644
--- a/runtime/tests/vm/dart/optimized_stacktrace_test.dart
+++ b/runtime/tests/vm/dart/optimized_stacktrace_test.dart
@@ -4,7 +4,7 @@
 // Test correct source positions in stack trace with optimized functions.
 import "package:expect/expect.dart";
 
-// (1) Test normal exception. 
+// (1) Test normal exception.
 foo(x) => bar(x);
 
 bar(x) {
@@ -19,8 +19,8 @@
     Expect.fail("Unreachable");
   } catch (e, stacktrace) {
     String s = stacktrace.toString();
-    Expect.equals(-1, s.indexOf("-1:-1"));
-    Expect.notEquals(-1, s.indexOf("11:18"));
+    Expect.isFalse(s.contains("-1:-1"));
+    Expect.isTrue(s.contains("11:18"));
   }
 
   // Optimized.
@@ -30,8 +30,8 @@
     Expect.fail("Unreachable");
   } catch (e, stacktrace) {
     String s = stacktrace.toString();
-    Expect.equals(-1, s.indexOf("-1:-1"));
-    Expect.notEquals(-1, s.indexOf("11:18"));
+    Expect.isFalse(s.contains("-1:-1"));
+    Expect.isTrue(s.contains("11:18"));
   }
 }
 
@@ -56,9 +56,9 @@
   } 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"));
+    Expect.isTrue(s.contains("maximus"));
+    Expect.isTrue(s.contains("moritz"));
+    Expect.isFalse(s.contains("-1:-1"));
   }
 
   try {
@@ -66,9 +66,9 @@
   } 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"));
+    Expect.isTrue(s.contains("maximus"));
+    Expect.isTrue(s.contains("moritz"));
+    Expect.isFalse(s.contains("-1:-1"));
   }
 }
 
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 45afdd9..8d62b96 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -70,7 +70,6 @@
 [ $arch == simmips ]
 # Tests needing an assembler.
 cc/Dart2JSCompileAll: Skip
-cc/UseDartApi: Skip
 # Tests needing Dart execution.
 dart/*: Skip
 
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index b8aed32..8f21b6d 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -117,6 +117,45 @@
 }
 
 
+void Assembler::SubuDetectOverflow(Register rd, Register rs, Register rt,
+                                   Register ro) {
+  ASSERT(rd != ro);
+  ASSERT(rd != TMP1);
+  ASSERT(ro != TMP1);
+  ASSERT(ro != rs);
+  ASSERT(ro != rt);
+  ASSERT(rs != TMP1);
+  ASSERT(rt != TMP1);
+
+  // This happens with some crankshaft code. Since Subu works fine if
+  // left == right, let's not make that restriction here.
+  if (rs == rt) {
+    mov(rd, ZR);
+    mov(ro, ZR);
+    return;
+  }
+
+  if (rd == rs) {
+    mov(TMP1, rs);  // Preserve left.
+    subu(rd, rs, rt);  // Left is overwritten.
+    xor_(ro, rd, TMP1);  // scratch is original left.
+    xor_(TMP1, TMP1, rs);  // scratch is original left.
+    and_(ro, TMP1, ro);
+  } else if (rd == rt) {
+    mov(TMP1, rt);  // Preserve right.
+    subu(rd, rs, rt);  // Right is overwritten.
+    xor_(ro, rd, rs);
+    xor_(TMP1, rs, TMP1);  // Original right.
+    and_(ro, TMP1, ro);
+  } else {
+    subu(rd, rs, rt);
+    xor_(ro, rd, rs);
+    xor_(TMP1, rs, rt);
+    and_(ro, TMP1, ro);
+  }
+}
+
+
 void Assembler::LoadObject(Register rd, const Object& object) {
   // Smi's and VM heap objects are never relocated; do not use object pool.
   if (object.IsSmi()) {
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index f21d030..770eecd 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -553,6 +553,12 @@
     EmitFpuLoadStore(SWC1, ft, addr);
   }
 
+  void xori(Register rt, Register rs, const Immediate& imm) {
+    ASSERT(Utils::IsUint(kImmBits, imm.value()));
+    const uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    EmitIType(XORI, rs, rt, imm_value);
+  }
+
   void xor_(Register rd, Register rs, Register rt) {
     EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
   }
@@ -573,6 +579,20 @@
     AdduDetectOverflow(rd, rs, rd, ro);
   }
 
+  // Subtraction of rt from rs (rs - rt) with the result placed in rd.
+  // After, ro < 0 if there was signed overflow, ro >= 0 otherwise.
+  // None of rd, rs, rt, or ro may be TMP1.
+  // ro must be different from the other registers.
+  void SubuDetectOverflow(Register rd, Register rs, Register rt, Register ro);
+
+  // ro must be different from rd and rs.
+  // None of rd, rs, rt, or ro may be TMP1.
+  void SubImmediateDetectOverflow(Register rd, Register rs, int32_t imm,
+                                  Register ro) {
+    LoadImmediate(rd, imm);
+    SubuDetectOverflow(rd, rs, rd, ro);
+  }
+
   void Branch(const ExternalLabel* label) {
     LoadImmediate(TMP1, label->address());
     jr(TMP1);
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 0bd651c..f5ff667 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -576,6 +576,19 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(Xori, assembler) {
+  __ LoadImmediate(T0, 51);
+  __ xori(V0, T0, Immediate(25));
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Xori, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
 ASSEMBLER_TEST_GENERATE(Slt, assembler) {
   __ LoadImmediate(R1, -1);
   __ LoadImmediate(R2, 0);
@@ -1108,6 +1121,54 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(SubOverflow_detect, assembler) {
+  Register left = T0;
+  Register right = T1;
+  Register result = T2;
+  Register overflow = T3;
+  Label error, done;
+
+  __ LoadImmediate(V0, 1);  // Success value.
+
+  __ LoadImmediate(left, 0x80000000);
+  __ LoadImmediate(right, 1);
+  __ SubuDetectOverflow(result, left, right, overflow);
+  __ bgez(overflow, &error);  // INT_MIN - 1 overflows.
+
+  __ LoadImmediate(left, 0x7fffffff);
+  __ LoadImmediate(right, 0x8000000);
+  __ SubuDetectOverflow(result, left, left, overflow);
+  __ bltz(overflow, &error);  // INT_MIN - INT_MAX does not overflow.
+
+  __ LoadImmediate(left, 0x80000000);
+  __ LoadImmediate(right, 0x80000000);
+  __ SubuDetectOverflow(result, left, right, overflow);
+  __ bltz(overflow, &error);  // INT_MIN - INT_MIN does not overflow.
+
+  __ LoadImmediate(left, 0x7fffffff);
+  __ LoadImmediate(right, 0x80000000);
+  __ SubuDetectOverflow(result, left, right, overflow);
+  __ bgez(overflow, &error);  // INT_MAX - INT_MIN overflows.
+
+  __ LoadImmediate(left, 1);
+  __ LoadImmediate(right, -1);
+  __ SubuDetectOverflow(result, left, right, overflow);
+  __ bltz(overflow, &error);  // 1 - -1 does not overflow.
+
+  __ b(&done);
+  __ Bind(&error);
+  __ mov(V0, ZR);
+  __ Bind(&done);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(SubOverflow_detect, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
 ASSEMBLER_TEST_GENERATE(Mtc1Mfc1, assembler) {
   __ mtc1(ZR, F0);
   __ mfc1(V0, F0);
diff --git a/runtime/vm/bit_vector.cc b/runtime/vm/bit_vector.cc
index 80b640b..b97c18e 100644
--- a/runtime/vm/bit_vector.cc
+++ b/runtime/vm/bit_vector.cc
@@ -88,10 +88,10 @@
 }
 
 
-void BitVector::Intersect(const BitVector& other) {
-  ASSERT(other.length() == length());
+void BitVector::Intersect(const BitVector* other) {
+  ASSERT(other->length() == length());
   for (int i = 0; i < data_length_; i++) {
-    data_[i] = data_[i] & other.data_[i];
+    data_[i] = data_[i] & other->data_[i];
   }
 }
 
diff --git a/runtime/vm/bit_vector.h b/runtime/vm/bit_vector.h
index 3dcd118..76f6450 100644
--- a/runtime/vm/bit_vector.h
+++ b/runtime/vm/bit_vector.h
@@ -83,7 +83,7 @@
   // bitvector kill.
   bool KillAndAdd(BitVector* kill, BitVector* gen);
 
-  void Intersect(const BitVector& other);
+  void Intersect(const BitVector* other);
 
   bool Contains(int i) const {
     ASSERT(i >= 0 && i < length());
diff --git a/runtime/vm/bit_vector_test.cc b/runtime/vm/bit_vector_test.cc
index de2fe4f..83bc2cf 100644
--- a/runtime/vm/bit_vector_test.cc
+++ b/runtime/vm/bit_vector_test.cc
@@ -91,7 +91,7 @@
     b->Add(1);
     b->Add(31);
     b->Add(32);
-    a->Intersect(*b);
+    a->Intersect(b);
     EXPECT_EQ(true, a->Equals(*b));
   }
 
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 06527b7..d52fc5e 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -51,7 +51,7 @@
 RawScript* Bootstrap::LoadCollectionDevScript(bool patch) {
   const char* url =
       patch ? "dart:_collection-dev-patch" : "dart:_collection-dev";
-  const char* source = patch ? collection_dev_source_ : collection_dev_source_;
+  const char* source = patch ? collection_dev_patch_ : collection_dev_source_;
   return LoadScript(url, source, patch);
 }
 
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index fdb616d..020d819 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -42,6 +42,7 @@
   static const char collection_source_[];
   static const char collection_patch_[];
   static const char collection_dev_source_[];
+  static const char collection_dev_patch_[];
   static const char crypto_source_[];
   static const char isolate_source_[];
   static const char isolate_patch_[];
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index e39278b..6d0b880 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -224,6 +224,10 @@
         // A canonicalization pass to remove e.g. smi checks on smi constants.
         optimizer.Canonicalize();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        // Canonicalization introduced more opportunities for constant
+        // propagation.
+        ConstantPropagator::Optimize(flow_graph);
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
       }
 
       // Propagate types and eliminate even more type tests.
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 435b7d8..78866cf 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -183,6 +183,11 @@
 enum Condition {
   EQ,  // equal
   NE,  // not equal
+  GT,  // greater than
+  GE,  // greater equal
+  LT,  // less than
+  LE,  // less equal
+  VS,  // overflow
 };
 
 
diff --git a/runtime/vm/cpu_mips.cc b/runtime/vm/cpu_mips.cc
index 06aa026..51a679b 100644
--- a/runtime/vm/cpu_mips.cc
+++ b/runtime/vm/cpu_mips.cc
@@ -7,6 +7,7 @@
 #if defined(TARGET_ARCH_MIPS)
 
 #if defined(HOST_ARCH_MIPS)
+#include <asm/cachectl.h> /* NOLINT */
 #include <sys/syscall.h>  /* NOLINT */
 #include <unistd.h>  /* NOLINT */
 #endif
@@ -16,7 +17,15 @@
 namespace dart {
 
 void CPU::FlushICache(uword start, uword size) {
-  UNIMPLEMENTED();
+#if defined(HOST_ARCH_MIPS)
+  int res;
+  // See http://www.linux-mips.org/wiki/Cacheflush_Syscall.
+  res = syscall(__NR_cacheflush, start, size, ICACHE);
+  ASSERT(res == 0);
+#else  // defined(HOST_ARCH_MIPS)
+  // When running in simulated mode we do not need to flush the ICache because
+  // we are not running on the actual hardware.
+#endif  // defined(HOST_ARCH_MIPS)
 }
 
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index e7ee27b..f8d8b96 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2404,6 +2404,11 @@
     case kExternalTypedDataFloat64ArrayCid :
       type = kFloat64;
       break;
+    case kTypedDataFloat32x4ArrayCid :
+    case kTypedDataFloat32x4ArrayViewCid :
+    case kExternalTypedDataFloat32x4ArrayCid :
+      type = kFloat32x4;
+      break;
     default:
       type = kInvalid;
       break;
@@ -2566,6 +2571,8 @@
       return NewTypedData(isolate, kTypedDataFloat32ArrayCid,  length);
     case kFloat64 :
       return NewTypedData(isolate, kTypedDataFloat64ArrayCid, length);
+    case kFloat32x4:
+      return NewTypedData(isolate, kTypedDataFloat32x4ArrayCid, length);
     default:
       return Api::NewError("%s expects argument 'type' to be of 'TypedData'",
                            CURRENT_FUNC);
@@ -2588,74 +2595,80 @@
   }
   CHECK_CALLBACK_STATE(isolate);
   switch (type) {
-    case kByteData :
+    case kByteData:
       return NewExternalByteData(isolate, data, length, peer, callback);
-    case kInt8 :
+    case kInt8:
       return NewExternalTypedData(kExternalTypedDataInt8ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kUint8 :
+    case kUint8:
       return NewExternalTypedData(kExternalTypedDataUint8ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kUint8Clamped :
+    case kUint8Clamped:
       return NewExternalTypedData(kExternalTypedDataUint8ClampedArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kInt16 :
+    case kInt16:
       return NewExternalTypedData(kExternalTypedDataInt16ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kUint16 :
+    case kUint16:
       return NewExternalTypedData(kExternalTypedDataUint16ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kInt32 :
+    case kInt32:
       return NewExternalTypedData(kExternalTypedDataInt32ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kUint32 :
+    case kUint32:
       return NewExternalTypedData(kExternalTypedDataUint32ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kInt64 :
+    case kInt64:
       return NewExternalTypedData(kExternalTypedDataInt64ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kUint64 :
+    case kUint64:
       return NewExternalTypedData(kExternalTypedDataUint64ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kFloat32 :
+    case kFloat32:
       return NewExternalTypedData(kExternalTypedDataFloat32ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
-    case kFloat64 :
+    case kFloat64:
       return NewExternalTypedData(kExternalTypedDataFloat64ArrayCid,
                                   data,
                                   length,
                                   peer,
                                   callback);
+    case kFloat32x4:
+      return NewExternalTypedData(kExternalTypedDataFloat32x4ArrayCid,
+                                  data,
+                                  length,
+                                  peer,
+                                  callback);
     default:
       return Api::NewError("%s expects argument 'type' to be of"
                            " 'external TypedData'", CURRENT_FUNC);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index cc2d2de..a47c70c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1359,6 +1359,55 @@
   EXPECT(peer == 42);
 }
 
+
+static void CheckFloat32x4Data(Dart_Handle obj) {
+  void* raw_data = NULL;
+  intptr_t len;
+  Dart_TypedData_Type type;
+  EXPECT_VALID(Dart_TypedDataAcquireData(obj, &type, &raw_data, &len));
+  EXPECT_EQ(kFloat32x4, type);
+  EXPECT_EQ(len, 10);
+  float* float_data = reinterpret_cast<float*>(raw_data);
+  for (int i = 0; i < len * 4; i++) {
+    EXPECT_EQ(0.0, float_data[i]);
+  }
+  EXPECT_VALID(Dart_TypedDataReleaseData(obj));
+}
+
+
+TEST_CASE(Float32x4List) {
+    const char* kScriptChars =
+      "import 'dart:typeddata';\n"
+      "Float32x4List float32x4() {\n"
+      "  return new Float32x4List(10);\n"
+      "}\n";
+  // Create a test library and Load up a test script in it.
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+
+  Dart_Handle obj = Dart_Invoke(lib, NewString("float32x4"), 0, NULL);
+  EXPECT_VALID(obj);
+  CheckFloat32x4Data(obj);
+
+  obj = Dart_NewTypedData(kFloat32x4, 10);
+  EXPECT_VALID(obj);
+  CheckFloat32x4Data(obj);
+
+  int peer = 0;
+  float data[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+                   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+  obj = Dart_NewExternalTypedData(kFloat32x4,
+                                  data,
+                                  10,
+                                  &peer,
+                                  ExternalTypedDataCallbackFinalizer);
+  CheckFloat32x4Data(obj);
+  Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+  EXPECT(peer == 42);
+}
+
+
 #endif
 
 
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 5315301b..34eb977 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -125,21 +125,49 @@
 }
 
 
-Dart_CObject* ApiMessageReader::AllocateDartCObjectUint8Array(intptr_t length) {
+static int GetTypedDataSizeInBytes(Dart_CObject::TypedDataType type) {
+  switch (type) {
+    case Dart_CObject::kInt8Array:
+    case Dart_CObject::kUint8Array:
+    case Dart_CObject::kUint8ClampedArray:
+      return 1;
+    case Dart_CObject::kInt16Array:
+    case Dart_CObject::kUint16Array:
+      return 2;
+    case Dart_CObject::kInt32Array:
+    case Dart_CObject::kUint32Array:
+    case Dart_CObject::kFloat32Array:
+      return 4;
+    case Dart_CObject::kInt64Array:
+    case Dart_CObject::kUint64Array:
+    case Dart_CObject::kFloat64Array:
+      return 8;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+
+Dart_CObject* ApiMessageReader::AllocateDartCObjectTypedData(
+    Dart_CObject::TypedDataType type, intptr_t length) {
   // Allocate a Dart_CObject structure followed by an array of bytes
   // for the byte array content. The pointer to the byte array content
   // is set up to this area.
+  intptr_t length_in_bytes = GetTypedDataSizeInBytes(type) * length;
   Dart_CObject* value =
       reinterpret_cast<Dart_CObject*>(
-          alloc_(NULL, 0, sizeof(Dart_CObject) + length));
+          alloc_(NULL, 0, sizeof(Dart_CObject) + length_in_bytes));
   ASSERT(value != NULL);
-  value->type = Dart_CObject::kUint8Array;
-  value->value.as_array.length = length;
+  value->type = Dart_CObject::kTypedData;
+  value->value.as_typed_data.type = type;
+  value->value.as_typed_data.length = length_in_bytes;
   if (length > 0) {
-    value->value.as_byte_array.values =
+    value->value.as_typed_data.values =
         reinterpret_cast<uint8_t*>(value) + sizeof(*value);
   } else {
-    value->value.as_byte_array.values = NULL;
+    value->value.as_typed_data.values = NULL;
   }
   return value;
 }
@@ -191,6 +219,47 @@
 }
 
 
+static Dart_CObject::TypedDataType GetTypedDataTypeFromView(
+    Dart_CObject_Internal* object) {
+  struct {
+    const char* name;
+    Dart_CObject::TypedDataType type;
+  } view_class_names[] = {
+    { "_Int8ArrayView", Dart_CObject::kInt8Array },
+    { "_Uint8ArrayView", Dart_CObject::kUint8Array },
+    { "_Uint8ClampedArrayView", Dart_CObject::kUint8ClampedArray },
+    { "_Int16ArrayView", Dart_CObject::kInt16Array },
+    { "_Uint16ArrayView", Dart_CObject::kUint16Array },
+    { "_Int32ArrayView", Dart_CObject::kInt32Array },
+    { "_Uint32ArrayView", Dart_CObject::kUint32Array },
+    { "_Int64ArrayView", Dart_CObject::kInt64Array },
+    { "_Uint64ArrayView", Dart_CObject::kUint64Array },
+    { "_ByteDataView", Dart_CObject::kUint8Array },
+    { "_Float32ArrayView", Dart_CObject::kFloat32Array },
+    { "_Float64ArrayView", Dart_CObject::kFloat64Array },
+    { NULL, Dart_CObject::kNumberOfTypedDataTypes },
+  };
+
+  char* library_url =
+      object->cls->internal.as_class.library_url->value.as_string;
+  char* class_name =
+      object->cls->internal.as_class.class_name->value.as_string;
+  if (strcmp("dart:typeddata", library_url) != 0) {
+    return Dart_CObject::kNumberOfTypedDataTypes;
+  }
+  int i = 0;
+  while (view_class_names[i].name != NULL) {
+    if (strncmp(view_class_names[i].name,
+                class_name,
+                strlen(view_class_names[i].name)) == 0) {
+      return view_class_names[i].type;
+    }
+    i++;
+  }
+  return Dart_CObject::kNumberOfTypedDataTypes;
+}
+
+
 Dart_CObject* ApiMessageReader::ReadInlinedObject(intptr_t object_id) {
   // Read the class header information and lookup the class.
   intptr_t class_header = ReadIntptrValue();
@@ -217,30 +286,29 @@
                Dart_CObject_Internal::kUninitialized));
 
     // Handle typed data views.
-    char* library_url =
-        object->cls->internal.as_class.library_url->value.as_string;
-    char* class_name =
-        object->cls->internal.as_class.class_name->value.as_string;
-    if (strcmp("dart:typeddata", library_url) == 0 &&
-        strncmp("_Uint8ArrayView", class_name, 15) == 0) {
+    Dart_CObject::TypedDataType type = GetTypedDataTypeFromView(object);
+    if (type != Dart_CObject::kNumberOfTypedDataTypes) {
       object->type =
           static_cast<Dart_CObject::Type>(Dart_CObject_Internal::kView);
-      // Skip type arguments.
-      ReadObjectImpl();
+      ReadObjectImpl();  // Skip type arguments.
       object->internal.as_view.buffer = ReadObjectImpl();
       object->internal.as_view.offset_in_bytes = ReadSmiValue();
       object->internal.as_view.length = ReadSmiValue();
+      ReadObjectImpl();  // Skip last field.
 
       // The buffer is fully read now as typed data objects are
       // serialized in-line.
       Dart_CObject* buffer = object->internal.as_view.buffer;
-      ASSERT(buffer->type == Dart_CObject::kUint8Array);
+      ASSERT(buffer->type == Dart_CObject::kTypedData);
 
       // Now turn the view into a byte array.
-      object->type = Dart_CObject::kUint8Array;
-      object->value.as_byte_array.length = object->internal.as_view.length;
-      object->value.as_byte_array.values =
-          buffer->value.as_byte_array.values +
+      object->type = Dart_CObject::kTypedData;
+      object->value.as_typed_data.type = type;
+      object->value.as_typed_data.length =
+          object->internal.as_view.length *
+          GetTypedDataSizeInBytes(type);
+      object->value.as_typed_data.values =
+          buffer->value.as_typed_data.values +
           object->internal.as_view.offset_in_bytes;
     } else {
       // TODO(sgjesse): Handle other instances. Currently this will
@@ -509,19 +577,67 @@
       ::free(utf16);
       return object;
     }
+
+#define READ_TYPED_DATA(type, ctype)                                           \
+    {                                                                          \
+      intptr_t len = ReadSmiValue();                                           \
+      Dart_CObject* object =                                                   \
+          AllocateDartCObjectTypedData(Dart_CObject::k##type##Array, len);     \
+      AddBackRef(object_id, object, kIsDeserialized);                          \
+      if (len > 0) {                                                           \
+        ctype* p =                                                             \
+            reinterpret_cast<ctype*>(object->value.as_typed_data.values);      \
+        for (intptr_t i = 0; i < len; i++) {                                   \
+          p[i] = Read<ctype>();                                                \
+        }                                                                      \
+      }                                                                        \
+      return object;                                                           \
+    }                                                                          \
+
+    case kTypedDataInt8ArrayCid:
+    case kExternalTypedDataInt8ArrayCid:
+      READ_TYPED_DATA(Int8, int8_t);
+
     case kTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ArrayCid: {
-      intptr_t len = ReadSmiValue();
-      Dart_CObject* object = AllocateDartCObjectUint8Array(len);
-      AddBackRef(object_id, object, kIsDeserialized);
-      if (len > 0) {
-        uint8_t* p = object->value.as_byte_array.values;
-        for (intptr_t i = 0; i < len; i++) {
-          p[i] = Read<uint8_t>();
-        }
-      }
-      return object;
-    }
+    case kExternalTypedDataUint8ArrayCid:
+      READ_TYPED_DATA(Uint8, uint8_t);
+
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+      READ_TYPED_DATA(Uint8Clamped, uint8_t);
+
+    case kTypedDataInt16ArrayCid:
+    case kExternalTypedDataInt16ArrayCid:
+      READ_TYPED_DATA(Int16, int16_t);
+
+    case kTypedDataUint16ArrayCid:
+    case kExternalTypedDataUint16ArrayCid:
+      READ_TYPED_DATA(Uint16, uint16_t);
+
+    case kTypedDataInt32ArrayCid:
+    case kExternalTypedDataInt32ArrayCid:
+      READ_TYPED_DATA(Int32, int32_t);
+
+    case kTypedDataUint32ArrayCid:
+    case kExternalTypedDataUint32ArrayCid:
+      READ_TYPED_DATA(Uint32, uint32_t);
+
+    case kTypedDataInt64ArrayCid:
+    case kExternalTypedDataInt64ArrayCid:
+      READ_TYPED_DATA(Int64, int64_t);
+
+    case kTypedDataUint64ArrayCid:
+    case kExternalTypedDataUint64ArrayCid:
+      READ_TYPED_DATA(Uint64, uint64_t);
+
+    case kTypedDataFloat32ArrayCid:
+    case kExternalTypedDataFloat32ArrayCid:
+      READ_TYPED_DATA(Float32, float);
+
+    case kTypedDataFloat64ArrayCid:
+    case kExternalTypedDataFloat64ArrayCid:
+      READ_TYPED_DATA(Float64, double);
+
     case kGrowableObjectArrayCid: {
       // A GrowableObjectArray is serialized as its length followed by
       // its backing store. The backing store is an array with a
@@ -924,22 +1040,34 @@
       }
       break;
     }
-    case Dart_CObject::kUint8Array: {
+    case Dart_CObject::kTypedData: {
       // Write out the serialization header value for this object.
       WriteInlinedHeader(object);
       // Write out the class and tags information.
-      WriteIndexedObject(kTypedDataUint8ArrayCid);
-      WriteIntptrValue(RawObject::ClassIdTag::update(
-          kTypedDataUint8ArrayCid, 0));
-      uint8_t* bytes = object->value.as_byte_array.values;
-      intptr_t len = object->value.as_byte_array.length;
+      intptr_t class_id;
+      switch (object->value.as_typed_data.type) {
+        case Dart_CObject::kInt8Array:
+          class_id = kTypedDataInt8ArrayCid;
+          break;
+        case Dart_CObject::kUint8Array:
+          class_id = kTypedDataUint8ArrayCid;
+          break;
+        default:
+          class_id = kTypedDataUint8ArrayCid;
+          UNIMPLEMENTED();
+      }
+
+      WriteIndexedObject(class_id);
+      WriteIntptrValue(RawObject::ClassIdTag::update(class_id, 0));
+      uint8_t* bytes = object->value.as_typed_data.values;
+      intptr_t len = object->value.as_typed_data.length;
       WriteSmi(len);
       for (intptr_t i = 0; i < len; i++) {
         Write<uint8_t>(bytes[i]);
       }
       break;
     }
-    case Dart_CObject::kExternalUint8Array: {
+    case Dart_CObject::kExternalTypedData: {
       // TODO(ager): we are writing C pointers into the message in
       // order to post external arrays through ports. We need to make
       // sure that messages containing pointers can never be posted
@@ -951,11 +1079,11 @@
       WriteIndexedObject(kExternalTypedDataUint8ArrayCid);
       WriteIntptrValue(RawObject::ClassIdTag::update(
           kExternalTypedDataUint8ArrayCid, 0));
-      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;
+      int length = object->value.as_external_typed_data.length;
+      uint8_t* data = object->value.as_external_typed_data.data;
+      void* peer = object->value.as_external_typed_data.peer;
       Dart_WeakPersistentHandleFinalizer callback =
-          object->value.as_external_byte_array.callback;
+          object->value.as_external_typed_data.callback;
       WriteSmi(length);
       WriteIntptrValue(reinterpret_cast<intptr_t>(data));
       WriteIntptrValue(reinterpret_cast<intptr_t>(peer));
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index d215ab0..3ad8fb9 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -88,8 +88,9 @@
   Dart_CObject* AllocateDartCObjectDouble(double value);
   // Allocates a Dart_CObject object for string data.
   Dart_CObject* AllocateDartCObjectString(intptr_t length);
-  // Allocates a C Dart_CObject object for byte data.
-  Dart_CObject* AllocateDartCObjectUint8Array(intptr_t length);
+  // Allocates a C Dart_CObject object for a typed data.
+  Dart_CObject* AllocateDartCObjectTypedData(
+      Dart_CObject::TypedDataType type, intptr_t length);
   // Allocates a C array of Dart_CObject objects.
   Dart_CObject* AllocateDartCObjectArray(intptr_t length);
   // Allocates a Dart_CObject_Internal object with the specified type.
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 08bef08..63fc459 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -111,7 +111,7 @@
                                          const Array& arguments,
                                          const Array& arguments_descriptor) {
   ASSERT(receiver.raw() == arguments.At(0));
-  // Allocate an InvocationMirror object.
+  // Allocate an Invocation object.
   const Library& core_lib = Library::Handle(Library::CoreLibrary());
 
   Class& invocation_mirror_class = Class::Handle(
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index cf4c340..e18ad81 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -224,23 +224,22 @@
 
 DART_EXPORT Dart_Handle Dart_ActivationFrameGetLocation(
                             Dart_ActivationFrame activation_frame,
-                            Dart_Handle* script_url,
-                            intptr_t* library_id,
-                            intptr_t* token_number) {
-  // TODO(hausner): Implement implement a way to recognize when there
+                            Dart_Handle* function_name,
+                            Dart_CodeLocation* location) {
+  // TODO(hausner): Implement a way to recognize when there
   // is no source code for the code in the frame.
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
-  if (script_url != NULL) {
-    *script_url = Api::NewHandle(isolate, frame->SourceUrl());
+  if (function_name != NULL) {
+    *function_name = Api::NewHandle(isolate, frame->QualifiedFunctionName());
   }
-  if (library_id != NULL) {
+
+  if (location != NULL) {
+    location->script_url = Api::NewHandle(isolate, frame->SourceUrl());
     const Library& lib = Library::Handle(frame->Library());
-    *library_id = lib.index();
-  }
-  if (token_number != NULL) {
-    *token_number = frame->TokenPos();
+    location->library_id = lib.index();
+    location->token_pos = frame->TokenPos();
   }
   return Api::True(isolate);
 }
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 717acbf..bfa3438 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -632,6 +632,10 @@
       Format(instr, "swc1 'ft, 'imms('rs)");
       break;
     }
+    case XORI: {
+      Format(instr, "xori 'rt, 'rs, 'immu");
+      break;
+    }
     default: {
       Unknown(instr);
       break;
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 03074f7..cb8ca07 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -19,7 +19,6 @@
                      GraphEntryInstr* graph_entry,
                      intptr_t max_block_id)
   : parent_(),
-    assigned_vars_(),
     current_ssa_temp_index_(0),
     max_block_id_(max_block_id),
     parsed_function_(builder.parsed_function()),
@@ -87,14 +86,12 @@
   postorder_.Clear();
   reverse_postorder_.Clear();
   parent_.Clear();
-  assigned_vars_.Clear();
   // Perform a depth-first traversal of the graph to build preorder and
   // postorder block orders.
   graph_entry_->DiscoverBlocks(NULL,  // Entry block predecessor.
                                &preorder_,
                                &postorder_,
                                &parent_,
-                               &assigned_vars_,
                                variable_count(),
                                num_non_copied_params());
   // Create an array of blocks in reverse postorder.
@@ -208,17 +205,231 @@
 #endif  // DEBUG
 
 
+LivenessAnalysis::LivenessAnalysis(
+  intptr_t variable_count,
+  const GrowableArray<BlockEntryInstr*>& postorder)
+    : variable_count_(variable_count),
+      postorder_(postorder),
+      live_out_(postorder.length()),
+      kill_(postorder.length()),
+      live_in_(postorder.length()) {
+}
+
+
+bool LivenessAnalysis::UpdateLiveOut(const BlockEntryInstr& block) {
+  BitVector* live_out = live_out_[block.postorder_number()];
+  bool changed = false;
+  Instruction* last = block.last_instruction();
+  ASSERT(last != NULL);
+  for (intptr_t i = 0; i < last->SuccessorCount(); i++) {
+    BlockEntryInstr* succ = last->SuccessorAt(i);
+    ASSERT(succ != NULL);
+    if (live_out->AddAll(live_in_[succ->postorder_number()])) {
+      changed = true;
+    }
+  }
+  return changed;
+}
+
+
+bool LivenessAnalysis::UpdateLiveIn(const BlockEntryInstr& block) {
+  BitVector* live_out = live_out_[block.postorder_number()];
+  BitVector* kill = kill_[block.postorder_number()];
+  BitVector* live_in = live_in_[block.postorder_number()];
+  return live_in->KillAndAdd(kill, live_out);
+}
+
+
+void LivenessAnalysis::ComputeLiveInAndLiveOutSets() {
+  const intptr_t block_count = postorder_.length();
+  bool changed;
+  do {
+    changed = false;
+
+    for (intptr_t i = 0; i < block_count; i++) {
+      const BlockEntryInstr& block = *postorder_[i];
+
+      // Live-in set depends only on kill set which does not
+      // change in this loop and live-out set.  If live-out
+      // set does not change there is no need to recompute
+      // live-in set.
+      if (UpdateLiveOut(block) && UpdateLiveIn(block)) {
+        changed = true;
+      }
+    }
+  } while (changed);
+}
+
+
+void LivenessAnalysis::Analyze() {
+  const intptr_t block_count = postorder_.length();
+  for (intptr_t i = 0; i < block_count; i++) {
+    live_out_.Add(new BitVector(variable_count_));
+    kill_.Add(new BitVector(variable_count_));
+    live_in_.Add(new BitVector(variable_count_));
+  }
+
+  ComputeInitialSets();
+  ComputeLiveInAndLiveOutSets();
+}
+
+
+static void PrintBitVector(const char* tag, BitVector* v) {
+  OS::Print("%s:", tag);
+  for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
+    OS::Print(" %"Pd"", it.Current());
+  }
+  OS::Print("\n");
+}
+
+
+void LivenessAnalysis::Dump() {
+  const intptr_t block_count = postorder_.length();
+  for (intptr_t i = 0; i < block_count; i++) {
+    BlockEntryInstr* block = postorder_[i];
+    OS::Print("block @%"Pd" -> ", block->block_id());
+
+    Instruction* last = block->last_instruction();
+    for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
+      BlockEntryInstr* succ = last->SuccessorAt(j);
+      OS::Print(" @%"Pd"", succ->block_id());
+    }
+    OS::Print("\n");
+
+    PrintBitVector("  live out", live_out_[i]);
+    PrintBitVector("  kill", kill_[i]);
+    PrintBitVector("  live in", live_in_[i]);
+  }
+}
+
+
+// Computes liveness information for local variables.
+class VariableLivenessAnalysis : public LivenessAnalysis {
+ public:
+  explicit VariableLivenessAnalysis(FlowGraph* flow_graph)
+      : LivenessAnalysis(flow_graph->variable_count(), flow_graph->postorder()),
+        flow_graph_(flow_graph),
+        num_non_copied_params_(flow_graph->num_non_copied_params()),
+        assigned_vars_() { }
+
+  // For every block (in preorder) compute and return set of variables that
+  // have new assigned values flowing out of that block.
+  const GrowableArray<BitVector*>& ComputeAssignedVars() {
+    // We can't directly return kill_ because it uses postorder numbering while
+    // SSA construction uses preorder numbering internally.
+    // We have to permute postorder into preorder.
+    assigned_vars_.Clear();
+
+    const intptr_t block_count = flow_graph_->preorder().length();
+    for (intptr_t i = 0; i < block_count; i++) {
+      BlockEntryInstr* block = flow_graph_->preorder()[i];
+      BitVector* kill = GetKillSet(block);
+      kill->Intersect(GetLiveOutSet(block));
+      assigned_vars_.Add(kill);
+    }
+
+    return assigned_vars_;
+  }
+
+  // Returns true if the value set by the given store reaches any load from the
+  // same local variable.
+  bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) {
+    if (store->is_dead()) {
+      return false;
+    }
+
+    if (store->is_last()) {
+      const intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
+      return GetLiveOutSet(block)->Contains(index);
+    }
+
+    return true;
+  }
+
+  // Returns true if the given load is the last for the local and the value
+  // of the local will not flow into another one.
+  bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) {
+    const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
+    return load->is_last() && !GetLiveOutSet(block)->Contains(index);
+  }
+
+ private:
+  virtual void ComputeInitialSets();
+
+  const FlowGraph* flow_graph_;
+  const intptr_t num_non_copied_params_;
+  GrowableArray<BitVector*> assigned_vars_;
+};
+
+
+void VariableLivenessAnalysis::ComputeInitialSets() {
+  const intptr_t block_count = postorder_.length();
+
+  BitVector* last_loads = new BitVector(variable_count_);
+  for (intptr_t i = 0; i < block_count; i++) {
+    BlockEntryInstr* block = postorder_[i];
+
+    BitVector* kill = kill_[i];
+    BitVector* live_in = live_in_[i];
+    last_loads->Clear();
+
+    // Iterate backwards starting at the last instruction.
+    for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+      Instruction* current = it.Current();
+
+      LoadLocalInstr* load = current->AsLoadLocal();
+      if (load != NULL) {
+        const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
+        live_in->Add(index);
+        if (!last_loads->Contains(index)) {
+          last_loads->Add(index);
+          load->mark_last();
+        }
+        continue;
+      }
+
+      StoreLocalInstr* store = current->AsStoreLocal();
+      if (store != NULL) {
+        const intptr_t index =
+            store->local().BitIndexIn(num_non_copied_params_);
+        if (kill->Contains(index)) {
+          if (!live_in->Contains(index)) {
+            store->mark_dead();
+          }
+        } else {
+          if (!live_in->Contains(index)) {
+            store->mark_last();
+          }
+          kill->Add(index);
+        }
+        live_in->Remove(index);
+        continue;
+      }
+    }
+  }
+}
+
+
 void FlowGraph::ComputeSSA(intptr_t next_virtual_register_number,
                            GrowableArray<Definition*>* inlining_parameters) {
   ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL));
   current_ssa_temp_index_ = next_virtual_register_number;
   GrowableArray<BitVector*> dominance_frontier;
   ComputeDominators(&dominance_frontier);
-  InsertPhis(preorder_, assigned_vars_, dominance_frontier);
+
+  VariableLivenessAnalysis variable_liveness(this);
+  variable_liveness.Analyze();
+
+  InsertPhis(preorder_,
+             variable_liveness.ComputeAssignedVars(),
+             dominance_frontier);
+
   GrowableArray<PhiInstr*> live_phis;
+
   // Rename uses to reference inserted phis where appropriate.
   // Collect phis that reach a non-environment use.
-  Rename(&live_phis, inlining_parameters);
+  Rename(&live_phis, &variable_liveness, inlining_parameters);
+
   // Propagate alive mark transitively from alive phis and then remove
   // non-live ones.
   RemoveDeadPhis(&live_phis);
@@ -399,6 +610,7 @@
 
 
 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
+                       VariableLivenessAnalysis* variable_liveness,
                        GrowableArray<Definition*>* inlining_parameters) {
   // TODO(fschneider): Support catch-entry.
   if (graph_entry_->SuccessorCount() > 1) {
@@ -439,7 +651,7 @@
 
   BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0);
   ASSERT(normal_entry != NULL);  // Must have entry.
-  RenameRecursive(normal_entry, &env, live_phis);
+  RenameRecursive(normal_entry, &env, live_phis, variable_liveness);
 }
 
 
@@ -462,7 +674,8 @@
 
 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry,
                                 GrowableArray<Definition*>* env,
-                                GrowableArray<PhiInstr*>* live_phis) {
+                                GrowableArray<PhiInstr*>* live_phis,
+                                VariableLivenessAnalysis* variable_liveness) {
   // 1. Process phis first.
   if (block_entry->IsJoinEntry()) {
     JoinEntryInstr* join = block_entry->AsJoinEntry();
@@ -527,25 +740,37 @@
       StoreLocalInstr* store = definition->AsStoreLocal();
       if ((load != NULL) || (store != NULL)) {
         intptr_t index;
+        Definition* result;
         if (store != NULL) {
-          index = store->local().BitIndexIn(num_non_copied_params_);
           // Update renaming environment.
-          (*env)[index] = store->value()->definition();
+          index = store->local().BitIndexIn(num_non_copied_params_);
+          result = store->value()->definition();
+
+          if (variable_liveness->IsStoreAlive(block_entry, store)) {
+            (*env)[index] = result;
+          } else {
+            (*env)[index] = constant_null();
+          }
         } else {
           // The graph construction ensures we do not have an unused LoadLocal
           // computation.
           ASSERT(definition->is_used());
           index = load->local().BitIndexIn(num_non_copied_params_);
+          result = (*env)[index];
 
-          PhiInstr* phi = (*env)[index]->AsPhi();
+          PhiInstr* phi = result->AsPhi();
           if ((phi != NULL) && !phi->is_alive()) {
             phi->mark_alive();
             live_phis->Add(phi);
           }
+
+          if (variable_liveness->IsLastLoad(block_entry, load)) {
+            (*env)[index] = constant_null();
+          }
         }
         // Update expression stack or remove from graph.
         if (definition->is_used()) {
-          env->Add((*env)[index]);
+          env->Add(result);
           // We remove load/store instructions when we find their use in 2a.
         } else {
           it.RemoveCurrentFromGraph();
@@ -572,7 +797,7 @@
     BlockEntryInstr* block = block_entry->dominated_blocks()[i];
     GrowableArray<Definition*> new_env(env->length());
     new_env.AddArray(*env);
-    RenameRecursive(block, &new_env, live_phis);
+    RenameRecursive(block, &new_env, live_phis, variable_liveness);
   }
 
   // 4. Process successor block. We have edge-split form, so that only blocks
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 13d9cba..d761fa2 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -13,6 +13,7 @@
 
 class FlowGraphBuilder;
 class ValueInliningContext;
+class VariableLivenessAnalysis;
 
 class BlockIterator : public ValueObject {
  public:
@@ -154,11 +155,14 @@
       GrowableArray<intptr_t>* label);
 
   void Rename(GrowableArray<PhiInstr*>* live_phis,
+              VariableLivenessAnalysis* variable_liveness,
               GrowableArray<Definition*>* inlining_parameters);
+
   void RenameRecursive(
       BlockEntryInstr* block_entry,
       GrowableArray<Definition*>* env,
-      GrowableArray<PhiInstr*>* live_phis);
+      GrowableArray<PhiInstr*>* live_phis,
+      VariableLivenessAnalysis* variable_liveness);
 
   void AttachEnvironment(Instruction* instr, GrowableArray<Definition*>* env);
 
@@ -192,6 +196,77 @@
   ConstantInstr* constant_null_;
 };
 
+
+class LivenessAnalysis : public ValueObject {
+ public:
+  LivenessAnalysis(intptr_t variable_count,
+                   const GrowableArray<BlockEntryInstr*>& postorder);
+
+  void Analyze();
+
+  virtual ~LivenessAnalysis() { }
+
+  BitVector* GetLiveInSetAt(intptr_t postorder_number) const {
+    return live_in_[postorder_number];
+  }
+
+  BitVector* GetLiveOutSetAt(intptr_t postorder_number) const {
+    return live_out_[postorder_number];
+  }
+
+  BitVector* GetLiveInSet(BlockEntryInstr* block) const {
+    return GetLiveInSetAt(block->postorder_number());
+  }
+
+  BitVector* GetKillSet(BlockEntryInstr* block) const {
+    return kill_[block->postorder_number()];
+  }
+
+  BitVector* GetLiveOutSet(BlockEntryInstr* block) const {
+    return GetLiveOutSetAt(block->postorder_number());
+  }
+
+  // Print results of liveness analysis.
+  void Dump();
+
+ protected:
+  // Compute initial values for live-out, kill and live-in sets.
+  virtual void ComputeInitialSets() = 0;
+
+  // Update live-out set for the given block: live-out should contain
+  // all values that are live-in for block's successors.
+  // Returns true if live-out set was changed.
+  bool UpdateLiveOut(const BlockEntryInstr& instr);
+
+  // Update live-in set for the given block: live-in should contain
+  // all values that are live-out from the block and are not defined
+  // by this block.
+  // Returns true if live-in set was changed.
+  bool UpdateLiveIn(const BlockEntryInstr& instr);
+
+  // Perform fix-point iteration updating live-out and live-in sets
+  // for blocks until they stop changing.
+  void ComputeLiveInAndLiveOutSets();
+
+  const intptr_t variable_count_;
+
+  const GrowableArray<BlockEntryInstr*>& postorder_;
+
+  // Live-out sets for each block.  They contain indices of variables
+  // that are live out from this block: that is values that were either
+  // defined in this block or live into it and that are used in some
+  // successor block.
+  GrowableArray<BitVector*> live_out_;
+
+  // Kill sets for each block.  They contain indices of variables that
+  // are defined by this block.
+  GrowableArray<BitVector*> kill_;
+
+  // Live-in sets for each block.  They contain indices of variables
+  // that are used by this block or its successors.
+  GrowableArray<BitVector*> live_in_;
+};
+
 }  // namespace dart
 
 #endif  // VM_FLOW_GRAPH_H_
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 3b89eba..a347c8f 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -66,9 +66,7 @@
     value_representations_(flow_graph.max_virtual_register_number()),
     block_order_(flow_graph.reverse_postorder()),
     postorder_(flow_graph.postorder()),
-    live_out_(block_order_.length()),
-    kill_(block_order_.length()),
-    live_in_(block_order_.length()),
+    liveness_(flow_graph),
     vreg_count_(flow_graph.max_virtual_register_number()),
     live_ranges_(flow_graph.max_virtual_register_number()),
     cpu_regs_(),
@@ -116,7 +114,7 @@
 }
 
 
-void FlowGraphAllocator::ComputeInitialSets() {
+void SSALivenessAnalysis::ComputeInitialSets() {
   const intptr_t block_count = postorder_.length();
   for (intptr_t i = 0; i < block_count; i++) {
     BlockEntryInstr* block = postorder_[i];
@@ -189,11 +187,10 @@
   }
 
   // Process initial definitions, ie, constants and incoming parameters.
-  GraphEntryInstr* graph_entry = flow_graph_.graph_entry();
-  for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) {
-    intptr_t vreg = (*graph_entry->initial_definitions())[i]->ssa_temp_index();
-    kill_[graph_entry->postorder_number()]->Add(vreg);
-    live_in_[graph_entry->postorder_number()]->Remove(vreg);
+  for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); i++) {
+    intptr_t vreg = (*graph_entry_->initial_definitions())[i]->ssa_temp_index();
+    kill_[graph_entry_->postorder_number()]->Add(vreg);
+    live_in_[graph_entry_->postorder_number()]->Remove(vreg);
   }
 
   // Update initial live_in sets to match live_out sets. Has to be
@@ -204,93 +201,6 @@
 }
 
 
-bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) {
-  BitVector* live_out = live_out_[instr.postorder_number()];
-  bool changed = false;
-  Instruction* last = instr.last_instruction();
-  ASSERT(last != NULL);
-  for (intptr_t i = 0; i < last->SuccessorCount(); i++) {
-    BlockEntryInstr* succ = last->SuccessorAt(i);
-    ASSERT(succ != NULL);
-    if (live_out->AddAll(live_in_[succ->postorder_number()])) {
-      changed = true;
-    }
-  }
-  return changed;
-}
-
-
-bool FlowGraphAllocator::UpdateLiveIn(const BlockEntryInstr& instr) {
-  BitVector* live_out = live_out_[instr.postorder_number()];
-  BitVector* kill = kill_[instr.postorder_number()];
-  BitVector* live_in = live_in_[instr.postorder_number()];
-  return live_in->KillAndAdd(kill, live_out);
-}
-
-
-void FlowGraphAllocator::ComputeLiveInAndLiveOutSets() {
-  const intptr_t block_count = postorder_.length();
-  bool changed;
-  do {
-    changed = false;
-
-    for (intptr_t i = 0; i < block_count; i++) {
-      const BlockEntryInstr& block = *postorder_[i];
-
-      // Live-in set depends only on kill set which does not
-      // change in this loop and live-out set.  If live-out
-      // set does not change there is no need to recompute
-      // live-in set.
-      if (UpdateLiveOut(block) && UpdateLiveIn(block)) {
-        changed = true;
-      }
-    }
-  } while (changed);
-}
-
-
-void FlowGraphAllocator::AnalyzeLiveness() {
-  const intptr_t block_count = postorder_.length();
-  for (intptr_t i = 0; i < block_count; i++) {
-    live_out_.Add(new BitVector(vreg_count_));
-    kill_.Add(new BitVector(vreg_count_));
-    live_in_.Add(new BitVector(vreg_count_));
-  }
-
-  ComputeInitialSets();
-  ComputeLiveInAndLiveOutSets();
-}
-
-
-static void PrintBitVector(const char* tag, BitVector* v) {
-  OS::Print("%s:", tag);
-  for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
-    OS::Print(" %"Pd"", it.Current());
-  }
-  OS::Print("\n");
-}
-
-
-void FlowGraphAllocator::DumpLiveness() {
-  const intptr_t block_count = postorder_.length();
-  for (intptr_t i = 0; i < block_count; i++) {
-    BlockEntryInstr* block = postorder_[i];
-    OS::Print("block @%"Pd" -> ", block->block_id());
-
-    Instruction* last = block->last_instruction();
-    for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
-      BlockEntryInstr* succ = last->SuccessorAt(j);
-      OS::Print(" @%"Pd"", succ->block_id());
-    }
-    OS::Print("\n");
-
-    PrintBitVector("  live out", live_out_[i]);
-    PrintBitVector("  kill", kill_[i]);
-    PrintBitVector("  live in", live_in_[i]);
-  }
-}
-
-
 void LiveRange::AddUse(intptr_t pos, Location* location_slot) {
   ASSERT(location_slot != NULL);
   ASSERT((first_use_interval_->start_ <= pos) &&
@@ -535,7 +445,9 @@
     // For every SSA value that is live out of this block, create an interval
     // that covers the whole block.  It will be shortened if we encounter a
     // definition of this value in this block.
-    for (BitVector::Iterator it(live_out_[i]); !it.Done(); it.Advance()) {
+    for (BitVector::Iterator it(liveness_.GetLiveOutSetAt(i));
+         !it.Done();
+         it.Advance()) {
       LiveRange* range = GetLiveRange(it.Current());
       range->AddUseInterval(block->start_pos(), block->end_pos());
     }
@@ -548,7 +460,7 @@
       // All values flowing into the loop header are live at the back-edge and
       // can interfere with phi moves.
       current_interference_set->AddAll(
-          live_in_[loop_header->entry()->postorder_number()]);
+          liveness_.GetLiveInSet(loop_header->entry()));
       loop_header->set_backedge_interference(
           current_interference_set);
     }
@@ -571,7 +483,9 @@
     // Check if any values live into the loop can be spilled for free.
     if (block_info->is_loop_header()) {
       current_interference_set = NULL;
-      for (BitVector::Iterator it(live_in_[i]); !it.Done(); it.Advance()) {
+      for (BitVector::Iterator it(liveness_.GetLiveInSetAt(i));
+           !it.Done();
+           it.Advance()) {
         LiveRange* range = GetLiveRange(it.Current());
         if (HasOnlyUnconstrainedUsesInLoop(range, block_info)) {
           range->MarkHasOnlyUnconstrainedUsesInLoop(block_info->loop_id());
@@ -2453,7 +2367,7 @@
   // Resolve non-linear control flow across branches.
   for (intptr_t i = 1; i < block_order_.length(); i++) {
     BlockEntryInstr* block = block_order_[i];
-    BitVector* live = live_in_[block->postorder_number()];
+    BitVector* live = liveness_.GetLiveInSet(block);
     for (BitVector::Iterator it(live); !it.Done(); it.Advance()) {
       LiveRange* range = GetLiveRange(it.Current());
       for (intptr_t j = 0; j < block->PredecessorCount(); j++) {
@@ -2520,7 +2434,7 @@
 
   EliminateEnvironments();
 
-  AnalyzeLiveness();
+  liveness_.Analyze();
 
   NumberInstructions();
 
@@ -2529,7 +2443,7 @@
   BuildLiveRanges();
 
   if (FLAG_print_ssa_liveness) {
-    DumpLiveness();
+    liveness_.Dump();
   }
 
   if (FLAG_print_ssa_liveranges) {
diff --git a/runtime/vm/flow_graph_allocator.h b/runtime/vm/flow_graph_allocator.h
index ab60b82..8919e38 100644
--- a/runtime/vm/flow_graph_allocator.h
+++ b/runtime/vm/flow_graph_allocator.h
@@ -5,6 +5,7 @@
 #ifndef VM_FLOW_GRAPH_ALLOCATOR_H_
 #define VM_FLOW_GRAPH_ALLOCATOR_H_
 
+#include "vm/flow_graph.h"
 #include "vm/growable_array.h"
 #include "vm/intermediate_language.h"
 
@@ -35,6 +36,21 @@
 };
 
 
+class SSALivenessAnalysis : public LivenessAnalysis {
+ public:
+  explicit SSALivenessAnalysis(const FlowGraph& flow_graph)
+      : LivenessAnalysis(flow_graph.max_virtual_register_number(),
+                         flow_graph.postorder()),
+        graph_entry_(flow_graph.graph_entry()) { }
+
+ private:
+  // Compute initial values for live-out, kill and live-in sets.
+  virtual void ComputeInitialSets();
+
+  GraphEntryInstr* graph_entry_;
+};
+
+
 class FlowGraphAllocator : public ValueObject {
  public:
   // Number of stack slots needed for a fpu register spill slot.
@@ -44,9 +60,6 @@
 
   void AllocateRegisters();
 
-  // Build live-in and live-out sets for each block.
-  void AnalyzeLiveness();
-
   // Map a virtual register number to its live range.
   LiveRange* GetLiveRange(intptr_t vreg);
 
@@ -56,27 +69,6 @@
   // Eliminate unnecessary environments from the IL.
   void EliminateEnvironments();
 
-  // Compute initial values for live-out, kill and live-in sets.
-  void ComputeInitialSets();
-
-  // Update live-out set for the given block: live-out should contain
-  // all values that are live-in for block's successors.
-  // Returns true if live-out set was changed.
-  bool UpdateLiveOut(const BlockEntryInstr& instr);
-
-  // Update live-in set for the given block: live-in should contain
-  // all values that are live-out from the block and are not defined
-  // by this block.
-  // Returns true if live-in set was changed.
-  bool UpdateLiveIn(const BlockEntryInstr& instr);
-
-  // Perform fix-point iteration updating live-out and live-in sets
-  // for blocks until they stop changing.
-  void ComputeLiveInAndLiveOutSets();
-
-  // Print results of liveness analysis.
-  void DumpLiveness();
-
   // Visit blocks in the code generation order (reverse post order) and
   // linearly assign consequent lifetime positions to every instruction.
   // We assign position as follows:
@@ -249,19 +241,7 @@
   // Mapping between lifetime positions and blocks containing them.
   GrowableArray<BlockInfo*> block_info_;
 
-  // Live-out sets for each block.  They contain indices of SSA values
-  // that are live out from this block: that is values that were either
-  // defined in this block or live into it and that are used in some
-  // successor block.
-  GrowableArray<BitVector*> live_out_;
-
-  // Kill sets for each block.  They contain indices of SSA values that
-  // are defined by this block.
-  GrowableArray<BitVector*> kill_;
-
-  // Live-in sets for each block.  They contain indices of SSA values
-  // that are used by this block or its successors.
-  GrowableArray<BitVector*> live_in_;
+  SSALivenessAnalysis liveness_;
 
   // Number of virtual registers.  Currently equal to the number of
   // SSA values.
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 8a54d5b..75cf6b3 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -19,6 +19,7 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, print_ast);
 DECLARE_FLAG(bool, print_scopes);
@@ -42,7 +43,19 @@
 
 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
                                              intptr_t stub_ix) {
-  UNIMPLEMENTED();
+  // Calls do not need stubs, they share a deoptimization trampoline.
+  ASSERT(reason() != kDeoptAtCall);
+  Assembler* assem = compiler->assembler();
+#define __ assem->
+  __ Comment("Deopt stub for id %"Pd"", deopt_id());
+  __ Bind(entry_label());
+  if (FLAG_trap_on_deoptimization) __ break_(0);
+
+  ASSERT(deoptimization_env() != NULL);
+
+  __ BranchLink(&StubCode::DeoptimizeLabel());
+  set_pc_offset(assem->CodeSize());
+#undef __
 }
 
 
@@ -1154,57 +1167,195 @@
 }
 
 
+#undef __
+#define __ compiler_->assembler()->
+
+
 void ParallelMoveResolver::EmitMove(int index) {
-  UNIMPLEMENTED();
+  MoveOperands* move = moves_[index];
+  const Location source = move->src();
+  const Location destination = move->dest();
+
+  if (source.IsRegister()) {
+    if (destination.IsRegister()) {
+      __ mov(destination.reg(), source.reg());
+    } else {
+      ASSERT(destination.IsStackSlot());
+      __ sw(source.reg(), destination.ToStackSlotAddress());
+    }
+  } else if (source.IsStackSlot()) {
+    if (destination.IsRegister()) {
+      __ lw(destination.reg(), source.ToStackSlotAddress());
+    } else {
+      ASSERT(destination.IsStackSlot());
+      MoveMemoryToMemory(destination.ToStackSlotAddress(),
+                         source.ToStackSlotAddress());
+    }
+  } else if (source.IsFpuRegister()) {
+    if (destination.IsFpuRegister()) {
+      __ movd(destination.fpu_reg(), source.fpu_reg());
+    } else {
+      if (destination.IsDoubleStackSlot()) {
+        __ sdc1(source.fpu_reg(), destination.ToStackSlotAddress());
+      } else {
+        ASSERT(destination.IsQuadStackSlot());
+        UNIMPLEMENTED();
+      }
+    }
+  } else if (source.IsDoubleStackSlot()) {
+    if (destination.IsFpuRegister()) {
+      __ ldc1(destination.fpu_reg(), source.ToStackSlotAddress());
+    } else {
+      ASSERT(destination.IsDoubleStackSlot());
+      __ ldc1(FpuTMP, source.ToStackSlotAddress());
+      __ sdc1(FpuTMP, destination.ToStackSlotAddress());
+    }
+  } else if (source.IsQuadStackSlot()) {
+    UNIMPLEMENTED();
+  } else {
+    ASSERT(source.IsConstant());
+    if (destination.IsRegister()) {
+      const Object& constant = source.constant();
+      __ LoadObject(destination.reg(), constant);
+    } else {
+      ASSERT(destination.IsStackSlot());
+      StoreObject(destination.ToStackSlotAddress(), source.constant());
+    }
+  }
+
+  move->Eliminate();
 }
 
 
 void ParallelMoveResolver::EmitSwap(int index) {
-  UNIMPLEMENTED();
+  MoveOperands* move = moves_[index];
+  const Location source = move->src();
+  const Location destination = move->dest();
+
+  if (source.IsRegister() && destination.IsRegister()) {
+    ASSERT(source.reg() != TMP1);
+    ASSERT(destination.reg() != TMP1);
+    __ mov(TMP1, source.reg());
+    __ mov(source.reg(), destination.reg());
+    __ mov(destination.reg(), TMP1);
+  } else if (source.IsRegister() && destination.IsStackSlot()) {
+    Exchange(source.reg(), destination.ToStackSlotAddress());
+  } else if (source.IsStackSlot() && destination.IsRegister()) {
+    Exchange(destination.reg(), source.ToStackSlotAddress());
+  } else if (source.IsStackSlot() && destination.IsStackSlot()) {
+    Exchange(destination.ToStackSlotAddress(), source.ToStackSlotAddress());
+  } else if (source.IsFpuRegister() && destination.IsFpuRegister()) {
+    __ movd(FpuTMP, source.fpu_reg());
+    __ movd(source.fpu_reg(), destination.fpu_reg());
+    __ movd(destination.fpu_reg(), FpuTMP);
+  } else if (source.IsFpuRegister() || destination.IsFpuRegister()) {
+    ASSERT(destination.IsDoubleStackSlot() ||
+           destination.IsQuadStackSlot() ||
+           source.IsDoubleStackSlot() ||
+           source.IsQuadStackSlot());
+    bool double_width = destination.IsDoubleStackSlot() ||
+                        source.IsDoubleStackSlot();
+    FRegister reg = source.IsFpuRegister() ? source.fpu_reg()
+                                           : destination.fpu_reg();
+    const Address& slot_address = source.IsFpuRegister()
+        ? destination.ToStackSlotAddress()
+        : source.ToStackSlotAddress();
+
+    if (double_width) {
+      __ ldc1(FpuTMP, slot_address);
+      __ sdc1(reg, slot_address);
+      __ movd(reg, FpuTMP);
+    } else {
+      UNIMPLEMENTED();
+    }
+  } else if (source.IsDoubleStackSlot() && destination.IsDoubleStackSlot()) {
+    const Address& source_slot_address = source.ToStackSlotAddress();
+    const Address& destination_slot_address = destination.ToStackSlotAddress();
+
+    ScratchFpuRegisterScope ensure_scratch(this, FpuTMP);
+    __ ldc1(FpuTMP, source_slot_address);
+    __ ldc1(ensure_scratch.reg(), destination_slot_address);
+    __ sdc1(FpuTMP, destination_slot_address);
+    __ sdc1(ensure_scratch.reg(), source_slot_address);
+  } else if (source.IsQuadStackSlot() && destination.IsQuadStackSlot()) {
+    UNIMPLEMENTED();
+  } else {
+    UNREACHABLE();
+  }
+
+  // The swap of source and destination has executed a move from source to
+  // destination.
+  move->Eliminate();
+
+  // Any unperformed (including pending) move with a source of either
+  // this move's source or destination needs to have their source
+  // changed to reflect the state of affairs after the swap.
+  for (int i = 0; i < moves_.length(); ++i) {
+    const MoveOperands& other_move = *moves_[i];
+    if (other_move.Blocks(source)) {
+      moves_[i]->set_src(destination);
+    } else if (other_move.Blocks(destination)) {
+      moves_[i]->set_src(source);
+    }
+  }
 }
 
 
 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst,
                                               const Address& src) {
-  UNIMPLEMENTED();
+  __ lw(TMP1, src);
+  __ sw(TMP1, dst);
 }
 
 
 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
-  UNIMPLEMENTED();
+  __ LoadObject(TMP1, obj);
+  __ sw(TMP1, dst);
 }
 
 
 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) {
-  UNIMPLEMENTED();
+  ASSERT(reg != TMP1);
+  __ mov(TMP1, reg);
+  __ lw(reg, mem);
+  __ sw(TMP1, mem);
 }
 
 
 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
-  UNIMPLEMENTED();
+  ScratchRegisterScope ensure_scratch(this, TMP1);
+  __ lw(ensure_scratch.reg(), mem1);
+  __ lw(TMP1, mem2);
+  __ sw(ensure_scratch.reg(), mem2);
+  __ sw(TMP1, mem1);
 }
 
 
 void ParallelMoveResolver::SpillScratch(Register reg) {
-  UNIMPLEMENTED();
+  __ Push(reg);
 }
 
 
 void ParallelMoveResolver::RestoreScratch(Register reg) {
-  UNIMPLEMENTED();
+  __ Pop(reg);
 }
 
 
 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
-  UNIMPLEMENTED();
+  __ AddImmediate(SP, -kDoubleSize);
+  __ sdc1(reg, Address(SP));
 }
 
 
 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
-  UNIMPLEMENTED();
+  __ ldc1(reg, Address(SP));
+  __ AddImmediate(SP, kDoubleSize);
 }
 
 
+#undef __
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 404caab..8833ac3 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -3371,7 +3371,7 @@
           for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
             BlockEntryInstr* pred = block->PredecessorAt(i);
             BitVector* pred_out = out_[pred->preorder_number()];
-            temp->Intersect(*pred_out);
+            temp->Intersect(pred_out);
           }
         }
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 71acde1..0c64c34 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -459,27 +459,6 @@
 }
 
 
-// ==== Recording assigned variables.
-void Definition::RecordAssignedVars(BitVector* assigned_vars,
-                                    intptr_t fixed_parameter_count) {
-  // Nothing to do for the base class.
-}
-
-
-void StoreLocalInstr::RecordAssignedVars(BitVector* assigned_vars,
-                                         intptr_t fixed_parameter_count) {
-  if (!local().is_captured()) {
-    assigned_vars->Add(local().BitIndexIn(fixed_parameter_count));
-  }
-}
-
-
-void Instruction::RecordAssignedVars(BitVector* assigned_vars,
-                                     intptr_t fixed_parameter_count) {
-  // Nothing to do for the base class.
-}
-
-
 void Value::AddToList(Value* value, Value** list) {
   Value* next = *list;
   *list = value;
@@ -682,7 +661,6 @@
     GrowableArray<BlockEntryInstr*>* preorder,
     GrowableArray<BlockEntryInstr*>* postorder,
     GrowableArray<intptr_t>* parent,
-    GrowableArray<BitVector*>* assigned_vars,
     intptr_t variable_count,
     intptr_t fixed_parameter_count) {
   // If this block has a predecessor (i.e., is not the graph entry) we can
@@ -711,16 +689,12 @@
   parent->Add(parent_number);
 
   // 4. Assign the preorder number and add the block entry to the list.
-  // Allocate an empty set of assigned variables for the block.
   set_preorder_number(preorder->length());
   preorder->Add(this);
-  BitVector* vars =
-      (variable_count == 0) ? NULL : new BitVector(variable_count);
-  assigned_vars->Add(vars);
-  // The preorder, parent, and assigned_vars arrays are all indexed by
+
+  // The preorder and parent arrays are indexed by
   // preorder block number, so they should stay in lockstep.
   ASSERT(preorder->length() == parent->length());
-  ASSERT(preorder->length() == assigned_vars->length());
 
   // 5. Iterate straight-line successors to record assigned variables and
   // find the last instruction in the block.  The graph entry block consists
@@ -729,18 +703,18 @@
   Instruction* last = this;
   for (ForwardInstructionIterator it(this); !it.Done(); it.Advance()) {
     last = it.Current();
-    if (vars != NULL) {
-      last->RecordAssignedVars(vars, fixed_parameter_count);
-    }
   }
   set_last_instruction(last);
 
   // Visit the block's successors in reverse so that they appear forwards
   // the reverse postorder block ordering.
   for (intptr_t i = last->SuccessorCount() - 1; i >= 0; --i) {
-    last->SuccessorAt(i)->DiscoverBlocks(this, preorder, postorder,
-                                         parent, assigned_vars,
-                                         variable_count, fixed_parameter_count);
+    last->SuccessorAt(i)->DiscoverBlocks(this,
+                                         preorder,
+                                         postorder,
+                                         parent,
+                                         variable_count,
+                                         fixed_parameter_count);
   }
 
   // 6. Assign postorder number and add the block entry to the list.
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index fd21acf..1b00413 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -623,11 +623,6 @@
 
   void Goto(JoinEntryInstr* entry);
 
-  // Mutate assigned_vars to add the local variable index for all
-  // frame-allocated locals assigned to by the instruction.
-  virtual void RecordAssignedVars(BitVector* assigned_vars,
-                                  intptr_t fixed_parameter_count);
-
   virtual const char* DebugName() const = 0;
 
   // Printing support.
@@ -991,7 +986,6 @@
       GrowableArray<BlockEntryInstr*>* preorder,
       GrowableArray<BlockEntryInstr*>* postorder,
       GrowableArray<intptr_t>* parent,
-      GrowableArray<BitVector*>* assigned_vars,
       intptr_t variable_count,
       intptr_t fixed_parameter_count);
 
@@ -1420,9 +1414,6 @@
   // NULL iterator.
   void ReplaceWith(Definition* other, ForwardInstructionIterator* iterator);
 
-  virtual void RecordAssignedVars(BitVector* assigned_vars,
-                                  intptr_t fixed_parameter_count);
-
   // Printing support. These functions are sometimes overridden for custom
   // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
   virtual void PrintTo(BufferFormatter* f) const;
@@ -2858,7 +2849,8 @@
 
 class LoadLocalInstr : public TemplateDefinition<0> {
  public:
-  explicit LoadLocalInstr(const LocalVariable& local) : local_(local) { }
+  explicit LoadLocalInstr(const LocalVariable& local)
+      : local_(local), is_last_(false) { }
 
   DECLARE_INSTRUCTION(LoadLocal)
   virtual CompileType ComputeType() const;
@@ -2874,8 +2866,12 @@
     return false;
   }
 
+  void mark_last() { is_last_ = true; }
+  bool is_last() const { return is_last_; }
+
  private:
   const LocalVariable& local_;
+  bool is_last_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
 };
@@ -2883,7 +2879,8 @@
 
 class StoreLocalInstr : public TemplateDefinition<1> {
  public:
-  StoreLocalInstr(const LocalVariable& local, Value* value) : local_(local) {
+  StoreLocalInstr(const LocalVariable& local, Value* value)
+      : local_(local), is_dead_(false), is_last_(false) {
     SetInputAt(0, value);
   }
 
@@ -2893,9 +2890,6 @@
   const LocalVariable& local() const { return local_; }
   Value* value() const { return inputs_[0]; }
 
-  virtual void RecordAssignedVars(BitVector* assigned_vars,
-                                  intptr_t fixed_parameter_count);
-
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
   virtual bool CanDeoptimize() const { return false; }
@@ -2905,8 +2899,16 @@
     return false;
   }
 
+  void mark_dead() { is_dead_ = true; }
+  bool is_dead() const { return is_dead_; }
+
+  void mark_last() { is_last_ = true; }
+  bool is_last() const { return is_last_; }
+
  private:
   const LocalVariable& local_;
+  bool is_dead_;
+  bool is_last_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
 };
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index b6ec1b0..9eb5cdc 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -405,6 +405,25 @@
 }
 
 
+static void LoadValueCid(FlowGraphCompiler* compiler,
+                         Register value_cid_reg,
+                         Register value_reg,
+                         Label* value_is_smi = NULL) {
+  Label done;
+  if (value_is_smi == NULL) {
+    __ LoadImmediate(value_cid_reg, kSmiCid);
+  }
+  __ andi(TMP1, value_reg, Immediate(kSmiTagMask));
+  if (value_is_smi == NULL) {
+    __ beq(TMP1, ZR, &done);
+  } else {
+    __ beq(TMP1, ZR, value_is_smi);
+  }
+  __ LoadClassId(value_cid_reg, value_reg);
+  __ Bind(&done);
+}
+
+
 // Emit code when ICData's targets are all Object == (which is ===).
 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler,
                                    const ICData& ic_data,
@@ -430,11 +449,62 @@
 }
 
 
+static Condition TokenKindToSmiCondition(Token::Kind kind) {
+  switch (kind) {
+    case Token::kEQ: return EQ;
+    case Token::kNE: return NE;
+    case Token::kLT: return LT;
+    case Token::kGT: return GT;
+    case Token::kLTE: return LE;
+    case Token::kGTE: return GE;
+    default:
+      UNREACHABLE();
+      return VS;
+  }
+}
+
+
 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
                                 const LocationSummary& locs,
                                 Token::Kind kind,
                                 BranchInstr* branch) {
-  UNIMPLEMENTED();
+  Location left = locs.in(0);
+  Location right = locs.in(1);
+  ASSERT(!left.IsConstant() || !right.IsConstant());
+
+  Condition true_condition = TokenKindToSmiCondition(kind);
+
+  if (left.IsConstant()) {
+    __ CompareObject(CMPRES, right.reg(), left.constant());
+    true_condition = FlowGraphCompiler::FlipCondition(true_condition);
+  } else if (right.IsConstant()) {
+    __ CompareObject(CMPRES, left.reg(), right.constant());
+  } else {
+    __ subu(CMPRES, left.reg(), right.reg());
+  }
+
+  if (branch != NULL) {
+    branch->EmitBranchOnCondition(compiler, true_condition);
+  } else {
+    Register result = locs.out().reg();
+    Label done, is_true;
+    switch (true_condition) {
+      case EQ: __ beq(CMPRES, ZR, &is_true); break;
+      case NE: __ bne(CMPRES, ZR, &is_true); break;
+      case GT: __ bgtz(CMPRES, &is_true); break;
+      case GE: __ bgez(CMPRES, &is_true); break;
+      case LT: __ bltz(CMPRES, &is_true); break;
+      case LE: __ blez(CMPRES, &is_true); break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+    __ LoadObject(result, Bool::False());
+    __ b(&done);
+    __ Bind(&is_true);
+    __ LoadObject(result, Bool::True());
+    __ Bind(&done);
+  }
 }
 
 
@@ -446,6 +516,14 @@
 }
 
 
+static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
+                                        const LocationSummary& locs,
+                                        Token::Kind kind,
+                                        BranchInstr* branch) {
+  UNIMPLEMENTED();
+}
+
+
 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
                                    const LocationSummary& locs,
                                    Token::Kind kind,
@@ -543,19 +621,135 @@
 
 
 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  if (operands_class_id() == kMintCid) {
+    const intptr_t kNumTemps = 2;
+    LocationSummary* locs =
+        new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    locs->set_in(0, Location::RequiresFpuRegister());
+    locs->set_in(1, Location::RequiresFpuRegister());
+    locs->set_temp(0, Location::RequiresRegister());
+    locs->set_temp(1, Location::RequiresRegister());
+    locs->set_out(Location::RequiresRegister());
+    return locs;
+  }
+  if (operands_class_id() == kDoubleCid) {
+    LocationSummary* summary =
+        new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    summary->set_in(0, Location::RequiresFpuRegister());
+    summary->set_in(1, Location::RequiresFpuRegister());
+    summary->set_out(Location::RequiresRegister());
+    return summary;
+  } else if (operands_class_id() == kSmiCid) {
+    LocationSummary* summary =
+        new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    summary->set_in(0, Location::RegisterOrConstant(left()));
+    // Only one input can be a constant operand. The case of two constant
+    // operands should be handled by constant propagation.
+    summary->set_in(1, summary->in(0).IsConstant()
+                           ? Location::RequiresRegister()
+                           : Location::RegisterOrConstant(right()));
+    summary->set_out(Location::RequiresRegister());
+    return summary;
+  }
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+  // Pick arbitrary fixed input registers because this is a call.
+  locs->set_in(0, Location::RegisterLocation(A0));
+  locs->set_in(1, Location::RegisterLocation(A1));
+  locs->set_out(Location::RegisterLocation(V0));
+  return locs;
 }
 
 
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  if (operands_class_id() == kSmiCid) {
+    EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
+    return;
+  }
+  if (operands_class_id() == kMintCid) {
+    EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
+    return;
+  }
+  if (operands_class_id() == kDoubleCid) {
+    EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
+    return;
+  }
+
+  // Push arguments for the call.
+  // TODO(fschneider): Split this instruction into different types to avoid
+  // explicitly pushing arguments to the call here.
+  Register left = locs()->in(0).reg();
+  Register right = locs()->in(1).reg();
+  __ Push(left);
+  __ Push(right);
+  if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
+    Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp);
+    // Load class into A2.
+    const intptr_t kNumArguments = 2;
+    LoadValueCid(compiler, A2, left);
+    compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
+                              A2,  // Class id register.
+                              kNumArguments,
+                              Array::Handle(),  // No named arguments.
+                              deopt,  // Deoptimize target.
+                              deopt_id(),
+                              token_pos(),
+                              locs());
+    return;
+  }
+  const String& function_name =
+      String::ZoneHandle(Symbols::New(Token::Str(kind())));
+  if (!compiler->is_optimizing()) {
+    compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
+                                   deopt_id(),
+                                   token_pos());
+  }
+  const intptr_t kNumArguments = 2;
+  const intptr_t kNumArgsChecked = 2;  // Type-feedback.
+  ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw());
+  if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
+    ASSERT(!ic_data()->IsNull());
+    if (ic_data()->NumberOfChecks() == 0) {
+      // IC call for reoptimization populates original ICData.
+      relational_ic_data = ic_data()->raw();
+    } else {
+      // Megamorphic call.
+      relational_ic_data = ic_data()->AsUnaryClassChecks();
+    }
+  } else {
+    relational_ic_data = ICData::New(compiler->parsed_function().function(),
+                                     function_name,
+                                     deopt_id(),
+                                     kNumArgsChecked);
+  }
+  compiler->GenerateInstanceCall(deopt_id(),
+                                 token_pos(),
+                                 kNumArguments,
+                                 Array::ZoneHandle(),  // No optional arguments.
+                                 locs(),
+                                 relational_ic_data);
 }
 
 
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
-  UNIMPLEMENTED();
+  if (operands_class_id() == kSmiCid) {
+    EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
+    return;
+  }
+  if (operands_class_id() == kMintCid) {
+    EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
+    return;
+  }
+  if (operands_class_id() == kDoubleCid) {
+    EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
+    return;
+  }
+  EmitNativeCode(compiler);
+  __ CompareObject(CMPRES, V0, Bool::True());
+  branch->EmitBranchOnCondition(compiler, EQ);
 }
 
 
@@ -880,13 +1074,196 @@
 
 
 LocationSummary* BinarySmiOpInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  if (op_kind() == Token::kTRUNCDIV) {
+    UNIMPLEMENTED();
+    return NULL;
+  } else {
+    const intptr_t kNumTemps = 0;
+    LocationSummary* summary =
+        new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    summary->set_in(0, Location::RequiresRegister());
+    summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+    // We make use of 3-operand instructions by not requiring result register
+    // to be identical to first input register as on Intel.
+    summary->set_out(Location::RequiresRegister());
+    return summary;
+  }
 }
 
 
 void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  if (op_kind() == Token::kSHL) {
+    UNIMPLEMENTED();
+    return;
+  }
+
+  ASSERT(!is_truncating());
+  Register left = locs()->in(0).reg();
+  Register result = locs()->out().reg();
+  Label* deopt = NULL;
+  if (CanDeoptimize()) {
+    deopt  = compiler->AddDeoptStub(deopt_id(), kDeoptBinarySmiOp);
+  }
+
+  if (locs()->in(1).IsConstant()) {
+    const Object& constant = locs()->in(1).constant();
+    ASSERT(constant.IsSmi());
+    int32_t imm = reinterpret_cast<int32_t>(constant.raw());
+    switch (op_kind()) {
+      case Token::kSUB: {
+        if (deopt == NULL) {
+          __ AddImmediate(result, left, -imm);
+        } else {
+          __ SubImmediateDetectOverflow(result, left, imm, CMPRES);
+          __ bltz(CMPRES, deopt);
+        }
+        break;
+      }
+      case Token::kADD: {
+        if (deopt == NULL) {
+          __ AddImmediate(result, left, imm);
+        } else {
+          __ AddImmediateDetectOverflow(result, left, imm, CMPRES);
+          __ bltz(CMPRES, deopt);
+        }
+        break;
+      }
+      case Token::kMUL: {
+        // Keep left value tagged and untag right value.
+        const intptr_t value = Smi::Cast(constant).Value();
+        if (value == 2) {
+          __ sll(result, left, 1);
+        } else {
+          __ LoadImmediate(TMP1, value);
+          __ mult(left, TMP1);
+          __ mflo(result);
+        }
+        if (deopt != NULL) {
+          UNIMPLEMENTED();
+        }
+        break;
+      }
+      case Token::kTRUNCDIV: {
+        UNIMPLEMENTED();
+        break;
+      }
+      case Token::kBIT_AND: {
+        // No overflow check.
+        if (Utils::IsUint(kImmBits, imm)) {
+          __ andi(result, left, Immediate(imm));
+        } else {
+          __ LoadImmediate(TMP1, imm);
+          __ and_(result, left, TMP1);
+        }
+        break;
+      }
+      case Token::kBIT_OR: {
+        // No overflow check.
+        if (Utils::IsUint(kImmBits, imm)) {
+          __ ori(result, left, Immediate(imm));
+        } else {
+          __ LoadImmediate(TMP1, imm);
+          __ or_(result, left, TMP1);
+        }
+        break;
+      }
+      case Token::kBIT_XOR: {
+        // No overflow check.
+        if (Utils::IsUint(kImmBits, imm)) {
+          __ xori(result, left, Immediate(imm));
+        } else {
+          __ LoadImmediate(TMP1, imm);
+          __ xor_(result, left, TMP1);
+        }
+        break;
+      }
+      case Token::kSHR: {
+        UNIMPLEMENTED();
+        break;
+      }
+
+      default:
+        UNREACHABLE();
+        break;
+    }
+    return;
+  }
+
+  Register right = locs()->in(1).reg();
+  switch (op_kind()) {
+    case Token::kADD: {
+      if (deopt == NULL) {
+        __ addu(result, left, right);
+      } else {
+        __ AdduDetectOverflow(result, left, right, CMPRES);
+        __ bltz(CMPRES, deopt);
+      }
+      break;
+    }
+    case Token::kSUB: {
+      if (deopt == NULL) {
+        __ subu(result, left, right);
+      } else {
+        __ SubuDetectOverflow(result, left, right, CMPRES);
+        __ bltz(CMPRES, deopt);
+      }
+      break;
+    }
+    case Token::kMUL: {
+      __ SmiUntag(left);
+      __ mult(left, right);
+      __ mflo(result);
+      if (deopt != NULL) {
+        UNIMPLEMENTED();
+      }
+      break;
+    }
+    case Token::kBIT_AND: {
+      // No overflow check.
+      __ and_(result, left, right);
+      break;
+    }
+    case Token::kBIT_OR: {
+      // No overflow check.
+      __ or_(result, left, right);
+      break;
+    }
+    case Token::kBIT_XOR: {
+      // No overflow check.
+      __ xor_(result, left, right);
+      break;
+    }
+    case Token::kTRUNCDIV: {
+      UNIMPLEMENTED();
+      break;
+    }
+    case Token::kSHR: {
+      UNIMPLEMENTED();
+      break;
+    }
+    case Token::kDIV: {
+      // Dispatches to 'Double./'.
+      // TODO(srdjan): Implement as conversion to double and double division.
+      UNREACHABLE();
+      break;
+    }
+    case Token::kMOD: {
+      // TODO(srdjan): Implement.
+      UNREACHABLE();
+      break;
+    }
+    case Token::kOR:
+    case Token::kAND: {
+      // Flow graph builder has dissected this operation to guarantee correct
+      // behavior (short-circuit evaluation).
+      UNREACHABLE();
+      break;
+    }
+    default:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
@@ -1034,13 +1411,44 @@
 
 
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  return MakeCallSummary();
 }
 
 
 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
+                                        kDeoptPolymorphicInstanceCallTestFail);
+  if (ic_data().NumberOfChecks() == 0) {
+    __ b(deopt);
+    return;
+  }
+  ASSERT(ic_data().num_args_tested() == 1);
+  if (!with_checks()) {
+    ASSERT(ic_data().HasOneTarget());
+    const Function& target = Function::ZoneHandle(ic_data().GetTargetAt(0));
+    compiler->GenerateStaticCall(instance_call()->deopt_id(),
+                                 instance_call()->token_pos(),
+                                 target,
+                                 instance_call()->ArgumentCount(),
+                                 instance_call()->argument_names(),
+                                 locs());
+    return;
+  }
+
+  // Load receiver into R0.
+  __ lw(T0, Address(SP, (instance_call()->ArgumentCount() - 1) * kWordSize));
+
+  LoadValueCid(compiler, T2, T0,
+               (ic_data().GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt);
+
+  compiler->EmitTestAndCall(ic_data(),
+                            T2,  // Class id register.
+                            instance_call()->ArgumentCount(),
+                            instance_call()->argument_names(),
+                            deopt,
+                            instance_call()->deopt_id(),
+                            instance_call()->token_pos(),
+                            locs());
 }
 
 
@@ -1067,13 +1475,21 @@
 
 
 LocationSummary* CheckSmiInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  return summary;
 }
 
 
 void CheckSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Register value = locs()->in(0).reg();
+  Label* deopt = compiler->AddDeoptStub(deopt_id(),
+                                        kDeoptCheckSmi);
+  __ andi(TMP1, value, Immediate(kSmiTagMask));
+  __ bne(TMP1, ZR, deopt);
 }
 
 
@@ -1196,6 +1612,10 @@
   switch (condition) {
     case EQ: return NE;
     case NE: return EQ;
+    case LT: return GE;
+    case LE: return GT;
+    case GT: return LE;
+    case GE: return LT;
     default:
       OS::Print("Error: Condition not recognized: %d\n", condition);
       UNIMPLEMENTED();
@@ -1219,21 +1639,33 @@
                                                Condition true_condition) {
   if (compiler->CanFallThroughTo(false_successor())) {
     // If the next block is the false successor we will fall through to it.
-    if (true_condition == EQ) {
-      __ beq(CMPRES, ZR, compiler->GetJumpLabel(true_successor()));
-    } else {
-      ASSERT(true_condition == NE);
-      __ bne(CMPRES, ZR, compiler->GetJumpLabel(true_successor()));
+    Label* label = compiler->GetJumpLabel(true_successor());
+    switch (true_condition) {
+      case EQ: __ beq(CMPRES, ZR, label); break;
+      case NE: __ bne(CMPRES, ZR, label); break;
+      case GT: __ bgtz(CMPRES, label); break;
+      case GE: __ bgez(CMPRES, label); break;
+      case LT: __ bltz(CMPRES, label); break;
+      case LE: __ blez(CMPRES, label); break;
+      default:
+        UNREACHABLE();
+        break;
     }
   } else {
     // If the next block is the true successor we negate comparison and fall
     // through to it.
     Condition false_condition = NegateCondition(true_condition);
-    if (false_condition == EQ) {
-      __ beq(CMPRES, ZR, compiler->GetJumpLabel(false_successor()));
-    } else {
-      ASSERT(false_condition == NE);
-      __ bne(CMPRES, ZR, compiler->GetJumpLabel(false_successor()));
+    Label* label = compiler->GetJumpLabel(false_successor());
+    switch (false_condition) {
+      case EQ: __ beq(CMPRES, ZR, label); break;
+      case NE: __ bne(CMPRES, ZR, label); break;
+      case GT: __ bgtz(CMPRES, label); break;
+      case GE: __ bgez(CMPRES, label); break;
+      case LT: __ bltz(CMPRES, label); break;
+      case LE: __ blez(CMPRES, label); break;
+      default:
+        UNREACHABLE();
+        break;
     }
     // Fall through or jump to the true successor.
     if (!compiler->CanFallThroughTo(true_successor())) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8b7c816..c62f845 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -593,17 +593,26 @@
     intptr_t leftover_size = original_size - used_size;
 
     uword addr = RawObject::ToAddr(obj.raw()) + used_size;
-    ASSERT(TypedData::InstanceSize(0) == Object::InstanceSize());
-    // Update the leftover space as an TypedDataInt8Array object.
-    RawTypedData* raw =
-        reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
-    uword tags = 0;
-    tags = RawObject::SizeTag::update(leftover_size, tags);
-    tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, tags);
-    raw->ptr()->tags_ = tags;
-    intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
-    ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
-    raw->ptr()->length_ = Smi::New(leftover_len);
+    if (leftover_size >= TypedData::InstanceSize(0)) {
+      // Update the leftover space as an TypedDataInt8Array object.
+      RawTypedData* raw =
+          reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
+      uword tags = 0;
+      tags = RawObject::SizeTag::update(leftover_size, tags);
+      tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, tags);
+      raw->ptr()->tags_ = tags;
+      intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
+      ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
+      raw->ptr()->length_ = Smi::New(leftover_len);
+    } else {
+      // Update the leftover space as a basic object.
+      ASSERT(leftover_size == Object::InstanceSize());
+      RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
+      uword tags = 0;
+      tags = RawObject::SizeTag::update(leftover_size, tags);
+      tags = RawObject::ClassIdTag::update(kInstanceCid, tags);
+      raw->ptr()->tags_ = tags;
+    }
   }
 }
 
@@ -1014,7 +1023,7 @@
 
   INIT_LIBRARY(Async, async, true);
   INIT_LIBRARY(Collection, collection, true);
-  INIT_LIBRARY(CollectionDev, collection_dev, false);
+  INIT_LIBRARY(CollectionDev, collection_dev, true);
   INIT_LIBRARY(Crypto, crypto, false);
   INIT_LIBRARY(Isolate, isolate, true);
   INIT_LIBRARY(Json, json, true);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index a81aaa0..02c4831 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4140,7 +4140,8 @@
   // All strings share the same maximum element count to keep things
   // simple.  We choose a value that will prevent integer overflow for
   // 2 byte strings, since it is the worst case.
-  static const intptr_t kSizeofRawString = sizeof(RawObject) + (2 * kWordSize);
+  static const intptr_t kSizeofRawString =
+      sizeof(RawInstance) + (2 * kWordSize);
   static const intptr_t kMaxElements = kSmiMax / kTwoByteChar;
 
   class CodePointIterator : public ValueObject {
@@ -4785,7 +4786,7 @@
 
   static intptr_t InstanceSize(intptr_t len) {
     // Ensure that variable length data is not adding to the object length.
-    ASSERT(sizeof(RawArray) == (sizeof(RawObject) + (2 * kWordSize)));
+    ASSERT(sizeof(RawArray) == (sizeof(RawInstance) + (2 * kWordSize)));
     ASSERT(0 <= len && len <= kMaxElements);
     return RoundedAllocationSize(sizeof(RawArray) + (len * kBytesPerElement));
   }
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 09da9c6..b606a43 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -8796,9 +8796,18 @@
     }
     factory_type_args = factory_type_args.Canonicalize();
     ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
-    const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos);
-    ArrayNode* list = new ArrayNode(TokenPos(), type, temp_local, element_list);
-    factory_param->Add(list);
+    if (element_list.length() == 0) {
+      // TODO(srdjan): Use Object::empty_array once issue 9871 has been fixed.
+      Array& empty_array = Array::ZoneHandle(Object::empty_array().raw());
+      LiteralNode* empty_array_literal =
+          new LiteralNode(TokenPos(), empty_array);
+      factory_param->Add(empty_array_literal);
+    } else {
+      const LocalVariable& temp_local = *BuildArrayTempLocal(type_pos);
+      ArrayNode* list =
+          new ArrayNode(TokenPos(), type, temp_local, element_list);
+      factory_param->Add(list);
+    }
     return CreateConstructorCallNode(literal_pos,
                                      factory_type_args,
                                      factory_method,
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index 7405738..e144c8a 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1682,6 +1682,13 @@
       }
       break;
     }
+    case XORI: {
+      // Format(instr, "xori 'rt, 'rs, 'immu");
+      int32_t rs_val = get_register(instr->RsField());
+      set_register(instr->RtField(), rs_val ^ instr->UImmField());
+      break;
+      break;
+    }
     default: {
       OS::PrintErr("Undecoded instruction: 0x%x at %p\n",
                     instr->InstructionBits(), instr);
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 41c9461..6e0911b 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -91,12 +91,12 @@
     case Dart_CObject::kString:
       EXPECT_STREQ(first->value.as_string, second->value.as_string);
       break;
-    case Dart_CObject::kUint8Array:
-      EXPECT_EQ(first->value.as_byte_array.length,
-                second->value.as_byte_array.length);
-      for (int i = 0; i < first->value.as_byte_array.length; i++) {
-        EXPECT_EQ(first->value.as_byte_array.values[i],
-                  second->value.as_byte_array.values[i]);
+    case Dart_CObject::kTypedData:
+      EXPECT_EQ(first->value.as_typed_data.length,
+                second->value.as_typed_data.length);
+      for (int i = 0; i < first->value.as_typed_data.length; i++) {
+        EXPECT_EQ(first->value.as_typed_data.values[i],
+                  second->value.as_typed_data.values[i]);
       }
       break;
     case Dart_CObject::kArray:
@@ -612,30 +612,30 @@
   // Write snapshot with object content.
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
-  const int kByteArrayLength = 256;
-  TypedData& byte_array = TypedData::Handle(
-      TypedData::New(kTypedDataUint8ArrayCid, kByteArrayLength));
-  for (int i = 0; i < kByteArrayLength; i++) {
-    byte_array.SetUint8(i, i);
+  const int kTypedDataLength = 256;
+  TypedData& typed_data = TypedData::Handle(
+      TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
+  for (int i = 0; i < kTypedDataLength; i++) {
+    typed_data.SetUint8(i, i);
   }
-  writer.WriteMessage(byte_array);
+  writer.WriteMessage(typed_data);
   intptr_t buffer_len = writer.BytesWritten();
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
                         Snapshot::kMessage, Isolate::Current());
-  TypedData& serialized_byte_array = TypedData::Handle();
-  serialized_byte_array ^= reader.ReadObject();
-  EXPECT(serialized_byte_array.IsTypedData());
+  TypedData& serialized_typed_data = TypedData::Handle();
+  serialized_typed_data ^= reader.ReadObject();
+  EXPECT(serialized_typed_data.IsTypedData());
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
   ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
   Dart_CObject* root = api_reader.ReadMessage();
-  EXPECT_EQ(Dart_CObject::kUint8Array, root->type);
-  EXPECT_EQ(kByteArrayLength, root->value.as_byte_array.length);
-  for (int i = 0; i < kByteArrayLength; i++) {
-    EXPECT(root->value.as_byte_array.values[i] == i);
+  EXPECT_EQ(Dart_CObject::kTypedData, root->type);
+  EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
+  for (int i = 0; i < kTypedDataLength; i++) {
+    EXPECT(root->value.as_typed_data.values[i] == i);
   }
   CheckEncodeDecodeMessage(root);
 }
@@ -724,26 +724,27 @@
   // Write snapshot with object content.
   uint8_t* buffer;
   MessageWriter writer(&buffer, &zone_allocator);
-  const int kByteArrayLength = 0;
-  TypedData& byte_array = TypedData::Handle(
-      TypedData::New(kTypedDataUint8ArrayCid, kByteArrayLength));
-  writer.WriteMessage(byte_array);
+  const int kTypedDataLength = 0;
+  TypedData& typed_data = TypedData::Handle(
+      TypedData::New(kTypedDataUint8ArrayCid, kTypedDataLength));
+  writer.WriteMessage(typed_data);
   intptr_t buffer_len = writer.BytesWritten();
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
                         Snapshot::kMessage, Isolate::Current());
-  TypedData& serialized_byte_array = TypedData::Handle();
-  serialized_byte_array ^= reader.ReadObject();
-  EXPECT(serialized_byte_array.IsTypedData());
+  TypedData& serialized_typed_data = TypedData::Handle();
+  serialized_typed_data ^= reader.ReadObject();
+  EXPECT(serialized_typed_data.IsTypedData());
 
   // Read object back from the snapshot into a C structure.
   ApiNativeScope scope;
   ApiMessageReader api_reader(buffer, buffer_len, &zone_allocator);
   Dart_CObject* root = api_reader.ReadMessage();
-  EXPECT_EQ(Dart_CObject::kUint8Array, root->type);
-  EXPECT_EQ(kByteArrayLength, root->value.as_byte_array.length);
-  EXPECT(root->value.as_byte_array.values == NULL);
+  EXPECT_EQ(Dart_CObject::kTypedData, root->type);
+  EXPECT_EQ(Dart_CObject::kUint8Array, root->value.as_typed_data.type);
+  EXPECT_EQ(kTypedDataLength, root->value.as_typed_data.length);
+  EXPECT(root->value.as_typed_data.values == NULL);
   CheckEncodeDecodeMessage(root);
 }
 
@@ -1908,8 +1909,9 @@
       for (int i = 0; i < kArrayLength; i++) {
         Dart_CObject* element = root->value.as_array.values[i];
         EXPECT_EQ(root->value.as_array.values[0], element);
-        EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
-        EXPECT_EQ(256, element->value.as_byte_array.length);
+        EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+        EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+        EXPECT_EQ(256, element->value.as_typed_data.length);
       }
     }
     {
@@ -1923,10 +1925,11 @@
       for (int i = 0; i < kArrayLength; i++) {
         Dart_CObject* element = root->value.as_array.values[i];
         EXPECT_EQ(root->value.as_array.values[0], element);
-        EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
-        EXPECT_EQ(128, element->value.as_byte_array.length);
-        EXPECT_EQ(1, element->value.as_byte_array.values[0]);
-        EXPECT_EQ(0, element->value.as_byte_array.values[1]);
+        EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+        EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+        EXPECT_EQ(128, element->value.as_typed_data.length);
+        EXPECT_EQ(1, element->value.as_typed_data.values[0]);
+        EXPECT_EQ(0, element->value.as_typed_data.values[1]);
       }
     }
     {
@@ -2110,8 +2113,9 @@
       for (int i = 0; i < kArrayLength; i++) {
         Dart_CObject* element = root->value.as_array.values[i];
         EXPECT_EQ(root->value.as_array.values[0], element);
-        EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
-        EXPECT_EQ(256, element->value.as_byte_array.length);
+        EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+        EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+        EXPECT_EQ(256, element->value.as_typed_data.length);
       }
     }
     {
@@ -2125,10 +2129,11 @@
       for (int i = 0; i < kArrayLength; i++) {
         Dart_CObject* element = root->value.as_array.values[i];
         EXPECT_EQ(root->value.as_array.values[0], element);
-        EXPECT_EQ(Dart_CObject::kUint8Array, element->type);
-        EXPECT_EQ(128, element->value.as_byte_array.length);
-        EXPECT_EQ(1, element->value.as_byte_array.values[0]);
-        EXPECT_EQ(0, element->value.as_byte_array.values[1]);
+        EXPECT_EQ(Dart_CObject::kTypedData, element->type);
+        EXPECT_EQ(Dart_CObject::kUint8Array, element->value.as_typed_data.type);
+        EXPECT_EQ(128, element->value.as_typed_data.length);
+        EXPECT_EQ(1, element->value.as_typed_data.values[0]);
+        EXPECT_EQ(0, element->value.as_typed_data.values[1]);
       }
     }
     {
@@ -2170,6 +2175,109 @@
 }
 
 
+static void CheckTypedData(Dart_CObject* object,
+                           Dart_CObject::TypedDataType typed_data_type,
+                           int len) {
+    EXPECT_EQ(Dart_CObject::kTypedData, object->type);
+    EXPECT_EQ(typed_data_type, object->value.as_typed_data.type);
+    EXPECT_EQ(len, object->value.as_typed_data.length);
+}
+
+UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) {
+  const int kArrayLength = 10;
+  static const char* kScriptChars =
+      "import 'dart:typeddata';\n"
+      "final int kArrayLength = 10;\n"
+      "getTypedDataList() {\n"
+      "  var list = new List(kArrayLength);\n"
+      "  list[0] = new Int8List(256);\n"
+      "  list[1] = new Uint8List(256);\n"
+      "  list[2] = new Int16List(256);\n"
+      "  list[3] = new Uint16List(256);\n"
+      "  return list;\n"
+      "}\n"
+      "getTypedDataViewList() {\n"
+      "  var list = new List(kArrayLength);\n"
+      "  list[0] = new Int8List.view(new Int8List(256));\n"
+      "  list[1] = new Uint8List.view(new Uint8List(256));\n"
+      "  list[2] = new Int16List.view(new Int16List(256));\n"
+      "  list[3] = new Uint16List.view(new Uint16List(256));\n"
+      "  list[4] = new Int8List.view(new Int16List(256));\n"
+      "  list[5] = new Uint8List.view(new Uint16List(256));\n"
+      "  list[6] = new Int16List.view(new Int8List(256));\n"
+      "  list[7] = new Uint16List.view(new Uint8List(256));\n"
+      "  return list;\n"
+      "}\n";
+
+  TestCase::CreateTestIsolate();
+  Isolate* isolate = Isolate::Current();
+  EXPECT(isolate != NULL);
+  Dart_EnterScope();
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  EXPECT_VALID(lib);
+
+  {
+    DARTSCOPE(isolate);
+    {
+      // Generate a list of Uint8Lists from Dart code.
+      ApiNativeScope scope;
+      Dart_CObject* root = GetDeserializedDartMessage(lib, "getTypedDataList");
+      EXPECT_NOTNULL(root);
+      EXPECT_EQ(Dart_CObject::kArray, root->type);
+      EXPECT_EQ(kArrayLength, root->value.as_array.length);
+      CheckTypedData(root->value.as_array.values[0],
+                     Dart_CObject::kInt8Array,
+                     256);
+      CheckTypedData(root->value.as_array.values[1],
+                     Dart_CObject::kUint8Array,
+                     256);
+      CheckTypedData(root->value.as_array.values[2],
+                     Dart_CObject::kInt16Array,
+                     512);
+      CheckTypedData(root->value.as_array.values[3],
+                     Dart_CObject::kUint16Array,
+                     512);
+    }
+    {
+      // Generate a list of Uint8List views from Dart code.
+      ApiNativeScope scope;
+      Dart_CObject* root =
+          GetDeserializedDartMessage(lib, "getTypedDataViewList");
+      EXPECT_NOTNULL(root);
+      EXPECT_EQ(Dart_CObject::kArray, root->type);
+      EXPECT_EQ(kArrayLength, root->value.as_array.length);
+      CheckTypedData(root->value.as_array.values[0],
+                     Dart_CObject::kInt8Array,
+                     256);
+      CheckTypedData(root->value.as_array.values[1],
+                     Dart_CObject::kUint8Array,
+                     256);
+      CheckTypedData(root->value.as_array.values[2],
+                     Dart_CObject::kInt16Array,
+                     512);
+      CheckTypedData(root->value.as_array.values[3],
+                     Dart_CObject::kUint16Array,
+                     512);
+      CheckTypedData(root->value.as_array.values[4],
+                     Dart_CObject::kInt8Array,
+                     512);
+      CheckTypedData(root->value.as_array.values[5],
+                     Dart_CObject::kUint8Array,
+                     512);
+      CheckTypedData(root->value.as_array.values[6],
+                     Dart_CObject::kInt16Array,
+                     256);
+      CheckTypedData(root->value.as_array.values[7],
+                     Dart_CObject::kUint16Array,
+                     256);
+    }
+  }
+  Dart_ExitScope();
+  Dart_ShutdownIsolate();
+}
+
+
 UNIT_TEST_CASE(PostCObject) {
   // Create a native port for posting from C to Dart
   TestIsolateScope __test_isolate__;
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index b39e01b..ecdf38e 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -257,7 +257,7 @@
       "} "
       "class StackFrame2Test {"
       "  StackFrame2Test() {}"
-      "  noSuchMethod(InvocationMirror im) {"
+      "  noSuchMethod(Invocation im) {"
       "    /* We should have 8 general frames and 3 dart frames as follows:"
       "     * exit frame"
       "     * dart frame corresponding to StackFrame.frameCount"
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 1a48f6b..c99c981 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1345,7 +1345,7 @@
 // Uses EAX, EBX, EDI as temporary registers.
 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
   // The target function was not found, so invoke method
-  // "dynamic noSuchMethod(InvocationMirror invocation)".
+  // "dynamic noSuchMethod(Invocation invocation)".
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index a56f2d9..91c919d 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -984,8 +984,24 @@
 }
 
 
+// Calls to the runtime to optimize the given function.
+// T0: function to be reoptimized.
+// S4: argument descriptor (preserved).
 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
-  __ Unimplemented("OptimizeFunction Stub");
+  __ EnterStubFrame();
+  __ Push(S4);
+  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
+  __ Push(TMP);  // Setup space on stack for return value.
+  __ Push(T0);
+  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
+  __ Pop(T0);  // Discard argument.
+  __ Pop(T0);  // Get Code object
+  __ Pop(S4);  // Restore argument descriptor.
+  __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
+  __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
+  __ LeaveStubFrame();
+  __ jr(T0);
+  __ break_(0);
 }
 
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 90d3b82..014b798 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1331,7 +1331,7 @@
 //   R10 : arguments descriptor array.
 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
   // The target function was not found, so invoke method
-  // "dynamic noSuchMethod(InvocationMirror invocation)".
+  // "dynamic noSuchMethod(Invocation invocation)".
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index 1cd4c5f..eaf38652 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -12,6 +12,7 @@
     'collection_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_gen.cc',
     'collection_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_patch_gen.cc',
     'collection_dev_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_dev_gen.cc',
+    'collection_dev_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/collection_dev_patch_gen.cc',
     'crypto_cc_file': '<(SHARED_INTERMEDIATE_DIR)/crypto_gen.cc',
     'math_cc_file': '<(SHARED_INTERMEDIATE_DIR)/math_gen.cc',
     'math_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/math_patch_gen.cc',
@@ -98,6 +99,7 @@
         'generate_collection_cc_file',
         'generate_collection_patch_cc_file',
         'generate_collection_dev_cc_file',
+        'generate_collection_dev_patch_cc_file',
         'generate_crypto_cc_file',
         'generate_math_cc_file',
         'generate_math_patch_cc_file',
@@ -131,6 +133,7 @@
         '<(collection_cc_file)',
         '<(collection_patch_cc_file)',
         '<(collection_dev_cc_file)',
+        '<(collection_dev_patch_cc_file)',
         '<(crypto_cc_file)',
         '<(math_cc_file)',
         '<(math_patch_cc_file)',
@@ -376,6 +379,44 @@
       ]
     },
     {
+      'target_name': 'generate_collection_dev_patch_cc_file',
+      'type': 'none',
+      'includes': [
+        # Load the runtime implementation sources.
+        '../lib/collection_dev_sources.gypi',
+      ],
+      'sources/': [
+        # Exclude all .[cc|h] files.
+        # This is only here for reference. Excludes happen after
+        # variable expansion, so the script has to do its own
+        # exclude processing of the sources being passed.
+        ['exclude', '\\.cc|h$'],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_collection_dev_patch_cc',
+          'inputs': [
+            '../tools/create_string_literal.py',
+            '<(builtin_in_cc_file)',
+            '<@(_sources)',
+          ],
+          'outputs': [
+            '<(collection_dev_patch_cc_file)',
+          ],
+          'action': [
+            'python',
+            'tools/create_string_literal.py',
+            '--output', '<(collection_dev_patch_cc_file)',
+            '--input_cc', '<(builtin_in_cc_file)',
+            '--include', 'vm/bootstrap.h',
+            '--var_name', 'dart::Bootstrap::collection_dev_patch_',
+            '<@(_sources)',
+          ],
+          'message': 'Generating ''<(collection_dev_patch_cc_file)'' file.'
+        },
+      ]
+    },
+    {
       'target_name': 'generate_collection_dev_cc_file',
       'type': 'none',
       'variables': {
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
new file mode 100755
index 0000000..3f0f947
--- /dev/null
+++ b/sdk/bin/dartanalyzer
@@ -0,0 +1,79 @@
+#!/bin/bash --posix
+# 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.
+
+set -e
+
+# Setting SCRIPT_DIR this way is ugly, but is needed to handle the case where
+# dart-sdk/bin has been symlinked to. On MacOS, readlink doesn't work
+# with this case.
+SCRIPT_DIR="$(cd "${0%/*}" ; pwd -P)"
+DART_ANALYZER_HOME="$(cd "${SCRIPT_DIR%/*}" ; pwd -P)"
+
+FOUND_BATCH=0
+FOUND_SDK=0
+for ARG in "$@"
+do
+  case $ARG in
+    -batch|--batch)
+      FOUND_BATCH=1
+      ;;
+    --dart-sdk)
+      FOUND_SDK=1
+      ;;
+    *)
+      ;;
+  esac
+done
+
+DART_SDK=""
+if [ $FOUND_SDK = 0 ] ; then
+  if [ -f $DART_ANALYZER_HOME/lib/core/core.dart ] ; then
+    DART_SDK="--dart-sdk $DART_ANALYZER_HOME"
+  else
+    DART_SDK_HOME=$(dirname $DART_ANALYZER_HOME)/dart-sdk
+    if [ -d $DART_SDK_HOME ] ; then
+      DART_SDK="--dart-sdk $DART_SDK_HOME"
+    else
+      DART_SDK_HOME=$(dirname $DART_SDK_HOME)/dart-sdk
+      if [ -d $DART_SDK_HOME ] ; then
+        DART_SDK="--dart-sdk $DART_SDK_HOME"
+      else
+        echo "Couldn't find Dart SDK. Specify with --dart-sdk cmdline argument"
+      fi
+    fi
+  fi
+fi
+
+if [ -f $DART_SDK_HOME/util/dartanalyzer/dartanalyzer.jar ] ; then
+  DART_ANALYZER_LIBS=$DART_SDK_HOME/util/dartanalyzer
+elif [ -f $DART_ANALYZER_HOME/util/dartanalyzer/dartanalyzer.jar ] ; then
+  DART_ANALYZER_LIBS=$DART_ANALYZER_HOME/util/dartanalyzer
+else
+  echo "Configuration problem. Couldn't find dartanalyzer.jar."
+  exit 1
+fi
+
+if [ -x /usr/libexec/java_home ]; then
+  export JAVA_HOME=$(/usr/libexec/java_home -v '1.6+')
+fi
+
+EXTRA_JVMARGS="-Xss2M "
+OS=`uname | tr "[A-Z]" "[a-z]"`
+if [ "$OS" == "darwin" ] ; then
+  # Bump up the heap on Mac VMs, some of which default to 128M or less.
+  # Users can specify DART_JVMARGS in the environment to override this
+  # setting.
+  EXTRA_JVMARGS+=" -Xmx256M -client "
+else
+  # On other architectures
+  # -batch invocations will do better with a server vm
+  # invocations for analyzing a single file do better with a client vm
+  if [ $FOUND_BATCH = 0 ] ; then
+    EXTRA_JVMARGS+=" -client "
+  fi
+fi
+
+exec java $EXTRA_JVMARGS $DART_JVMARGS -ea -jar \
+  "$DART_ANALYZER_LIBS/dartanalyzer.jar" ${DART_SDK} $@
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
new file mode 100644
index 0000000..9a2af5e
--- /dev/null
+++ b/sdk/bin/dartanalyzer.bat
@@ -0,0 +1,58 @@
+@echo off

+rem Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

+rem for details. All rights reserved. Use of this source code is governed by a

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

+

+set SCRIPT_DIR=%~dp0

+if %SCRIPT_DIR:~-1%==\ set SCRIPT_DIR=%SCRIPT_DIR:~0,-1%

+

+for %%I in ("%SCRIPT_DIR%\..") do set "DART_ANALYZER_HOME=%%~fI"

+if %DART_ANALYZER_HOME:~-1%==\ set DART_ANALYZER_HOME=%DART_ANALYZER_HOME:~0,-1%

+

+set FOUND_BATCH=0

+set FOUND_SDK=0

+for %%a in (%*) do (

+  if [%%a] == [--batch] set FOUND_BATCH=1

+  if [%%a] == [-b] set FOUND_BATCH=1

+  if [%%a] == [--dart-sdk]  set FOUND_SDK=1

+)

+

+setlocal EnableDelayedExpansion

+set DART_SDK=""

+if [%FOUND_SDK%] == [0] (

+  if exist "%DART_ANALYZER_HOME%\lib\core\core.dart" (

+    set DART_SDK=--dart-sdk "%DART_ANALYZER_HOME%"

+  ) else (

+    for /f %%i in ('echo %DART_ANALYZER_HOME%') do set DART_SDK_HOME=%%~dpi\dart-sdk

+    if exist "!DART_SDK_HOME!" (

+      set DART_SDK=--dart-sdk !DART_SDK_HOME!

+    ) else (

+      for /f %%j in ('call echo !DART_SDK_HOME!') do set DART_SDK_HOME=%%~dpj\dart-sdk

+      if exist "!DART_SDK_HOME!" (

+        set DART_SDK=--dart-sdk !DART_SDK_HOME!

+      ) else (

+        echo Couldn't find Dart SDK. Specify with --dart-sdk cmdline argument

+      )

+    )

+  )

+)

+endlocal & set "DART_SDK=%DART_SDK%" & set "DART_SDK_HOME=%DART_SDK_HOME%"

+

+if exist "%DART_SDK_HOME%\util\dartanalyzer\dartanalyzer.jar" (

+  set DART_ANALYZER_LIBS=%DART_SDK_HOME%\util\dartanalyzer

+) else if exist "%DART_ANALYZER_HOME%\util\dartanalyzer\dartanalyzer.jar" (

+  set DART_ANALYZER_LIBS=%DART_ANALYZER_HOME%\util\dartanalyzer

+) else (

+  echo Configuration problem. Couldn't find dartanalyzer.jar.

+  exit /b 1

+)

+

+setlocal EnableDelayedExpansion

+set EXTRA_JVMARGS=-Xss2M 

+if [%FOUND_BATCH%] == [1] (

+  set EXTRA_JVMARGS=!EXTRA_JVMARGS! -client

+)

+endlocal & set "EXTRA_JVMARGS=%EXTRA_JVMARGS%"

+

+java %EXTRA_JVMARGS% %DART_JVMARGS% -ea -jar \

+  "%DART_ANALYZER_LIBS%\dartanalyzer.jar" %DART_SDK% %*

diff --git a/sdk/lib/_collection_dev/collection_dev.dart b/sdk/lib/_collection_dev/collection_dev.dart
index 385d029..79ca515 100644
--- a/sdk/lib/_collection_dev/collection_dev.dart
+++ b/sdk/lib/_collection_dev/collection_dev.dart
@@ -6,11 +6,12 @@
 
 import 'dart:collection';
 
+import 'dart:core' hide Symbol;
+import 'dart:core' as core;
+
 part 'arrays.dart';
 part 'iterable.dart';
 part 'list.dart';
 part 'sort.dart';
+part 'symbol.dart';
 part 'to_string.dart';
-
-// TODO(floitsch): move this into core, another hidden library or remove it.
-const deprecated = 0;
diff --git a/sdk/lib/_collection_dev/collection_dev_sources.gypi b/sdk/lib/_collection_dev/collection_dev_sources.gypi
index 4f941b6..f994b42 100644
--- a/sdk/lib/_collection_dev/collection_dev_sources.gypi
+++ b/sdk/lib/_collection_dev/collection_dev_sources.gypi
@@ -11,6 +11,7 @@
     'iterable.dart',
     'list.dart',
     'sort.dart',
+    'symbol.dart',
     'to_string.dart',
   ],
 }
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 60777e9..c82fa03 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -10,7 +10,7 @@
  * All other methods are implemented in terms of [length] and [elementAt],
  * including [iterator].
  */
-abstract class ListIterable<E> extends Iterable<E> {
+abstract class ListIterable<E> extends IterableBase<E> {
   int get length;
   E elementAt(int i);
 
@@ -298,7 +298,7 @@
 
 typedef T _Transformation<S, T>(S value);
 
-class MappedIterable<S, T> extends Iterable<T> {
+class MappedIterable<S, T> extends IterableBase<T> {
   final Iterable<S> _iterable;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
@@ -356,7 +356,7 @@
 
 typedef bool _ElementPredicate<E>(E element);
 
-class WhereIterable<E> extends Iterable<E> {
+class WhereIterable<E> extends IterableBase<E> {
   final Iterable<E> _iterable;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
@@ -389,7 +389,7 @@
 
 typedef Iterable<T> _ExpandFunction<S, T>(S sourceElement);
 
-class ExpandIterable<S, T> extends Iterable<T> {
+class ExpandIterable<S, T> extends IterableBase<T> {
   final Iterable<S> _iterable;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
@@ -436,7 +436,7 @@
   }
 }
 
-class TakeIterable<E> extends Iterable<E> {
+class TakeIterable<E> extends IterableBase<E> {
   final Iterable<E> _iterable;
   final int _takeCount;
 
@@ -474,7 +474,7 @@
   }
 }
 
-class TakeWhileIterable<E> extends Iterable<E> {
+class TakeWhileIterable<E> extends IterableBase<E> {
   final Iterable<E> _iterable;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
@@ -511,7 +511,7 @@
   }
 }
 
-class SkipIterable<E> extends Iterable<E> {
+class SkipIterable<E> extends IterableBase<E> {
   final Iterable<E> _iterable;
   final int _skipCount;
 
@@ -550,7 +550,7 @@
   E get current => _iterator.current;
 }
 
-class SkipWhileIterable<E> extends Iterable<E> {
+class SkipWhileIterable<E> extends IterableBase<E> {
   final Iterable<E> _iterable;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
@@ -588,7 +588,7 @@
 /**
  * The always empty [Iterable].
  */
-class EmptyIterable<E> extends Iterable<E> {
+class EmptyIterable<E> extends IterableBase<E> {
   const EmptyIterable();
 
   Iterator<E> get iterator => const EmptyIterator();
@@ -666,3 +666,379 @@
 abstract class BidirectionalIterator<T> implements Iterator<T> {
   bool movePrevious();
 }
+
+/**
+ * This class provides default implementations for Iterables (including Lists).
+ *
+ * The uses of this class will be replaced by mixins.
+ */
+class IterableMixinWorkaround {
+  static bool contains(Iterable iterable, var element) {
+    for (final e in iterable) {
+      if (element == e) return true;
+    }
+    return false;
+  }
+
+  static void forEach(Iterable iterable, void f(o)) {
+    for (final e in iterable) {
+      f(e);
+    }
+  }
+
+  static bool any(Iterable iterable, bool f(o)) {
+    for (final e in iterable) {
+      if (f(e)) return true;
+    }
+    return false;
+  }
+
+  static bool every(Iterable iterable, bool f(o)) {
+    for (final e in iterable) {
+      if (!f(e)) return false;
+    }
+    return true;
+  }
+
+  static dynamic reduce(Iterable iterable,
+                        dynamic combine(previousValue, element)) {
+    Iterator iterator = iterable.iterator;
+    if (!iterator.moveNext()) throw new StateError("No elements");
+    var value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  static dynamic fold(Iterable iterable,
+                      dynamic initialValue,
+                      dynamic combine(dynamic previousValue, element)) {
+    for (final element in iterable) {
+      initialValue = combine(initialValue, element);
+    }
+    return initialValue;
+  }
+
+  /**
+   * Removes elements matching [test] from [list].
+   *
+   * This is performed in two steps, to avoid exposing an inconsistent state
+   * to the [test] function. First the elements to retain are found, and then
+   * the original list is updated to contain those elements.
+   */
+  static void removeWhereList(List list, bool test(var element)) {
+    List retained = [];
+    int length = list.length;
+    for (int i = 0; i < length; i++) {
+      var element = list[i];
+      if (!test(element)) {
+        retained.add(element);
+      }
+      if (length != list.length) {
+        throw new ConcurrentModificationError(list);
+      }
+    }
+    if (retained.length == length) return;
+    list.length = retained.length;
+    for (int i = 0; i < retained.length; i++) {
+      list[i] = retained[i];
+    }
+  }
+
+  static bool isEmpty(Iterable iterable) {
+    return !iterable.iterator.moveNext();
+  }
+
+  static dynamic first(Iterable iterable) {
+    Iterator it = iterable.iterator;
+    if (!it.moveNext()) {
+      throw new StateError("No elements");
+    }
+    return it.current;
+  }
+
+  static dynamic last(Iterable iterable) {
+    Iterator it = iterable.iterator;
+    if (!it.moveNext()) {
+      throw new StateError("No elements");
+    }
+    dynamic result;
+    do {
+      result = it.current;
+    } while(it.moveNext());
+    return result;
+  }
+
+  static dynamic single(Iterable iterable) {
+    Iterator it = iterable.iterator;
+    if (!it.moveNext()) throw new StateError("No elements");
+    dynamic result = it.current;
+    if (it.moveNext()) throw new StateError("More than one element");
+    return result;
+  }
+
+  static dynamic firstWhere(Iterable iterable,
+                               bool test(dynamic value),
+                               dynamic orElse()) {
+    for (dynamic element in iterable) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  static dynamic lastWhere(Iterable iterable,
+                           bool test(dynamic value),
+                           dynamic orElse()) {
+    dynamic result = null;
+    bool foundMatching = false;
+    for (dynamic element in iterable) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  static dynamic lastWhereList(List list,
+                               bool test(dynamic value),
+                               dynamic orElse()) {
+    // TODO(floitsch): check that arguments are of correct type?
+    for (int i = list.length - 1; i >= 0; i--) {
+      dynamic element = list[i];
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) {
+    dynamic result = null;
+    bool foundMatching = false;
+    for (dynamic element in iterable) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw new StateError("More than one matching element");
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    throw new StateError("No matching element");
+  }
+
+  static dynamic elementAt(Iterable iterable, int index) {
+    if (index is! int || index < 0) throw new RangeError.value(index);
+    int remaining = index;
+    for (dynamic element in iterable) {
+      if (remaining == 0) return element;
+      remaining--;
+    }
+    throw new RangeError.value(index);
+  }
+
+  static String join(Iterable iterable, [String separator]) {
+    StringBuffer buffer = new StringBuffer();
+    buffer.writeAll(iterable, separator);
+    return buffer.toString();
+  }
+
+  static String joinList(List list, [String separator]) {
+    if (list.isEmpty) return "";
+    if (list.length == 1) return "${list[0]}";
+    StringBuffer buffer = new StringBuffer();
+    if (separator.isEmpty) {
+      for (int i = 0; i < list.length; i++) {
+        buffer.write(list[i]);
+      }
+    } else {
+      buffer.write(list[0]);
+      for (int i = 1; i < list.length; i++) {
+        buffer.write(separator);
+        buffer.write(list[i]);
+      }
+    }
+    return buffer.toString();
+  }
+
+  static Iterable where(Iterable iterable, bool f(var element)) {
+    return new WhereIterable(iterable, f);
+  }
+
+  static Iterable map(Iterable iterable, f(var element)) {
+    return new MappedIterable(iterable, f);
+  }
+
+  static Iterable mapList(List list, f(var element)) {
+    return new MappedListIterable(list, f);
+  }
+
+  static Iterable expand(Iterable iterable, Iterable f(var element)) {
+    return new ExpandIterable(iterable, f);
+  }
+
+  static Iterable takeList(List list, int n) {
+    // The generic type is currently lost. It will be fixed with mixins.
+    return new SubListIterable(list, 0, n);
+  }
+
+  static Iterable takeWhile(Iterable iterable, bool test(var value)) {
+    // The generic type is currently lost. It will be fixed with mixins.
+    return new TakeWhileIterable(iterable, test);
+  }
+
+  static Iterable skipList(List list, int n) {
+    // The generic type is currently lost. It will be fixed with mixins.
+    return new SubListIterable(list, n, null);
+  }
+
+  static Iterable skipWhile(Iterable iterable, bool test(var value)) {
+    // The generic type is currently lost. It will be fixed with mixins.
+    return new SkipWhileIterable(iterable, test);
+  }
+
+  static Iterable reversedList(List list) {
+    return new ReversedListIterable(list);
+  }
+
+  static void sortList(List list, int compare(a, b)) {
+    if (compare == null) compare = Comparable.compare;
+    Sort.sort(list, compare);
+  }
+
+  static int indexOfList(List list, var element, int start) {
+    return Arrays.indexOf(list, element, start, list.length);
+  }
+
+  static int lastIndexOfList(List list, var element, int start) {
+    if (start == null) start = list.length - 1;
+    return Arrays.lastIndexOf(list, element, start);
+  }
+
+  static void _rangeCheck(List list, int start, int end) {
+    if (start < 0 || start > list.length) {
+      throw new RangeError.range(start, 0, list.length);
+    }
+    if (end < start || end > list.length) {
+      throw new RangeError.range(end, start, list.length);
+    }
+  }
+
+  static Iterable getRangeList(List list, int start, int end) {
+    _rangeCheck(list, start, end);
+    // The generic type is currently lost. It will be fixed with mixins.
+    return new SubListIterable(list, start, end);
+  }
+
+  static void setRangeList(List list, int start, int end,
+                           Iterable from, int skipCount) {
+    _rangeCheck(list, start, end);
+    int length = end - start;
+    if (length == 0) return;
+
+    if (skipCount < 0) throw new ArgumentError(skipCount);
+
+    // TODO(floitsch): Make this accept more.
+    List otherList;
+    int otherStart;
+    if (from is List) {
+      otherList = from;
+      otherStart = skipCount;
+    } else {
+      otherList = from.skip(skipCount).toList(growable: false);
+      otherStart = 0;
+    }
+    if (otherStart + length > otherList.length) {
+      throw new StateError("Not enough elements");
+    }
+    Arrays.copy(otherList, otherStart, list, start, length);
+  }
+
+  static void replaceRangeList(List list, int start, int end,
+                               Iterable iterable) {
+    _rangeCheck(list, start, end);
+    // TODO(floitsch): optimize this.
+    list.removeRange(start, end);
+    list.insertAll(start, iterable);
+  }
+
+  static void fillRangeList(List list, int start, int end, fillValue) {
+    _rangeCheck(list, start, end);
+    for (int i = start; i < end; i++) {
+      list[i] = fillValue;
+    }
+  }
+
+  static void insertAllList(List list, int index, Iterable iterable) {
+    if (index < 0 || index > list.length) {
+      throw new RangeError.range(index, 0, list.length);
+    }
+    if (iterable is! List && iterable is! Set) {
+      iterable = iterable.toList(growable: false);
+    }
+    int insertionLength = iterable.length;
+    list.length += insertionLength;
+    list.setRange(index + insertionLength, list.length, list, index);
+    for (var element in iterable) {
+      list[index++] = element;
+    }
+  }
+
+  static void setAllList(List list, int index, Iterable iterable) {
+    if (index < 0 || index > list.length) {
+      throw new RangeError.range(index, 0, list.length);
+    }
+    for (var element in iterable) {
+      list[index++] = element;
+    }
+  }
+
+  static Map<int, dynamic> asMapList(List l) {
+    return new ListMapView(l);
+  }
+
+  static bool setContainsAll(Set set, Iterable other) {
+    for (var element in other) {
+      if (!set.contains(element)) return false;
+    }
+    return true;
+  }
+
+  static Set setIntersection(Set set, Set other, Set result) {
+    Set smaller;
+    Set larger;
+    if (set.length < other.length) {
+      smaller = set;
+      larger = other;
+    } else {
+      smaller = other;
+      larger = set;
+    }
+    for (var element in smaller) {
+      if (larger.contains(element)) {
+        result.add(element);
+      }
+    }
+    return result;
+  }
+
+  static Set setUnion(Set set, Set other, Set result) {
+    result.addAll(set);
+    result.addAll(other);
+    return result;
+  }
+
+  static Set setDifference(Set set, Set other, Set result) {
+    for (var element in set) {
+      if (!other.contains(element)) {
+        result.add(element);
+      }
+    }
+    return result;
+  }
+}
diff --git a/sdk/lib/_collection_dev/list.dart b/sdk/lib/_collection_dev/list.dart
index 3ab841d..93e49ae 100644
--- a/sdk/lib/_collection_dev/list.dart
+++ b/sdk/lib/_collection_dev/list.dart
@@ -25,6 +25,11 @@
         "Cannot add to a fixed-length list");
   }
 
+  void insertAll(int at, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot add to a fixed-length list");
+  }
+
   void addAll(Iterable<E> iterable) {
     throw new UnsupportedError(
         "Cannot add to a fixed-length list");
@@ -70,14 +75,14 @@
         "Cannot remove from a fixed-length list");
   }
 
-  void removeRange(int start, int length) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot remove from a fixed-length list");
   }
 
-  void insertRange(int start, int length, [E initialValue]) {
+  void replaceRange(int start, int end, Iterable<E> iterable) {
     throw new UnsupportedError(
-        "Cannot insert range in a fixed-length list");
+        "Cannot remove from a fixed-length list");
   }
 }
 
@@ -100,6 +105,11 @@
         "Cannot change the length of an unmodifiable list");
   }
 
+  void setAll(int at, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot modify an unmodifiable list");
+  }
+
   void add(E value) {
     throw new UnsupportedError(
         "Cannot add to an unmodifiable list");
@@ -110,6 +120,11 @@
         "Cannot add to an unmodifiable list");
   }
 
+  void insertAll(int at, Iterable<E> iterable) {
+    throw new UnsupportedError(
+        "Cannot add to an unmodifiable list");
+  }
+
   void addAll(Iterable<E> iterable) {
     throw new UnsupportedError(
         "Cannot add to an unmodifiable list");
@@ -160,19 +175,24 @@
         "Cannot remove from an unmodifiable list");
   }
 
-  void setRange(int start, int length, List<E> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
     throw new UnsupportedError(
         "Cannot modify an unmodifiable list");
   }
 
-  void removeRange(int start, int length) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot remove from an unmodifiable list");
   }
 
-  void insertRange(int start, int length, [E initialValue]) {
+  void replaceRange(int start, int end, Iterable<E> iterable) {
     throw new UnsupportedError(
-        "Cannot insert range in an unmodifiable list");
+        "Cannot remove from an unmodifiable list");
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    throw new UnsupportedError(
+        "Cannot modify an unmodifiable list");
   }
 }
 
diff --git a/sdk/lib/_collection_dev/symbol.dart b/sdk/lib/_collection_dev/symbol.dart
new file mode 100644
index 0000000..1a81f47
--- /dev/null
+++ b/sdk/lib/_collection_dev/symbol.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart._collection.dev;
+
+/**
+ * Implementation of [core.Symbol].  This class uses the same name as
+ * a core class so a user can't tell the difference.
+ *
+ * The purpose of this class is to hide [_name] from user code, but
+ * make it accessible to Dart platform code via the static method
+ * [getName].
+ */
+class Symbol implements core.Symbol {
+  final String _name;
+
+  external const Symbol(String name);
+
+  /**
+   * Platform-private method used by the mirror system to create
+   * otherwise invalid names.
+   */
+  const Symbol.unvalidated(this._name);
+
+  bool operator ==(other) => other is Symbol && _name == other._name;
+
+  int get hashCode {
+    const arbitraryPrime = 664597;
+    return 0x1fffffff & (arbitraryPrime * _name.hashCode);
+  }
+
+  /// Platform-private accessor which cannot be called from user libraries.
+  static String getName(Symbol symbol) => symbol._name;
+}
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index b3c72c4..41c5ac1 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -105,7 +105,7 @@
         ..close();
     code = ''; // Non-null signals success.
   }
-  return new Future.immediate(code);
+  return new Future.value(code);
 }
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 1e2ab51..4493412 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -1275,7 +1275,7 @@
 
   add(String value) {}
 
-  void addError(AsyncError error) {}
+  void addError(Object error) {}
 
   void close() {}
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index d1f08f9..4031beb 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -344,7 +344,7 @@
     count += value.length;
   }
 
-  void addError(AsyncError error) { sink.addError(error); }
+  void addError(Object error) { sink.addError(error); }
 
   void close() { sink.close(); }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/js/builder.dart b/sdk/lib/_internal/compiler/implementation/js/builder.dart
index 5247d67..7e71928 100644
--- a/sdk/lib/_internal/compiler/implementation/js/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/builder.dart
@@ -158,7 +158,7 @@
 /// * dot access.
 /// * method calls.
 /// * [] access.
-/// * array, string, boolean, null and numeric literals (no hex).
+/// * array, string, regexp, boolean, null and numeric literals.
 /// * most operators.
 /// * brackets.
 /// * var declarations.
@@ -173,10 +173,9 @@
 /// Literal strings are passed through to the final JS source code unchanged,
 /// including the choice of surrounding quotes, so if you parse
 /// r'var x = "foo\n\"bar\""' you will end up with
-///   var x = "foo\n\"bar\"" in the final program.  String literals are
-/// restricted to a small subset of the full set of allowed JS escapes in order
-/// to get early errors for unintentional escape sequences without complicating
-/// this parser unneccessarily.
+///   var x = "foo\n\"bar\"" in the final program.  \x and \u escapes are not
+/// allowed in string and regexp literals because the machinery for checking
+/// their correctness is rather involved.
 class MiniJsParser {
   MiniJsParser(this.src, this.interpolatedValues)
       : lastCategory = NONE,
@@ -184,7 +183,7 @@
         lastPosition = 0,
         position = 0,
         valuesUsed = 0 {
-    getSymbol();
+    getToken();
   }
 
   int lastCategory;
@@ -230,6 +229,7 @@
       case RPAREN: return "RPAREN";
       case LBRACE: return "LBRACE";
       case RBRACE: return "RBRACE";
+      case LSQUARE: return "LSQUARE";
       case RSQUARE: return "RSQUARE";
       case STRING: return "STRING";
       case COMMA: return "COMMA";
@@ -284,12 +284,37 @@
   static final UNARY_OPERATORS =
       ['++', '--', '+', '-', '~', '!', 'typeof', 'void', 'delete'].toSet();
 
+  static final OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS =
+      ['typeof', 'void', 'delete', 'in', 'instanceof'].toSet();
+
   static int category(int code) {
     if (code >= CATEGORIES.length) return OTHER;
     return CATEGORIES[code];
   }
 
-  void getSymbol() {
+  String getDelimited(int startPosition) {
+    position = startPosition;
+    int delimiter = src.codeUnitAt(startPosition);
+    int currentCode;
+    do {
+      position++;
+      if (position >= src.length) error("Unterminated literal");
+      currentCode = src.codeUnitAt(position);
+      if (currentCode == charCodes.$BACKSLASH) {
+        if (++position >= src.length) error("Unterminated literal");
+        int escaped = src.codeUnitAt(position);
+        if (escaped == charCodes.$x || escaped == charCodes.$X ||
+            escaped == charCodes.$u || escaped == charCodes.$U ||
+            category(escaped) == NUMERIC) {
+          error('Numeric and hex escapes are not allowed in literals');
+        }
+      }
+    } while (currentCode != delimiter);
+    position++;
+    return src.substring(lastPosition, position);
+  }
+
+  void getToken() {
     while (position < src.length &&
            category(src.codeUnitAt(position)) == WHITESPACE) {
       position++;
@@ -303,42 +328,44 @@
     int code = src.codeUnitAt(position);
     lastPosition = position;
     if (code == charCodes.$SQ || code == charCodes.$DQ) {
-      int currentCode;
-      do {
-        position++;
-        if (position >= src.length) {
-          throw new MiniJsParserError(this, "Unterminated string");
-        }
-        currentCode = src.codeUnitAt(position);
-        if (currentCode == charCodes.$BACKSLASH) {
-          if (++position >= src.length) {
-            throw new MiniJsParserError(this, "Unterminated string");
-          }
-          int escapedCode = src.codeUnitAt(position);
-          if (!(escapedCode == charCodes.$BACKSLASH ||
-                escapedCode == charCodes.$SQ ||
-                escapedCode == charCodes.$DQ ||
-                escapedCode == charCodes.$n)) {
-            throw new MiniJsParserError(
-                this,
-                'Only escapes allowed in string literals are '
-                r'''\\, \', \" and \n''');
-          }
-        }
-      } while (currentCode != code);
+      // String literal.
       lastCategory = STRING;
+      lastToken = getDelimited(position);
+    } else if (code == charCodes.$0 &&
+               position + 2 < src.length &&
+               src.codeUnitAt(position + 1) == charCodes.$x) {
+      // Hex literal.
+      for (position += 2; position < src.length; position++) {
+        int cat = category(src.codeUnitAt(position));
+        if (cat != NUMERIC && cat != ALPHA) break;
+      }
+      lastCategory = NUMERIC;
+      lastToken = src.substring(lastPosition, position);
+      int.parse(lastToken, onError: (_) {
+        error("Unparseable number");
+      });
+    } else if (code == charCodes.$SLASH) {
+      // Tokens that start with / are special due to regexp literals.
+      lastCategory = SYMBOL;
       position++;
+      if (position < src.length && src.codeUnitAt(position) == charCodes.$EQ) {
+        position++;
+      }
       lastToken = src.substring(lastPosition, position);
     } else {
+      // All other tokens handled here.
       int cat = category(src.codeUnitAt(position));
       int newCat;
       do {
         position++;
         if (position == src.length) break;
         int code = src.codeUnitAt(position);
-        // Special code to disallow ! in non-first position in token, so that
-        // !! parses as two tokens and != parses as one.
-        newCat = (code == charCodes.$BANG) ? NONE : category(code);
+        // Special code to disallow ! and / in non-first position in token, so
+        // that !! parses as two tokens and != parses as one, while =/ parses
+        // as a an equals token followed by a regexp literal start.
+        newCat = (code == charCodes.$BANG || code == charCodes.$SLASH)
+            ?  NONE
+            : category(code);
       } while (!singleCharCategory(cat) &&
                (cat == newCat ||
                 (cat == ALPHA && newCat == NUMERIC) ||    // eg. level42.
@@ -347,18 +374,16 @@
       lastToken = src.substring(lastPosition, position);
       if (cat == NUMERIC) {
         double.parse(lastToken, (_) {
-          throw new MiniJsParserError(this, "Unparseable number");
+          error("Unparseable number");
         });
       } else if (cat == SYMBOL) {
         int binaryPrecendence = BINARY_PRECEDENCE[lastToken];
         if (binaryPrecendence == null && !UNARY_OPERATORS.contains(lastToken)) {
-          throw new MiniJsParserError(this, "Unknown operator");
+          error("Unknown operator");
         }
         if (isAssignment(lastToken)) lastCategory = ASSIGNMENT;
       } else if (cat == ALPHA) {
-        if (lastToken == 'typeof' || lastToken == 'void' ||
-            lastToken == 'delete' || lastToken == 'in' ||
-            lastToken == 'instanceof') {
+        if (OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(lastToken)) {
           lastCategory = SYMBOL;
         }
       }
@@ -366,15 +391,13 @@
   }
 
   void expectCategory(int cat) {
-    if (cat != lastCategory) {
-      throw new MiniJsParserError(this, "Expected ${categoryToString(cat)}");
-    }
-    getSymbol();
+    if (cat != lastCategory) error("Expected ${categoryToString(cat)}");
+    getToken();
   }
 
   bool acceptCategory(int cat) {
     if (cat == lastCategory) {
-      getSymbol();
+      getToken();
       return true;
     }
     return false;
@@ -382,12 +405,16 @@
 
   bool acceptString(String string) {
     if (lastToken == string) {
-      getSymbol();
+      getToken();
       return true;
     }
     return false;
   }
 
+  void error(message) {
+    throw new MiniJsParserError(this, message);
+  }
+
   Expression parsePrimary() {
     String last = lastToken;
     if (acceptCategory(ALPHA)) {
@@ -420,14 +447,21 @@
         expectCategory(RSQUARE);
       }
       return new ArrayInitializer(values.length, values);
+    } else if (last.startsWith("/")) {
+      String regexp = getDelimited(lastPosition);
+      getToken();
+      String flags = lastToken;
+      if (!acceptCategory(ALPHA)) flags = "";
+      Expression expression = new RegExpLiteral(regexp + flags);
+      return expression;
     } else if (acceptCategory(HASH)) {
       if (interpolatedValues == null ||
           valuesUsed >= interpolatedValues.length) {
-        throw new MiniJsParserError(this, "Too few values for #es");
+        error("Too few values for '#'s");
       }
       return interpolatedValues[valuesUsed++];
     } else {
-      throw new MiniJsParserError(this, "Expected primary expression");
+      error("Expected primary expression");
     }
   }
 
@@ -435,9 +469,7 @@
     Expression receiver = parsePrimary();
     while (true) {
       if (acceptCategory(DOT)) {
-        String identifier = lastToken;
-        expectCategory(ALPHA);
-        receiver = new PropertyAccess.field(receiver, identifier);
+        receiver = getDotRhs(receiver);
       } else if (acceptCategory(LSQUARE)) {
         Expression inBraces = parseExpression();
         expectCategory(RSQUARE);
@@ -466,16 +498,34 @@
                new New(receiver, arguments) :
                new Call(receiver, arguments);
         constructor = false;
+      } else if (!constructor && acceptCategory(LSQUARE)) {
+        Expression inBraces = parseExpression();
+        expectCategory(RSQUARE);
+        receiver = new PropertyAccess(receiver, inBraces);
+      } else if (!constructor && acceptCategory(DOT)) {
+        receiver = getDotRhs(receiver);
       } else {
-        if (constructor) {
-          // JS allows new without (), but we don't.
-          throw new MiniJsParserError(this, "Parentheses are required for new");
-        }
+        // JS allows new without (), but we don't.
+        if (constructor) error("Parentheses are required for new");
         return receiver;
       }
     }
   }
 
+  Expression getDotRhs(Expression receiver) {
+    String identifier = lastToken;
+    // In ES5 keywords like delete and continue are allowed as property
+    // names, and the IndexedDB API uses that, so we need to allow it here.
+    if (acceptCategory(SYMBOL)) {
+      if (!OPERATORS_THAT_LOOK_LIKE_IDENTIFIERS.contains(identifier)) {
+        error("Expected alphanumeric identifier");
+      }
+    } else {
+      expectCategory(ALPHA);
+    }
+    return new PropertyAccess.field(receiver, identifier);
+  }
+
   Expression parsePostfix() {
     Expression expression = parseCall();
     String operator = lastToken;
@@ -582,11 +632,10 @@
   Expression expression() {
     Expression expression = parseVarDeclarationOrExpression();
     if (lastCategory != NONE || position != src.length) {
-      throw new MiniJsParserError(
-          this, "Unparsed junk: ${categoryToString(lastCategory)}");
+      error("Unparsed junk: ${categoryToString(lastCategory)}");
     }
     if (interpolatedValues != null && valuesUsed != interpolatedValues.length) {
-      throw new MiniJsParserError(this, "Too many values for #es");
+      error("Too many values for #es");
     }
     return expression;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index 6f0b755..5fe00a4 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -519,7 +519,9 @@
   accept(NodeVisitor visitor) => visitor.visitLiteralExpression(this);
 
   void visitChildren(NodeVisitor visitor) {
-    for (Expression expr in inputs) expr.accept(visitor);
+    if (inputs != null) {
+      for (Expression expr in inputs) expr.accept(visitor);
+    }
   }
 
   // Code that uses JS must take care of operator precedences, and
@@ -916,7 +918,7 @@
 }
 
 /**
- * [RegExpLiteral]s, despite being called "Literal", are not inheriting from
+ * [RegExpLiteral]s, despite being called "Literal", do not inherit from
  * [Literal]. Indeed, regular expressions in JavaScript have a side-effect and
  * are thus not in the same category as numbers or strings.
  */
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index 5af3a42..91d46b5 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -836,13 +836,14 @@
     List<Expression> inputs = node.inputs;
 
     List<String> parts = template.split('#');
-    if (parts.length != inputs.length + 1) {
+    int inputsLength = inputs == null ? 0 : inputs.length;
+    if (parts.length != inputsLength + 1) {
       compiler.internalError('Wrong number of arguments for JS: $template');
     }
     // Code that uses JS must take care of operator precedences, and
     // put parenthesis if needed.
     out(parts[0]);
-    for (int i = 0; i < inputs.length; i++) {
+    for (int i = 0; i < inputsLength; i++) {
       visit(inputs[i]);
       out(parts[i + 1]);
     }
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 69caf46..98e41ed 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -676,8 +676,9 @@
   // classes.
   Element dispatchPropertyName;
   Element getNativeInterceptorMethod;
-  Element setNativeInterceptorMethod;
   Element defineNativeMethodsFinishMethod;
+  Element getDispatchPropertyMethod;
+  Element setDispatchPropertyMethod;
 
   bool seenAnyClass = false;
 
@@ -861,12 +862,20 @@
         compiler.findInterceptor(const SourceString('interceptedNames'));
     dispatchPropertyName =
         compiler.findInterceptor(const SourceString('dispatchPropertyName'));
+    getDispatchPropertyMethod =
+        compiler.findInterceptor(const SourceString('getDispatchProperty'));
+    setDispatchPropertyMethod =
+        compiler.findInterceptor(const SourceString('setDispatchProperty'));
     getNativeInterceptorMethod =
         compiler.findInterceptor(const SourceString('getNativeInterceptor'));
-    setNativeInterceptorMethod =
-        compiler.findInterceptor(const SourceString('setNativeInterceptor'));
     defineNativeMethodsFinishMethod =
         compiler.findHelper(const SourceString('defineNativeMethodsFinish'));
+
+    // These methods are overwritten with generated versions.
+    canBeInlined[getInterceptorMethod] = false;
+    canBeInlined[getDispatchPropertyMethod] = false;
+    canBeInlined[setDispatchPropertyMethod] = false;
+
     List<ClassElement> classes = [
       jsInterceptorClass =
           compiler.findInterceptor(const SourceString('Interceptor')),
@@ -1021,7 +1030,6 @@
         // TODO(9577): Make it so that these are not needed when there are no
         // native classes.
         enqueuer.registerStaticUse(getNativeInterceptorMethod);
-        enqueuer.registerStaticUse(setNativeInterceptorMethod);
         enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
       }
     }
@@ -1098,7 +1106,6 @@
     // TODO(9577): Make it so that these are not needed when there are no native
     // classes.
     enqueuer.registerStaticUse(getNativeInterceptorMethod);
-    enqueuer.registerStaticUse(setNativeInterceptorMethod);
     enqueuer.registerStaticUse(defineNativeMethodsFinishMethod);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 124a132..effe177 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -343,7 +343,7 @@
 
     return [
       js('var $supportsProtoName = false'),
-      js('var tmp = (defineClass("c", ["f?"], {})).prototype'),
+      js('var tmp = defineClass("c", ["f?"], {}).prototype'),
 
       js.if_(js('tmp.__proto__'), [
         js('tmp.__proto__ = {}'),
diff --git a/sdk/lib/_internal/compiler/implementation/lib/collection_dev_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/collection_dev_patch.dart
new file mode 100644
index 0000000..f224f24
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/lib/collection_dev_patch.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+patch class Symbol implements core.Symbol {
+  patch const Symbol(String name)
+      : this._name = name;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart
index 1fd94cd..10afb9a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/collection_patch.dart
@@ -301,7 +301,7 @@
   }
 }
 
-class HashMapKeyIterable<E> extends Iterable<E> {
+class HashMapKeyIterable<E> extends IterableBase<E> {
   final _map;
   HashMapKeyIterable(this._map);
 
@@ -653,7 +653,7 @@
   LinkedHashMapCell(this._key, this._value);
 }
 
-class LinkedHashMapKeyIterable<E> extends Iterable<E> {
+class LinkedHashMapKeyIterable<E> extends IterableBase<E> {
   final _map;
   LinkedHashMapKeyIterable(this._map);
 
@@ -1316,4 +1316,4 @@
       return true;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
index 75446c7..d84b4a5 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/constant_map.dart
@@ -67,7 +67,7 @@
   }
 }
 
-class _ConstantMapKeyIterable extends Iterable<String> {
+class _ConstantMapKeyIterable extends IterableBase<String> {
   ConstantMap _map;
   _ConstantMapKeyIterable(this._map);
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
index 6569d60..56baf45 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/core_patch.dart
@@ -11,6 +11,7 @@
                               Primitives,
                               TypeImpl,
                               stringJoinUnchecked;
+import "dart:_collection-dev" as _symbol_dev;
 
 patch void print(var object) {
   Primitives.printString(object.toString());
@@ -22,7 +23,7 @@
 
   patch String toString() => Primitives.objectToString(this);
 
-  patch dynamic noSuchMethod(InvocationMirror invocation) {
+  patch dynamic noSuchMethod(Invocation invocation) {
     throw new NoSuchMethodError(this,
                                 invocation.memberName,
                                 invocation.positionalArguments,
@@ -39,9 +40,19 @@
 patch class Function {
   patch static apply(Function function,
                      List positionalArguments,
-                     [Map<String,dynamic> namedArguments]) {
+                     [Map<Symbol, dynamic> namedArguments]) {
     return Primitives.applyFunction(
-        function, positionalArguments, namedArguments);
+        function, positionalArguments, _toMangledNames(namedArguments));
+  }
+
+  static Map<String, dynamic> _toMangledNames(
+      Map<Symbol, dynamic> namedArguments) {
+    if (namedArguments == null) return null;
+    Map<String, dynamic> result = {};
+    namedArguments.forEach((symbol, value) {
+      result[_symbol_dev.Symbol.getName(symbol)] = value;
+    });
+    return result;
   }
 }
 
@@ -288,29 +299,3 @@
     }
   }
 }
-
-patch class StackTrace {
-  patch String get fullStackTrace {
-    throw new UnsupportedError('fullStackTrace');
-  }
-
-  patch String get stackTrace {
-    throw new UnsupportedError('stackTrace');
-  }
-}
-
-patch class Symbol {
-  final String _name;
-
-  patch const Symbol(String name) :
-    this._name = name;
-
-  patch bool operator ==(other) {
-    return other is Symbol && _name == other._name;
-  }
-
-  patch int get hashCode {
-    const arbitraryPrime = 664597;
-    return 0x1fffffff & (arbitraryPrime * _name.hashCode);
-  }
-}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
index 70c46ec..915fbf1 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/interceptors.dart
@@ -22,7 +22,8 @@
                               stringReplaceAllFuncUnchecked,
                               stringReplaceAllUnchecked,
                               stringReplaceFirstUnchecked,
-                              TypeImpl;
+                              TypeImpl,
+                              lookupDispatchRecord;
 import 'dart:_foreign_helper' show JS;
 
 part 'js_array.dart';
@@ -48,28 +49,98 @@
  */
 var dispatchPropertyName = '_zzyzx';
 
+getDispatchProperty(object) {
+  // TODO(sra): Implement the magic.
+  // This is a magic method: the compiler replaces it with a runtime generated
+  // function
+  //
+  //     function(object){return object._zzyzx;}
+  //
+  // where _zzyzx is replaced with the actual [dispatchPropertyName].
+  //
+  // The body is the CSP compliant version.
+  return JS('', '#[#]', object, dispatchPropertyName);
+}
+
+setDispatchProperty(object, value) {
+  // TODO(sra): Implement the magic.
+  // This is a magic method: the compiler replaces it with a runtime generated
+  // function
+  //
+  //     function(object, value){object._zzyzx = value;}
+  //
+  // where _zzyzx is replaced with the actual [dispatchPropertyName].
+  //
+  // The body is the CSP compliant version.
+  JS('void', '#[#] = #', object, dispatchPropertyName, value);
+}
+
+makeDispatchRecord(interceptor, proto, extension) {
+  // Dispatch records are stored in the prototype chain, and in some cases, on
+  // instances.
+  //
+  // The record layout and field usage is designed to minimize the number of
+  // operations on the common paths.
+  //
+  // [interceptor] is the interceptor - a holder of methods for the object,
+  // i.e. the prototype of the interceptor class.
+  //
+  // [proto] is usually the prototype, used to check that the dispatch record
+  // matches the object and is not the dispatch record of a superclass.  Other
+  // values:
+  //  - `false` for leaf classes that need no check.
+  //  - `true` for Dart classes where the object is its own interceptor (unused)
+  //  - a function used to continue matching.
+  //
+  // [extension] is used for irregular cases.
+  //
+  //     proto  interceptor extension action
+  //     -----  ----------- --------- ------
+  //     false  I                     use interceptor I
+  //     true   -                     use object
+  //     P      I                     if object's prototype is P, use I
+  //     F      -           P         if object's prototype is P, call F
+
+  return JS('', '{i: #, p: #, e: #}', interceptor, proto, extension);
+}
+
+dispatchRecordInterceptor(record) => JS('', '#.i', record);
+dispatchRecordProto(record) => JS('', '#.p', record);
+dispatchRecordExtension(record) => JS('', '#.e', record);
+
 /**
  * Returns the interceptor for a native class instance. Used by
  * [getInterceptor].
  */
 getNativeInterceptor(object) {
-  // This is a magic method: the compiler replaces it with a runtime generated
-  // function
-  //
-  //     function(object){return object._zzyzx();}
-  //
-  // where _zzyzx is replaced with the actual [dispatchPropertyName].
-  //
-  // The body is the CSP compliant version.
-  return JS('', '#[#]()', object, dispatchPropertyName);
-}
+  var record = getDispatchProperty(object);
 
-setNativeInterceptor(prototype, function) {
-  JS('', '#[#]=#', prototype, dispatchPropertyName, function);
+  if (record != null) {
+    var proto = dispatchRecordProto(record);
+    if (false == proto) return dispatchRecordInterceptor(record);
+    if (true == proto) return object;
+    var objectProto = JS('', 'Object.getPrototypeOf(#)', object);
+    if (JS('bool', '# === #', proto, objectProto)) {
+      return dispatchRecordInterceptor(record);
+    }
+
+    var extension = dispatchRecordExtension(record);
+    if (JS('bool', '# === #', extension, objectProto)) {
+      // The extension handler will do any required patching.  A typical use
+      // case is where one native class represents two Dart classes.  The
+      // extension method will inspect the native object instance to determine
+      // its class and patch the instance.  Needed to fix dartbug.com/9654.
+      return JS('', '(#)(#, #)', proto, object, record);
+    }
+  }
+
+  record = lookupDispatchRecord(object);
+  setDispatchProperty(JS('', 'Object.getPrototypeOf(#)', object), record);
+  return getNativeInterceptor(object);
 }
 
 /**
- * If [InvocationMirror.invokeOn] is being used, this variable
+ * If [Invocation.invokeOn] is being used, this variable
  * contains a JavaScript array with the names of methods that are
  * intercepted.
  */
@@ -132,7 +203,7 @@
 
   String toString() => Primitives.objectToString(this);
 
-  dynamic noSuchMethod(InvocationMirror invocation) {
+  dynamic noSuchMethod(Invocation invocation) {
     throw new NoSuchMethodError(this,
                                 invocation.memberName,
                                 invocation.positionalArguments,
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index 2702d9d..49cf730 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -111,14 +111,14 @@
   patch static _read(int id, int bytes) {
     throw new UnsupportedError("RandomAccessFile._read");
   }
-  patch static _readList(int id, List<int> buffer, int offset, int bytes) {
-    throw new UnsupportedError("RandomAccessFile._readList");
+  patch static _readInto(int id, List<int> buffer, int start, int end) {
+    throw new UnsupportedError("RandomAccessFile._readInto");
   }
   patch static _writeByte(int id, int value) {
     throw new UnsupportedError("RandomAccessFile._writeByte");
   }
-  patch static _writeList(int id, List<int> buffer, int offset, int bytes) {
-    throw new UnsupportedError("RandomAccessFile._writeList");
+  patch static _writeFrom(int id, List<int> buffer, int start, int end) {
+    throw new UnsupportedError("RandomAccessFile._writeFrom");
   }
   patch static _position(int id) {
     throw new UnsupportedError("RandomAccessFile._position");
diff --git a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
index 22e13da..db10b54 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/isolate_helper.dart
@@ -33,8 +33,8 @@
     _port.send(message);
   }
 
-  void addError(AsyncError errorEvent) {
-    throw new UnimplementedError("signalError on isolate streams");
+  void addError(errorEvent) {
+    throw new UnimplementedError("addError on isolate streams");
   }
 
   void close() {
@@ -450,7 +450,7 @@
     // such as d8 and jsshell. We should move this code to a helper
     // library that is only loaded when testing on those engines.
 
-    var stack = JS('String|Null', '(new Error()).stack');
+    var stack = JS('String|Null', 'new Error().stack');
     if (stack == null) {
       // According to Internet Explorer documentation, the stack
       // property is not set until the exception is thrown. The stack
@@ -835,7 +835,7 @@
   SendPort _port;
 
   /**
-   * Future of the underlying port, so that we can detect when this port can be
+   * Future.sync the underlying port, so that we can detect when this port can be
    * sent on messages.
    */
   Future<SendPort> _futurePort;
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
index 7a57e31..ca01210 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_array.dart
@@ -36,6 +36,16 @@
     JS('void', r'#.splice(#, 0, #)', this, index, value);
   }
 
+  void insertAll(int index, Iterable<E> iterable) {
+    checkGrowable(this, 'insertAll');
+    IterableMixinWorkaround.insertAllList(this, index, iterable);
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    checkMutable(this, 'setAll');
+    IterableMixinWorkaround.setAllList(this, index, iterable);
+  }
+
   E removeLast() {
     checkGrowable(this, 'removeLast');
     if (length == 0) throw new RangeError.value(-1);
@@ -160,34 +170,6 @@
     return IterableMixinWorkaround.getRangeList(this, start, end);
   }
 
-  void insertRange(int start, int length, [E initialValue]) {
-    checkGrowable(this, 'insertRange');
-    if (length == 0) {
-      return;
-    }
-    if (length is !int) throw new ArgumentError(length);
-    if (length < 0) throw new ArgumentError(length);
-    if (start is !int) throw new ArgumentError(start);
-
-    var receiver = this;
-    var receiverLength = receiver.length;
-    if (start < 0 || start > receiverLength) {
-      throw new RangeError.value(start);
-    }
-    receiver.length = receiverLength + length;
-    Arrays.copy(receiver,
-                start,
-                receiver,
-                start + length,
-                receiverLength - start);
-    if (initialValue != null) {
-      for (int i = start; i < start + length; i++) {
-        receiver[i] = initialValue;
-      }
-    }
-    receiver.length = receiverLength + length;
-  }
-
   E get first {
     if (length > 0) return this[0];
     throw new StateError("No elements");
@@ -204,34 +186,36 @@
     throw new StateError("More than one element");
   }
 
-  void removeRange(int start, int length) {
+  void removeRange(int start, int end) {
     checkGrowable(this, 'removeRange');
-    if (length == 0) {
-      return;
+    int receiverLength = this.length;
+    if (start < 0 || start > receiverLength) {
+      throw new RangeError.range(start, 0, receiverLength);
     }
-    checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
-    checkNull(length); // TODO(ahe): This is not specified but co19 tests it.
-    if (start is !int) throw new ArgumentError(start);
-    if (length is !int) throw new ArgumentError(length);
-    if (length < 0) throw new ArgumentError(length);
-    var receiverLength = this.length;
-    if (start < 0 || start >= receiverLength) {
-      throw new RangeError.value(start);
-    }
-    if (start + length > receiverLength) {
-      throw new RangeError.value(start + length);
+    if (end < start || end > receiverLength) {
+      throw new RangeError.range(end, start, receiverLength);
     }
     Arrays.copy(this,
-                start + length,
+                end,
                 this,
                 start,
-                receiverLength - length - start);
-    this.length = receiverLength - length;
+                receiverLength - end);
+    this.length = receiverLength - (end - start);
   }
 
-  void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
     checkMutable(this, 'set range');
-    IterableMixinWorkaround.setRangeList(this, start, length, from, startFrom);
+    IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    checkMutable(this, 'fill range');
+    IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+  }
+
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    checkGrowable(this, 'removeRange');
+    IterableMixinWorkaround.replaceRangeList(this, start, end, iterable);
   }
 
   bool any(bool f(E element)) => IterableMixinWorkaround.any(this, f);
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
index b77092f..a6ed014 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_helper.dart
@@ -16,6 +16,8 @@
 import 'dart:_interceptors' show getInterceptor,
                                  interceptedNames,
                                  dispatchPropertyName,
+                                 makeDispatchRecord,
+                                 setDispatchProperty,
                                  Interceptor,
                                  JSIndexable;
 
@@ -63,7 +65,7 @@
 createInvocationMirror(name, internalName, type, arguments, argumentNames) =>
     new JSInvocationMirror(name, internalName, type, arguments, argumentNames);
 
-class JSInvocationMirror implements InvocationMirror {
+class JSInvocationMirror implements Invocation {
   static const METHOD = 0;
   static const GETTER = 1;
   static const SETTER = 2;
@@ -503,7 +505,7 @@
 
   static applyFunction(Function function,
                        List positionalArguments,
-                       Map<String, dynamic> namedArguments) {
+                       Map<Symbol, dynamic> namedArguments) {
     int argumentCount = 0;
     StringBuffer buffer = new StringBuffer();
     List arguments = [];
@@ -627,7 +629,7 @@
     // Otherwise, produce a stack trace and record it in the wrapper.
     // This is a slower way to create a stack trace which works on
     // some browsers, but may simply evaluate to null.
-    String stackTrace = JS('', '(new Error()).stack');
+    String stackTrace = JS('', 'new Error().stack');
     JS('void', '#.stack = #', wrapper, stackTrace);
   }
   return wrapper;
@@ -822,13 +824,13 @@
  * exception.
  */
 StackTrace getTraceFromException(exception) {
-  return new StackTrace(JS("var", r"#.stack", exception));
+  return new _StackTrace(JS("var", r"#.stack", exception));
 }
 
-class StackTrace {
-  var stack;
-  StackTrace(this.stack);
-  String toString() => stack != null ? stack : '';
+class _StackTrace implements StackTrace {
+  var _stack;
+  _StackTrace(this._stack);
+  String toString() => _stack != null ? _stack : '';
 }
 
 
diff --git a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
index e6184c0..56a494da 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/js_string.dart
@@ -89,42 +89,6 @@
     return JS('String', r'#.substring(#, #)', this, startIndex, endIndex);
   }
 
-  String slice([int startIndex, int endIndex]) {
-    int start, end;
-    if (startIndex == null) {
-      start = 0;
-    } else if (startIndex is! int) {
-      throw new ArgumentError("startIndex is not int");
-    } else if (startIndex >= 0) {
-      start = startIndex;
-    } else {
-      start = this.length + startIndex;
-    }
-    if (start < 0 || start > this.length) {
-      throw new RangeError(
-          "startIndex out of range: $startIndex (length: $length)");
-    }
-    if (endIndex == null) {
-      end = this.length;
-    } else if (endIndex is! int) {
-      throw new ArgumentError("endIndex is not int");
-    } else if (endIndex >= 0) {
-      end = endIndex;
-    } else {
-      end = this.length + endIndex;
-    }
-    if (end < 0 || end > this.length) {
-      throw new RangeError(
-          "endIndex out of range: $endIndex (length: $length)");
-    }
-    if (end < start) {
-      throw new ArgumentError(
-          "End before start: $endIndex < $startIndex (length: $length)");
-    }
-    return JS('String', '#.substring(#, #)', this, start, end);
-  }
-
-
   String toLowerCase() {
     return JS('String', r'#.toLowerCase()', this);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
index a41e099..020b836 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart
@@ -23,6 +23,13 @@
 
 bool _mirrorsEnabled = false;
 
+patch class MirrorSystem {
+  patch static String getName(Symbol symbol) {
+    throw new UnimplementedError('MirrorSystem.getName is not yet implemented '
+                                 'in dart2js');
+  }
+}
+
 /**
  * Stub class for the mirror system.
  */
diff --git a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
index 566fb58..345120a 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/native_helper.dart
@@ -224,71 +224,6 @@
       value);
 }
 
-/**
- * This method looks up the type name of [obj] in [methods]. [methods]
- * is a Javascript object. If it cannot find it, it looks into the
- * [_dynamicMetadata] array. If the method can still not be found, it
- * creates a method that will throw a [NoSuchMethodError].
- *
- * Once it has a method, the prototype of [obj] is patched with that
- * method, on the property [name]. The method is then invoked.
- *
- * This method returns the result of invoking the found method.
- */
-dynamicBind(var obj,
-            String name,
-            var methods,
-            List arguments) {
-  // The tag is related to the class name.  E.g. the dart:html class
-  // '_ButtonElement' has the tag 'HTMLButtonElement'.  TODO(erikcorry): rename
-  // getTypeNameOf to getTypeTag.
-
-  var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
-  var method = null;
-  if (!isDartObject(obj)) {
-    String tag = getTypeNameOf(obj);
-
-    method = dynamicBindLookup(hasOwnPropertyFunction, tag, methods);
-    if (method == null) {
-      String secondTag = alternateTag(obj, tag);
-      if (secondTag != null) {
-        method = dynamicBindLookup(hasOwnPropertyFunction, secondTag, methods);
-      }
-    }
-  }
-
-  // If we didn't find the method then look up in the Dart Object class, using
-  // getTypeNameOf in case the minifier has renamed Object.
-  if (method == null) {
-    String nameOfObjectClass = getTypeNameOf(const Object());
-    method = lookupDynamicClass(
-        hasOwnPropertyFunction, methods, nameOfObjectClass);
-  }
-
-  if (method == null) {
-    // Throw the `TypeError` that would have happened if this dynamic bind hook
-    // had not been installed on `Object.prototype`.
-    JS('void',
-       // `(function(){...})()` converts statement `throw` into an expression.
-       '(function(){throw new TypeError(# + " is not a function");})()',
-       name);
-  } else {
-    var proto = JS('var', 'Object.getPrototypeOf(#)', obj);
-    // Patch the method onto the prototype to avoid repeating the lookup.  We
-    // expect that there is nothing called [name] on the immediate prototype,
-    // except it is OK to patch over the dispatch hook on `Object.prototype`.
-    // What this means is we are calling method [name] on a plain JavaScript
-    // Object.  If the patched method needs to access the dispatch hook (for
-    // example, a check against being called from a yet-to-be-patched subclass),
-    // it gets the hook from [dynamicDispatchTable].
-    if (!callHasOwnProperty(hasOwnPropertyFunction, proto, name) ||
-        JS('bool', '# === Object.prototype', proto)) {
-      defineProperty(proto, name, method);
-    }
-  }
-
-  return JS('var', '#.apply(#, #)', method, obj, arguments);
-}
 
 // Is [obj] an instance of a Dart-defined class?
 bool isDartObject(obj) {
@@ -296,7 +231,93 @@
   return JS('bool', '((#) instanceof (#))', obj, JS_DART_OBJECT_CONSTRUCTOR());
 }
 
-dynamicBindLookup(var hasOwnPropertyFunction, String tag, var methods) {
+// For each method name and class inheritance subtree, we use an ordinary JS
+// object as a hash map to store the methods for each class.  Entries are added
+// in native_emitter.dart (see dynamicName).  In order to avoid class names
+// clashing with the method names on Object.prototype (needed for native
+// objects) we must always use hasOwnProperty.
+lookupDynamicClass(var hasOwnPropertyFunction, var methods, String className) {
+  return callHasOwnProperty(hasOwnPropertyFunction, methods, className)
+      ? propertyGet(methods, className)
+      : null;
+}
+
+/// A JavaScript object mapping tags to interceptors.
+var interceptorsByTag;
+
+/// A JavaScript object mapping tags to `true` or `false`.
+var leafTags;
+
+/**
+ * Associates tags with an interceptor.  Called from generated code.  The tags
+ * are all 'leaf' tags representing classes that have no subclasses with
+ * different behaviour.
+ *
+ * [tags] is a string of `|`-separated tags.
+ */
+void defineNativeMethods(String tags, interceptorClass) {
+  defineNativeMethodsCommon(tags, interceptorClass, true);
+}
+
+/**
+ * Associates tags with an interceptor.  Called from generated code.  The tags
+ * are all non-'leaf' tags, representing classes that have a subclass with
+ * different behaviour.
+ */
+void defineNativeMethodsNonleaf(String tags, interceptorClass) {
+  defineNativeMethodsCommon(tags, interceptorClass, false);
+}
+
+void defineNativeMethodsCommon(String tags, var interceptorClass, bool isLeaf) {
+  var methods = JS('', '#.prototype', interceptorClass);
+  if (interceptorsByTag == null) interceptorsByTag = JS('=Object', '{}');
+  if (leafTags == null) leafTags = JS('=Object', '{}');
+
+  var tagsList = JS('=List', '#.split("|")', tags);
+  for (int i = 0; i < tagsList.length; i++) {
+    var tag = tagsList[i];
+    JS('void', '#[#] = #', interceptorsByTag, tag, methods);
+    JS('void', '#[#] = #', leafTags, tag, isLeaf);
+  }
+}
+
+void defineNativeMethodsFinish() {
+  // TODO(sra): Investigate placing a dispatch record on Object.prototype that
+  // returns an interceptor for JavaScript objects.  This avoids needing a test
+  // in every interceptor, and prioritizes the performance of known native
+  // classes over unknown.
+}
+
+lookupDispatchRecord(obj) {
+  var hasOwnPropertyFunction = JS('var', 'Object.prototype.hasOwnProperty');
+  var interceptor = null;
+  assert(!isDartObject(obj));
+  String tag = getTypeNameOf(obj);
+
+  interceptor = lookupInterceptor(
+      hasOwnPropertyFunction, tag, interceptorsByTag);
+
+  if (interceptor == null) {
+    String secondTag = alternateTag(obj, tag);
+    if (secondTag != null) {
+      interceptor = lookupInterceptor(
+          hasOwnPropertyFunction, secondTag, interceptorsByTag);
+    }
+  }
+  if (interceptor == null) {
+    // TODO(sra): Think about the error case.
+    interceptor = JS('', '{__what: "interceptor not found", __tag: #}', tag);
+  }
+  var isLeaf = JS('', '#[#]', leafTags, tag);
+  if (true == isLeaf) {
+    return makeDispatchRecord(interceptor, false, null);
+  } else {
+    var proto = JS('', 'Object.getPrototypeOf(#)', obj);
+    return makeDispatchRecord(interceptor, proto, null);
+  }
+}
+
+lookupInterceptor(var hasOwnPropertyFunction, String tag, var methods) {
   var method = lookupDynamicClass(hasOwnPropertyFunction, methods, tag);
   // Look at the inheritance data, getting the class tags and using them
   // to check the methods table for this method name.
@@ -314,148 +335,6 @@
   return method;
 }
 
-// For each method name and class inheritance subtree, we use an ordinary JS
-// object as a hash map to store the method for each class.  Entries are added
-// in native_emitter.dart (see dynamicName).  In order to avoid the class names
-// clashing with the method names on Object.prototype (needed for native
-// objects) we must always use hasOwnProperty.
-lookupDynamicClass(var hasOwnPropertyFunction,
-                       var methods,
-                       String className) {
-  return callHasOwnProperty(hasOwnPropertyFunction, methods, className) ?
-         propertyGet(methods, className) :
-         null;
-}
-
-/**
- * Code for doing the dynamic dispatch on JavaScript prototypes that are not
- * available at compile-time. Each property of a native Dart class
- * is registered through this function, which is called with the
- * following pattern:
- *
- * dynamicFunction('propertyName').prototypeName = // JS code
- *
- * What this function does is:
- * - Creates a map of { prototypeName: JS code }.
- * - Attaches 'propertyName' to the JS Object prototype that will
- *   intercept at runtime all calls to propertyName.
- * - Sets the value of 'propertyName' to the returned method from
- *   [dynamicBind].
- *
- */
-dynamicFunction(name) {
-  var table = dynamicFunctionTable;
-  if (table == null) {
-    dynamicFunctionTable = table = JS('=Object', '{}');
-  }
-
-  var f = JS('var', '#[#]', table, name);
-  if (f != null && JS('bool', '!!#.methods', f)) {
-    return JS('var', '#.methods', f);
-  }
-
-  // TODO(ngeoffray): We could make this a map if the code we
-  // generate plays well with a Dart map.
-  var methods = JS('=Object', '{}');
-
-  var bind = JS('var',
-      'function() {'
-        'return #(this, #, #, Array.prototype.slice.call(arguments));'
-      '}',
-    DART_CLOSURE_TO_JS(dynamicBind), name, methods);
-
-  JS('void', '#.methods = #', bind, methods);
-  // Install dispatch function on `Object.prototype`, so that `x.name()` will
-  // initially enter the dispatch code for any object.
-  defineProperty(JS('var', 'Object.prototype'), name, bind);
-  // Install dispatch function in table, so it can be called without relying on
-  // patching on the line above.
-  defineProperty(table, name, bind);
-  return methods;
-}
-
-/**
- * Table of dispatch _bind_ functions created by [dynamicFunction].
- *
- *  methodName -> dispatchFunction
- */
-var dynamicFunctionTable;
-
-
-/**
- * Associates a tag of a leaf native class (with no subclasses) with the
- * interceptor for that class.  Called from generated code.
- */
-void defineNativeMethods(String tag, interceptorClass) {
-  var methods = JS('', '#.prototype', interceptorClass);
-  var method = dispatchPropertyName;
-  JS('void', '#[#]=#', dynamicFunction(method), tag,
-      _unguardedConstantJSFunction(methods));
-}
-
-/**
- * Associates a tag of a native class with subclasses with the interceptor for
- * that class.  Called from generated code.
- */
-void defineNativeMethodsNonleaf(String tag, interceptorClass) {
-  var methods = JS('', '#.prototype', interceptorClass);
-  var method = dispatchPropertyName;
-  JS('void', '#[#]=#', dynamicFunction(method), tag,
-      _guardedConstantJSFunction(method, methods));
-}
-
-void defineNativeMethodsFinish() {
-  // Replace dispatch hook on Object.prototype with one that returns an
-  // interceptor for JavaScript objects.  This avoids needing a test in every
-  // interceptor, and prioritizes the performance of known native classes over
-  // unknown.
-  JS('void', 'Object.prototype[#]=#', dispatchPropertyName,
-      _guardedConstantJSFunctionForObject(dispatchPropertyName,
-          JS('', 'Object.getPrototypeOf(#)', const Interceptor())));
-}
-
-/**
- * Returns a JavaScript function that returns [value].
- */
-_unguardedConstantJSFunction(var value) {
-  return JS('', 'function(){return #}', value);
-}
-
-/**
- * Returns a JavaScript function that returns [value] when called from a patched
- * prototype, and calls the dispatch hook when called from an unpatched
- * prototype.
- */
-_guardedConstantJSFunction(String name, var value) {
-  return JS('',
-      'function(){'
-        'if(Object.getPrototypeOf(this).hasOwnProperty(#))'
-          'return #;'
-        'return #(#,this);'
-      '}',
-      name,
-      value,
-      RAW_DART_FUNCTION_REF(_redispatchGetNativeInterceptorHook), name);
-}
-
-_redispatchGetNativeInterceptorHook(name, receiver) {
-  return JS('', '#[#].call(#)', dynamicFunctionTable, name, receiver);
-}
-
-_guardedConstantJSFunctionForObject(String name, var value) {
-  var objectPrototype = JS('', 'Object.prototype');
-  return JS('',
-      'function(){'
-        'if (Object.getPrototypeOf(this) === #)'
-          'return #;'
-        'return #(#,this);'
-      '}',
-      objectPrototype,
-      value,
-      RAW_DART_FUNCTION_REF(_redispatchGetNativeInterceptorHook), name);
-}
-
-
 /**
  * This class encodes the class hierarchy when we need it for dynamic
  * dispatch.
diff --git a/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart b/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart
index bdd5d23..f8243c5 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/regexp_helper.dart
@@ -114,7 +114,7 @@
   }
 }
 
-class _AllMatchesIterable extends Iterable<Match> {
+class _AllMatchesIterable extends IterableBase<Match> {
   final JSSyntaxRegExp _re;
   final String _str;
 
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index c86321f..17f40f6 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -265,11 +265,9 @@
   compiler.librariesToAnalyzeWhenRun = libraries;
   bool success = compiler.run(null);
   if (success && !compilationFailed) {
-    return new Future<MirrorSystem>.immediate(
-        new Dart2JsMirrorSystem(compiler));
+    return new Future<MirrorSystem>.value(new Dart2JsMirrorSystem(compiler));
   } else {
-    return new Future<MirrorSystem>.immediateError(
-        'Failed to create mirror system.');
+    return new Future<MirrorSystem>.error('Failed to create mirror system.');
   }
 }
 
@@ -1626,7 +1624,7 @@
   Future<InstanceMirror> operator[](int index) {
     if (index < 0) throw new RangeError('Negative index');
     if (index >= _constant.length) throw new RangeError('Index out of bounds');
-    return new Future<InstanceMirror>.immediate(
+    return new Future<InstanceMirror>.value(
         _convertConstantToInstanceMirror(mirrors, _constant.entries[index]));
   }
 }
@@ -1663,7 +1661,7 @@
   Future<InstanceMirror> operator[](String key) {
     int index = _list.indexOf(key);
     if (index == -1) return null;
-    return new Future<InstanceMirror>.immediate(
+    return new Future<InstanceMirror>.value(
         _convertConstantToInstanceMirror(mirrors, _constant.values[index]));
   }
 }
@@ -1709,7 +1707,7 @@
   Future<InstanceMirror> getField(String fieldName) {
     Constant fieldConstant = _fieldMap[fieldName];
     if (fieldConstant != null) {
-      return new Future<InstanceMirror>.immediate(
+      return new Future<InstanceMirror>.value(
           _convertConstantToInstanceMirror(mirrors, fieldConstant));
     }
     return super.getField(fieldName);
@@ -1745,13 +1743,13 @@
 
   Future<InstanceMirror> getField(String fieldName) {
     if (fieldName == 'isDocComment') {
-      return new Future.immediate(
+      return new Future.value(
           new Dart2JsBoolConstantMirror.fromBool(mirrors, isDocComment));
     } else if (fieldName == 'text') {
-      return new Future.immediate(
+      return new Future.value(
           new Dart2JsStringConstantMirror.fromString(mirrors, text));
     } else if (fieldName == 'trimmedText') {
-      return new Future.immediate(
+      return new Future.value(
           new Dart2JsStringConstantMirror.fromString(mirrors, trimmedText));
     }
     // TODO(johnniwinther): Which exception/error should be thrown here?
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
index 2a2c1fe..41a085e 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util.dart
@@ -4,7 +4,7 @@
 
 library mirrors_util;
 
-import 'dart:collection' show Queue;
+import 'dart:collection' show Queue, IterableBase;
 
 // TODO(rnystrom): Use "package:" URL (#4968).
 import 'mirrors.dart';
@@ -55,7 +55,7 @@
   throw new Exception('Unexpected owner: ${owner}');
 }
 
-class HierarchyIterable extends Iterable<ClassMirror> {
+class HierarchyIterable extends IterableBase<ClassMirror> {
   final bool includeType;
   final ClassMirror type;
 
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index c8598e8..9504271 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -2013,7 +2013,7 @@
             {'className': currentClass, 'memberName': name});
         // We still need to register the invocation, because we might
         // call [:super.noSuchMethod:] that does a
-        // [:InvocationMirror.invokeOn:].
+        // [:Invocation.invokeOn:].
         world.registerDynamicInvocation(selector.name, selector);
         compiler.backend.registerSuperNoSuchMethod(mapping);
       }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
index 92fcdc5..4ae62ed 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
@@ -5,7 +5,7 @@
 /**
  * An abstract string representation.
  */
-abstract class ByteString extends Iterable<int> implements SourceString {
+abstract class ByteString extends IterableBase<int> implements SourceString {
   final List<int> bytes;
   final int offset;
   final int length;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
index aa85287..262a64b 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
@@ -7,7 +7,7 @@
 /**
  * A keyword in the Dart programming language.
  */
-class Keyword extends Iterable<int> implements SourceString {
+class Keyword extends IterableBase<int> implements SourceString {
   static const List<Keyword> values = const <Keyword> [
       const Keyword("assert"),
       const Keyword("break"),
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart b/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
index e3cd591..8bdf120 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
@@ -4,7 +4,7 @@
 
 library scanner;
 
-import 'dart:collection' show LinkedHashMap;
+import 'dart:collection' show LinkedHashMap, IterableBase;
 import 'dart:uri';
 
 import 'scanner_implementation.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
index 5d1a42a..e898f41 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/string_scanner.dart
@@ -53,7 +53,7 @@
   }
 }
 
-class SubstringWrapper extends Iterable<int> implements SourceString {
+class SubstringWrapper extends IterableBase<int> implements SourceString {
   final String internalString;
   final int begin;
   final int end;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index fcf4e87..23b4f78 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -185,7 +185,7 @@
   String slowToString() => value.slowToString();
 }
 
-abstract class SourceString extends Iterable<int> {
+abstract class SourceString extends IterableBase<int> {
   const factory SourceString(String string) = StringWrapper;
 
   void printOn(StringBuffer sb);
@@ -205,7 +205,7 @@
   bool isPrivate();
 }
 
-class StringWrapper extends Iterable<int> implements SourceString {
+class StringWrapper extends IterableBase<int> implements SourceString {
   final String stringValue;
 
   const StringWrapper(String this.stringValue);
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 4157fc9..b75ba4a 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -20,7 +20,7 @@
   var file = (new File(filename)).openSync();
   var length = file.lengthSync();
   var buffer = new List<int>(length);
-  var bytes = file.readListSync(buffer, 0, length);
+  var bytes = file.readIntoSync(buffer, 0, length);
   file.closeSync();
   return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
 }
@@ -45,7 +45,7 @@
     dartCharactersRead += source.length;
     sourceFiles[resourceUri.toString()] =
       new SourceFile(relativize(cwd, resourceUri, isWindows), source);
-    return new Future.immediate(source);
+    return new Future.value(source);
   }
 }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index d32bfb3..97c585c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1138,7 +1138,6 @@
     }
 
     PartialFunctionElement function = element;
-    if (function == backend.getInterceptorMethod) return false;
     bool canBeInlined = backend.canBeInlined[function];
     if (canBeInlined == false) return false;
     if (!selector.applies(function, compiler)) return false;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index e201af0..936ad61 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -89,33 +89,6 @@
   }
 }
 
-// Stop-gap until the core classes have such a class.
-class OrderedSet<T> {
-  final LinkedHashMap<T, bool> map = new LinkedHashMap<T, bool>();
-
-  void add(T x) {
-    if (!map.containsKey(x)) {
-      map[x] = true;
-    }
-  }
-
-  bool contains(T x) => map.containsKey(x);
-
-  bool remove(T x) => map.remove(x) != null;
-
-  bool get isEmpty => map.isEmpty;
-
-  void forEach(f) => map.keys.forEach(f);
-
-  T get first {
-    var iterator = map.keys.iterator;
-    if (!iterator.moveNext()) throw new StateError("No elements");
-    return iterator.current;
-  }
-
-  get length => map.length;
-}
-
 typedef void ElementAction(Element element);
 
 abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
@@ -168,7 +141,7 @@
    * we do this most of the time, because it reduces the size unless there
    * is only one variable.
    */
-  final OrderedSet<String> collectedVariableDeclarations;
+  final LinkedHashSet<String> collectedVariableDeclarations;
 
   /**
    * Set of variables and parameters that have already been declared.
@@ -188,7 +161,7 @@
   SsaCodeGenerator(this.backend, CodegenWorkItem work)
     : this.work = work,
       declaredLocals = new Set<String>(),
-      collectedVariableDeclarations = new OrderedSet<String>(),
+      collectedVariableDeclarations = new LinkedHashSet<String>(),
       currentContainer = new js.Block.empty(),
       parameters = <js.Parameter>[],
       expressionStack = <js.Expression>[],
@@ -261,7 +234,7 @@
   }
 
   void insertStatementAtStart(js.Statement statement) {
-    currentContainer.statements.insertRange(0, 1, statement);
+    currentContainer.statements.insert(0, statement);
   }
 
   /**
@@ -857,6 +830,7 @@
                   inits.add(new js.VariableInitialization(declaration,
                                                           assignment.value));
                   collectedVariableDeclarations.remove(id);
+                  declaredLocals.add(id);
                 }
                 jsInitialization = new js.VariableDeclarationList(inits);
               }
@@ -1743,23 +1717,22 @@
       }
       pushStatement(new js.LiteralStatement(code), node);
     } else {
-      // We can parse simple JS with the mini parser.  At the moment we can't
-      // handle expression interpolation with # and we can't handle JSON
-      // literals and function literals, both of which contain "{".
-      if (!code.contains("#") && !code.contains("{")) {
-        js.Expression codeAst = js.js(code);
-        push(codeAst, node);
-        if (!inputs.isEmpty) {
-          compiler.internalError("Too many arguments to JS expression",
-                                 instruction: node);
-        }
-      } else {
-        List<js.Expression> data = <js.Expression>[];
+      List<js.Expression> interpolatedExpressions;
+      if (!inputs.isEmpty) {
+        interpolatedExpressions = <js.Expression>[];
         for (int i = 0; i < inputs.length; i++) {
           use(inputs[i]);
-          data.add(pop());
+          interpolatedExpressions.add(pop());
         }
-        push(new js.LiteralExpression.withData(code, data), node);
+      }
+      // We can parse simple JS with the mini parser.  At the moment we can't
+      // handle JSON literals and function literals, both of which contain "{".
+      if (!code.contains("{") && !code.startsWith("throw ")) {
+        js.Expression codeAst = js.js(code, interpolatedExpressions);
+        push(codeAst, node);
+      } else {
+        push(new js.LiteralExpression.withData(code, interpolatedExpressions),
+             node);
       }
     }
     registerForeignType(node.instructionType);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 745f489..fdea257 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -659,7 +659,7 @@
     if (index == dominatedBlocks.length) {
       dominatedBlocks.add(block);
     } else {
-      dominatedBlocks.insertRange(index, 1, block);
+      dominatedBlocks.insert(index, block);
     }
     assert(block.dominator == null);
     block.dominator = this;
@@ -673,7 +673,7 @@
     if (index == dominatedBlocks.length - 1) {
       dominatedBlocks.removeLast();
     } else {
-      dominatedBlocks.removeRange(index, 1);
+      dominatedBlocks.removeRange(index, index + 1);
     }
     assert(identical(block.dominator, this));
     block.dominator = null;
diff --git a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
index 3b1b210..3b0c2fb 100644
--- a/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tools/mini_parser.dart
@@ -6,7 +6,7 @@
 
 import 'dart:io';
 import 'dart:typeddata';
-
+import 'dart:collection';
 import 'dart:utf';
 
 import '../elements/elements.dart';
@@ -164,7 +164,7 @@
   try {
     int size = file.lengthSync();
     List<int> bytes = new Uint8List(size + 1);
-    file.readListSync(bytes, 0, size);
+    file.readIntoSync(bytes, 0, size);
     bytes[size] = $EOF;
     threw = false;
     return bytes;
diff --git a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
index 2166f7d..8f962ad 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
@@ -11,7 +11,7 @@
  * representing its content after removing quotes and resolving escapes in
  * its source.
  */
-abstract class DartString extends Iterable<int> {
+abstract class DartString extends IterableBase<int> {
   factory DartString.empty() => const LiteralDartString("");
   // This is a convenience constructor. If you need a const literal DartString,
   // use [const LiteralDartString(string)] directly.
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 4f265f0..13ea311 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -212,7 +212,7 @@
  * [: (A, D) :], [: (B, C) :] and finally [: (B, D) :].
  */
 class ConcreteTypeCartesianProduct
-    extends Iterable<ConcreteTypesEnvironment> {
+    extends IterableBase<ConcreteTypesEnvironment> {
   final ConcreteTypesInferrer inferrer;
   final ClassElement typeOfThis;
   final Map<Element, ConcreteType> concreteTypes;
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 48c6c1c..35965c0 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -4,7 +4,7 @@
 
 library types;
 
-import 'dart:collection' show Queue;
+import 'dart:collection' show Queue, IterableBase;
 
 import '../dart2jslib.dart' hide Selector;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index d3f93ca..614b657 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -4,7 +4,7 @@
 
 part of org_dartlang_compiler_util;
 
-class Link<T> extends Iterable<T> {
+class Link<T> extends IterableBase<T> {
   T get head => null;
   Link<T> get tail => null;
 
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 9d4056a..c9c0e66 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -4,6 +4,7 @@
 
 library org_dartlang_compiler_util;
 
+import "dart:collection";
 import 'util_implementation.dart';
 import 'characters.dart';
 
diff --git a/sdk/lib/_internal/compiler/samples/leap/leap_server.dart b/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
index d898f59..1f9d63f 100644
--- a/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
+++ b/sdk/lib/_internal/compiler/samples/leap/leap_server.dart
@@ -82,11 +82,11 @@
     new Conversation(request, request.response).handle();
   }
 
-  static onError(AsyncError e) {
-    if (e.error is HttpParserException) {
-      print('Error: ${e.error.message}');
+  static onError(error) {
+    if (error is HttpParserException) {
+      print('Error: ${error.message}');
     } else {
-      print('Error: ${e.error}');
+      print('Error: ${error}');
     }
   }
 
@@ -116,7 +116,7 @@
     print('HTTP server started on http://$host:${server.port}/');
     server.listen(Conversation.onRequest, onError: Conversation.onError);
   }).catchError((e) {
-    print("HttpServer.bind error: ${e.error}");
+    print("HttpServer.bind error: $e");
     exit(1);
   });
 }
diff --git a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
index 9190f31..47eb828 100644
--- a/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/bin/dartdoc.dart
@@ -39,7 +39,7 @@
 
   final argParser = new ArgParser();
 
-  final Path libPath = scriptDir.append('../../../../');
+  Path libPath = scriptDir.append('../../../../');
 
   String packageRoot;
 
@@ -172,6 +172,14 @@
         }
       });
 
+  argParser.addOption('library-root',
+      help: 'Sets the library root directory to the specified directory.',
+      callback: (libraryRoot) {
+        if (libraryRoot != null) {
+          libPath = new Path(libraryRoot);
+        }
+      });
+
   // TODO(amouravski): This method is deprecated. Remove on April 22.
   argParser.addOption('pkg',
       help: 'Deprecated: same as --package-root.',
@@ -243,6 +251,8 @@
     })
     .catchError((e) {
       print('Error: generation failed: ${e}');
+      var trace = getAttachedStackTrace(e);
+      if (trace != null) print("StackTrace: $trace");
       dartdoc.cleanup();
       exit(1);
     })
diff --git a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
index 38d1706..b20f3cb 100644
--- a/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
+++ b/sdk/lib/_internal/dartdoc/lib/dartdoc.dart
@@ -126,7 +126,7 @@
         }
       },
       onDone: () => completer.complete(),
-      onError: (e) => completer.completeError(e.error, e.stackTrace));
+      onError: (e) => completer.completeError(e));
   return completer.future;
 }
 
@@ -149,7 +149,7 @@
 
 void _compileScript() {
   port.receive((message, replyTo) {
-    new Future.of(() {
+    new Future.sync(() {
       var clientScript = (message['mode'] == MODE_STATIC) ?
           'static' : 'live-nav';
       var dartPath = pathos.join(message['libPath'], 'lib', '_internal',
@@ -163,8 +163,10 @@
       });
     }).then((_) {
       replyTo.send(['success']);
-    }).catchError((e) {
-      replyTo.send(['error', e.error.toString(), e.stackTrace.toString()]);
+    }).catchError((error) {
+      var trace = getAttachedStackTrace(error);
+      var traceString = trace == null ? "" : trace.toString();
+      replyTo.send(['error', error.toString(), traceString]);
     });
   });
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart b/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
index e197b0b..90455c0 100755
--- a/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/json_serializer.dart
@@ -54,7 +54,8 @@
   // TODO(jacobr): this code works only because futures for mirrors return
   // immediately.
   for(String memberName in members) {
-    var result = deprecatedFutureValue(mirror.getFieldAsync(memberName));
+    var result =
+        deprecatedFutureValue(mirror.getFieldAsync(new Symbol(memberName)));
     _serialize(memberName, result.reflectee, printer);
   }
   printer.endObject();
@@ -62,19 +63,25 @@
 
 void determineAllMembers(ClassMirror classMirror,
     List<String> members) {
-  for(String getterName in classMirror.getters.keys) {
-    if (!members.contains(getterName)) {
-      members.add(getterName);
+  for(Symbol getterName in classMirror.getters.keys) {
+    if (!members.contains(MirrorSystem.getName(getterName))) {
+      members.add(MirrorSystem.getName(getterName));
     }
   }
-  for(String fieldName in classMirror.variables.keys) {
-    if (!members.contains(fieldName)) {
-      members.add(fieldName);
+  for(Symbol fieldName in classMirror.variables.keys) {
+    if (!members.contains(MirrorSystem.getName(fieldName))) {
+      members.add(MirrorSystem.getName(fieldName));
     }
   }
   if (classMirror.superclass != null &&
+
+      // TODO(ahe): What is this test for?  Consider removing it,
+      // dart2js will issue an error if there is a cycle in superclass
+      // hierarchy.
       classMirror.superclass.qualifiedName != classMirror.qualifiedName &&
-      classMirror.superclass.qualifiedName != 'dart.core.Object') {
+
+      MirrorSystem.getName(classMirror.superclass.qualifiedName) !=
+          'dart.core.Object') {
     determineAllMembers(classMirror.superclass, members);
   }
 }
diff --git a/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart b/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
index 26c9484..d3ec7ae 100644
--- a/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
+++ b/sdk/lib/_internal/dartdoc/lib/src/markdown/inline_parser.dart
@@ -80,8 +80,7 @@
       syntaxes = defaultSyntaxes;
     }
     // Custom link resolver goes after the generic text syntax.
-    syntaxes.insertRange(1, 1,
-        new LinkSyntax(linkResolver: document.linkResolver));
+    syntaxes.insert(1, new LinkSyntax(linkResolver: document.linkResolver));
   }
 
   List<Node> parse() {
@@ -388,7 +387,7 @@
 
     // Remove the unmatched children.
     final unmatchedTags = parser._stack.sublist(index + 1);
-    parser._stack.removeRange(index + 1, parser._stack.length - index - 1);
+    parser._stack.removeRange(index + 1, parser._stack.length);
 
     // Flatten them out onto this tag.
     for (final unmatched in unmatchedTags) {
diff --git a/sdk/lib/_internal/dartdoc/test/test_files/packages/fake_package/fake_package.dart b/sdk/lib/_internal/dartdoc/test/test_files/packages/fake_package/fake_package.dart
deleted file mode 100644
index 0025791..0000000
--- a/sdk/lib/_internal/dartdoc/test/test_files/packages/fake_package/fake_package.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-library fake_package;
-class FakePackage {
-
-}
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index d5f8a46..f41f2253 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -119,7 +119,9 @@
   "_collection-dev": const LibraryInfo(
       "_collection_dev/collection_dev.dart",
       category: "Internal",
-      documented: false),
+      documented: false,
+      dart2jsPatchPath:
+          "_internal/compiler/implementation/lib/collection_dev_patch.dart"),
 
   "_js_helper": const LibraryInfo(
       "_internal/compiler/implementation/lib/js_helper.dart",
diff --git a/sdk/lib/async/async_error.dart b/sdk/lib/async/async_error.dart
index fa90e87..05fbb88b2 100644
--- a/sdk/lib/async/async_error.dart
+++ b/sdk/lib/async/async_error.dart
@@ -4,70 +4,24 @@
 
 part of dart.async;
 
-/**
- * Error result of an asynchronous computation.
- */
-class AsyncError {
-  /** The actual error thrown by the computation. */
-  final error;
-  /** Stack trace corresponding to the error, if available. */
-  final Object stackTrace;
-  /** Asynchronous error leading to this error, if error handling fails. */
-  final AsyncError cause;
+final Expando _stackTraceExpando = new Expando("asynchronous error");
 
-  // TODO(lrn): When possible, combine into one constructor with both optional
-  // positional and named arguments.
-  AsyncError(this.error, [this.stackTrace]): cause = null;
-  AsyncError.withCause(this.error, this.stackTrace, this.cause);
-
-  void _writeOn(StringSink buffer) {
-    buffer.write("'");
-    String message;
-    try {
-      message = error.toString();
-    } catch (e) {
-      message = Error.safeToString(error);
-    }
-    buffer.write(message);
-    buffer.write("'\n");
-    if (stackTrace != null) {
-      buffer.write("Stack trace:\n");
-      buffer.writeln(stackTrace.toString());
-    }
-  }
-
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("AsyncError: ");
-    _writeOn(buffer);
-    AsyncError cause = this.cause;
-    while (cause != null) {
-      buffer.write("Caused by: ");
-      cause._writeOn(buffer);
-      cause = cause.cause;
-    }
-    return buffer.toString();
-  }
-
-  throwDelayed() {
-    reportError() {
-      print("Uncaught Error: $error");
-      if (stackTrace != null) {
-        print("Stack Trace:\n$stackTrace\n");
-      }
-    }
-
-    try {
-      Timer.run(() {
-        reportError();
-        // TODO(floitsch): we potentially want to call the global error handler
-        // directly so that we can pass the stack trace.
-        throw error;
-      });
-    } catch (e) {
-      // Unfortunately there is not much more we can do...
-      reportError();
-    }
-  }
+void _attachStackTrace(o, st) {
+  if (o == null || o is bool || o is num || o is String) return;
+  _stackTraceExpando[o] = st;
 }
 
+/**
+ * *This is an experimental API.*
+ *
+ * Get the [StackTrace] attached to [o].
+ *
+ * If object [o] was thrown and caught in a dart:async method, a [StackTrace]
+ * object was attached to it. Use [getAttachedStackTrace] to get that object.
+ *
+ * Returns [null] if no [StackTrace] was attached.
+ */
+getAttachedStackTrace(o) {
+  if (o == null || o is bool || o is num || o is String) return null;
+  return _stackTraceExpando[o];
+}
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 96bf0cc..7219719 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -25,7 +25,7 @@
  *         // Invoked when the future is completed with a value.
  *         return 42;  // The successor is completed with the value 42.
  *       },
- *       onError: (AsyncError e) {
+ *       onError: (e) {
  *         // Invoked when the future is completed with an error.
  *         if (canHandle(e)) {
  *           return 499;  // The successor is completed with the value 499.
@@ -84,31 +84,43 @@
  */
 // TODO(floitsch): document chaining.
 abstract class Future<T> {
+
   /**
-   * Creates a future containing the result of calling [function].
+   * Creates a future containing the result of calling [computation]
+   * asynchronously with [runAsync].
    *
-   * 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 result of executing [computation] throws, the returned future is
+   * completed with the error. If a thrown value is an [AsyncError], it is used
+   * directly, instead of wrapping this error again in another [AsyncError].
    *
    * 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.
+   * If a value is returned, it becomes the result of the created future.
    */
-  factory Future.of(function()) {
+  factory Future(computation()) {
+    _ThenFuture<dynamic, T> future =
+        new _ThenFuture<dynamic, T>((_) => computation());
+    runAsync(() => future._sendValue(null));
+    return future;
+  }
+
+  /**
+   * Creates a future containing the result of immediately calling
+   * [computation].
+   *
+   * if the result of executing [computation] throws, the returned future is
+   * completed with the error. If a thrown value is an [AsyncError], it is used
+   * directly, instead of wrapping this error again in another [AsyncError].
+   *
+   * 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.
+   */
+  factory Future.sync(computation()) {
     try {
-      var result = function();
+      var result = computation();
       return new _FutureImpl<T>().._setOrChainValue(result);
     } catch (error, stackTrace) {
       return new _FutureImpl<T>.immediateError(error, stackTrace);
@@ -119,18 +131,18 @@
    * A future whose value is available in the next event-loop iteration.
    *
    * If [value] is not a [Future], using this constructor is equivalent
-   * to [:new Future.of(() => value):].
+   * to [:new Future.sync(() => value):].
    *
    * See [Completer] to create a Future and complete it later.
    */
-  factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value);
+  factory Future.value([T value]) => new _FutureImpl<T>.immediate(value);
 
   /**
    * A future that completes with an error in the next event-loop iteration.
    *
    * See [Completer] to create a Future and complete it later.
    */
-  factory Future.immediateError(var error, [Object stackTrace]) {
+  factory Future.error(var error, [Object stackTrace]) {
     return new _FutureImpl<T>.immediateError(error, stackTrace);
   }
 
@@ -187,7 +199,7 @@
     Iterator iterator = input.iterator;
     void nextElement(_) {
       if (iterator.moveNext()) {
-        new Future.of(() => f(iterator.current))
+        new Future.sync(() => f(iterator.current))
             .then(nextElement, onError: doneSignal._setError);
       } else {
         doneSignal._setValue(null);
@@ -207,9 +219,7 @@
    * [this] completes with an error).
    *
    * If the invoked callback throws an exception, the returned future `f` is
-   * completed with the error. If the value thrown is an [AsyncError], it is
-   * used directly, as the error result. Otherwise it is wrapped in an
-   * [AsyncError] first.
+   * completed with the error.
    *
    * If the invoked callback returns a [Future] `f2` then `f` and `f2` are
    * chained. That is, `f` is completed with the completion value of `f2`.
@@ -221,7 +231,7 @@
    * with a `test` parameter, instead of handling both value and error in a
    * single [then] call.
    */
-  Future then(onValue(T value), { onError(AsyncError asyncError) });
+  Future then(onValue(T value), { onError(Object error) });
 
   /**
    * Handles errors emitted by this [Future].
@@ -233,8 +243,8 @@
    *
    * When [this] completes with an error, [test] is called with the
    * error's value. If the invocation returns [true], [onError] is called with
-   * the error wrapped in an [AsyncError]. The result of [onError] is handled
-   * exactly the same as for [then]'s [onError].
+   * the error. The result of [onError] is handled exactly the same as for
+   * [then]'s [onError].
    *
    * If [test] returns false, the exception is not handled by [onError], but is
    * thrown unmodified, thus forwarding it to `f`.
@@ -250,12 +260,12 @@
    *
    * This method is equivalent to:
    *
-   *     Future catchError(onError(AsyncError asyncError),
-   *                       {bool test(Object error)}) {
+   *     Future catchError(onError(error),
+   *                       {bool test(error)}) {
    *       this.then((v) => v,  // Forward the value.
    *                 // But handle errors, if the [test] succeeds.
-   *                 onError: (AsyncError e) {
-   *                   if (test == null || test(e.error)) {
+   *                 onError: (e) {
+   *                   if (test == null || test(e)) {
    *                     return onError(e);
    *                   }
    *                   throw e;
@@ -263,7 +273,7 @@
    *     }
    *
    */
-  Future catchError(onError(AsyncError asyncError),
+  Future catchError(onError(Object error),
                     {bool test(Object error)});
 
   /**
@@ -295,7 +305,7 @@
    *                   if (f2 is Future) return f2.then((_) => v);
    *                   return v
    *                 },
-   *                 onError: (AsyncError e) {
+   *                 onError: (e) {
    *                   var f2 = action();
    *                   if (f2 is Future) return f2.then((_) { throw e; });
    *                   throw e;
@@ -352,12 +362,6 @@
    * while trying to produce a value.
    *
    * The argument [exception] should not be `null`.
-   *
-   * If [exception] is an [AsyncError], it is used directly as the error
-   * message sent to the future's listeners, and [stackTrace] is ignored.
-   *
-   * Otherwise the [exception] and an optional [stackTrace] is combined into an
-   * [AsyncError] and sent to this future's listeners.
    */
   void completeError(Object exception, [Object stackTrace]);
 
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index c793d8f..3660b9f 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -7,7 +7,6 @@
 deprecatedFutureValue(_FutureImpl future) =>
   future._isComplete ? future._resultOrListeners : null;
 
-
 class _CompleterImpl<T> implements Completer<T> {
   final Future<T> future;
   bool _isComplete = false;
@@ -24,14 +23,12 @@
   void completeError(Object error, [Object stackTrace = null]) {
     if (_isComplete) throw new StateError("Future already completed");
     _isComplete = true;
-    AsyncError asyncError;
-    if (error is AsyncError) {
-      asyncError = error;
-    } else {
-      asyncError = new AsyncError(error, stackTrace);
+    if (stackTrace != null) {
+      // Force the stack trace onto the error, even if it already had one.
+      _attachStackTrace(error, stackTrace);
     }
     _FutureImpl future = this.future;
-    future._setError(asyncError);
+    future._setError(error);
   }
 
   bool get isCompleted => _isComplete;
@@ -51,7 +48,7 @@
     return new _FutureListenerWrapper(future);
   }
   void _sendValue(T value);
-  void _sendError(AsyncError error);
+  void _sendError(error);
 }
 
 /** Adapter for a [_FutureImpl] to be a future result listener. */
@@ -60,7 +57,7 @@
   _FutureListener _nextListener;
   _FutureListenerWrapper(this.future);
   _sendValue(T value) { future._setValue(value); }
-  _sendError(AsyncError error) { future._setError(error); }
+  _sendError(error) { future._setError(error); }
 }
 
 class _FutureImpl<T> implements Future<T> {
@@ -85,7 +82,7 @@
   /**
    * Either the result, or a list of listeners until the future completes.
    *
-   * The result of the future is either a value or an [AsyncError].
+   * The result of the future is either a value or an error.
    * A result is only stored when the future has completed.
    *
    * The listeners is an internally linked list of [_FutureListener]s.
@@ -104,13 +101,11 @@
   }
 
   _FutureImpl.immediateError(var error, [Object stackTrace]) {
-    AsyncError asyncError;
-    if (error is AsyncError) {
-      asyncError = error;
-    } else {
-      asyncError = new AsyncError(error, stackTrace);
+    if (stackTrace != null) {
+      // Force stack trace onto error, even if it had already one.
+      _attachStackTrace(error, stackTrace);
     }
-    _setError(asyncError);
+    _setError(error);
   }
 
   factory _FutureImpl.wait(Iterable<Future> futures) {
@@ -121,7 +116,7 @@
     void handleError(error) {
       if (values != null) {
         values = null;
-        completer.completeError(error.error, error.stackTrace);
+        completer.completeError(error);
       }
     }
     // As each future completes, put its value into the corresponding
@@ -139,14 +134,14 @@
       });
     }
     if (remaining == 0) {
-      return new Future.immediate(const []);
+      return new Future.value(const []);
     }
     values = new List(remaining);
     completer = new Completer<List>();
     return completer.future;
   }
 
-  Future then(f(T value), { onError(AsyncError error) }) {
+  Future then(f(T value), { onError(error) }) {
     if (!_isComplete) {
       if (onError == null) {
         return new _ThenFuture(f).._subscribeTo(this);
@@ -167,7 +162,7 @@
     }
   }
 
-  Future catchError(f(AsyncError asyncError), { bool test(error) }) {
+  Future catchError(f(error), { bool test(error) }) {
     if (_hasValue) {
       return new _FutureWrapper(this);
     }
@@ -190,7 +185,7 @@
     } else {
       assert(_hasError);
       _clearUnhandledError();
-      AsyncError error = _resultOrListeners;
+      var error = _resultOrListeners;
       Timer.run(() {
         whenFuture._sendError(error);
       });
@@ -208,10 +203,10 @@
   }
 
   /** Handle a late listener on a completed future with an error. */
-  Future _handleError(onError(AsyncError error), bool test(error)) {
+  Future _handleError(onError(error), bool test(error)) {
     assert(_hasError);
     _clearUnhandledError();
-    AsyncError error = _resultOrListeners;
+    var error = _resultOrListeners;
     _CatchErrorFuture errorFuture = new _CatchErrorFuture(onError, test);
     Timer.run(() { errorFuture._sendError(error); });
     return errorFuture;
@@ -232,7 +227,7 @@
     }
   }
 
-  void _setError(AsyncError error) {
+  void _setError(error) {
     if (_isComplete) throw new StateError("Future already completed");
     _FutureListener listeners = _removeListeners();
     _state = _ERROR;
@@ -257,12 +252,13 @@
       if (_hasUnhandledError) {
         // No error handler has been added since the error was set.
         _clearUnhandledError();
-        AsyncError error = _resultOrListeners;
-        print("Uncaught Error: ${error.error}");
-        if (error.stackTrace != null) {
-          print("Stack Trace:\n${error.stackTrace}\n");
+        var error = _resultOrListeners;
+        print("Uncaught Error: ${error}");
+        var trace = getAttachedStackTrace(error);
+        if (trace != null) {
+          print("Stack Trace:\n$trace\n");
         }
-        throw error.error;
+        throw error;
       }
     });
   }
@@ -351,7 +347,7 @@
 
   void _sendValue(S value);
 
-  void _sendError(AsyncError error);
+  void _sendError(error);
 
   void _subscribeTo(_FutureImpl future) {
     future._addListener(this);
@@ -360,7 +356,7 @@
 
 /** The onValue and onError handlers return either a value or a future */
 typedef dynamic _FutureOnValue<T>(T value);
-typedef dynamic _FutureOnError(AsyncError error);
+typedef dynamic _FutureOnError(error);
 /** Test used by [Future.catchError] to handle skip some errors. */
 typedef bool _FutureErrorTest(var error);
 /** Used by [WhenFuture]. */
@@ -379,17 +375,14 @@
     var result;
     try {
       result = _onValue(value);
-    } on AsyncError catch (e) {
-      _setError(e);
-      return;
     } catch (e, s) {
-      _setError(new AsyncError(e, s));
+      _setError(_asyncError(e, s));
       return;
     }
     _setOrChainValue(result);
   }
 
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     _setError(error);
   }
 }
@@ -405,16 +398,16 @@
     _setValue(value);
   }
 
-  _sendError(AsyncError error) {
+  _sendError(error) {
     assert(_onError != null);
     // if _test is supplied, check if it returns true, otherwise just
     // forward the error unmodified.
     if (_test != null) {
       bool matchesTest;
       try {
-        matchesTest = _test(error.error);
+        matchesTest = _test(error);
       } catch (e, s) {
-        _setError(new AsyncError.withCause(e, s, error));
+        _setError(_asyncError(e, s));
         return;
       }
       if (!matchesTest) {
@@ -426,11 +419,8 @@
     var result;
     try {
       result = _onError(error);
-    } on AsyncError catch (e) {
-      _setError(e);
-      return;
     } catch (e, s) {
-      _setError(new AsyncError.withCause(e, s, error));
+      _setError(_asyncError(e, s));
       return;
     }
     _setOrChainValue(result);
@@ -445,16 +435,13 @@
 
   // The _sendValue method is inherited from ThenFuture.
 
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     assert(_onError != null);
     var result;
     try {
       result = _onError(error);
-    } on AsyncError catch (e) {
-      _setError(e);
-      return;
     } catch (e, s) {
-      _setError(new AsyncError.withCause(e, s, error));
+      _setError(_asyncError(e, s));
       return;
     }
     _setOrChainValue(result);
@@ -477,17 +464,14 @@
         }, onError: _setError);
         return;
       }
-    } on AsyncError catch (e) {
-      _setError(e);
-      return;
     } catch (e, s) {
-      _setError(new AsyncError(e, s));
+      _setError(_asyncError(e, s));
       return;
     }
     _setValue(value);
   }
 
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     try {
       var result = _action();
       if (result is Future) {
@@ -498,10 +482,8 @@
         }, onError: _setError);
         return;
       }
-    } on AsyncError catch (e) {
-      error = e;
     } catch (e, s) {
-      error = new AsyncError.withCause(e, s, error);
+      error = _asyncError(e, s);
     }
     _setError(error);
   }
@@ -519,11 +501,11 @@
 
   _FutureWrapper(this._future);
 
-  Future then(function(T value), { onError(AsyncError error) }) {
+  Future then(function(T value), { onError(error) }) {
     return _future.then(function, onError: onError);
   }
 
-  Future catchError(function(AsyncError error), {bool test(var error)}) {
+  Future catchError(function(error), {bool test(var error)}) {
     return _future.catchError(function, test: test);
   }
 
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 7da4451..62174c8 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -115,30 +115,28 @@
     }
 
     controller = new StreamController<T>(
-        onPauseStateChange: () {
-          if (controller.isPaused) {
-            timer.cancel();
-            timer = null;
-            watch.stop();
-          } else {
-            assert(timer == null);
-            Duration elapsed = watch.elapsed;
-            watch.start();
-            timer = new Timer(period - elapsed, () {
-              timer = null;
-              startPeriodicTimer();
-              sendEvent();
-            });
-          }
+        onListen: () {
+          watch.start();
+          startPeriodicTimer();
         },
-        onSubscriptionStateChange: () {
-          if (controller.hasListener) {
-            watch.start();
-            startPeriodicTimer();
-          } else {
-            if (timer != null) timer.cancel();
+        onPause: () {
+          timer.cancel();
+          timer = null;
+          watch.stop();
+        },
+        onResume: () {
+          assert(timer == null);
+          Duration elapsed = watch.elapsed;
+          watch.start();
+          timer = new Timer(period - elapsed, () {
             timer = null;
-          }
+            startPeriodicTimer();
+            sendEvent();
+          });
+        },
+        onCancel: () {
+          if (timer != null) timer.cancel();
+          timer = null;
         });
     return controller.stream;
   }
@@ -170,17 +168,17 @@
    * is called. If [onData] is null, nothing happens.
    *
    * On errors from this stream, the [onError] handler is given a
-   * [AsyncError] object describing the error.
+   * object describing the error.
    *
    * If this stream closes, the [onDone] handler is called.
    *
-   * If [unsubscribeOnError] is true, the subscription is ended when
+   * If [cancelOnError] is true, the subscription is ended when
    * the first error is reported. The default is false.
    */
   StreamSubscription<T> listen(void onData(T event),
-                               { void onError(AsyncError error),
+                               { void onError(error),
                                  void onDone(),
-                                 bool unsubscribeOnError});
+                                 bool cancelOnError});
 
   /**
    * Creates a new stream from this stream that discards some data events.
@@ -217,7 +215,7 @@
    * [Stream.transformEvent] to handle the event by writing a data event to
    * the output sink
    */
-  Stream<T> handleError(void handle(AsyncError error), { bool test(error) }) {
+  Stream<T> handleError(void handle( error), { bool test(error) }) {
     return new _HandleErrorStream<T>(this, handle, test);
   }
 
@@ -237,9 +235,7 @@
    * Binds this stream as the input of the provided [StreamConsumer].
    */
   Future pipe(StreamConsumer<T> streamConsumer) {
-    // TODO(floitsch): switch to:
-    // streamConsumer.addStream(this).then((_) => streamConsumer.close());
-    return streamConsumer.consume(this);
+    return streamConsumer.addStream(this).then((_) => streamConsumer.close());
   }
 
   /**
@@ -275,12 +271,12 @@
       onError: result._setError,
       onDone: () {
         if (!seenFirst) {
-          result._setError(new AsyncError(new StateError("No elements")));
+          result._setError(new StateError("No elements"));
         } else {
           result._setValue(value);
         }
       },
-      unsubscribeOnError: true
+      cancelOnError: true
     );
     return result;
   }
@@ -300,13 +296,13 @@
           _cancelAndError(subscription, result)
         );
       },
-      onError: (AsyncError e) {
+      onError: (e) {
         result._setError(e);
       },
       onDone: () {
         result._setValue(value);
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return result;
   }
 
@@ -338,7 +334,7 @@
         onDone: () {
           future._setValue(false);
         },
-        unsubscribeOnError: true);
+        cancelOnError: true);
     return future;
   }
 
@@ -370,7 +366,7 @@
         onDone: () {
           future._setValue(true);
         },
-        unsubscribeOnError: true);
+        cancelOnError: true);
     return future;
   }
 
@@ -402,7 +398,7 @@
         onDone: () {
           future._setValue(false);
         },
-        unsubscribeOnError: true);
+        cancelOnError: true);
     return future;
   }
 
@@ -417,7 +413,7 @@
       onDone: () {
         future._setValue(count);
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -434,7 +430,7 @@
       onDone: () {
         future._setValue(true);
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -452,7 +448,7 @@
       onDone: () {
         future._setValue(result);
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -470,7 +466,7 @@
       onDone: () {
         future._setValue(result);
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -550,9 +546,9 @@
       },
       onError: future._setError,
       onDone: () {
-        future._setError(new AsyncError(new StateError("No elements")));
+        future._setError(new StateError("No elements"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -579,9 +575,9 @@
           future._setValue(result);
           return;
         }
-        future._setError(new AsyncError(new StateError("No elements")));
+        future._setError(new StateError("No elements"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -603,7 +599,7 @@
           subscription.cancel();
           // This is the second element we get.
           Error error = new StateError("More than one element");
-          future._setError(new AsyncError(error));
+          future._setError(error);
           return;
         }
         foundResult = true;
@@ -615,9 +611,9 @@
           future._setValue(result);
           return;
         }
-        future._setError(new AsyncError(new StateError("No elements")));
+        future._setError(new StateError("No elements"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -659,10 +655,9 @@
           _runUserCode(defaultValue, future._setValue, future._setError);
           return;
         }
-        future._setError(
-            new AsyncError(new StateError("firstMatch ended without match")));
+        future._setError(new StateError("firstMatch ended without match"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -703,10 +698,9 @@
           _runUserCode(defaultValue, future._setValue, future._setError);
           return;
         }
-        future._setError(
-            new AsyncError(new StateError("lastMatch ended without match")));
+        future._setError(new StateError("lastMatch ended without match"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -731,8 +725,8 @@
             if (isMatch) {
               if (foundResult) {
                 subscription.cancel();
-                future._setError(new AsyncError(
-                    new StateError('Multiple matches for "single"')));
+                future._setError(
+                    new StateError('Multiple matches for "single"'));
                 return;
               }
               foundResult = true;
@@ -748,10 +742,9 @@
           future._setValue(result);
           return;
         }
-        future._setError(
-            new AsyncError(new StateError("single ended without match")));
+        future._setError(new StateError("single ended without match"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 
@@ -780,10 +773,9 @@
       },
       onError: future._setError,
       onDone: () {
-        future._setError(new AsyncError(
-            new StateError("Not enough elements for elementAt")));
+        future._setError(new StateError("Not enough elements for elementAt"));
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return future;
   }
 }
@@ -809,7 +801,7 @@
   void onData(void handleData(T data));
 
   /** Set or override the error event handler of this subscription. */
-  void onError(void handleError(AsyncError error));
+  void onError(void handleError(error));
 
   /** Set or override the done event handler of this subscription. */
   void onDone(void handleDone());
@@ -832,6 +824,20 @@
    * Resume after a pause.
    */
   void resume();
+
+  /**
+   * Returns a future that handles the [onDone] and [onError] callbacks.
+   *
+   * This method *overwrites* the existing [onDone] and [onError] callbacks
+   * with new ones that complete the returned future.
+   *
+   * In case of an error the subscription will automatically cancel (even
+   * when it was listening with `cancelOnError` set to `false`).
+   *
+   * In case of a `done` event the future completes with the given
+   * [futureValue].
+   */
+  Future asFuture([var futureValue]);
 }
 
 
@@ -842,7 +848,7 @@
   /** Create a data event */
   void add(T event);
   /** Create an async error. */
-  void addError(AsyncError errorEvent);
+  void addError(errorEvent);
   /** Request a stream to close. */
   void close();
 }
@@ -859,24 +865,24 @@
   Stream<T> asBroadcastStream() => _stream.asBroadcastStream();
 
   StreamSubscription<T> listen(void onData(T value),
-                               { void onError(AsyncError error),
+                               { void onError(error),
                                  void onDone(),
-                                 bool unsubscribeOnError }) {
+                                 bool cancelOnError }) {
     return _stream.listen(onData, onError: onError, onDone: onDone,
-                          unsubscribeOnError: unsubscribeOnError);
+                          cancelOnError: cancelOnError);
   }
 }
 
 /**
  * [EventSink] wrapper that only exposes the [EventSink] interface.
  */
-class EventSinkView<T> extends EventSink<T> {
+class _EventSinkView<T> extends EventSink<T> {
   final EventSink<T> _sink;
 
-  EventSinkView(this._sink);
+  _EventSinkView(this._sink);
 
   void add(T value) { _sink.add(value); }
-  void addError(AsyncError error) { _sink.addError(error); }
+  void addError(error) { _sink.addError(error); }
   void close() { _sink.close(); }
 }
 
@@ -891,12 +897,41 @@
 abstract class StreamConsumer<S> {
   Future addStream(Stream<S> stream);
   Future close();
+}
 
 
+/**
+ * A [StreamSink] unifies the asynchronous methods from [StreamConsumer<S>] and
+ * the synchronous methods from [EventSink<S>].
+ *
+ * The [EventSink<S>] methods can't be used while the [addStream] is called.
+ * As soon as the [addStream]'s [Future] completes with a value, the
+ * [EventSink<S>] methods can be used again.
+ *
+ * If [addStream] is called after any of the [EventSink<S>] methods, it'll
+ * be delayed until the underlying system has consumed the data added by the
+ * [EventSink<S>] methods.
+ *
+ * When [EventSink<S>] methods are used, the [done] [Future] can be used to
+ * catch any errors.
+ *
+ * When [close] is called, it will return the [done] [Future].
+ */
+abstract class StreamSink<S> implements StreamConsumer<S>, EventSink<S> {
+  /**
+   * Close the [StreamSink<S>]. It'll return the [done] Future.
+   */
+  Future close();
+
   /**
-   * Consume is deprecated. Use [addStream] followed by [close] instead.
+   * The [done] Future completes with the same values as [close], except
+   * for the following case:
+   *
+   * * The synchronous methods of [EventSink<S>] were called, resulting in an
+   *   error. If there is no active future (like from an addStream call), the
+   *   [done] future will complete with that error
    */
-  Future consume(Stream<S> stream);
+  Future get done;
 }
 
 
@@ -926,7 +961,7 @@
    */
   factory StreamTransformer({
       void handleData(S data, EventSink<T> sink),
-      void handleError(AsyncError error, EventSink<T> sink),
+      void handleError(error, EventSink<T> sink),
       void handleDone(EventSink<T> sink)}) {
     return new _StreamTransformerImpl<S, T>(handleData,
                                             handleError,
@@ -973,23 +1008,15 @@
     StreamController controller;
     StreamSubscription subscription;
     controller = new StreamController<T>(
-        onPauseStateChange: () {
-          if (controller.isPaused) {
-            subscription.pause();
-          } else {
-            subscription.resume();
-          }
+        onListen: () {
+          subscription = transformingStream.listen(
+              controller.add,
+              onError: controller.addError,
+              onDone: controller.close);
         },
-        onSubscriptionStateChange: () {
-          if (controller.hasListener) {
-            subscription = transformingStream.listen(
-                controller.add,
-                onError: controller.addError,
-                onDone: controller.close);
-          } else {
-            subscription.cancel();
-          }
-        });
+        onPause: () => subscription.pause(),
+        onResume: () => subscription.resume(),
+        onCancel: () => subscription.cancel());
     return controller.stream;
   }
 
@@ -1010,7 +1037,7 @@
    * The method may generate any number of events on the sink, but should
    * not throw.
    */
-  void handleError(AsyncError error, EventSink<T> sink) {
+  void handleError(error, EventSink<T> sink) {
     sink.addError(error);
   }
 
@@ -1042,13 +1069,13 @@
       : _source = source, _transformer = transformer;
 
   StreamSubscription<T> listen(void onData(T data),
-                               { void onError(AsyncError error),
+                               { void onError(error),
                                  void onDone(),
-                                 bool unsubscribeOnError }) {
-    unsubscribeOnError = identical(true, unsubscribeOnError);
+                                 bool cancelOnError }) {
+    cancelOnError = identical(true, cancelOnError);
     return new _EventTransformStreamSubscription(_source, _transformer,
                                                  onData, onError, onDone,
-                                                 unsubscribeOnError);
+                                                 cancelOnError);
   }
 }
 
@@ -1058,7 +1085,7 @@
   /** The transformer used to transform events. */
   final StreamEventTransformer<S, T> _transformer;
   /** Whether to unsubscribe when emitting an error. */
-  final bool _unsubscribeOnError;
+  final bool _cancelOnError;
   /** Whether this stream has sent a done event. */
   bool _isClosed = false;
   /** Source of incoming events. */
@@ -1069,9 +1096,9 @@
   _EventTransformStreamSubscription(Stream<S> source,
                                     this._transformer,
                                     void onData(T data),
-                                    void onError(AsyncError error),
+                                    void onError(error),
                                     void onDone(),
-                                    this._unsubscribeOnError)
+                                    this._cancelOnError)
       : super(onData, onError, onDone) {
     _sink = new _EventOutputSinkWrapper<T>(this);
     _subscription = source.listen(_handleData,
@@ -1107,11 +1134,11 @@
     }
   }
 
-  void _handleError(AsyncError error) {
+  void _handleError(error) {
     try {
       _transformer.handleError(error, _sink);
     } catch (e, s) {
-      _sendError(_asyncError(e, s, error));
+      _sendError(_asyncError(e, s));
     }
   }
 
@@ -1130,10 +1157,10 @@
     _onData(data);
   }
 
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     if (_isClosed) return;
     _onError(error);
-    if (_unsubscribeOnError) {
+    if (_cancelOnError) {
       cancel();
     }
   }
@@ -1154,6 +1181,6 @@
   _EventOutputSinkWrapper(this._sink);
 
   void add(T data) { _sink._sendData(data); }
-  void addError(AsyncError error) { _sink._sendError(error); }
+  void addError(error) { _sink._sendError(error); }
   void close() { _sink._sendDone(); }
 }
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 24a9999..3e7dbdc 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -50,44 +50,37 @@
   final _StreamImpl<T> stream;
 
   /**
-   * A controller with a broadcast [stream]..
    *
-   * The [onPauseStateChange] function is called when the stream becomes
-   * paused or resumes after being paused. The current pause state can
-   * be read from [isPaused]. Ignored if [:null:].
-   *
-   * The [onSubscriptionStateChange] function is called when the stream
-   * receives its first listener or loses its last. The current subscription
-   * state can be read from [hasListener]. Ignored if [:null:].
-   */
-  StreamController.broadcast({void onPauseStateChange(),
-                              void onSubscriptionStateChange()})
-      : stream = new _MultiControllerStream<T>(onSubscriptionStateChange,
-                                               onPauseStateChange);
-
-  /**
+   * If the stream is canceled before the controller needs new data the
+   * [onResume] call might not be executed.
+      : stream = new _MultiControllerStream<T>(
+            onListen, onPause, onResume, onCancel);
    * A controller with a [stream] that supports only one single subscriber.
    *
    * The controller will buffer all incoming events until the subscriber is
    * registered.
    *
-   * The [onPauseStateChange] function is called when the stream becomes
-   * paused or resumes after being paused. The current pause state can
-   * be read from [isPaused]. Ignored if [:null:].
+   * The [onPause] function is called when the stream becomes
+   * paused. [onResume] is called when the stream resumed.
    *
-   * The [onSubscriptionStateChange] function is called when the stream
-   * receives its first listener or loses its last. The current subscription
-   * state can be read from [hasListener]. Ignored if [:null:].
+   * The [onListen] callback is called when the stream
+   * receives its listener. [onCancel] when the listener cancels
+   * its subscription.
+   *
+   * If the stream is canceled before the controller needs new data the
+   * [onResume] call might not be executed.
    */
-  StreamController({void onPauseStateChange(),
-                    void onSubscriptionStateChange()})
-      : stream = new _SingleControllerStream<T>(onSubscriptionStateChange,
-                                                onPauseStateChange);
+  StreamController({void onListen(),
+                    void onPause(),
+                    void onResume(),
+                    void onCancel()})
+      : stream = new _SingleControllerStream<T>(
+            onListen, onPause, onResume, onCancel);
 
   /**
    * Returns a view of this object that only exposes the [EventSink] interface.
    */
-  EventSink<T> get sink => new EventSinkView<T>(this);
+  EventSink<T> get sink => new _EventSinkView<T>(this);
 
   /**
    * Whether the stream is closed for adding more events.
@@ -111,23 +104,16 @@
   /**
    * Send or enqueue an error event.
    *
-   * If [error] is not an [AsyncError], [error] and an optional [stackTrace]
-   * is combined into an [AsyncError] and sent this stream's listeners.
-   *
-   * Otherwise, if [error] is an [AsyncError], it is used directly as the
-   * error object reported to listeners, and the [stackTrace] is ignored.
-   *
    * If a subscription has requested to be unsubscribed on errors,
    * it will be unsubscribed after receiving this event.
    */
   void addError(Object error, [Object stackTrace]) {
-    AsyncError asyncError;
-    if (error is AsyncError) {
-      asyncError = error;
-    } else {
-      asyncError = new AsyncError(error, stackTrace);
+    if (stackTrace != null) {
+      // Force stack trace overwrite. Even if the error already contained
+      // a stack trace.
+      _attachStackTrace(error, stackTrace);
     }
-    stream._addError(asyncError);
+    stream._addError(error);
   }
 
   /**
@@ -141,56 +127,32 @@
 
 typedef void _NotificationHandler();
 
-class _MultiControllerStream<T> extends _MultiStreamImpl<T> {
-  _NotificationHandler _subscriptionHandler;
-  _NotificationHandler _pauseHandler;
-
-  _MultiControllerStream(this._subscriptionHandler, this._pauseHandler);
-
-  void _onSubscriptionStateChange() {
-    if (_subscriptionHandler != null) {
-      try {
-        _subscriptionHandler();
-      } catch (e, s) {
-        new AsyncError(e, s).throwDelayed();
-      }
-    }
-  }
-
-  void _onPauseStateChange() {
-    if (_pauseHandler != null) {
-      try {
-        _pauseHandler();
-      } catch (e, s) {
-        new AsyncError(e, s).throwDelayed();
-      }
-    }
-  }
-}
-
 class _SingleControllerStream<T> extends _SingleStreamImpl<T> {
-  _NotificationHandler _subscriptionHandler;
-  _NotificationHandler _pauseHandler;
+  _NotificationHandler _onListen;
+  _NotificationHandler _onPause;
+  _NotificationHandler _onResume;
+  _NotificationHandler _onCancel;
 
-  _SingleControllerStream(this._subscriptionHandler, this._pauseHandler);
-
-  void _onSubscriptionStateChange() {
-    if (_subscriptionHandler != null) {
-      try {
-        _subscriptionHandler();
-      } catch (e, s) {
-        new AsyncError(e, s).throwDelayed();
-      }
+  // TODO(floitsch): share this code with _MultiControllerStream.
+  _runGuarded(_NotificationHandler notificationHandler) {
+    if (notificationHandler == null) return;
+    try {
+      notificationHandler();
+    } catch (e, s) {
+      _throwDelayed(e, s);
     }
   }
 
+  _SingleControllerStream(this._onListen,
+                          this._onPause,
+                          this._onResume,
+                          this._onCancel);
+
+  void _onSubscriptionStateChange() {
+    _runGuarded(_hasListener ? _onListen : _onCancel);
+  }
+
   void _onPauseStateChange() {
-    if (_pauseHandler != null) {
-      try {
-        _pauseHandler();
-      } catch (e, s) {
-        new AsyncError(e, s).throwDelayed();
-      }
-    }
+    _runGuarded(_isPaused ? _onPause : _onResume);
   }
 }
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index e6de3d7..8fa1848 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -55,6 +55,20 @@
 /// state, shifted by this amount.
 const int _LISTENER_PAUSE_COUNT_SHIFT = 3;
 
+/** Throws the given error in the next cycle. */
+_throwDelayed(var error, [Object stackTrace]) {
+  // We are going to reach the top-level here, but there might be a global
+  // exception handler. This means that we shouldn't print the stack trace.
+  // TODO(floitsch): Find better solution that doesn't print the stack trace
+  // if there is a global exception handler.
+  runAsync(() {
+    if (stackTrace != null) print(stackTrace);
+    var trace = getAttachedStackTrace(error);
+    if (trace != null && trace != stackTrace) print(trace);
+    throw error;
+  });
+}
+
 
 // -------------------------------------------------------------------
 // Common base class for single and multi-subscription streams.
@@ -77,18 +91,18 @@
   // Stream interface.
 
   StreamSubscription<T> listen(void onData(T data),
-                               { void onError(AsyncError error),
+                               { void onError(error),
                                  void onDone(),
-                                 bool unsubscribeOnError }) {
+                                 bool cancelOnError }) {
     if (_isComplete) {
       return new _DoneSubscription(onDone);
     }
     if (onData == null) onData = _nullDataHandler;
     if (onError == null) onError = _nullErrorHandler;
     if (onDone == null) onDone = _nullDoneHandler;
-    unsubscribeOnError = identical(true, unsubscribeOnError);
+    cancelOnError = identical(true, cancelOnError);
     _StreamSubscriptionImpl subscription =
-        _createSubscription(onData, onError, onDone, unsubscribeOnError);
+        _createSubscription(onData, onError, onDone, cancelOnError);
     _addListener(subscription);
     return subscription;
   }
@@ -123,7 +137,7 @@
    * If a subscription has requested to be unsubscribed on errors,
    * it will be unsubscribed after receiving this event.
    */
-  void _addError(AsyncError error) {
+  void _addError(error) {
     if (_isClosed) throw new StateError("Sending on closed stream");
     if (!_mayFireState) {
       // Not the time to send events.
@@ -374,9 +388,9 @@
   /** Create a subscription object. Called by [subcribe]. */
   _StreamSubscriptionImpl<T> _createSubscription(
       void onData(T data),
-      void onError(AsyncError error),
+      void onError(error),
       void onDone(),
-      bool unsubscribeOnError);
+      bool cancelOnError);
 
   /**
    * Adds a listener to this stream.
@@ -493,10 +507,8 @@
     _forEachSubscriber((subscriber) {
       try {
         subscriber._sendData(value);
-      } on AsyncError catch (e) {
-        e.throwDelayed();
       } catch (e, s) {
-        new AsyncError(e, s).throwDelayed();
+        _throwDelayed(e, s);
       }
     });
   }
@@ -504,17 +516,15 @@
   /**
    * Sends an error event directly to each subscriber.
    */
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     assert(!_isPaused);
     assert(!_isComplete);
     if (!_hasListener) return;
     _forEachSubscriber((subscriber) {
       try {
         subscriber._sendError(error);
-      } on AsyncError catch (e) {
-        e.throwDelayed();
       } catch (e, s) {
-        new AsyncError.withCause(e, s, error).throwDelayed();
+        _throwDelayed(e, s);
       }
     });
   }
@@ -533,10 +543,8 @@
       _cancel(subscriber);
       try {
         subscriber._sendDone();
-      } on AsyncError catch (e) {
-        e.throwDelayed();
       } catch (e, s) {
-        new AsyncError(e, s).throwDelayed();
+        _throwDelayed(e, s);
       }
     });
     assert(!_hasListener);
@@ -592,11 +600,11 @@
    */
   _StreamSubscriptionImpl<T> _createSubscription(
       void onData(T data),
-      void onError(AsyncError error),
+      void onError(error),
       void onDone(),
-      bool unsubscribeOnError) {
+      bool cancelOnError) {
     return new _StreamSubscriptionImpl<T>(
-        this, onData, onError, onDone, unsubscribeOnError);
+        this, onData, onError, onDone, cancelOnError);
   }
 
   void _addListener(_StreamListener subscription) {
@@ -712,11 +720,11 @@
    */
   _StreamListener<T> _createSubscription(
       void onData(T data),
-      void onError(AsyncError error),
+      void onError(error),
       void onDone(),
-      bool unsubscribeOnError) {
+      bool cancelOnError) {
     return new _StreamSubscriptionImpl<T>(
-        this, onData, onError, onDone, unsubscribeOnError);
+        this, onData, onError, onDone, cancelOnError);
   }
 
   // -------------------------------------------------------------------
@@ -841,7 +849,7 @@
     throw new UnsupportedError("Cannot inject events into generated stream");
   }
 
-  void _addError(AsyncError value) {
+  void _addError(value) {
     throw new UnsupportedError("Cannot inject events into generated stream");
   }
 
@@ -876,7 +884,7 @@
         stream._sendDone();
       }
     } catch (e, s) {
-      stream._sendError(new AsyncError(e, s));
+      stream._sendError(_asyncError(e, s));
       stream._sendDone();
       _isDone = true;
     }
@@ -901,7 +909,7 @@
  */
 class _StreamSubscriptionImpl<T> extends _StreamListener<T>
                                  implements StreamSubscription<T> {
-  final bool _unsubscribeOnError;
+  final bool _cancelOnError;
   // TODO(ahe): Restore type when feature is implemented in dart2js
   // checked mode. http://dartbug.com/7733
   var /* _DataHandler<T> */ _onData;
@@ -911,14 +919,14 @@
                           this._onData,
                           this._onError,
                           this._onDone,
-                          this._unsubscribeOnError) : super(source);
+                          this._cancelOnError) : super(source);
 
   void onData(void handleData(T event)) {
     if (handleData == null) handleData = _nullDataHandler;
     _onData = handleData;
   }
 
-  void onError(void handleError(AsyncError error)) {
+  void onError(void handleError(error)) {
     if (handleError == null) handleError = _nullErrorHandler;
     _onError = handleError;
   }
@@ -932,9 +940,9 @@
     _onData(data);
   }
 
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     _onError(error);
-    if (_unsubscribeOnError) _source._cancel(this);
+    if (_cancelOnError) _source._cancel(this);
   }
 
   void _sendDone() {
@@ -955,13 +963,26 @@
     if (!_isSubscribed || !isPaused) return;
     _source._resume(this, false);
   }
+
+  Future asFuture([var futureValue]) {
+    _FutureImpl<T> result = new _FutureImpl<T>();
+
+    // Overwrite the onDone and onError handlers.
+    onDone(() { result._setValue(futureValue); });
+    onError((error) {
+      cancel();
+      result._setError(error);
+    });
+
+    return result;
+  }
 }
 
 // Internal helpers.
 
 // Types of the different handlers on a stream. Types used to type fields.
 typedef void _DataHandler<T>(T value);
-typedef void _ErrorHandler(AsyncError error);
+typedef void _ErrorHandler(error);
 typedef void _DoneHandler();
 
 
@@ -969,8 +990,8 @@
 void _nullDataHandler(var value) {}
 
 /** Default error handler, reports the error to the global handler. */
-void _nullErrorHandler(AsyncError error) {
-  error.throwDelayed();
+void _nullErrorHandler(error) {
+  _throwDelayed(error);
 }
 
 /** Default done handler, does nothing. */
@@ -987,7 +1008,7 @@
 
 /** A delayed data event. */
 class _DelayedData<T> extends _DelayedEvent{
-  T value;
+  final T value;
   _DelayedData(this.value);
   void perform(_StreamImpl<T> stream) {
     stream._sendData(value);
@@ -996,7 +1017,7 @@
 
 /** A delayed error event. */
 class _DelayedError extends _DelayedEvent {
-  AsyncError error;
+  final error;
   _DelayedError(this.error);
   void perform(_StreamImpl stream) {
     stream._sendError(error);
@@ -1100,7 +1121,7 @@
 /** Abstract type for an internal interface for sending events. */
 abstract class _EventOutputSink<T> {
   _sendData(T data);
-  _sendError(AsyncError error);
+  _sendError(error);
   _sendDone();
 }
 
@@ -1175,7 +1196,7 @@
   }
 
   _sendData(T data);
-  _sendError(AsyncError error);
+  _sendError(error);
   _sendDone();
 }
 
@@ -1263,7 +1284,7 @@
 
   void onData(void handleAction(T value)) {}
 
-  void onError(void handleError(AsyncError error)) {}
+  void onError(void handleError(error)) {}
 
   void onDone(void handleDone()) {
     _handler = handleDone;
@@ -1298,6 +1319,20 @@
     }
     _pauseCount = 0;
   }
+
+  Future asFuture([var futureValue]) {
+    // TODO(floitsch): share more code.
+    _FutureImpl<T> result = new _FutureImpl<T>();
+
+    // Overwrite the onDone and onError handlers.
+    onDone(() { result._setValue(futureValue); });
+    onError((error) {
+      cancel();
+      result._setError(error);
+    });
+
+    return result;
+  }
 }
 
 class _SingleStreamMultiplexer<T> extends _MultiStreamImpl<T> {
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index aa3da2a..4e40a61 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -4,36 +4,29 @@
 
 part of dart.async;
 
-/** Utility function to create an [AsyncError] if [error] isn't one already. */
-AsyncError _asyncError(Object error, Object stackTrace, [AsyncError cause]) {
-  if (error is AsyncError) return error;
-  if (cause == null) return new AsyncError(error, stackTrace);
-  return new AsyncError.withCause(error, stackTrace, cause);
+/**
+ * Utility function to attach a stack trace to an [error]  if it doesn't have
+ * one already.
+ */
+_asyncError(Object error, Object stackTrace) {
+  if (stackTrace == null) return error;
+  if (getAttachedStackTrace(error) != null) return error;
+  _attachStackTrace(error, stackTrace);
+  return error;
 }
 
 /** Runs user code and takes actions depending on success or failure. */
-_runUserCode(userCode(), onSuccess(value), onError(AsyncError error),
-             { AsyncError cause }) {
-  var result;
+_runUserCode(userCode(), onSuccess(value), onError(error)) {
   try {
-    result = userCode();
-  } on AsyncError catch (e) {
-    return onError(e);
+    onSuccess(userCode());
   } catch (e, s) {
-    if (cause == null) {
-      onError(new AsyncError(e, s));
-    } else {
-      onError(new AsyncError.withCause(e, s, cause));
-    }
-    // onError is allowed to return. Don't execute the onSuccess below.
-    return;
+    onError(_asyncError(e, s));
   }
-  onSuccess(result);
 }
 
 /** Helper function to make an onError argument to [_runUserCode]. */
 _cancelAndError(StreamSubscription subscription, _FutureImpl future) =>
-  (AsyncError error) {
+  (error) {
     subscription.cancel();
     future._setError(error);
   };
@@ -56,22 +49,22 @@
   bool get isBroadcast => _source.isBroadcast;
 
   StreamSubscription<T> listen(void onData(T value),
-                              { void onError(AsyncError error),
+                              { void onError(error),
                                 void onDone(),
-                                bool unsubscribeOnError }) {
+                                bool cancelOnError }) {
     if (onData == null) onData = _nullDataHandler;
     if (onError == null) onError = _nullErrorHandler;
     if (onDone == null) onDone = _nullDoneHandler;
-    unsubscribeOnError = identical(true, unsubscribeOnError);
-    return _createSubscription(onData, onError, onDone, unsubscribeOnError);
+    cancelOnError = identical(true, cancelOnError);
+    return _createSubscription(onData, onError, onDone, cancelOnError);
   }
 
   StreamSubscription<T> _createSubscription(void onData(T value),
-                                            void onError(AsyncError error),
+                                            void onError(error),
                                             void onDone(),
-                                            bool unsubscribeOnError) {
+                                            bool cancelOnError) {
     return new _ForwardingStreamSubscription<S, T>(
-        this, onData, onError, onDone, unsubscribeOnError);
+        this, onData, onError, onDone, cancelOnError);
   }
 
   // Override the following methods in subclasses to change the behavior.
@@ -81,7 +74,7 @@
     sink._sendData(outputData);
   }
 
-  void _handleError(AsyncError error, _EventOutputSink<T> sink) {
+  void _handleError(error, _EventOutputSink<T> sink) {
     sink._sendError(error);
   }
 
@@ -116,7 +109,7 @@
     _onData = handleData;
   }
 
-  void onError(void handleError(AsyncError error)) {
+  void onError(void handleError(error)) {
     if (handleError == null) handleError = _nullErrorHandler;
     _onError = handleError;
   }
@@ -131,6 +124,19 @@
   void resume();
 
   void cancel();
+
+  Future asFuture([var futureValue]) {
+    _FutureImpl<T> result = new _FutureImpl<T>();
+
+    // Overwrite the onDone and onError handlers.
+    onDone(() { result._setValue(futureValue); });
+    onError((error) {
+      cancel();
+      result._setError(error);
+    });
+
+    return result;
+  }
 }
 
 
@@ -140,15 +146,15 @@
 class _ForwardingStreamSubscription<S, T>
     extends _BaseStreamSubscription<T> implements _EventOutputSink<T> {
   final _ForwardingStream<S, T> _stream;
-  final bool _unsubscribeOnError;
+  final bool _cancelOnError;
 
   StreamSubscription<S> _subscription;
 
   _ForwardingStreamSubscription(this._stream,
                                 void onData(T data),
-                                void onError(AsyncError error),
+                                void onError(error),
                                 void onDone(),
-                                this._unsubscribeOnError)
+                                this._cancelOnError)
       : super(onData, onError, onDone) {
     // Don't unsubscribe on incoming error, only if we send an error forwards.
     _subscription =
@@ -182,9 +188,9 @@
     _onData(data);
   }
 
-  void _sendError(AsyncError error) {
+  void _sendError(error) {
     _onError(error);
-    if (_unsubscribeOnError) {
+    if (_cancelOnError) {
       _subscription.cancel();
       _subscription = null;
     }
@@ -207,7 +213,7 @@
     _stream._handleData(data, this);
   }
 
-  void _handleError(AsyncError error) {
+  void _handleError(error) {
     _stream._handleError(error, this);
   }
 
@@ -291,7 +297,7 @@
 }
 
 
-typedef void _ErrorTransformation(AsyncError error);
+typedef void _ErrorTransformation(error);
 typedef bool _ErrorTest(error);
 
 /**
@@ -303,17 +309,17 @@
   final _ErrorTest _test;
 
   _HandleErrorStream(Stream<T> source,
-                    void transform(AsyncError event),
+                    void transform(event),
                     bool test(error))
       : this._transform = transform, this._test = test, super(source);
 
-  void _handleError(AsyncError error, _EventOutputSink<T> sink) {
+  void _handleError(Object error, _EventOutputSink<T> sink) {
     bool matches = true;
     if (_test != null) {
       try {
-        matches = _test(error.error);
+        matches = _test(error);
       } catch (e, s) {
-        sink._sendError(_asyncError(e, s, error));
+        sink._sendError(_asyncError(e, s));
         return;
       }
     }
@@ -321,7 +327,7 @@
       try {
         _transform(error);
       } catch (e, s) {
-        sink._sendError(_asyncError(e, s, error));
+        sink._sendError(_asyncError(e, s));
         return;
       }
     } else {
@@ -463,7 +469,7 @@
 // Stream transformations and event transformations.
 
 typedef void _TransformDataHandler<S, T>(S data, EventSink<T> sink);
-typedef void _TransformErrorHandler<T>(AsyncError data, EventSink<T> sink);
+typedef void _TransformErrorHandler<T>(data, EventSink<T> sink);
 typedef void _TransformDoneHandler<T>(EventSink<T> sink);
 
 /** Default data handler forwards all data. */
@@ -472,7 +478,7 @@
 }
 
 /** Default error handler forwards all errors. */
-void _defaultHandleError(AsyncError error, EventSink sink) {
+void _defaultHandleError(error, EventSink sink) {
   sink.addError(error);
 }
 
@@ -500,7 +506,7 @@
   final _TransformDoneHandler<T> _handleDone;
 
   _StreamTransformerImpl(void handleData(S data, EventSink<T> sink),
-                         void handleError(AsyncError data, EventSink<T> sink),
+                         void handleError(data, EventSink<T> sink),
                          void handleDone(EventSink<T> sink))
       : this._handleData  = (handleData == null  ? _defaultHandleData
                                                  : handleData),
@@ -513,7 +519,7 @@
     _handleData(data, sink);
   }
 
-  void handleError(AsyncError error, EventSink<T> sink) {
+  void handleError(error, EventSink<T> sink) {
     _handleError(error, sink);
   }
 
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index 8a7fdb0..b321e41 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -46,7 +46,10 @@
    * Runs the given [callback] asynchronously as soon as possible.
    */
   static void run(void callback()) {
-    schedule() {
+    // Optimizing a group of Timer.run callbacks to be executed in the
+    // same Timer callback.
+    _runCallbacks.add(callback);
+    if (_runCallbacks.length == 1) {
       new Timer(const Duration(milliseconds: 0), () {
         List runCallbacks = _runCallbacks;
         // Create new list to make sure we don't call newly added callbacks in
@@ -63,17 +66,11 @@
             _runCallbacks.addAll(
                 runCallbacks.sublist(i));
             _runCallbacks.addAll(newCallbacks);
-            if (!_runCallbacks.isEmpty) schedule();
             throw;
           }
         }
       });
     }
-
-    // Optimizing a group of Timer.run callbacks to be executed in the
-    // same Timer callback.
-    _runCallbacks.add(callback);
-    if (_runCallbacks.length == 1) schedule();
   }
 
   /**
diff --git a/sdk/lib/collection/collection.dart b/sdk/lib/collection/collection.dart
index 0bbd8f2..03287d7 100644
--- a/sdk/lib/collection/collection.dart
+++ b/sdk/lib/collection/collection.dart
@@ -7,6 +7,7 @@
 import 'dart:_collection-dev';
 
 part 'collections.dart';
+part 'iterable.dart';
 part 'iterator.dart';
 part 'maps.dart';
 part 'queue.dart';
diff --git a/sdk/lib/collection/collection_sources.gypi b/sdk/lib/collection/collection_sources.gypi
index 84259ef..7fe56d8 100644
--- a/sdk/lib/collection/collection_sources.gypi
+++ b/sdk/lib/collection/collection_sources.gypi
@@ -10,6 +10,7 @@
     'collections.dart',
     'hash_map.dart',
     'hash_set.dart',
+    'iterable.dart',
     'iterator.dart',
     'linked_hash_map.dart',
     'linked_hash_set.dart',
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index 400ce90..2f00717 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -5,329 +5,6 @@
 part of dart.collection;
 
 /**
- * This class provides default implementations for Iterables (including Lists).
- *
- * Once Dart receives Mixins it will be replaced with mixin classes.
- */
-@deprecated
-class IterableMixinWorkaround {
-  static bool contains(Iterable iterable, var element) {
-    for (final e in iterable) {
-      if (element == e) return true;
-    }
-    return false;
-  }
-
-  static void forEach(Iterable iterable, void f(o)) {
-    for (final e in iterable) {
-      f(e);
-    }
-  }
-
-  static bool any(Iterable iterable, bool f(o)) {
-    for (final e in iterable) {
-      if (f(e)) return true;
-    }
-    return false;
-  }
-
-  static bool every(Iterable iterable, bool f(o)) {
-    for (final e in iterable) {
-      if (!f(e)) return false;
-    }
-    return true;
-  }
-
-  static dynamic reduce(Iterable iterable,
-                        dynamic combine(previousValue, element)) {
-    Iterator iterator = iterable.iterator;
-    if (!iterator.moveNext()) throw new StateError("No elements");
-    var value = iterator.current;
-    while (iterator.moveNext()) {
-      value = combine(value, iterator.current);
-    }
-    return value;
-  }
-
-  static dynamic fold(Iterable iterable,
-                      dynamic initialValue,
-                      dynamic combine(dynamic previousValue, element)) {
-    for (final element in iterable) {
-      initialValue = combine(initialValue, element);
-    }
-    return initialValue;
-  }
-
-  /**
-   * Removes elements matching [test] from [list].
-   *
-   * This is performed in two steps, to avoid exposing an inconsistent state
-   * to the [test] function. First the elements to retain are found, and then
-   * the original list is updated to contain those elements.
-   */
-  static void removeWhereList(List list, bool test(var element)) {
-    List retained = [];
-    int length = list.length;
-    for (int i = 0; i < length; i++) {
-      var element = list[i];
-      if (!test(element)) {
-        retained.add(element);
-      }
-      if (length != list.length) {
-        throw new ConcurrentModificationError(list);
-      }
-    }
-    if (retained.length == length) return;
-    list.length = retained.length;
-    for (int i = 0; i < retained.length; i++) {
-      list[i] = retained[i];
-    }
-  }
-
-  static bool isEmpty(Iterable iterable) {
-    return !iterable.iterator.moveNext();
-  }
-
-  static dynamic first(Iterable iterable) {
-    Iterator it = iterable.iterator;
-    if (!it.moveNext()) {
-      throw new StateError("No elements");
-    }
-    return it.current;
-  }
-
-  static dynamic last(Iterable iterable) {
-    Iterator it = iterable.iterator;
-    if (!it.moveNext()) {
-      throw new StateError("No elements");
-    }
-    dynamic result;
-    do {
-      result = it.current;
-    } while(it.moveNext());
-    return result;
-  }
-
-  static dynamic single(Iterable iterable) {
-    Iterator it = iterable.iterator;
-    if (!it.moveNext()) throw new StateError("No elements");
-    dynamic result = it.current;
-    if (it.moveNext()) throw new StateError("More than one element");
-    return result;
-  }
-
-  static dynamic firstWhere(Iterable iterable,
-                               bool test(dynamic value),
-                               dynamic orElse()) {
-    for (dynamic element in iterable) {
-      if (test(element)) return element;
-    }
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
-
-  static dynamic lastWhere(Iterable iterable,
-                           bool test(dynamic value),
-                           dynamic orElse()) {
-    dynamic result = null;
-    bool foundMatching = false;
-    for (dynamic element in iterable) {
-      if (test(element)) {
-        result = element;
-        foundMatching = true;
-      }
-    }
-    if (foundMatching) return result;
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
-
-  static dynamic lastWhereList(List list,
-                               bool test(dynamic value),
-                               dynamic orElse()) {
-    // TODO(floitsch): check that arguments are of correct type?
-    for (int i = list.length - 1; i >= 0; i--) {
-      dynamic element = list[i];
-      if (test(element)) return element;
-    }
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
-
-  static dynamic singleWhere(Iterable iterable, bool test(dynamic value)) {
-    dynamic result = null;
-    bool foundMatching = false;
-    for (dynamic element in iterable) {
-      if (test(element)) {
-        if (foundMatching) {
-          throw new StateError("More than one matching element");
-        }
-        result = element;
-        foundMatching = true;
-      }
-    }
-    if (foundMatching) return result;
-    throw new StateError("No matching element");
-  }
-
-  static dynamic elementAt(Iterable iterable, int index) {
-    if (index is! int || index < 0) throw new RangeError.value(index);
-    int remaining = index;
-    for (dynamic element in iterable) {
-      if (remaining == 0) return element;
-      remaining--;
-    }
-    throw new RangeError.value(index);
-  }
-
-  static String join(Iterable iterable, [String separator]) {
-    StringBuffer buffer = new StringBuffer();
-    buffer.writeAll(iterable, separator);
-    return buffer.toString();
-  }
-
-  static String joinList(List list, [String separator]) {
-    if (list.isEmpty) return "";
-    if (list.length == 1) return "${list[0]}";
-    StringBuffer buffer = new StringBuffer();
-    if (separator.isEmpty) {
-      for (int i = 0; i < list.length; i++) {
-        buffer.write(list[i]);
-      }
-    } else {
-      buffer.write(list[0]);
-      for (int i = 1; i < list.length; i++) {
-        buffer.write(separator);
-        buffer.write(list[i]);
-      }
-    }
-    return buffer.toString();
-  }
-
-  static Iterable where(Iterable iterable, bool f(var element)) {
-    return new WhereIterable(iterable, f);
-  }
-
-  static Iterable map(Iterable iterable, f(var element)) {
-    return new MappedIterable(iterable, f);
-  }
-
-  static Iterable mapList(List list, f(var element)) {
-    return new MappedListIterable(list, f);
-  }
-
-  static Iterable expand(Iterable iterable, Iterable f(var element)) {
-    return new ExpandIterable(iterable, f);
-  }
-
-  static Iterable takeList(List list, int n) {
-    // The generic type is currently lost. It will be fixed with mixins.
-    return new SubListIterable(list, 0, n);
-  }
-
-  static Iterable takeWhile(Iterable iterable, bool test(var value)) {
-    // The generic type is currently lost. It will be fixed with mixins.
-    return new TakeWhileIterable(iterable, test);
-  }
-
-  static Iterable skipList(List list, int n) {
-    // The generic type is currently lost. It will be fixed with mixins.
-    return new SubListIterable(list, n, null);
-  }
-
-  static Iterable skipWhile(Iterable iterable, bool test(var value)) {
-    // The generic type is currently lost. It will be fixed with mixins.
-    return new SkipWhileIterable(iterable, test);
-  }
-
-  static Iterable reversedList(List list) {
-    return new ReversedListIterable(list);
-  }
-
-  static void sortList(List list, int compare(a, b)) {
-    if (compare == null) compare = Comparable.compare;
-    Sort.sort(list, compare);
-  }
-
-  static int indexOfList(List list, var element, int start) {
-    return Arrays.indexOf(list, element, start, list.length);
-  }
-
-  static int lastIndexOfList(List list, var element, int start) {
-    if (start == null) start = list.length - 1;
-    return Arrays.lastIndexOf(list, element, start);
-  }
-
-  static Iterable getRangeList(List list, int start, int end) {
-    if (start < 0 || start > list.length) {
-      throw new RangeError.range(start, 0, list.length);
-    }
-    if (end < start || end > list.length) {
-      throw new RangeError.range(end, start, list.length);
-    }
-    // The generic type is currently lost. It will be fixed with mixins.
-    return new SubListIterable(list, start, end);
-  }
-
-  static void setRangeList(List list, int start, int length,
-                           List from, int startFrom) {
-    if (length == 0) return;
-
-    if (length < 0) throw new ArgumentError(length);
-    if (start < 0) throw new RangeError.value(start);
-    if (start + length > list.length) {
-      throw new RangeError.value(start + length);
-    }
-
-    Arrays.copy(from, startFrom, list, start, length);
-  }
-
-  static Map<int, dynamic> asMapList(List l) {
-    return new ListMapView(l);
-  }
-
-  static bool setContainsAll(Set set, Iterable other) {
-    for (var element in other) {
-      if (!set.contains(element)) return false;
-    }
-    return true;
-  }
-
-  static Set setIntersection(Set set, Set other, Set result) {
-    Set smaller;
-    Set larger;
-    if (set.length < other.length) {
-      smaller = set;
-      larger = other;
-    } else {
-      smaller = other;
-      larger = set;
-    }
-    for (var element in smaller) {
-      if (larger.contains(element)) {
-        result.add(element);
-      }
-    }
-    return result;
-  }
-
-  static Set setUnion(Set set, Set other, Set result) {
-    result.addAll(set);
-    result.addAll(other);
-    return result;
-  }
-
-  static Set setDifference(Set set, Set other, Set result) {
-    for (var element in set) {
-      if (!other.contains(element)) {
-        result.add(element);
-      }
-    }
-    return result;
-  }
-}
-
-/**
  * An unmodifiable [List] view of another List.
  *
  * The source of the elements may be a [List] or any [Iterable] with
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index f658b52..c459f99 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -5,7 +5,7 @@
 part of dart.collection;
 
 /** Common parts of [HashSet] and [LinkedHashSet] implementations. */
-abstract class _HashSetBase<E> extends Iterable<E> implements Set<E> {
+abstract class _HashSetBase<E> extends IterableBase<E> implements Set<E> {
   // Set.
   bool containsAll(Iterable<E> other) {
     for (E object in other) {
diff --git a/sdk/lib/collection/iterable.dart b/sdk/lib/collection/iterable.dart
new file mode 100644
index 0000000..2ec143b
--- /dev/null
+++ b/sdk/lib/collection/iterable.dart
@@ -0,0 +1,384 @@
+// 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.collection;
+
+/**
+ * This [Iterable] mixin implements all [Iterable] members except `iterator`.
+ *
+ * All other methods are implemented in terms of `iterator`.
+ */
+abstract class IterableMixin<E> implements Iterable<E> {
+  Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+
+  Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
+
+  Iterable expand(Iterable f(E element)) =>
+      new ExpandIterable<E, dynamic>(this, f);
+
+  bool contains(E element) {
+    for (E e in this) {
+      if (e == element) return true;
+    }
+    return false;
+  }
+
+  void forEach(void f(E element)) {
+    for (E element in this) f(element);
+  }
+
+  E reduce(E combine(E value, E element)) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) {
+      throw new StateError("No elements");
+    }
+    E value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  dynamic fold(var initialValue,
+               dynamic combine(var previousValue, E element)) {
+    var value = initialValue;
+    for (E element in this) value = combine(value, element);
+    return value;
+  }
+
+  bool every(bool f(E element)) {
+    for (E element in this) {
+      if (!f(element)) return false;
+    }
+    return true;
+  }
+
+  String join([String separator]) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) return "";
+    StringBuffer buffer = new StringBuffer();
+    if (separator == null || separator == "") {
+      do {
+        buffer.write("${iterator.current}");
+      } while (iterator.moveNext());
+    } else {
+      buffer.write("${iterator.current}");
+      while (iterator.moveNext()) {
+        buffer.write(separator);
+        buffer.write("${iterator.current}");
+      }
+    }
+    return buffer.toString();
+  }
+
+  bool any(bool f(E element)) {
+    for (E element in this) {
+      if (f(element)) return true;
+    }
+    return false;
+  }
+
+  List<E> toList({ bool growable: true }) =>
+      new List<E>.from(this, growable: growable);
+
+  Set<E> toSet() => new Set<E>.from(this);
+
+  int get length {
+    int count = 0;
+    Iterator it = iterator;
+    while (it.moveNext()) {
+      count++;
+    }
+    return count;
+  }
+
+  bool get isEmpty => !iterator.moveNext();
+
+  Iterable<E> take(int n) {
+    return new TakeIterable<E>(this, n);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return new TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int n) {
+    return new SkipIterable<E>(this, n);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return new SkipWhileIterable<E>(this, test);
+  }
+
+  E get first {
+    Iterator it = iterator;
+    if (!it.moveNext()) {
+      throw new StateError("No elements");
+    }
+    return it.current;
+  }
+
+  E get last {
+    Iterator it = iterator;
+    if (!it.moveNext()) {
+      throw new StateError("No elements");
+    }
+    E result;
+    do {
+      result = it.current;
+    } while(it.moveNext());
+    return result;
+  }
+
+  E get single {
+    Iterator it = iterator;
+    if (!it.moveNext()) throw new StateError("No elements");
+    E result = it.current;
+    if (it.moveNext()) throw new StateError("More than one element");
+    return result;
+  }
+
+  E firstWhere(bool test(E value), { E orElse() }) {
+    // TODO(floitsch): check that arguments are of correct type?
+    for (E element in this) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E lastWhere(bool test(E value), {E orElse()}) {
+    // TODO(floitsch): check that arguments are of correct type?
+    E result = null;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E singleWhere(bool test(E value)) {
+    // TODO(floitsch): check that argument is of correct type?
+    E result = null;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw new StateError("More than one matching element");
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    throw new StateError("No matching element");
+  }
+
+  E elementAt(int index) {
+    if (index is! int || index < 0) throw new RangeError.value(index);
+    int remaining = index;
+    for (E element in this) {
+      if (remaining == 0) return element;
+      remaining--;
+    }
+    throw new RangeError.value(index);
+  }
+}
+
+/**
+ * Base class for implementing [Iterable].
+ *
+ * This class implements all methods of [Iterable] except [Iterable.iterator]
+ * in terms of `iterator`.
+ */
+abstract class IterableBase<E> implements Iterable<E> {
+  // TODO(lrn): Base this on IterableMixin if there ever becomes a way
+  // to combine const constructors and mixins.
+  const IterableBase();
+
+  Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+
+  Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
+
+  Iterable expand(Iterable f(E element)) =>
+      new ExpandIterable<E, dynamic>(this, f);
+
+  bool contains(E element) {
+    for (E e in this) {
+      if (e == element) return true;
+    }
+    return false;
+  }
+
+  void forEach(void f(E element)) {
+    for (E element in this) f(element);
+  }
+
+  E reduce(E combine(E value, E element)) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) {
+      throw new StateError("No elements");
+    }
+    E value = iterator.current;
+    while (iterator.moveNext()) {
+      value = combine(value, iterator.current);
+    }
+    return value;
+  }
+
+  dynamic fold(var initialValue,
+               dynamic combine(var previousValue, E element)) {
+    var value = initialValue;
+    for (E element in this) value = combine(value, element);
+    return value;
+  }
+
+  bool every(bool f(E element)) {
+    for (E element in this) {
+      if (!f(element)) return false;
+    }
+    return true;
+  }
+
+  String join([String separator]) {
+    Iterator<E> iterator = this.iterator;
+    if (!iterator.moveNext()) return "";
+    StringBuffer buffer = new StringBuffer();
+    if (separator == null || separator == "") {
+      do {
+        buffer.write("${iterator.current}");
+      } while (iterator.moveNext());
+    } else {
+      buffer.write("${iterator.current}");
+      while (iterator.moveNext()) {
+        buffer.write(separator);
+        buffer.write("${iterator.current}");
+      }
+    }
+    return buffer.toString();
+  }
+
+  bool any(bool f(E element)) {
+    for (E element in this) {
+      if (f(element)) return true;
+    }
+    return false;
+  }
+
+  List<E> toList({ bool growable: true }) =>
+      new List<E>.from(this, growable: growable);
+
+  Set<E> toSet() => new Set<E>.from(this);
+
+  int get length {
+    int count = 0;
+    Iterator it = iterator;
+    while (it.moveNext()) {
+      count++;
+    }
+    return count;
+  }
+
+  bool get isEmpty => !iterator.moveNext();
+
+  Iterable<E> take(int n) {
+    return new TakeIterable<E>(this, n);
+  }
+
+  Iterable<E> takeWhile(bool test(E value)) {
+    return new TakeWhileIterable<E>(this, test);
+  }
+
+  Iterable<E> skip(int n) {
+    return new SkipIterable<E>(this, n);
+  }
+
+  Iterable<E> skipWhile(bool test(E value)) {
+    return new SkipWhileIterable<E>(this, test);
+  }
+
+  E get first {
+    Iterator it = iterator;
+    if (!it.moveNext()) {
+      throw new StateError("No elements");
+    }
+    return it.current;
+  }
+
+  E get last {
+    Iterator it = iterator;
+    if (!it.moveNext()) {
+      throw new StateError("No elements");
+    }
+    E result;
+    do {
+      result = it.current;
+    } while(it.moveNext());
+    return result;
+  }
+
+  E get single {
+    Iterator it = iterator;
+    if (!it.moveNext()) throw new StateError("No elements");
+    E result = it.current;
+    if (it.moveNext()) throw new StateError("More than one element");
+    return result;
+  }
+
+  E firstWhere(bool test(E value), { E orElse() }) {
+    // TODO(floitsch): check that arguments are of correct type?
+    for (E element in this) {
+      if (test(element)) return element;
+    }
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E lastWhere(bool test(E value), {E orElse()}) {
+    // TODO(floitsch): check that arguments are of correct type?
+    E result = null;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    if (orElse != null) return orElse();
+    throw new StateError("No matching element");
+  }
+
+  E singleWhere(bool test(E value)) {
+    // TODO(floitsch): check that argument is of correct type?
+    E result = null;
+    bool foundMatching = false;
+    for (E element in this) {
+      if (test(element)) {
+        if (foundMatching) {
+          throw new StateError("More than one matching element");
+        }
+        result = element;
+        foundMatching = true;
+      }
+    }
+    if (foundMatching) return result;
+    throw new StateError("No matching element");
+  }
+
+  E elementAt(int index) {
+    if (index is! int || index < 0) throw new RangeError.value(index);
+    int remaining = index;
+    for (E element in this) {
+      if (remaining == 0) return element;
+      remaining--;
+    }
+    throw new RangeError.value(index);
+  }
+}
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 354e59e..ccde096 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -174,6 +174,9 @@
 
   Iterable map(f(E element)) => new MappedListIterable(this, f);
 
+  Iterable expand(Iterable f(E element)) =>
+      new ExpandIterable<E, dynamic>(this, f);
+
   E reduce(E combine(E previousValue, E element)) {
     if (length == 0) throw new StateError("No elements");
     E value = this[0];
@@ -242,7 +245,7 @@
   void remove(Object element) {
     for (int i = 0; i < this.length; i++) {
       if (this[i] == element) {
-        this.setRange(i, this.length - i - 1, this, i + 1);
+        this.setRange(i, i + this.length - 1, this, i + 1);
         this.length -= 1;
         return;
       }
@@ -298,14 +301,18 @@
     return new ListMapView(this);
   }
 
-  List<E> sublist(int start, [int end]) {
-    if (end == null) end = length;
+  void _rangeCheck(int start, int end) {
     if (start < 0 || start > this.length) {
       throw new RangeError.range(start, 0, this.length);
     }
     if (end < start || end > this.length) {
       throw new RangeError.range(end, start, this.length);
     }
+  }
+
+  List<E> sublist(int start, [int end]) {
+    if (end == null) end = length;
+    _rangeCheck(start, end);
     int length = end - start;
     List<E> result = new List<E>()..length = length;
     for (int i = 0; i < length; i++) {
@@ -315,73 +322,62 @@
   }
 
   Iterable<E> getRange(int start, int end) {
-    if (start < 0 || start > this.length) {
-      throw new RangeError.range(start, 0, this.length);
-    }
-    if (end < start || end > this.length) {
-      throw new RangeError.range(end, start, this.length);
-    }
+    _rangeCheck(start, end);
     return new SubListIterable(this, start, end);
   }
 
-  void insertRange(int start, int length, [E initialValue]) {
-    if (start < 0 || start > this.length) {
-      throw new RangeError.range(start, 0, this.length);
-    }
-    int oldLength = this.length;
-    int moveLength = oldLength - start;
-    this.length += length;
-    if (moveLength > 0) {
-      this.setRange(start + length, moveLength, this, start);
-    }
-    for (int i = 0; i < length; i++) {
-      this[start + i] = initialValue;
-    }
-  }
-
-  void removeRange(int start, int length) {
-    if (start < 0 || start > this.length) {
-      throw new RangeError.range(start, 0, this.length);
-    }
-    if (length < 0 || start + length > this.length) {
-      throw new RangeError.range(length, 0, this.length - start);
-    }
-    int end = start + length;
-    setRange(start, this.length - end, this, end);
+  void removeRange(int start, int end) {
+    _rangeCheck(start, end);
+    int length = end - start;
+    setRange(start, this.length - length, this, end);
     this.length -= length;
   }
 
-  void clearRange(int start, int length, [E fill]) {
-    for (int i = 0; i < length; i++) {
-      this[start + i] = fill;
+  void fillRange(int start, int end, [E fill]) {
+    _rangeCheck(start, end);
+    for (int i = start; i < end; i++) {
+      this[i] = fill;
     }
   }
 
-  void setRange(int start, int length, List<E> from, [int startFrom]) {
-    if (start < 0 || start > this.length) {
-      throw new RangeError.range(start, 0, this.length);
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _rangeCheck(start, end);
+    int length = end - start;
+    if (length == 0) return;
+
+    if (skipCount < 0) throw new ArgumentError(skipCount);
+
+    List otherList;
+    int otherStart;
+    // TODO(floitsch): Make this accept more.
+    if (iterable is List) {
+      otherList = iterable;
+      otherStart = skipCount;
+    } else {
+      otherList = iterable.skip(skipCount).toList(growable: false);
+      otherStart = 0;
     }
-    if (length < 0 || start + length > this.length) {
-      throw new RangeError.range(length, 0, this.length - start);
+    if (otherStart + length > otherList.length) {
+      throw new StateError("Not enough elements");
     }
-    if (startFrom == null) {
-      startFrom = 0;
-    }
-    if (startFrom < 0 || startFrom + length > from.length) {
-      throw new RangeError.range(startFrom, 0, from.length - length);
-    }
-    if (startFrom < start) {
+    if (otherStart < start) {
       // Copy backwards to ensure correct copy if [from] is this.
       for (int i = length - 1; i >= 0; i--) {
-        this[start + i] = from[startFrom + i];
+        this[start + i] = otherList[otherStart + i];
       }
     } else {
       for (int i = 0; i < length; i++) {
-        this[start + i] = from[startFrom + i];
+        this[start + i] = otherList[otherStart + i];
       }
     }
   }
 
+  void replaceRange(int start, int end, Iterable<E> newContents) {
+    // TODO(floitsch): Optimize this.
+    removeRange(start, end);
+    insertAll(start, newContents);
+  }
+
   int indexOf(E element, [int startIndex = 0]) {
     if (startIndex >= this.length) {
       return -1;
@@ -421,5 +417,58 @@
     return -1;
   }
 
+  void insert(int index, E element) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    if (index == this.length) {
+      add(element);
+      return;
+    }
+    // We are modifying the length just below the is-check. Without the check
+    // Array.copy could throw an exception, leaving the list in a bad state
+    // (with a length that has been increased, but without a new element).
+    if (index is! int) throw new ArgumentError(index);
+    this.length++;
+    setRange(index + 1, this.length, this, index);
+    this[index] = element;
+  }
+
+  E removeAt(int index) {
+    E result = this[index];
+    setRange(index, this.length - 1, this, index + 1);
+    length--;
+    return result;
+  }
+
+  void insertAll(int index, Iterable<E> iterable) {
+    if (index < 0 || index > length) {
+      throw new RangeError.range(index, 0, length);
+    }
+    // TODO(floitsch): we can probably detect more cases.
+    if (iterable is! List && iterable is! Set && iterable is! SubListIterable) {
+      iterable = iterable.toList();
+    }
+    int insertionLength = iterable.length;
+    // There might be errors after the length change, in which case the list
+    // will end up being modified but the operation not complete. Unless we
+    // always go through a "toList" we can't really avoid that.
+    this.length += insertionLength;
+    setRange(index + insertionLength, this.length, this, index);
+    setAll(index, iterable);
+  }
+
+  void setAll(int index, Iterable<E> iterable) {
+    if (iterable is List) {
+      setRange(index, index + iterable.length, iterable);
+    } else {
+      for (E element in iterable) {
+        this[index++] = element;
+      }
+    }
+  }
+
   Iterable<E> get reversed => new ReversedListIterable(this);
+
+  String toString() => ToString.iterableToString(this);
 }
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 85947d0..a66248e 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -160,7 +160,7 @@
  *
  * Can do [removeAll] and [retainAll] in linear time.
  */
-class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
+class DoubleLinkedQueue<E> extends IterableBase<E> implements Queue<E> {
   _DoubleLinkedQueueEntrySentinel<E> _sentinel;
   int _elementCount = 0;
 
@@ -354,7 +354,7 @@
  * Operations like [removeAll] and [removeWhere] are very
  * inefficient. If those are needed, use a [DoubleLinkedQueue] instead.
  */
-class ListQueue<E> extends Iterable<E> implements Queue<E>{
+class ListQueue<E> extends IterableBase<E> implements Queue<E> {
   static const int _INITIAL_CAPACITY = 8;
   List<E> _table;
   int _head;
@@ -458,17 +458,17 @@
       if (length + addCount >= _table.length) {
         _preGrow(length + addCount);
         // After preGrow, all elements are at the start of the list.
-        _table.setRange(length, addCount, list, 0);
+        _table.setRange(length, length + addCount, list, 0);
         _tail += addCount;
       } else {
         // Adding addCount elements won't reach _head.
         int endSpace = _table.length - _tail;
         if (addCount < endSpace) {
-          _table.setRange(_tail, addCount, list, 0);
+          _table.setRange(_tail, _tail + addCount, list, 0);
           _tail += addCount;
         } else {
           int preSpace = addCount - endSpace;
-          _table.setRange(_tail, endSpace, list, 0);
+          _table.setRange(_tail, _tail + endSpace, list, 0);
           _table.setRange(0, preSpace, list, endSpace);
           _tail = preSpace;
         }
@@ -653,7 +653,7 @@
     List<E> newTable = new List<E>(_table.length * 2);
     int split = _table.length - _head;
     newTable.setRange(0, split, _table, _head);
-    newTable.setRange(split, _head, _table, 0);
+    newTable.setRange(split, split + _head, _table, 0);
     _head = 0;
     _tail = _table.length;
     _table = newTable;
@@ -668,7 +668,7 @@
     } else {
       int firstPartSize = _table.length - _head;
       target.setRange(0, firstPartSize, _table, _head);
-      target.setRange(firstPartSize, _tail, _table, 0);
+      target.setRange(firstPartSize, firstPartSize + _tail, _table, 0);
       return _tail + firstPartSize;
     }
   }
diff --git a/sdk/lib/collection/splay_tree.dart b/sdk/lib/collection/splay_tree.dart
index 3b83641..1461cc6 100644
--- a/sdk/lib/collection/splay_tree.dart
+++ b/sdk/lib/collection/splay_tree.dart
@@ -505,7 +505,7 @@
   T _getValue(_SplayTreeNode node);
 }
 
-class _SplayTreeKeyIterable<K> extends Iterable<K> {
+class _SplayTreeKeyIterable<K> extends IterableBase<K> {
   _SplayTree<K> _tree;
   _SplayTreeKeyIterable(this._tree);
   int get length => _tree._count;
@@ -513,7 +513,7 @@
   Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree);
 }
 
-class _SplayTreeValueIterable<K, V> extends Iterable<V> {
+class _SplayTreeValueIterable<K, V> extends IterableBase<V> {
   SplayTreeMap<K, V> _map;
   _SplayTreeValueIterable(this._map);
   int get length => _map._count;
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index df5da14..391000c 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -5,7 +5,8 @@
 library dart.core;
 
 import "dart:collection";
-import "dart:_collection-dev";
+import "dart:_collection-dev" hide Symbol;
+import "dart:_collection-dev" as _collection_dev;
 
 part "bool.dart";
 part "comparable.dart";
@@ -18,7 +19,7 @@
 part "function.dart";
 part "identical.dart";
 part "int.dart";
-part "invocation_mirror.dart";
+part "invocation.dart";
 part "iterable.dart";
 part "iterator.dart";
 part "list.dart";
diff --git a/sdk/lib/core/corelib_sources.gypi b/sdk/lib/core/corelib_sources.gypi
index 10ae786..9d6126fa 100644
--- a/sdk/lib/core/corelib_sources.gypi
+++ b/sdk/lib/core/corelib_sources.gypi
@@ -17,7 +17,7 @@
     'function.dart',
     'identical.dart',
     'int.dart',
-    'invocation_mirror.dart',
+    'invocation.dart',
     'iterable.dart',
     'iterator.dart',
     'list.dart',
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 9902b82..31daa8f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -22,7 +22,7 @@
   static const int FRIDAY = 5;
   static const int SATURDAY = 6;
   static const int SUNDAY = 7;
-  static const int DAYS_IN_WEEK = 7;
+  static const int DAYS_PER_WEEK = 7;
 
   // Month constants that are returned by the [month] getter.
   static const int JANUARY = 1;
@@ -37,6 +37,7 @@
   static const int OCTOBER = 10;
   static const int NOVEMBER = 11;
   static const int DECEMBER = 12;
+  static const int MONTHS_PER_YEAR = 12;
 
   /**
    * The milliseconds since 1970-01-01T00:00:00Z (UTC). This value is
diff --git a/sdk/lib/core/function.dart b/sdk/lib/core/function.dart
index 4653294..2ef7f74 100644
--- a/sdk/lib/core/function.dart
+++ b/sdk/lib/core/function.dart
@@ -21,13 +21,17 @@
    * This includes giving the same errors if [function] isn't callable or
    * if it expects different parameters.
    *
-   * Example: [: Function.apply(foo, [1,2,3], {"f": 4, "g": 5}) :] gives
-   * exactly the same result as [: foo(1, 2, 3, f: 4, g: 5) :].
+   * Example: [:
+   * Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
+   * namedArguments[const Symbol("f")] = 4;
+   * namedArguments[const Symbol("g")] = 5;
+   * Function.apply(foo, [1,2,3], namedArguments); :]
+   * gives exactly the same result as [: foo(1, 2, 3, f: 4, g: 5) :].
    *
    * If [positionalArguments] is null, it's considered an empty list.
    * If [namedArguments] is omitted or null, it is considered an empty map.
    */
   external static apply(Function function,
                         List positionalArguments,
-                        [Map<String,dynamic> namedArguments]);
+                        [Map<Symbol, dynamic> namedArguments]);
 }
diff --git a/sdk/lib/core/invocation_mirror.dart b/sdk/lib/core/invocation.dart
similarity index 97%
rename from sdk/lib/core/invocation_mirror.dart
rename to sdk/lib/core/invocation.dart
index 3b5cda0..2e4dd90 100644
--- a/sdk/lib/core/invocation_mirror.dart
+++ b/sdk/lib/core/invocation.dart
@@ -11,7 +11,7 @@
  * an object doesn't support the member invocation that was attempted
  * on it.
  */
-abstract class InvocationMirror {
+abstract class Invocation {
   /** The name of the invoked member. */
   String get memberName;
 
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index d1583dc..9a0bf6f 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -48,7 +48,7 @@
    * multiple times over the the returned [Iterable] will invoke the supplied
    * function [f] multiple times on the same element.
    */
-  Iterable map(f(E element)) => new MappedIterable<E, dynamic>(this, f);
+  Iterable map(f(E element));
 
   /**
    * Returns a lazy [Iterable] with all elements that satisfy the
@@ -60,8 +60,7 @@
    * multiple times over the the returned [Iterable] will invoke the supplied
    * function [f] multiple times on the same element.
    */
-  Iterable<E> where(bool f(E element)) => new WhereIterable<E>(this, f);
-
+  Iterable<E> where(bool f(E element));
 
   /**
    * Expand each element of this [Iterable] into zero or more elements.
@@ -72,28 +71,20 @@
    * The returned [Iterable] is lazy, and will call [f] for each element
    * of this every time it's iterated.
    */
-  Iterable expand(Iterable f(E element)) =>
-      new ExpandIterable<E, dynamic>(this, f);
+  Iterable expand(Iterable f(E element));
 
   /**
    * Check whether the collection contains an element equal to [element].
    */
-  bool contains(E element) {
-    for (E e in this) {
-      if (e == element) return true;
-    }
-    return false;
-  }
+  bool contains(E element);
 
   /**
    * Applies the function [f] to each element of this collection.
    */
-  void forEach(void f(E element)) {
-    for (E element in this) f(element);
-  }
+  void forEach(void f(E element));
 
   /**
-   * Reduce a collection to a single value by iteratively combining elements
+   * Reduces a collection to a single value by iteratively combining elements
    * of the collection using the provided function.
    *
    * Example of calculating the sum of an iterable:
@@ -101,21 +92,13 @@
    *     iterable.reduce((value, element) => value + element);
    *
    */
-  E reduce(E combine(E value, E element)) {
-    Iterator<E> iterator = this.iterator;
-    if (!iterator.moveNext()) {
-      throw new StateError("No elements");
-    }
-    E value = iterator.current;
-    while (iterator.moveNext()) {
-      value = combine(value, iterator.current);
-    }
-    return value;
-  }
+  E reduce(E combine(E value, E element));
 
   /**
-   * Reduce a collection to a single value by iteratively combining each element
-   * of the collection with an existing value using the provided function.
+   * Reduces a collection to a single value by iteratively combining each
+   * element of the collection with an existing value using the provided
+   * function.
+   *
    * Use [initialValue] as the initial value, and the function [combine] to
    * create a new value from the previous one and an element.
    *
@@ -125,25 +108,16 @@
    *
    */
   dynamic fold(var initialValue,
-               dynamic combine(var previousValue, E element)) {
-    var value = initialValue;
-    for (E element in this) value = combine(value, element);
-    return value;
-  }
+               dynamic combine(var previousValue, E element));
 
   /**
    * Returns true if every elements of this collection satisify the
    * predicate [f]. Returns false otherwise.
    */
-  bool every(bool f(E element)) {
-    for (E element in this) {
-      if (!f(element)) return false;
-    }
-    return true;
-  }
+  bool every(bool f(E element));
 
   /**
-   * Convert each element to a [String] and concatenate the strings.
+   * Converts each element to a [String] and concatenates the strings.
    *
    * Converts each element to a [String] by calling [Object.toString] on it.
    * Then concatenates the strings, optionally separated by the [separator]
@@ -159,16 +133,20 @@
    * Returns true if one element of this collection satisfies the
    * predicate [f]. Returns false otherwise.
    */
-  bool any(bool f(E element)) {
-    for (E element in this) {
-      if (f(element)) return true;
-    }
-    return false;
-  }
+  bool any(bool f(E element));
 
-  List<E> toList({ bool growable: true }) =>
-      new List<E>.from(this, growable: growable);
-  Set<E> toSet() => new Set<E>.from(this);
+  /**
+   * Creates a [List] containing the elements of this [Iterable].
+   *
+   * The elements will be in iteration order. The list is fixed-length
+   * if [growable] is false.
+   */
+  List<E> toList({ bool growable: true });
+
+  /**
+   * Creates a [Set] containing the elements of this [Iterable].
+   */
+  Set<E> toSet();
 
   /**
    * Returns the number of elements in [this].
@@ -176,19 +154,12 @@
    * Counting all elements may be involve running through all elements and can
    * therefore be slow.
    */
-  int get length {
-    int count = 0;
-    Iterator it = iterator;
-    while (it.moveNext()) {
-      count++;
-    }
-    return count;
-  }
+  int get length;
 
   /**
    * Returns true if there is no element in this collection.
    */
-  bool get isEmpty => !iterator.moveNext();
+  bool get isEmpty;
 
   /**
    * Returns an [Iterable] with at most [n] elements.
@@ -196,9 +167,7 @@
    * The returned [Iterable] may contain fewer than [n] elements, if [this]
    * contains fewer than [n] elements.
    */
-  Iterable<E> take(int n) {
-    return new TakeIterable<E>(this, n);
-  }
+  Iterable<E> take(int n);
 
   /**
    * Returns an [Iterable] that stops once [test] is not satisfied anymore.
@@ -209,9 +178,7 @@
    * it discards [:e:] and moves into the finished state. That is, it will not
    * ask or provide any more elements.
    */
-  Iterable<E> takeWhile(bool test(E value)) {
-    return new TakeWhileIterable<E>(this, test);
-  }
+  Iterable<E> takeWhile(bool test(E value));
 
   /**
    * Returns an [Iterable] that skips the first [n] elements.
@@ -219,9 +186,7 @@
    * If [this] has fewer than [n] elements, then the resulting [Iterable] will
    * be empty.
    */
-  Iterable<E> skip(int n) {
-    return new SkipIterable<E>(this, n);
-  }
+  Iterable<E> skip(int n);
 
   /**
    * Returns an [Iterable] that skips elements while [test] is satisfied.
@@ -232,9 +197,7 @@
    * discarded. Once an element satisfies the [test] the iterator stops testing
    * and uses every element unconditionally.
    */
-  Iterable<E> skipWhile(bool test(E value)) {
-    return new SkipWhileIterable<E>(this, test);
-  }
+  Iterable<E> skipWhile(bool test(E value));
 
   /**
    * Returns the first element.
@@ -242,43 +205,21 @@
    * If [this] is empty throws a [StateError]. Otherwise this method is
    * equivalent to [:this.elementAt(0):]
    */
-  E get first {
-    Iterator it = iterator;
-    if (!it.moveNext()) {
-      throw new StateError("No elements");
-    }
-    return it.current;
-  }
+  E get first;
 
   /**
    * Returns the last element.
    *
    * If [this] is empty throws a [StateError].
    */
-  E get last {
-    Iterator it = iterator;
-    if (!it.moveNext()) {
-      throw new StateError("No elements");
-    }
-    E result;
-    do {
-      result = it.current;
-    } while(it.moveNext());
-    return result;
-  }
+  E get last;
 
   /**
    * Returns the single element in [this].
    *
    * If [this] is empty or has more than one element throws a [StateError].
    */
-  E get single {
-    Iterator it = iterator;
-    if (!it.moveNext()) throw new StateError("No elements");
-    E result = it.current;
-    if (it.moveNext()) throw new StateError("More than one element");
-    return result;
-  }
+  E get single;
 
   /**
    * Returns the first element that satisfies the given predicate [f].
@@ -287,14 +228,7 @@
    * returned. By default, when [orElse] is `null`, a [StateError] is
    * thrown.
    */
-  E firstWhere(bool test(E value), { E orElse() }) {
-    // TODO(floitsch): check that arguments are of correct type?
-    for (E element in this) {
-      if (test(element)) return element;
-    }
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
+  E firstWhere(bool test(E value), { E orElse() });
 
   /**
    * Returns the last element that satisfies the given predicate [f].
@@ -303,41 +237,13 @@
    * returned. By default, when [orElse] is [:null:], a [StateError] is
    * thrown.
    */
-  E lastWhere(bool test(E value), {E orElse()}) {
-    // TODO(floitsch): check that arguments are of correct type?
-    E result = null;
-    bool foundMatching = false;
-    for (E element in this) {
-      if (test(element)) {
-        result = element;
-        foundMatching = true;
-      }
-    }
-    if (foundMatching) return result;
-    if (orElse != null) return orElse();
-    throw new StateError("No matching element");
-  }
+  E lastWhere(bool test(E value), {E orElse()});
 
   /**
    * Returns the single element that satisfies [f]. If no or more than one
    * element match then a [StateError] is thrown.
    */
-  E singleWhere(bool test(E value)) {
-    // TODO(floitsch): check that argument is of correct type?
-    E result = null;
-    bool foundMatching = false;
-    for (E element in this) {
-      if (test(element)) {
-        if (foundMatching) {
-          throw new StateError("More than one matching element");
-        }
-        result = element;
-        foundMatching = true;
-      }
-    }
-    if (foundMatching) return result;
-    throw new StateError("No matching element");
-  }
+  E singleWhere(bool test(E value));
 
   /**
    * Returns the [index]th element.
@@ -349,21 +255,13 @@
    * function may simply return any element without any iteration if there are
    * at least [index] elements in [this].
    */
-  E elementAt(int index) {
-    if (index is! int || index < 0) throw new RangeError.value(index);
-    int remaining = index;
-    for (E element in this) {
-      if (remaining == 0) return element;
-      remaining--;
-    }
-    throw new RangeError.value(index);
-  }
+  E elementAt(int index);
 }
 
 
 typedef E _Generator<E>(int index);
 
-class _GeneratorIterable<E> extends Iterable<E> {
+class _GeneratorIterable<E> extends IterableBase<E> {
   final int _count;
   final _Generator<E> _generator;
   _GeneratorIterable(this._count, this._generator);
@@ -395,7 +293,7 @@
 /**
  * An [Iterator] that allows moving backwards as well as forwards.
  */
-abstract class BidirectionalIterator<T> extends Iterator<T> {
+abstract class BidirectionalIterator<E> implements Iterator<E> {
   /**
    * Move back to the previous element.
    *
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 27a857e..59d4cd1 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -189,6 +189,30 @@
   void insert(int index, E element);
 
   /**
+   * Inserts all elements of [iterable] at position [index] in the list.
+   *
+   * This increases the length of the list by the length of [iterable] and
+   * shifts all later elements towards the end of the list.
+   *
+   * It is an error if the [index] does not point inside the list or at the
+   * position after the last element.
+   */
+  void insertAll(int index, Iterable<E> iterable);
+
+  /**
+   * Overwrites elements of `this` with the elemenst of [iterable] starting
+   * at position [index] in the list.
+   *
+   * This operation does not increase the length of the list.
+   *
+   * It is an error if the [index] does not point inside the list or at the
+   * position after the last element.
+   *
+   * It is an error if the [iterable] is longer than [length] - [index].
+   */
+  void setAll(int index, Iterable<E> iterable);
+
+  /**
    * Removes [value] from the list. Returns true if [value] was
    * in the list. Returns false otherwise. The method has no effect
    * if [value] value was not in the list.
@@ -263,40 +287,51 @@
   Iterable<E> getRange(int start, int end);
 
   /**
-   * Copies [length] elements of [from], starting
-   * at [startFrom], into the list, starting at [start].
-   * If [length] is 0, this method does not do anything.
-   * Throws an [ArgumentError] if [length] is negative.
-   * Throws an [RangeError] if [start] or
-   * [:start + length - 1:] are out of range for [:this:], or if
-   * [startFrom] or [:startFrom + length - 1:] are out of range for [from].
+   * Copies the elements of [iterable], skipping the [skipCount] first elements
+   * into the range [start] - [end] (excluding) of `this`.
+   *
+   * If [start] equals [end] and represent a legal range, this method has
+   * no effect.
+   *
+   * It is an error if [start]..[end] is not a valid range pointing into the
+   * `this`.
+   *
+   * It is an error if the [iterable] does not have enough elements after
+   * skipping [skipCount] elements.
    */
-  void setRange(int start, int length, List<E> from, [int startFrom]);
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
 
   /**
-   * Removes [length] elements from the list, beginning at [start].
-   * Throws an [UnsupportedError] if the list is
-   * not extendable.
-   * If [length] is 0, this method does not do anything.
-   * Throws an [ArgumentError] if [length] is negative.
-   * Throws an [RangeError] if [start] or
-   * [:start + length: - 1] are out of range.
+   * Removes the elements in the range [start]..[end] (excluding).
+   *
+   * It is an error if [start]..[end] is not a valid range pointing into the
+   * `this`.
    */
-  void removeRange(int start, int length);
+  void removeRange(int start, int end);
 
   /**
-   * Inserts a new range into the list, starting from [start] to
-   * [:start + length - 1:]. The entries are filled with [fill].
-   * Throws an [UnsupportedError] if the list is
-   * not extendable.
-   * If [length] is 0, this method does not do anything.
-   * If [start] is the length of the list, this method inserts the
-   * range at the end of the list.
-   * Throws an [ArgumentError] if [length] is negative.
-   * Throws an [RangeError] if [start] is negative or if
-   * [start] is greater than the length of the list.
+   * Sets the elements in the range [start]..[end] (excluding) to the given
+   * [fillValue].
+   *
+   * It is an error if [start]..[end] is not a valid range pointing into the
+   * `this`.
    */
-  void insertRange(int start, int length, [E fill]);
+  void fillRange(int start, int end, [E fillValue]);
+
+  /**
+   * Removes the elements in the range [start]..[end] (excluding) and replaces
+   * them with the contents of the [iterable].
+   *
+   * It is an error if [start]..[end] is not a valid range pointing into the
+   * `this`.
+   *
+   * Example:
+   *
+   *     var list = [1, 2, 3, 4, 5];
+   *     list.replaceRange(1, 3, [6, 7, 8, 9]);
+   *     print(list);  // [1, 6, 7, 8, 9, 4, 5]
+   */
+  void replaceRange(int start, int end, Iterable<E> iterable);
 
   /**
    * Returns an unmodifiable [Map] view of `this`.
diff --git a/sdk/lib/core/object.dart b/sdk/lib/core/object.dart
index 74cc651..3b61927 100644
--- a/sdk/lib/core/object.dart
+++ b/sdk/lib/core/object.dart
@@ -50,14 +50,14 @@
   /**
    * [noSuchMethod] is invoked when users invoke a non-existant method
    * on an object. The name of the method and the arguments of the
-   * invocation are passed to [noSuchMethod] in an [InvocationMirror].
+   * invocation are passed to [noSuchMethod] in an [Invocation].
    * If [noSuchMethod] returns a value, that value becomes the result of
    * the original invocation.
    *
    * The default behavior of [noSuchMethod] is to throw a
    * [noSuchMethodError].
    */
-  external dynamic noSuchMethod(InvocationMirror invocation);
+  external dynamic noSuchMethod(Invocation invocation);
 
   /**
    * A representation of the runtime type of the object.
diff --git a/sdk/lib/core/set.dart b/sdk/lib/core/set.dart
index 1a8fd15..ff8d4b3 100644
--- a/sdk/lib/core/set.dart
+++ b/sdk/lib/core/set.dart
@@ -8,7 +8,7 @@
  * This class is the public interface of a set. A set is a collection
  * without duplicates.
  */
-abstract class Set<E> extends Iterable<E> {
+abstract class Set<E> extends IterableBase<E> {
   factory Set() => new HashSet<E>();
 
   /**
diff --git a/sdk/lib/core/stacktrace.dart b/sdk/lib/core/stacktrace.dart
index a82a840..ef8cc4d 100644
--- a/sdk/lib/core/stacktrace.dart
+++ b/sdk/lib/core/stacktrace.dart
@@ -14,15 +14,14 @@
  * them programmatically.
  */
 abstract class StackTrace {
-  // Returns a String object that contains the full stack trace starting from
-  // the point where an exception has ocurred to the entry function which is
-  // typically 'main'.
-  // 'toString()' on a stack trace object essentially invokes this getter.
-  external String get fullStackTrace;
-
-  // Returns a String object that contains a stack trace starting from the
-  // point where an exception has ocurred to the point where the exception
-  // is caught.
-  external String get stackTrace;
+  /**
+   * Returns a [String] representation of the stack trace.
+   *
+   * The string represents the full stack trace starting from
+   * the point where a throw ocurred to the top of the current call sequence.
+   *
+   * The exact format of the string representation is not final.
+   */
+  String toString();
 }
 
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 36a2e60..ebcfe10 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -139,22 +139,6 @@
   String operator +(String other);
 
   /**
-   * Returns a slice of this string from [startIndex] to [endIndex].
-   *
-   * If [startIndex] is omitted, it defaults to the start of the string.
-   *
-   * If [endIndex] is omitted, it defaults to the end of the string.
-   *
-   * If either index is negative, it's taken as a negative index from the
-   * end of the string. Their effective value is computed by adding the
-   * negative value to the [length] of the string.
-   *
-   * The effective indices, after  must be non-negative, no greater than the
-   * length of the string, and [endIndex] must not be less than [startIndex].
-   */
-  String slice([int startIndex, int endIndex]);
-
-  /**
    * Returns a substring of this string in the given range.
    * [startIndex] is inclusive and [endIndex] is exclusive.
    */
@@ -267,7 +251,7 @@
 /**
  * The runes (integer Unicode code points) of a [String].
  */
-class Runes extends Iterable<int> {
+class Runes extends IterableBase<int> {
   final String string;
   Runes(this.string);
 
diff --git a/sdk/lib/core/symbol.dart b/sdk/lib/core/symbol.dart
index e2b686c..163307f 100644
--- a/sdk/lib/core/symbol.dart
+++ b/sdk/lib/core/symbol.dart
@@ -6,18 +6,13 @@
 
 /// Opaque name used by mirrors, invocations and [Function.apply].
 class Symbol {
-
   /**
    * Constructs a new Symbol.
    *
    * An [ArgumentError] is thrown if [name] starts with an underscore,
    * or if [name] is not a [String].  An [ArgumentError] is thrown if
-   * [name] is not an empty string and is not a valid identifier
-   * optionally followed by [:'=':].
+   * [name] is not an empty string and is not a valid qualified
+   * identifier optionally followed by [:'=':].
    */
-  external const Symbol(String name);
-
-  external bool operator ==(other);
-
-  external int get hashCode;
+  const factory Symbol(String name) = _collection_dev.Symbol;
 }
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index abb637f..17ea084 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -3,6 +3,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -510,6 +511,19 @@
 
 
 @DocsEditable
+@DomName('AutocompleteErrorEvent')
+class AutocompleteErrorEvent extends Event native "*AutocompleteErrorEvent" {
+
+  @DomName('AutocompleteErrorEvent.reason')
+  @DocsEditable
+  final String reason;
+}
+// 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('HTMLBRElement')
 class BRElement extends Element native "*HTMLBRElement" {
 
@@ -557,77 +571,6 @@
 
 
 @DocsEditable
-@DomName('BatteryManager')
-class BatteryManager extends EventTarget native "*BatteryManager" {
-
-  @DomName('BatteryManager.chargingchangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> chargingChangeEvent = const EventStreamProvider<Event>('chargingchange');
-
-  @DomName('BatteryManager.chargingtimechangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> chargingTimeChangeEvent = const EventStreamProvider<Event>('chargingtimechange');
-
-  @DomName('BatteryManager.dischargingtimechangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> dischargingTimeChangeEvent = const EventStreamProvider<Event>('dischargingtimechange');
-
-  @DomName('BatteryManager.levelchangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> levelChangeEvent = const EventStreamProvider<Event>('levelchange');
-
-  @DomName('BatteryManager.charging')
-  @DocsEditable
-  final bool charging;
-
-  @DomName('BatteryManager.chargingTime')
-  @DocsEditable
-  final num chargingTime;
-
-  @DomName('BatteryManager.dischargingTime')
-  @DocsEditable
-  final num dischargingTime;
-
-  @DomName('BatteryManager.level')
-  @DocsEditable
-  final num level;
-
-  @JSName('addEventListener')
-  @DomName('BatteryManager.addEventListener')
-  @DocsEditable
-  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  @DomName('BatteryManager.dispatchEvent')
-  @DocsEditable
-  bool dispatchEvent(Event event) native;
-
-  @JSName('removeEventListener')
-  @DomName('BatteryManager.removeEventListener')
-  @DocsEditable
-  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
-
-  @DomName('BatteryManager.onchargingchange')
-  @DocsEditable
-  Stream<Event> get onChargingChange => chargingChangeEvent.forTarget(this);
-
-  @DomName('BatteryManager.onchargingtimechange')
-  @DocsEditable
-  Stream<Event> get onChargingTimeChange => chargingTimeChangeEvent.forTarget(this);
-
-  @DomName('BatteryManager.ondischargingtimechange')
-  @DocsEditable
-  Stream<Event> get onDischargingTimeChange => dischargingTimeChangeEvent.forTarget(this);
-
-  @DomName('BatteryManager.onlevelchange')
-  @DocsEditable
-  Stream<Event> get onLevelChange => levelChangeEvent.forTarget(this);
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-@DocsEditable
 @DomName('BeforeLoadEvent')
 class BeforeLoadEvent extends Event native "*BeforeLoadEvent" {
 
@@ -1087,6 +1030,15 @@
 
 
 @DocsEditable
+@DomName('CanvasProxy')
+class CanvasProxy native "*CanvasProxy" {
+}
+// 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
 /**
  * A rendering context for a canvas element.
  *
@@ -1109,6 +1061,10 @@
 @DomName('CanvasRenderingContext2D')
 class CanvasRenderingContext2D extends CanvasRenderingContext native "*CanvasRenderingContext2D" {
 
+  @DomName('CanvasRenderingContext2D.currentPath')
+  @DocsEditable
+  DomPath currentPath;
+
   @DomName('CanvasRenderingContext2D.fillStyle')
   @DocsEditable
   @Creates('String|CanvasGradient|CanvasPattern')
@@ -1951,6 +1907,23 @@
 
 
 @DocsEditable
+@DomName('CSSFontFaceLoadEvent')
+class CssFontFaceLoadEvent extends Event native "*CSSFontFaceLoadEvent" {
+
+  @DomName('CSSFontFaceLoadEvent.error')
+  @DocsEditable
+  final DomError error;
+
+  @DomName('CSSFontFaceLoadEvent.fontface')
+  @DocsEditable
+  final CssFontFaceRule fontface;
+}
+// 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('CSSFontFaceRule')
 class CssFontFaceRule extends CssRule native "*CSSFontFaceRule" {
 
@@ -2127,6 +2100,8 @@
 
   static const int WEBKIT_KEYFRAME_RULE = 8;
 
+  static const int WEBKIT_REGION_RULE = 16;
+
   @DomName('CSSRule.cssText')
   @DocsEditable
   String cssText;
@@ -5450,6 +5425,15 @@
 // for 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('CustomElementConstructor')
+class CustomElementConstructor native "*CustomElementConstructor" {
+}
+// 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.
 
 
@@ -5807,6 +5791,31 @@
   void $dom_initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) 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('HTMLDialogElement')
+class DialogElement extends Element native "*HTMLDialogElement" {
+
+  @DomName('HTMLDialogElement.open')
+  @DocsEditable
+  bool open;
+
+  @DomName('HTMLDialogElement.close')
+  @DocsEditable
+  void close() native;
+
+  @DomName('HTMLDialogElement.show')
+  @DocsEditable
+  void show() native;
+
+  @DomName('HTMLDialogElement.showModal')
+  @DocsEditable
+  void showModal() native;
+}
 // 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.
@@ -6102,6 +6111,10 @@
   @DocsEditable
   final String domain;
 
+  @DomName('Document.fontloader')
+  @DocsEditable
+  final FontLoader fontloader;
+
   @JSName('head')
   /// Moved to [HtmlDocument].
   @DomName('Document.head')
@@ -6228,12 +6241,12 @@
   /// Deprecated: use new Element.tag(tagName) instead.
   @DomName('Document.createElement')
   @DocsEditable
-  Element $dom_createElement(String tagName) native;
+  Element $dom_createElement(String localName_OR_tagName, [String typeExtension]) native;
 
   @JSName('createElementNS')
   @DomName('Document.createElementNS')
   @DocsEditable
-  Element $dom_createElementNS(String namespaceURI, String qualifiedName) native;
+  Element $dom_createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) native;
 
   @JSName('createEvent')
   @DomName('Document.createEvent')
@@ -6379,6 +6392,41 @@
   @Experimental
   void $dom_webkitExitPointerLock() native;
 
+  @JSName('webkitGetNamedFlows')
+  @DomName('Document.webkitGetNamedFlows')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  DomNamedFlowCollection getNamedFlows() native;
+
+  @DomName('Document.webkitRegister')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  CustomElementConstructor register(String name, [Map options]) {
+    if (?options) {
+      var options_1 = convertDartToNative_Dictionary(options);
+      return _register_1(name, options_1);
+    }
+    return _register_2(name);
+  }
+  @JSName('webkitRegister')
+  @DomName('Document.webkitRegister')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  CustomElementConstructor _register_1(name, options) native;
+  @JSName('webkitRegister')
+  @DomName('Document.webkitRegister')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  CustomElementConstructor _register_2(name) native;
+
   @DomName('Document.onabort')
   @DocsEditable
   Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
@@ -6961,6 +7009,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<DomMimeType> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<DomMimeType> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   DomMimeType removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -6981,16 +7037,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<DomMimeType> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<DomMimeType> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [DomMimeType initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<DomMimeType> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [DomMimeType fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<DomMimeType> getRange(int start, int end) =>
@@ -7027,6 +7087,27 @@
 
 
 @DocsEditable
+@DomName('WebKitNamedFlowCollection')
+class DomNamedFlowCollection native "*WebKitNamedFlowCollection" {
+
+  @DomName('DOMNamedFlowCollection.length')
+  @DocsEditable
+  final int length;
+
+  @DomName('DOMNamedFlowCollection.item')
+  @DocsEditable
+  WebKitNamedFlow item(int index) native;
+
+  @DomName('DOMNamedFlowCollection.namedItem')
+  @DocsEditable
+  WebKitNamedFlow namedItem(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('DOMParser')
 class DomParser native "*DOMParser" {
 
@@ -7047,6 +7128,65 @@
 
 
 @DocsEditable
+@DomName('Path')
+class DomPath native "*Path" {
+
+  @DomName('DOMPath.DOMPath')
+  @DocsEditable
+  factory DomPath([path_OR_text]) {
+    if (!?path_OR_text) {
+      return DomPath._create_1();
+    }
+    if ((path_OR_text is DomPath || path_OR_text == null)) {
+      return DomPath._create_2(path_OR_text);
+    }
+    if ((path_OR_text is String || path_OR_text == null)) {
+      return DomPath._create_3(path_OR_text);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+  static DomPath _create_1() => JS('DomPath', 'new Path()');
+  static DomPath _create_2(path_OR_text) => JS('DomPath', 'new Path(#)', path_OR_text);
+  static DomPath _create_3(path_OR_text) => JS('DomPath', 'new Path(#)', path_OR_text);
+
+  @DomName('DOMPath.arc')
+  @DocsEditable
+  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native;
+
+  @DomName('DOMPath.arcTo')
+  @DocsEditable
+  void arcTo(num x1, num y1, num x2, num y2, num radius) native;
+
+  @DomName('DOMPath.bezierCurveTo')
+  @DocsEditable
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native;
+
+  @DomName('DOMPath.closePath')
+  @DocsEditable
+  void closePath() native;
+
+  @DomName('DOMPath.lineTo')
+  @DocsEditable
+  void lineTo(num x, num y) native;
+
+  @DomName('DOMPath.moveTo')
+  @DocsEditable
+  void moveTo(num x, num y) native;
+
+  @DomName('DOMPath.quadraticCurveTo')
+  @DocsEditable
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) native;
+
+  @DomName('DOMPath.rect')
+  @DocsEditable
+  void rect(num x, num y, num width, num height) 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('Plugin')
 class DomPlugin native "*Plugin" {
 
@@ -7223,6 +7363,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<DomPlugin> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<DomPlugin> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   DomPlugin removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7243,16 +7391,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<DomPlugin> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<DomPlugin> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [DomPlugin initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<DomPlugin> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [DomPlugin fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<DomPlugin> getRange(int start, int end) =>
@@ -7633,6 +7785,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7653,16 +7813,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [String initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [String fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<String> getRange(int start, int end) =>
@@ -7897,8 +8061,16 @@
     return _childElements.fold(initialValue, combine);
   }
 
-  void setRange(int start, int rangeLength, List from,
-                [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
+    throw new UnimplementedError();
+  }
+
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void fillRange(int start, int end, [Element fillValue]) {
     throw new UnimplementedError();
   }
 
@@ -7919,11 +8091,7 @@
     _childElements.retainWhere(test);
   }
 
-  void removeRange(int start, int rangeLength) {
-    throw new UnimplementedError();
-  }
-
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void removeRange(int start, int end) {
     throw new UnimplementedError();
   }
 
@@ -7956,6 +8124,14 @@
     }
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void setAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
   void clear() {
     // It is unclear if we want to keep non element nodes?
     _element.text = '';
@@ -8040,16 +8216,12 @@
     throw new UnsupportedError('');
   }
 
-  void setRange(int start, int rangeLength, List from,
-                [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
     throw new UnsupportedError('');
   }
 
-  void removeRange(int start, int rangeLength) {
-    throw new UnsupportedError('');
-  }
-
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError('');
   }
 
@@ -8915,6 +9087,14 @@
   @Experimental
   String pseudo;
 
+  @JSName('webkitRegionOverset')
+  @DomName('Element.webkitRegionOverset')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  final String regionOverset;
+
   @JSName('webkitShadowRoot')
   @DomName('Element.webkitShadowRoot')
   @DocsEditable
@@ -9048,6 +9228,14 @@
   @Experimental
   ShadowRoot createShadowRoot() native;
 
+  @JSName('webkitGetRegionFlowRanges')
+  @DomName('Element.webkitGetRegionFlowRanges')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  List<Range> getRegionFlowRanges() native;
+
   @JSName('webkitRequestFullScreen')
   @DomName('Element.webkitRequestFullScreen')
   @DocsEditable
@@ -10357,6 +10545,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<File> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<File> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   File removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -10377,16 +10573,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<File> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<File> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [File initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<File> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [File fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<File> getRange(int start, int end) =>
@@ -10841,6 +11041,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -10861,16 +11069,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [num initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [num fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<num> getRange(int start, int end) =>
@@ -11067,6 +11279,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11087,16 +11307,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [num initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [num fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<num> getRange(int start, int end) =>
@@ -11151,6 +11375,69 @@
 
 
 @DocsEditable
+@DomName('FontLoader')
+class FontLoader extends EventTarget native "*FontLoader" {
+
+  @DomName('FontLoader.errorEvent')
+  @DocsEditable
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('FontLoader.loadEvent')
+  @DocsEditable
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('FontLoader.loading')
+  @DocsEditable
+  final bool loading;
+
+  @JSName('addEventListener')
+  @DomName('FontLoader.addEventListener')
+  @DocsEditable
+  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+  @DomName('FontLoader.checkFont')
+  @DocsEditable
+  bool checkFont(String font, String text) native;
+
+  @DomName('FontLoader.dispatchEvent')
+  @DocsEditable
+  bool dispatchEvent(Event evt) native;
+
+  @DomName('FontLoader.loadFont')
+  @DocsEditable
+  void loadFont(Map params) {
+    var params_1 = convertDartToNative_Dictionary(params);
+    _loadFont_1(params_1);
+    return;
+  }
+  @JSName('loadFont')
+  @DomName('FontLoader.loadFont')
+  @DocsEditable
+  void _loadFont_1(params) native;
+
+  @DomName('FontLoader.notifyWhenFontsReady')
+  @DocsEditable
+  void notifyWhenFontsReady(VoidCallback callback) native;
+
+  @JSName('removeEventListener')
+  @DomName('FontLoader.removeEventListener')
+  @DocsEditable
+  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native;
+
+  @DomName('FontLoader.onerror')
+  @DocsEditable
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  @DomName('FontLoader.onload')
+  @DocsEditable
+  Stream<Event> get onLoad => loadEvent.forTarget(this);
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
 @DomName('FormData')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -11233,6 +11520,10 @@
   @DocsEditable
   bool checkValidity() native;
 
+  @DomName('HTMLFormElement.requestAutocomplete')
+  @DocsEditable
+  void requestAutocomplete() native;
+
   @DomName('HTMLFormElement.reset')
   @DocsEditable
   void reset() native;
@@ -11326,21 +11617,20 @@
     int watchId;
     var controller;
     controller = new StreamController<Geoposition>(
-      onSubscriptionStateChange: () {
-        if (controller.hasListener) {
-          assert(watchId == null);
-          watchId = $dom_watchPosition(
-              (position) {
-                controller.add(_ensurePosition(position));
-              },
-              (error) {
-                controller.addError(error);
-              },
-              options);
-        } else {
-          assert(watchId != null);
-          $dom_clearWatch(watchId);
-        }
+      onListen: () {
+        assert(watchId == null);
+        watchId = $dom_watchPosition(
+            (position) {
+              controller.add(_ensurePosition(position));
+            },
+            (error) {
+              controller.addError(error);
+            },
+            options);
+      },
+      onCancel: () {
+        assert(watchId != null);
+        $dom_clearWatch(watchId);
       });
 
     return controller.stream;
@@ -11713,6 +12003,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11733,16 +12031,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -11928,6 +12230,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11948,16 +12258,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -13966,6 +14280,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -13986,16 +14308,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -14192,6 +14518,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -14212,16 +14546,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -14418,6 +14756,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -14438,16 +14784,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -16673,14 +17023,6 @@
   @DocsEditable
   final String vendorSub;
 
-  @JSName('webkitBattery')
-  @DomName('Navigator.webkitBattery')
-  @DocsEditable
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental
-  final BatteryManager battery;
-
   @JSName('webkitPersistentStorage')
   @DomName('Navigator.webkitPersistentStorage')
   @DocsEditable
@@ -16705,6 +17047,10 @@
   @DocsEditable
   bool javaEnabled() native;
 
+  @DomName('Navigator.registerProtocolHandler')
+  @DocsEditable
+  void registerProtocolHandler(String scheme, String url, String title) native;
+
   @JSName('webkitGetGamepads')
   @DomName('Navigator.webkitGetGamepads')
   @DocsEditable
@@ -16811,6 +17157,14 @@
     }
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnimplementedError();
+  }
+
   Node removeLast() {
     final result = last;
     if (result != null) {
@@ -16881,23 +17235,28 @@
   }
 
   // FIXME: implement these.
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable,
+                [int skipCount = 0]) {
     throw new UnsupportedError(
         "Cannot setRange on immutable List.");
   }
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot removeRange on immutable List.");
   }
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError(
-        "Cannot insertRange on immutable List.");
-  }
 
   Iterable<Node> getRange(int start, int end) {
     throw new UnimplementedError("NodeList.getRange");
   }
 
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnimplementedError("NodeList.replaceRange");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnimplementedError("NodeList.fillRange");
+  }
+
   List<Node> sublist(int start, [int end]) {
     if (end == null) end == length;
     return Lists.getRange(this, start, end, <Node>[]);
@@ -16997,7 +17356,7 @@
   @Creates('Null')
   var _model;
   bool _hasLocalModel;
-  StreamController<Node> _modelChangedStream;
+  Set<StreamController<Node>> _modelChangedStreams;
 
   /**
    * The data model which is inherited through the tree.
@@ -17014,7 +17373,7 @@
   @Experimental
   get model {
     // If we have a change handler then we've cached the model locally.
-    if (_modelChangedStream != null) {
+    if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
       return _model;
     }
     // Otherwise start looking up the tree.
@@ -17034,8 +17393,8 @@
     _ModelTreeObserver.initialize();
 
     if (changed) {
-      if (_modelChangedStream != null) {
-        _modelChangedStream.add(this);
+      if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
+        _modelChangedStreams.toList().forEach((stream) => stream.add(this));
       }
       // Propagate new model to all descendants.
       _ModelTreeObserver.propagateModel(this, value, false);
@@ -17064,12 +17423,14 @@
    * Get a stream of models, whenever the model changes.
    */
   Stream<Node> get onModelChanged {
-    if (_modelChangedStream == null) {
-      // Ensure the model is cached locally to minimize change notifications.
-      _model = model;
-      _modelChangedStream = new StreamController.broadcast();
+    if (_modelChangedStreams == null) {
+      _modelChangedStreams = new Set<StreamController<Node>>();
     }
-    return _modelChangedStream.stream;
+    var controller;
+    controller = new StreamController(
+        onListen: () { _modelChangedStreams.add(controller); },
+        onCancel: () { _modelChangedStreams.remove(controller); });
+    return controller.stream;
   }
 
   /**
@@ -17428,6 +17789,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -17448,16 +17817,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -18070,6 +18443,138 @@
   @DomName('Performance.now')
   @DocsEditable
   num now() native;
+
+  @JSName('webkitClearMarks')
+  @DomName('Performance.webkitClearMarks')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void clearMarks(String markName) native;
+
+  @JSName('webkitClearMeasures')
+  @DomName('Performance.webkitClearMeasures')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void clearMeasures(String measureName) native;
+
+  @JSName('webkitClearResourceTimings')
+  @DomName('Performance.webkitClearResourceTimings')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void clearResourceTimings() native;
+
+  @JSName('webkitGetEntries')
+  @DomName('Performance.webkitGetEntries')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  PerformanceEntryList getEntries() native;
+
+  @JSName('webkitGetEntriesByName')
+  @DomName('Performance.webkitGetEntriesByName')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  PerformanceEntryList getEntriesByName(String name, String entryType) native;
+
+  @JSName('webkitGetEntriesByType')
+  @DomName('Performance.webkitGetEntriesByType')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  PerformanceEntryList getEntriesByType(String entryType) native;
+
+  @JSName('webkitMark')
+  @DomName('Performance.webkitMark')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void mark(String markName) native;
+
+  @JSName('webkitMeasure')
+  @DomName('Performance.webkitMeasure')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void measure(String measureName, String startMark, String endMark) native;
+
+  @JSName('webkitSetResourceTimingBufferSize')
+  @DomName('Performance.webkitSetResourceTimingBufferSize')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void setResourceTimingBufferSize(int maxSize) 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('PerformanceEntry')
+class PerformanceEntry native "*PerformanceEntry" {
+
+  @DomName('PerformanceEntry.duration')
+  @DocsEditable
+  final num duration;
+
+  @DomName('PerformanceEntry.entryType')
+  @DocsEditable
+  final String entryType;
+
+  @DomName('PerformanceEntry.name')
+  @DocsEditable
+  final String name;
+
+  @DomName('PerformanceEntry.startTime')
+  @DocsEditable
+  final num startTime;
+}
+// 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('PerformanceEntryList')
+class PerformanceEntryList native "*PerformanceEntryList" {
+
+  @DomName('PerformanceEntryList.length')
+  @DocsEditable
+  final int length;
+
+  @DomName('PerformanceEntryList.item')
+  @DocsEditable
+  PerformanceEntry item(int index) native;
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+@DocsEditable
+@DomName('PerformanceMark')
+class PerformanceMark extends PerformanceEntry native "*PerformanceMark" {
+}
+// 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('PerformanceMeasure')
+class PerformanceMeasure extends PerformanceEntry native "*PerformanceMeasure" {
 }
 // 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
@@ -18102,6 +18607,63 @@
 
 
 @DocsEditable
+@DomName('PerformanceResourceTiming')
+class PerformanceResourceTiming extends PerformanceEntry native "*PerformanceResourceTiming" {
+
+  @DomName('PerformanceResourceTiming.connectEnd')
+  @DocsEditable
+  final num connectEnd;
+
+  @DomName('PerformanceResourceTiming.connectStart')
+  @DocsEditable
+  final num connectStart;
+
+  @DomName('PerformanceResourceTiming.domainLookupEnd')
+  @DocsEditable
+  final num domainLookupEnd;
+
+  @DomName('PerformanceResourceTiming.domainLookupStart')
+  @DocsEditable
+  final num domainLookupStart;
+
+  @DomName('PerformanceResourceTiming.fetchStart')
+  @DocsEditable
+  final num fetchStart;
+
+  @DomName('PerformanceResourceTiming.initiatorType')
+  @DocsEditable
+  final String initiatorType;
+
+  @DomName('PerformanceResourceTiming.redirectEnd')
+  @DocsEditable
+  final num redirectEnd;
+
+  @DomName('PerformanceResourceTiming.redirectStart')
+  @DocsEditable
+  final num redirectStart;
+
+  @DomName('PerformanceResourceTiming.requestStart')
+  @DocsEditable
+  final num requestStart;
+
+  @DomName('PerformanceResourceTiming.responseEnd')
+  @DocsEditable
+  final num responseEnd;
+
+  @DomName('PerformanceResourceTiming.responseStart')
+  @DocsEditable
+  final num responseStart;
+
+  @DomName('PerformanceResourceTiming.secureConnectionStart')
+  @DocsEditable
+  final num secureConnectionStart;
+}
+// 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('PerformanceTiming')
 class PerformanceTiming native "*PerformanceTiming" {
 
@@ -19772,6 +20334,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SourceBuffer> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SourceBuffer> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SourceBuffer removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -19792,16 +20362,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SourceBuffer> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SourceBuffer> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SourceBuffer initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SourceBuffer> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SourceBuffer fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SourceBuffer> getRange(int start, int end) =>
@@ -20060,6 +20634,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SpeechGrammar> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SpeechGrammar> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SpeechGrammar removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -20080,16 +20662,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SpeechGrammar> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SpeechGrammar> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SpeechGrammar initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SpeechGrammar> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SpeechGrammar fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SpeechGrammar> getRange(int start, int end) =>
@@ -21511,6 +22097,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<TextTrackCue> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<TextTrackCue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   TextTrackCue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21531,16 +22125,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<TextTrackCue> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<TextTrackCue> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [TextTrackCue initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<TextTrackCue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [TextTrackCue fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<TextTrackCue> getRange(int start, int end) =>
@@ -21724,6 +22322,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<TextTrack> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<TextTrack> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   TextTrack removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21744,16 +22350,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<TextTrack> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<TextTrack> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [TextTrack initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<TextTrack> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [TextTrack fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<TextTrack> getRange(int start, int end) =>
@@ -22163,6 +22773,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Touch> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Touch> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Touch removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22183,16 +22801,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Touch> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Touch> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Touch initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Touch> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Touch fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Touch> getRange(int start, int end) =>
@@ -22639,6 +23261,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22659,16 +23289,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -22865,6 +23499,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -22885,16 +23527,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -23091,6 +23737,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23111,16 +23765,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -23314,6 +23972,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23334,16 +24000,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -23577,6 +24247,21 @@
 
 
 @DocsEditable
+@DomName('WebKitCSSRegionRule')
+class WebKitCssRegionRule extends CssRule native "*WebKitCSSRegionRule" {
+
+  @DomName('WebKitCSSRegionRule.cssRules')
+  @DocsEditable
+  @Returns('_CssRuleList')
+  @Creates('_CssRuleList')
+  final List<CssRule> cssRules;
+}
+// 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('WebKitNamedFlow')
 class WebKitNamedFlow extends EventTarget native "*WebKitNamedFlow" {
 
@@ -25019,7 +25704,7 @@
   const _BeforeUnloadEventStreamProvider(this._eventType);
 
   Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
-    var controller = new StreamController.broadcast();
+    var controller = new StreamController();
     var stream = new _EventStream(e, _eventType, useCapture);
     stream.listen((event) {
       var wrapped = new _BeforeUnloadEvent(event);
@@ -25588,6 +26273,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Rect> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Rect> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Rect removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25608,16 +26301,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Rect> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Rect> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Rect initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Rect> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Rect fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Rect> getRange(int start, int end) =>
@@ -25802,6 +26499,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<CssRule> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<CssRule> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   CssRule removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25822,16 +26527,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<CssRule> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<CssRule> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [CssRule initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<CssRule> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [CssRule fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<CssRule> getRange(int start, int end) =>
@@ -26007,6 +26716,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<_CSSValue> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<_CSSValue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   _CSSValue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -26027,16 +26744,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<_CSSValue> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<_CSSValue> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [_CSSValue initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<_CSSValue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [_CSSValue fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<_CSSValue> getRange(int start, int end) =>
@@ -26280,6 +27001,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Entry> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Entry> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Entry removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -26300,16 +27029,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Entry> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Entry> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Entry initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Entry> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Entry fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Entry> getRange(int start, int end) =>
@@ -26485,6 +27218,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<_EntrySync> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<_EntrySync> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   _EntrySync removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -26505,16 +27246,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<_EntrySync> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<_EntrySync> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [_EntrySync initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<_EntrySync> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [_EntrySync fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<_EntrySync> getRange(int start, int end) =>
@@ -26733,6 +27478,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Gamepad> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Gamepad> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Gamepad removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -26753,16 +27506,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Gamepad> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Gamepad> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Gamepad initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Gamepad> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Gamepad fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Gamepad> getRange(int start, int end) =>
@@ -27001,6 +27758,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27021,16 +27786,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -27277,6 +28046,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SpeechInputResult> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SpeechInputResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SpeechInputResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27297,16 +28074,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SpeechInputResult> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SpeechInputResult> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SpeechInputResult initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SpeechInputResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SpeechInputResult fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SpeechInputResult> getRange(int start, int end) =>
@@ -27482,6 +28263,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SpeechRecognitionResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27502,16 +28291,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SpeechRecognitionResult> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SpeechRecognitionResult> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SpeechRecognitionResult initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SpeechRecognitionResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SpeechRecognitionResult fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SpeechRecognitionResult> getRange(int start, int end) =>
@@ -27687,6 +28480,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<StyleSheet> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<StyleSheet> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   StyleSheet removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27707,16 +28508,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<StyleSheet> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<StyleSheet> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [StyleSheet initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<StyleSheet> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [StyleSheet fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<StyleSheet> getRange(int start, int end) =>
@@ -28467,9 +29272,9 @@
   bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
-      { void onError(AsyncError error),
-      void onDone(),
-      bool unsubscribeOnError}) {
+      { void onError(error),
+        void onDone(),
+        bool cancelOnError}) {
 
     return new _EventStreamSubscription<T>(
         this._target, this._eventType, onData, this._useCapture);
@@ -28511,7 +29316,7 @@
   }
 
   /// Has no effect.
-  void onError(void handleError(AsyncError error)) {}
+  void onError(void handleError(error)) {}
 
   /// Has no effect.
   void onDone(void handleDone()) {}
@@ -28545,6 +29350,12 @@
       _target.$dom_removeEventListener(_eventType, _onData, _useCapture);
     }
   }
+
+  Future asFuture([var futureValue]) {
+    // We just need a future that will never succeed or fail.
+    Completer completer = new Completer();
+    return completer.future;
+  }
 }
 
 
@@ -28634,7 +29445,7 @@
   static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
 
   /** Controller to produce KeyEvents for the stream. */
-  final StreamController _controller = new StreamController.broadcast();
+  final StreamController _controller = new StreamController();
 
   static const _EVENT_TYPE = 'KeyEvent';
 
@@ -29855,14 +30666,14 @@
     // Catch and report them a global exceptions.
     try {
       if (node._hasLocalModel != true && node._model != model &&
-          node._modelChangedStream != null) {
+          node._modelChangedStreams != null &&
+          !node._modelChangedStreams.isEmpty) {
         node._model = model;
-        node._modelChangedStream.add(node);
+        node._modelChangedStreams.toList()
+          .forEach((controller) => controller.add(node));
       }
-    } on AsyncError catch (e) {
-      e.throwDelayed();
     } catch (e, s) {
-      new AsyncError(e, s).throwDelayed();
+      new Future.error(e, s);
     }
     for (var child = node.$dom_firstChild; child != null;
         child = child.nextNode) {
@@ -30836,6 +31647,12 @@
 
   void insert(int index, E element) => _list.insert(index, element);
 
+  void insertAll(int index, Iterable<E> iterable) =>
+      _list.insertAll(index, iterable);
+
+  void setAll(int index, Iterable<E> iterable) =>
+      _list.setAll(index, iterable);
+
   E removeAt(int index) => _list.removeAt(index);
 
   E removeLast() => _list.removeLast();
@@ -30844,14 +31661,18 @@
 
   Iterable<E> getRange(int start, int end) => _list.getRange(start, end);
 
-  void setRange(int start, int length, List<E> from, [int startFrom]) {
-    _list.setRange(start, length, from, startFrom);
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _list.setRange(start, end, iterable, skipCount);
   }
 
-  void removeRange(int start, int length) { _list.removeRange(start, length); }
+  void removeRange(int start, int end) { _list.removeRange(start, end); }
 
-  void insertRange(int start, int length, [E fill]) {
-    _list.insertRange(start, length, fill);
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    _list.replaceRange(start, end, iterable);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    _list.fillRange(start, end, fillValue);
   }
 
   Map<int, E> asMap() => _list.asMap();
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 181104f..cb67dad 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -3,6 +3,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
@@ -616,6 +617,23 @@
 
 
 @DocsEditable
+@DomName('AutocompleteErrorEvent')
+class AutocompleteErrorEvent extends Event {
+  AutocompleteErrorEvent.internal() : super.internal();
+
+  @DomName('AutocompleteErrorEvent.reason')
+  @DocsEditable
+  String get reason native "AutocompleteErrorEvent_reason_Getter";
+
+}
+// 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('HTMLBRElement')
 class BRElement extends _Element_Merged {
   BRElement.internal() : super.internal();
@@ -683,79 +701,6 @@
 
 
 @DocsEditable
-@DomName('BatteryManager')
-class BatteryManager extends EventTarget {
-  BatteryManager.internal() : super.internal();
-
-  @DomName('BatteryManager.chargingchangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> chargingChangeEvent = const EventStreamProvider<Event>('chargingchange');
-
-  @DomName('BatteryManager.chargingtimechangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> chargingTimeChangeEvent = const EventStreamProvider<Event>('chargingtimechange');
-
-  @DomName('BatteryManager.dischargingtimechangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> dischargingTimeChangeEvent = const EventStreamProvider<Event>('dischargingtimechange');
-
-  @DomName('BatteryManager.levelchangeEvent')
-  @DocsEditable
-  static const EventStreamProvider<Event> levelChangeEvent = const EventStreamProvider<Event>('levelchange');
-
-  @DomName('BatteryManager.charging')
-  @DocsEditable
-  bool get charging native "BatteryManager_charging_Getter";
-
-  @DomName('BatteryManager.chargingTime')
-  @DocsEditable
-  num get chargingTime native "BatteryManager_chargingTime_Getter";
-
-  @DomName('BatteryManager.dischargingTime')
-  @DocsEditable
-  num get dischargingTime native "BatteryManager_dischargingTime_Getter";
-
-  @DomName('BatteryManager.level')
-  @DocsEditable
-  num get level native "BatteryManager_level_Getter";
-
-  @DomName('BatteryManager.addEventListener')
-  @DocsEditable
-  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "BatteryManager_addEventListener_Callback";
-
-  @DomName('BatteryManager.dispatchEvent')
-  @DocsEditable
-  bool dispatchEvent(Event event) native "BatteryManager_dispatchEvent_Callback";
-
-  @DomName('BatteryManager.removeEventListener')
-  @DocsEditable
-  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "BatteryManager_removeEventListener_Callback";
-
-  @DomName('BatteryManager.onchargingchange')
-  @DocsEditable
-  Stream<Event> get onChargingChange => chargingChangeEvent.forTarget(this);
-
-  @DomName('BatteryManager.onchargingtimechange')
-  @DocsEditable
-  Stream<Event> get onChargingTimeChange => chargingTimeChangeEvent.forTarget(this);
-
-  @DomName('BatteryManager.ondischargingtimechange')
-  @DocsEditable
-  Stream<Event> get onDischargingTimeChange => dischargingTimeChangeEvent.forTarget(this);
-
-  @DomName('BatteryManager.onlevelchange')
-  @DocsEditable
-  Stream<Event> get onLevelChange => levelChangeEvent.forTarget(this);
-
-}
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// WARNING: Do not edit - generated code.
-
-
-@DocsEditable
 @DomName('BeforeLoadEvent')
 class BeforeLoadEvent extends Event {
   BeforeLoadEvent.internal() : super.internal();
@@ -1284,6 +1229,19 @@
 
 
 @DocsEditable
+@DomName('CanvasProxy')
+class CanvasProxy extends NativeFieldWrapperClass1 {
+  CanvasProxy.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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 /**
  * A rendering context for a canvas element.
  *
@@ -1309,6 +1267,14 @@
 class CanvasRenderingContext2D extends CanvasRenderingContext {
   CanvasRenderingContext2D.internal() : super.internal();
 
+  @DomName('CanvasRenderingContext2D.currentPath')
+  @DocsEditable
+  DomPath get currentPath native "CanvasRenderingContext2D_currentPath_Getter";
+
+  @DomName('CanvasRenderingContext2D.currentPath')
+  @DocsEditable
+  void set currentPath(DomPath value) native "CanvasRenderingContext2D_currentPath_Setter";
+
   @DomName('CanvasRenderingContext2D.fillStyle')
   @DocsEditable
   dynamic get fillStyle native "CanvasRenderingContext2D_fillStyle_Getter";
@@ -2376,6 +2342,27 @@
 
 
 @DocsEditable
+@DomName('CSSFontFaceLoadEvent')
+class CssFontFaceLoadEvent extends Event {
+  CssFontFaceLoadEvent.internal() : super.internal();
+
+  @DomName('CSSFontFaceLoadEvent.error')
+  @DocsEditable
+  DomError get error native "CSSFontFaceLoadEvent_error_Getter";
+
+  @DomName('CSSFontFaceLoadEvent.fontface')
+  @DocsEditable
+  CssFontFaceRule get fontface native "CSSFontFaceLoadEvent_fontface_Getter";
+
+}
+// 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('CSSFontFaceRule')
 class CssFontFaceRule extends CssRule {
   CssFontFaceRule.internal() : super.internal();
@@ -2587,6 +2574,8 @@
 
   static const int WEBKIT_KEYFRAME_RULE = 8;
 
+  static const int WEBKIT_REGION_RULE = 16;
+
   @DomName('CSSRule.cssText')
   @DocsEditable
   String get cssText native "CSSRule_cssText_Getter";
@@ -5932,6 +5921,19 @@
 // WARNING: Do not edit - generated code.
 
 
+@DocsEditable
+@DomName('CustomElementConstructor')
+class CustomElementConstructor extends NativeFieldWrapperClass1 {
+  CustomElementConstructor.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.
+
+// WARNING: Do not edit - generated code.
+
+
 @DomName('CustomEvent')
 class CustomEvent extends Event {
   factory CustomEvent(String type,
@@ -6472,6 +6474,39 @@
   void $dom_initDeviceOrientationEvent(String type, bool bubbles, bool cancelable, num alpha, num beta, num gamma, bool absolute) native "DeviceOrientationEvent_initDeviceOrientationEvent_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('HTMLDialogElement')
+class DialogElement extends _Element_Merged {
+  DialogElement.internal() : super.internal();
+
+  @DomName('HTMLDialogElement.open')
+  @DocsEditable
+  bool get open native "HTMLDialogElement_open_Getter";
+
+  @DomName('HTMLDialogElement.open')
+  @DocsEditable
+  void set open(bool value) native "HTMLDialogElement_open_Setter";
+
+  @DomName('HTMLDialogElement.close')
+  @DocsEditable
+  void close() native "HTMLDialogElement_close_Callback";
+
+  @DomName('HTMLDialogElement.show')
+  @DocsEditable
+  void show() native "HTMLDialogElement_show_Callback";
+
+  @DomName('HTMLDialogElement.showModal')
+  @DocsEditable
+  void showModal() native "HTMLDialogElement_showModal_Callback";
+
+}
 // 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.
@@ -6703,6 +6738,10 @@
   @DocsEditable
   String get domain native "Document_domain_Getter";
 
+  @DomName('Document.fontloader')
+  @DocsEditable
+  FontLoader get fontloader native "Document_fontloader_Getter";
+
   /// Moved to [HtmlDocument].
   @DomName('Document.head')
   @DocsEditable
@@ -6817,14 +6856,41 @@
   @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";
+  Element $dom_createElement(String localName_OR_tagName, [String typeExtension]) {
+    if ((localName_OR_tagName is String || localName_OR_tagName == null) && !?typeExtension) {
+      return _createElement_1(localName_OR_tagName);
+    }
+    if ((localName_OR_tagName is String || localName_OR_tagName == null) && (typeExtension is String || typeExtension == null)) {
+      return _createElement_2(localName_OR_tagName, typeExtension);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
 
-  @DomName('Document.createElementNS')
+  @DomName('Document._createElement_1')
   @DocsEditable
-  Element $dom_createElementNS(String namespaceURI, String qualifiedName) native "Document_createElementNS_Callback";
+  Element _createElement_1(localName_OR_tagName) native "Document__createElement_1_Callback";
+
+  @DomName('Document._createElement_2')
+  @DocsEditable
+  Element _createElement_2(localName_OR_tagName, typeExtension) native "Document__createElement_2_Callback";
+
+  Element $dom_createElementNS(String namespaceURI, String qualifiedName, [String typeExtension]) {
+    if ((namespaceURI is String || namespaceURI == null) && (qualifiedName is String || qualifiedName == null) && !?typeExtension) {
+      return _createElementNS_1(namespaceURI, qualifiedName);
+    }
+    if ((namespaceURI is String || namespaceURI == null) && (qualifiedName is String || qualifiedName == null) && (typeExtension is String || typeExtension == null)) {
+      return _createElementNS_2(namespaceURI, qualifiedName, typeExtension);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @DomName('Document._createElementNS_1')
+  @DocsEditable
+  Element _createElementNS_1(namespaceURI, qualifiedName) native "Document__createElementNS_1_Callback";
+
+  @DomName('Document._createElementNS_2')
+  @DocsEditable
+  Element _createElementNS_2(namespaceURI, qualifiedName, typeExtension) native "Document__createElementNS_2_Callback";
 
   @DomName('Document.createEvent')
   @DocsEditable
@@ -6944,6 +7010,20 @@
   @Experimental
   void $dom_webkitExitPointerLock() native "Document_webkitExitPointerLock_Callback";
 
+  @DomName('Document.webkitGetNamedFlows')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  DomNamedFlowCollection getNamedFlows() native "Document_webkitGetNamedFlows_Callback";
+
+  @DomName('Document.webkitRegister')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  CustomElementConstructor register(String name, [Map options]) native "Document_webkitRegister_Callback";
+
   @DomName('Document.onabort')
   @DocsEditable
   Stream<Event> get onAbort => Element.abortEvent.forTarget(this);
@@ -7532,6 +7612,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<DomMimeType> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<DomMimeType> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   DomMimeType removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7552,16 +7640,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<DomMimeType> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<DomMimeType> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [DomMimeType initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<DomMimeType> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [DomMimeType fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<DomMimeType> getRange(int start, int end) =>
@@ -7601,6 +7693,31 @@
 
 
 @DocsEditable
+@DomName('WebKitNamedFlowCollection')
+class DomNamedFlowCollection extends NativeFieldWrapperClass1 {
+  DomNamedFlowCollection.internal();
+
+  @DomName('DOMNamedFlowCollection.length')
+  @DocsEditable
+  int get length native "DOMNamedFlowCollection_length_Getter";
+
+  @DomName('DOMNamedFlowCollection.item')
+  @DocsEditable
+  WebKitNamedFlow item(int index) native "DOMNamedFlowCollection_item_Callback";
+
+  @DomName('DOMNamedFlowCollection.namedItem')
+  @DocsEditable
+  WebKitNamedFlow namedItem(String name) native "DOMNamedFlowCollection_namedItem_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('DOMParser')
 class DomParser extends NativeFieldWrapperClass1 {
   DomParser.internal();
@@ -7627,6 +7744,75 @@
 
 
 @DocsEditable
+@DomName('Path')
+class DomPath extends NativeFieldWrapperClass1 {
+  DomPath.internal();
+
+  @DomName('DOMPath.DOMPath')
+  @DocsEditable
+  factory DomPath([path_OR_text]) {
+    if (!?path_OR_text) {
+      return DomPath._create_1();
+    }
+    if ((path_OR_text is DomPath || path_OR_text == null)) {
+      return DomPath._create_2(path_OR_text);
+    }
+    if ((path_OR_text is String || path_OR_text == null)) {
+      return DomPath._create_3(path_OR_text);
+    }
+    throw new ArgumentError("Incorrect number or type of arguments");
+  }
+
+  @DocsEditable
+  static DomPath _create_1() native "DOMPath__create_1constructorCallback";
+
+  @DocsEditable
+  static DomPath _create_2(path_OR_text) native "DOMPath__create_2constructorCallback";
+
+  @DocsEditable
+  static DomPath _create_3(path_OR_text) native "DOMPath__create_3constructorCallback";
+
+  @DomName('DOMPath.arc')
+  @DocsEditable
+  void arc(num x, num y, num radius, num startAngle, num endAngle, bool anticlockwise) native "DOMPath_arc_Callback";
+
+  @DomName('DOMPath.arcTo')
+  @DocsEditable
+  void arcTo(num x1, num y1, num x2, num y2, num radius) native "DOMPath_arcTo_Callback";
+
+  @DomName('DOMPath.bezierCurveTo')
+  @DocsEditable
+  void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y, num x, num y) native "DOMPath_bezierCurveTo_Callback";
+
+  @DomName('DOMPath.closePath')
+  @DocsEditable
+  void closePath() native "DOMPath_closePath_Callback";
+
+  @DomName('DOMPath.lineTo')
+  @DocsEditable
+  void lineTo(num x, num y) native "DOMPath_lineTo_Callback";
+
+  @DomName('DOMPath.moveTo')
+  @DocsEditable
+  void moveTo(num x, num y) native "DOMPath_moveTo_Callback";
+
+  @DomName('DOMPath.quadraticCurveTo')
+  @DocsEditable
+  void quadraticCurveTo(num cpx, num cpy, num x, num y) native "DOMPath_quadraticCurveTo_Callback";
+
+  @DomName('DOMPath.rect')
+  @DocsEditable
+  void rect(num x, num y, num width, num height) native "DOMPath_rect_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('Plugin')
 class DomPlugin extends NativeFieldWrapperClass1 {
   DomPlugin.internal();
@@ -7808,6 +7994,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<DomPlugin> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<DomPlugin> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   DomPlugin removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7828,16 +8022,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<DomPlugin> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<DomPlugin> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [DomPlugin initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<DomPlugin> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [DomPlugin fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<DomPlugin> getRange(int start, int end) =>
@@ -8236,6 +8434,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -8256,16 +8462,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [String initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [String fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<String> getRange(int start, int end) =>
@@ -8521,8 +8731,16 @@
     return _childElements.fold(initialValue, combine);
   }
 
-  void setRange(int start, int rangeLength, List from,
-                [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
+    throw new UnimplementedError();
+  }
+
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void fillRange(int start, int end, [Element fillValue]) {
     throw new UnimplementedError();
   }
 
@@ -8543,11 +8761,7 @@
     _childElements.retainWhere(test);
   }
 
-  void removeRange(int start, int rangeLength) {
-    throw new UnimplementedError();
-  }
-
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void removeRange(int start, int end) {
     throw new UnimplementedError();
   }
 
@@ -8580,6 +8794,14 @@
     }
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void setAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
   void clear() {
     // It is unclear if we want to keep non element nodes?
     _element.text = '';
@@ -8664,16 +8886,12 @@
     throw new UnsupportedError('');
   }
 
-  void setRange(int start, int rangeLength, List from,
-                [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
     throw new UnsupportedError('');
   }
 
-  void removeRange(int start, int rangeLength) {
-    throw new UnsupportedError('');
-  }
-
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError('');
   }
 
@@ -9383,6 +9601,13 @@
   @Experimental
   void set pseudo(String value) native "Element_webkitPseudo_Setter";
 
+  @DomName('Element.webkitRegionOverset')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  String get regionOverset native "Element_webkitRegionOverset_Getter";
+
   @DomName('Element.webkitShadowRoot')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -9523,6 +9748,13 @@
   @Experimental
   ShadowRoot createShadowRoot() native "Element_webkitCreateShadowRoot_Callback";
 
+  @DomName('Element.webkitGetRegionFlowRanges')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  List<Range> getRegionFlowRanges() native "Element_webkitGetRegionFlowRanges_Callback";
+
   @DomName('Element.webkitMatchesSelector')
   @DocsEditable
   @Experimental()
@@ -10907,6 +11139,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<File> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<File> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   File removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -10927,16 +11167,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<File> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<File> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [File initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<File> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [File fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<File> getRange(int start, int end) =>
@@ -11421,6 +11665,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11441,16 +11693,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [num initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [num fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<num> getRange(int start, int end) =>
@@ -11664,6 +11920,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   num removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -11684,16 +11948,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<num> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<num> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [num initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<num> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [num fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<num> getRange(int start, int end) =>
@@ -11761,6 +12029,63 @@
 
 
 @DocsEditable
+@DomName('FontLoader')
+class FontLoader extends EventTarget {
+  FontLoader.internal() : super.internal();
+
+  @DomName('FontLoader.errorEvent')
+  @DocsEditable
+  static const EventStreamProvider<Event> errorEvent = const EventStreamProvider<Event>('error');
+
+  @DomName('FontLoader.loadEvent')
+  @DocsEditable
+  static const EventStreamProvider<Event> loadEvent = const EventStreamProvider<Event>('load');
+
+  @DomName('FontLoader.loading')
+  @DocsEditable
+  bool get loading native "FontLoader_loading_Getter";
+
+  @DomName('FontLoader.addEventListener')
+  @DocsEditable
+  void $dom_addEventListener(String type, EventListener listener, [bool useCapture]) native "FontLoader_addEventListener_Callback";
+
+  @DomName('FontLoader.checkFont')
+  @DocsEditable
+  bool checkFont(String font, String text) native "FontLoader_checkFont_Callback";
+
+  @DomName('FontLoader.dispatchEvent')
+  @DocsEditable
+  bool dispatchEvent(Event evt) native "FontLoader_dispatchEvent_Callback";
+
+  @DomName('FontLoader.loadFont')
+  @DocsEditable
+  void loadFont(Map params) native "FontLoader_loadFont_Callback";
+
+  @DomName('FontLoader.notifyWhenFontsReady')
+  @DocsEditable
+  void notifyWhenFontsReady(VoidCallback callback) native "FontLoader_notifyWhenFontsReady_Callback";
+
+  @DomName('FontLoader.removeEventListener')
+  @DocsEditable
+  void $dom_removeEventListener(String type, EventListener listener, [bool useCapture]) native "FontLoader_removeEventListener_Callback";
+
+  @DomName('FontLoader.onerror')
+  @DocsEditable
+  Stream<Event> get onError => errorEvent.forTarget(this);
+
+  @DomName('FontLoader.onload')
+  @DocsEditable
+  Stream<Event> get onLoad => loadEvent.forTarget(this);
+
+}
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
 @DomName('FormData')
 @SupportedBrowser(SupportedBrowser.CHROME)
 @SupportedBrowser(SupportedBrowser.FIREFOX)
@@ -11877,6 +12202,10 @@
   @DocsEditable
   bool checkValidity() native "HTMLFormElement_checkValidity_Callback";
 
+  @DomName('HTMLFormElement.requestAutocomplete')
+  @DocsEditable
+  void requestAutocomplete() native "HTMLFormElement_requestAutocomplete_Callback";
+
   @DomName('HTMLFormElement.reset')
   @DocsEditable
   void reset() native "HTMLFormElement_reset_Callback";
@@ -11975,21 +12304,20 @@
     int watchId;
     var controller;
     controller = new StreamController<Geoposition>(
-      onSubscriptionStateChange: () {
-        if (controller.hasListener) {
-          assert(watchId == null);
-          watchId = $dom_watchPosition(
-              (position) {
-                controller.add(_ensurePosition(position));
-              },
-              (error) {
-                controller.addError(error);
-              },
-              options);
-        } else {
-          assert(watchId != null);
-          $dom_clearWatch(watchId);
-        }
+      onListen: () {
+        assert(watchId == null);
+        watchId = $dom_watchPosition(
+            (position) {
+              controller.add(_ensurePosition(position));
+            },
+            (error) {
+              controller.addError(error);
+            },
+            options);
+      },
+      onCancel: () {
+        assert(watchId != null);
+        $dom_clearWatch(watchId);
       });
 
     return controller.stream;
@@ -12356,6 +12684,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12376,16 +12712,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -12573,6 +12913,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -12593,16 +12941,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -14946,6 +15298,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -14966,16 +15326,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -15189,6 +15553,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -15209,16 +15581,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -15432,6 +15808,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -15452,16 +15836,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -17979,13 +18367,6 @@
   @DocsEditable
   String get vendorSub native "Navigator_vendorSub_Getter";
 
-  @DomName('Navigator.webkitBattery')
-  @DocsEditable
-  @SupportedBrowser(SupportedBrowser.CHROME)
-  @SupportedBrowser(SupportedBrowser.SAFARI)
-  @Experimental
-  BatteryManager get battery native "Navigator_webkitBattery_Getter";
-
   @DomName('Navigator.webkitPersistentStorage')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18008,6 +18389,10 @@
   @DocsEditable
   bool javaEnabled() native "Navigator_javaEnabled_Callback";
 
+  @DomName('Navigator.registerProtocolHandler')
+  @DocsEditable
+  void registerProtocolHandler(String scheme, String url, String title) native "Navigator_registerProtocolHandler_Callback";
+
   @DomName('Navigator.webkitGetGamepads')
   @DocsEditable
   @SupportedBrowser(SupportedBrowser.CHROME)
@@ -18119,6 +18504,14 @@
     }
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnimplementedError();
+  }
+
   Node removeLast() {
     final result = last;
     if (result != null) {
@@ -18189,23 +18582,28 @@
   }
 
   // FIXME: implement these.
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable,
+                [int skipCount = 0]) {
     throw new UnsupportedError(
         "Cannot setRange on immutable List.");
   }
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot removeRange on immutable List.");
   }
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError(
-        "Cannot insertRange on immutable List.");
-  }
 
   Iterable<Node> getRange(int start, int end) {
     throw new UnimplementedError("NodeList.getRange");
   }
 
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnimplementedError("NodeList.replaceRange");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnimplementedError("NodeList.fillRange");
+  }
+
   List<Node> sublist(int start, [int end]) {
     if (end == null) end == length;
     return Lists.getRange(this, start, end, <Node>[]);
@@ -18304,7 +18702,7 @@
   // notifications.
   var _model;
   bool _hasLocalModel;
-  StreamController<Node> _modelChangedStream;
+  Set<StreamController<Node>> _modelChangedStreams;
 
   /**
    * The data model which is inherited through the tree.
@@ -18321,7 +18719,7 @@
   @Experimental
   get model {
     // If we have a change handler then we've cached the model locally.
-    if (_modelChangedStream != null) {
+    if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
       return _model;
     }
     // Otherwise start looking up the tree.
@@ -18341,8 +18739,8 @@
     _ModelTreeObserver.initialize();
 
     if (changed) {
-      if (_modelChangedStream != null) {
-        _modelChangedStream.add(this);
+      if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
+        _modelChangedStreams.toList().forEach((stream) => stream.add(this));
       }
       // Propagate new model to all descendants.
       _ModelTreeObserver.propagateModel(this, value, false);
@@ -18371,12 +18769,14 @@
    * Get a stream of models, whenever the model changes.
    */
   Stream<Node> get onModelChanged {
-    if (_modelChangedStream == null) {
-      // Ensure the model is cached locally to minimize change notifications.
-      _model = model;
-      _modelChangedStream = new StreamController.broadcast();
+    if (_modelChangedStreams == null) {
+      _modelChangedStreams = new Set<StreamController<Node>>();
     }
-    return _modelChangedStream.stream;
+    var controller;
+    controller = new StreamController(
+        onListen: () { _modelChangedStreams.add(controller); },
+        onCancel: () { _modelChangedStreams.remove(controller); });
+    return controller.stream;
   }
 
   /**
@@ -18734,6 +19134,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -18754,16 +19162,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -19500,6 +19912,145 @@
   @DocsEditable
   num now() native "Performance_now_Callback";
 
+  @DomName('Performance.webkitClearMarks')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void clearMarks(String markName) native "Performance_webkitClearMarks_Callback";
+
+  @DomName('Performance.webkitClearMeasures')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void clearMeasures(String measureName) native "Performance_webkitClearMeasures_Callback";
+
+  @DomName('Performance.webkitClearResourceTimings')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void clearResourceTimings() native "Performance_webkitClearResourceTimings_Callback";
+
+  @DomName('Performance.webkitGetEntries')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  PerformanceEntryList getEntries() native "Performance_webkitGetEntries_Callback";
+
+  @DomName('Performance.webkitGetEntriesByName')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  PerformanceEntryList getEntriesByName(String name, String entryType) native "Performance_webkitGetEntriesByName_Callback";
+
+  @DomName('Performance.webkitGetEntriesByType')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  PerformanceEntryList getEntriesByType(String entryType) native "Performance_webkitGetEntriesByType_Callback";
+
+  @DomName('Performance.webkitMark')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void mark(String markName) native "Performance_webkitMark_Callback";
+
+  @DomName('Performance.webkitMeasure')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void measure(String measureName, String startMark, String endMark) native "Performance_webkitMeasure_Callback";
+
+  @DomName('Performance.webkitSetResourceTimingBufferSize')
+  @DocsEditable
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental
+  void setResourceTimingBufferSize(int maxSize) native "Performance_webkitSetResourceTimingBufferSize_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('PerformanceEntry')
+class PerformanceEntry extends NativeFieldWrapperClass1 {
+  PerformanceEntry.internal();
+
+  @DomName('PerformanceEntry.duration')
+  @DocsEditable
+  num get duration native "PerformanceEntry_duration_Getter";
+
+  @DomName('PerformanceEntry.entryType')
+  @DocsEditable
+  String get entryType native "PerformanceEntry_entryType_Getter";
+
+  @DomName('PerformanceEntry.name')
+  @DocsEditable
+  String get name native "PerformanceEntry_name_Getter";
+
+  @DomName('PerformanceEntry.startTime')
+  @DocsEditable
+  num get startTime native "PerformanceEntry_startTime_Getter";
+
+}
+// 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('PerformanceEntryList')
+class PerformanceEntryList extends NativeFieldWrapperClass1 {
+  PerformanceEntryList.internal();
+
+  @DomName('PerformanceEntryList.length')
+  @DocsEditable
+  int get length native "PerformanceEntryList_length_Getter";
+
+  @DomName('PerformanceEntryList.item')
+  @DocsEditable
+  PerformanceEntry item(int index) native "PerformanceEntryList_item_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('PerformanceMark')
+class PerformanceMark extends PerformanceEntry {
+  PerformanceMark.internal() : super.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.
+
+// WARNING: Do not edit - generated code.
+
+
+@DocsEditable
+@DomName('PerformanceMeasure')
+class PerformanceMeasure extends PerformanceEntry {
+  PerformanceMeasure.internal() : super.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
@@ -19538,6 +20089,67 @@
 
 
 @DocsEditable
+@DomName('PerformanceResourceTiming')
+class PerformanceResourceTiming extends PerformanceEntry {
+  PerformanceResourceTiming.internal() : super.internal();
+
+  @DomName('PerformanceResourceTiming.connectEnd')
+  @DocsEditable
+  num get connectEnd native "PerformanceResourceTiming_connectEnd_Getter";
+
+  @DomName('PerformanceResourceTiming.connectStart')
+  @DocsEditable
+  num get connectStart native "PerformanceResourceTiming_connectStart_Getter";
+
+  @DomName('PerformanceResourceTiming.domainLookupEnd')
+  @DocsEditable
+  num get domainLookupEnd native "PerformanceResourceTiming_domainLookupEnd_Getter";
+
+  @DomName('PerformanceResourceTiming.domainLookupStart')
+  @DocsEditable
+  num get domainLookupStart native "PerformanceResourceTiming_domainLookupStart_Getter";
+
+  @DomName('PerformanceResourceTiming.fetchStart')
+  @DocsEditable
+  num get fetchStart native "PerformanceResourceTiming_fetchStart_Getter";
+
+  @DomName('PerformanceResourceTiming.initiatorType')
+  @DocsEditable
+  String get initiatorType native "PerformanceResourceTiming_initiatorType_Getter";
+
+  @DomName('PerformanceResourceTiming.redirectEnd')
+  @DocsEditable
+  num get redirectEnd native "PerformanceResourceTiming_redirectEnd_Getter";
+
+  @DomName('PerformanceResourceTiming.redirectStart')
+  @DocsEditable
+  num get redirectStart native "PerformanceResourceTiming_redirectStart_Getter";
+
+  @DomName('PerformanceResourceTiming.requestStart')
+  @DocsEditable
+  num get requestStart native "PerformanceResourceTiming_requestStart_Getter";
+
+  @DomName('PerformanceResourceTiming.responseEnd')
+  @DocsEditable
+  num get responseEnd native "PerformanceResourceTiming_responseEnd_Getter";
+
+  @DomName('PerformanceResourceTiming.responseStart')
+  @DocsEditable
+  num get responseStart native "PerformanceResourceTiming_responseStart_Getter";
+
+  @DomName('PerformanceResourceTiming.secureConnectionStart')
+  @DocsEditable
+  num get secureConnectionStart native "PerformanceResourceTiming_secureConnectionStart_Getter";
+
+}
+// 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('PerformanceTiming')
 class PerformanceTiming extends NativeFieldWrapperClass1 {
   PerformanceTiming.internal();
@@ -21361,6 +21973,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SourceBuffer> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SourceBuffer> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SourceBuffer removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21381,16 +22001,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SourceBuffer> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SourceBuffer> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SourceBuffer initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SourceBuffer> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SourceBuffer fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SourceBuffer> getRange(int start, int end) =>
@@ -21687,6 +22311,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SpeechGrammar> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SpeechGrammar> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SpeechGrammar removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -21707,16 +22339,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SpeechGrammar> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SpeechGrammar> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SpeechGrammar initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SpeechGrammar> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SpeechGrammar fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SpeechGrammar> getRange(int start, int end) =>
@@ -23428,6 +24064,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<TextTrackCue> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<TextTrackCue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   TextTrackCue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23448,16 +24092,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<TextTrackCue> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<TextTrackCue> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [TextTrackCue initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<TextTrackCue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [TextTrackCue fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<TextTrackCue> getRange(int start, int end) =>
@@ -23645,6 +24293,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<TextTrack> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<TextTrack> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   TextTrack removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -23665,16 +24321,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<TextTrack> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<TextTrack> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [TextTrack initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<TextTrack> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [TextTrack fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<TextTrack> getRange(int start, int end) =>
@@ -24079,6 +24739,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Touch> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Touch> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Touch removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -24099,16 +24767,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Touch> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Touch> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Touch initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Touch> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Touch fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Touch> getRange(int start, int end) =>
@@ -24596,6 +25268,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -24616,16 +25296,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -24839,6 +25523,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -24859,16 +25551,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -25082,6 +25778,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25102,16 +25806,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -25323,6 +26031,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   int removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -25343,16 +26059,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<int> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<int> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [int initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<int> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [int fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<int> getRange(int start, int end) =>
@@ -25638,6 +26358,23 @@
 
 
 @DocsEditable
+@DomName('WebKitCSSRegionRule')
+class WebKitCssRegionRule extends CssRule {
+  WebKitCssRegionRule.internal() : super.internal();
+
+  @DomName('WebKitCSSRegionRule.cssRules')
+  @DocsEditable
+  List<CssRule> get cssRules native "WebKitCSSRegionRule_cssRules_Getter";
+
+}
+// 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('WebKitNamedFlow')
 class WebKitNamedFlow extends EventTarget {
   WebKitNamedFlow.internal() : super.internal();
@@ -26809,7 +27546,7 @@
   const _BeforeUnloadEventStreamProvider(this._eventType);
 
   Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
-    var controller = new StreamController.broadcast();
+    var controller = new StreamController();
     var stream = new _EventStream(e, _eventType, useCapture);
     stream.listen((event) {
       var wrapped = new _BeforeUnloadEvent(event);
@@ -27429,6 +28166,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Rect> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Rect> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Rect removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27449,16 +28194,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Rect> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Rect> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Rect initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Rect> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Rect fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Rect> getRange(int start, int end) =>
@@ -27651,6 +28400,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<CssRule> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<CssRule> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   CssRule removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27671,16 +28428,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<CssRule> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<CssRule> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [CssRule initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<CssRule> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [CssRule fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<CssRule> getRange(int start, int end) =>
@@ -27860,6 +28621,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<_CSSValue> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<_CSSValue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   _CSSValue removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -27880,16 +28649,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<_CSSValue> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<_CSSValue> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [_CSSValue initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<_CSSValue> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [_CSSValue fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<_CSSValue> getRange(int start, int end) =>
@@ -28305,6 +29078,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Entry> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Entry> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Entry removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28325,16 +29106,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Entry> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Entry> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Entry initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Entry> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Entry fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Entry> getRange(int start, int end) =>
@@ -28514,6 +29299,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<_EntrySync> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<_EntrySync> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   _EntrySync removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28534,16 +29327,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<_EntrySync> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<_EntrySync> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [_EntrySync initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<_EntrySync> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [_EntrySync fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<_EntrySync> getRange(int start, int end) =>
@@ -28784,6 +29581,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Gamepad> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Gamepad> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Gamepad removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -28804,16 +29609,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Gamepad> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Gamepad> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Gamepad initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Gamepad> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Gamepad fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Gamepad> getRange(int start, int end) =>
@@ -29084,6 +29893,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Node removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29104,16 +29921,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Node> getRange(int start, int end) =>
@@ -29378,6 +30199,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SpeechInputResult> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SpeechInputResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SpeechInputResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29398,16 +30227,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SpeechInputResult> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SpeechInputResult> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SpeechInputResult initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SpeechInputResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SpeechInputResult fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SpeechInputResult> getRange(int start, int end) =>
@@ -29587,6 +30420,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<SpeechRecognitionResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   SpeechRecognitionResult removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29607,16 +30448,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<SpeechRecognitionResult> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<SpeechRecognitionResult> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [SpeechRecognitionResult initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<SpeechRecognitionResult> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [SpeechRecognitionResult fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<SpeechRecognitionResult> getRange(int start, int end) =>
@@ -29796,6 +30641,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<StyleSheet> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<StyleSheet> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   StyleSheet removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -29816,16 +30669,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<StyleSheet> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<StyleSheet> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [StyleSheet initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<StyleSheet> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [StyleSheet fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<StyleSheet> getRange(int start, int end) =>
@@ -30604,9 +31461,9 @@
   bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
-      { void onError(AsyncError error),
-      void onDone(),
-      bool unsubscribeOnError}) {
+      { void onError(error),
+        void onDone(),
+        bool cancelOnError}) {
 
     return new _EventStreamSubscription<T>(
         this._target, this._eventType, onData, this._useCapture);
@@ -30648,7 +31505,7 @@
   }
 
   /// Has no effect.
-  void onError(void handleError(AsyncError error)) {}
+  void onError(void handleError(error)) {}
 
   /// Has no effect.
   void onDone(void handleDone()) {}
@@ -30682,6 +31539,12 @@
       _target.$dom_removeEventListener(_eventType, _onData, _useCapture);
     }
   }
+
+  Future asFuture([var futureValue]) {
+    // We just need a future that will never succeed or fail.
+    Completer completer = new Completer();
+    return completer.future;
+  }
 }
 
 
@@ -30771,7 +31634,7 @@
   static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
 
   /** Controller to produce KeyEvents for the stream. */
-  final StreamController _controller = new StreamController.broadcast();
+  final StreamController _controller = new StreamController();
 
   static const _EVENT_TYPE = 'KeyEvent';
 
@@ -31992,14 +32855,14 @@
     // Catch and report them a global exceptions.
     try {
       if (node._hasLocalModel != true && node._model != model &&
-          node._modelChangedStream != null) {
+          node._modelChangedStreams != null &&
+          !node._modelChangedStreams.isEmpty) {
         node._model = model;
-        node._modelChangedStream.add(node);
+        node._modelChangedStreams.toList()
+          .forEach((controller) => controller.add(node));
       }
-    } on AsyncError catch (e) {
-      e.throwDelayed();
     } catch (e, s) {
-      new AsyncError(e, s).throwDelayed();
+      new Future.error(e, s);
     }
     for (var child = node.$dom_firstChild; child != null;
         child = child.nextNode) {
@@ -32391,6 +33254,12 @@
 
   void insert(int index, E element) => _list.insert(index, element);
 
+  void insertAll(int index, Iterable<E> iterable) =>
+      _list.insertAll(index, iterable);
+
+  void setAll(int index, Iterable<E> iterable) =>
+      _list.setAll(index, iterable);
+
   E removeAt(int index) => _list.removeAt(index);
 
   E removeLast() => _list.removeLast();
@@ -32399,14 +33268,18 @@
 
   Iterable<E> getRange(int start, int end) => _list.getRange(start, end);
 
-  void setRange(int start, int length, List<E> from, [int startFrom]) {
-    _list.setRange(start, length, from, startFrom);
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _list.setRange(start, end, iterable, skipCount);
   }
 
-  void removeRange(int start, int length) { _list.removeRange(start, length); }
+  void removeRange(int start, int end) { _list.removeRange(start, end); }
 
-  void insertRange(int start, int length, [E fill]) {
-    _list.insertRange(start, length, fill);
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    _list.replaceRange(start, end, iterable);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    _list.fillRange(start, end, fillValue);
   }
 
   Map<int, E> asMap() => _list.asMap();
diff --git a/sdk/lib/html/html_common/filtered_element_list.dart b/sdk/lib/html/html_common/filtered_element_list.dart
index bb253e6..0efe3d5 100644
--- a/sdk/lib/html/html_common/filtered_element_list.dart
+++ b/sdk/lib/html/html_common/filtered_element_list.dart
@@ -46,7 +46,7 @@
       throw new ArgumentError("Invalid list length");
     }
 
-    removeRange(newLength, len - newLength);
+    removeRange(newLength, len);
   }
 
   String join([String separator = ""]) => _filtered.join(separator);
@@ -71,18 +71,23 @@
     throw new UnsupportedError('TODO(jacobr): should we impl?');
   }
 
-  void setRange(int start, int rangeLength, List from, [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
     throw new UnimplementedError();
   }
 
-  void removeRange(int start, int rangeLength) {
-    _filtered.sublist(start, start + rangeLength).forEach((el) => el.remove());
+  void fillRange(int start, int end, [Element fillValue]) {
+    throw new UnimplementedError();
   }
 
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
     throw new UnimplementedError();
   }
 
+  void removeRange(int start, int end) {
+    _filtered.sublist(start, end).forEach((el) => el.remove());
+  }
+
   void clear() {
     // Currently, ElementList#clear clears even non-element nodes, so we follow
     // that behavior.
@@ -105,6 +110,10 @@
     _childNodes.insert(index, value);
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    _childNodes.insertAll(index, iterable);
+  }
+
   Element removeAt(int index) {
     final result = this[index];
     result.remove();
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index a6d84a6..cdd2742 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -143,7 +143,7 @@
    try {
       return _completeRequest($dom_delete());
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -152,7 +152,7 @@
    try {
       return _completeRequest($dom_update(value));
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -367,7 +367,7 @@
       {int version, void onUpgradeNeeded(VersionChangeEvent),
       void onBlocked(Event)}) {
     if ((version == null) != (onUpgradeNeeded == null)) {
-      return new Future.immediateError(new ArgumentError(
+      return new Future.error(new ArgumentError(
           'version and onUpgradeNeeded must be specified together'));
     }
     try {
@@ -386,7 +386,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -401,7 +401,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -414,7 +414,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -492,7 +492,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -503,7 +503,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -514,7 +514,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -714,7 +714,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -723,7 +723,7 @@
     try {
       return _completeRequest($dom_clear());
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -732,7 +732,7 @@
     try {
       return _completeRequest($dom_delete(key_OR_keyRange));
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -747,7 +747,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -762,7 +762,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -773,7 +773,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index 6fad318..87c0ebe 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -45,7 +45,7 @@
    try {
       return _completeRequest($dom_delete());
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -54,7 +54,7 @@
    try {
       return _completeRequest($dom_update(value));
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -261,7 +261,7 @@
       {int version, void onUpgradeNeeded(VersionChangeEvent),
       void onBlocked(Event)}) {
     if ((version == null) != (onUpgradeNeeded == null)) {
-      return new Future.immediateError(new ArgumentError(
+      return new Future.error(new ArgumentError(
           'version and onUpgradeNeeded must be specified together'));
     }
     try {
@@ -280,7 +280,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -295,7 +295,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -308,7 +308,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -388,7 +388,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -399,7 +399,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -410,7 +410,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -749,7 +749,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -758,7 +758,7 @@
     try {
       return _completeRequest($dom_clear());
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -767,7 +767,7 @@
     try {
       return _completeRequest($dom_delete(key_OR_keyRange));
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -782,7 +782,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -797,7 +797,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -808,7 +808,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
diff --git a/sdk/lib/io/buffer_list.dart b/sdk/lib/io/buffer_list.dart
index 25a4fdd..72dc92f 100644
--- a/sdk/lib/io/buffer_list.dart
+++ b/sdk/lib/io/buffer_list.dart
@@ -94,19 +94,15 @@
         while (remaining > 0) {
           int bytesInFirst = _buffers.first.length - _index;
           if (bytesInFirst <= remaining) {
-            result.setRange(count - remaining,
-                            bytesInFirst,
-                            _buffers.first,
-                            _index);
+            int startIndex = count - remaining;
+            int endIndex = startIndex + bytesInFirst;
+            result.setRange(startIndex, endIndex, _buffers.first, _index);
             _buffers.removeFirst();
             _index = 0;
             _length -= bytesInFirst;
             remaining -= bytesInFirst;
           } else {
-            result.setRange(count - remaining,
-                            remaining,
-                            _buffers.first,
-                            _index);
+            result.setRange(count - remaining, count, _buffers.first, _index);
             _index = remaining;
             _length -= remaining;
             remaining = 0;
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index f4d6907..9350ad6 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -58,26 +58,36 @@
 
 
 // Object for holding a buffer and an offset.
-class _BufferAndOffset {
-  _BufferAndOffset(List this.buffer, int this.offset);
+class _BufferAndStart {
+  _BufferAndStart(List this.buffer, int this.start);
   List buffer;
-  int offset;
+  int start;
 }
 
 // Ensure that the input List can be serialized through a native port.
 // Only builtin Lists can be serialized through. If user-defined Lists
 // get here, the contents is copied to a Uint8List. This has the added
 // benefit that it is faster to access from the C code as well.
-_BufferAndOffset _ensureFastAndSerializableBuffer(
-    List buffer, int offset, int bytes) {
+_BufferAndStart _ensureFastAndSerializableBuffer(
+    List buffer, int start, int end) {
   if (buffer is Uint8List ||
       buffer is Int8List ||
+      buffer is Uint16List ||
+      buffer is Int16List ||
+      buffer is Uint32List ||
+      buffer is Int32List ||
+      buffer is Uint64List ||
+      buffer is Int64List ||
+      buffer is ByteData ||
+      buffer is Float32List ||
+      buffer is Float64List ||
       _BufferUtils._isBuiltinList(buffer)) {
-    return new _BufferAndOffset(buffer, offset);
+    return new _BufferAndStart(buffer, start);
   }
-  var newBuffer = new Uint8List(bytes);
-  int j = offset;
-  for (int i = 0; i < bytes; i++) {
+  int length = end - start;
+  var newBuffer = new Uint8List(length);
+  int j = start;
+  for (int i = 0; i < length; i++) {
     int value = buffer[j];
     if (value is! int) {
       throw new ArgumentError("List element is not an integer at index $j");
@@ -85,7 +95,7 @@
     newBuffer[i] = value;
     j++;
   }
-  return new _BufferAndOffset(newBuffer, 0);
+  return new _BufferAndStart(newBuffer, 0);
 }
 
 
diff --git a/sdk/lib/io/data_transformer.dart b/sdk/lib/io/data_transformer.dart
index cb7d705..4a4001d 100644
--- a/sdk/lib/io/data_transformer.dart
+++ b/sdk/lib/io/data_transformer.dart
@@ -51,7 +51,8 @@
       }
     } catch (e, s) {
       _closed = true;
-      sink.addError(new AsyncError(e, s));
+      // TODO(floitsch): we are losing the stack trace.
+      sink.addError(e);
       sink.close();
     }
   }
@@ -65,7 +66,8 @@
         sink.add(out);
       }
     } catch (e, s) {
-      sink.addError(new AsyncError(e, s));
+      // TODO(floitsch): we are losing the stack trace.
+      sink.addError(e);
       _closed = true;
     }
     if (!_closed) _filter.end();
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 6b6cc38..3aaf219 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -64,14 +64,14 @@
       } else {
         future = future.then((index) {
           if (index != notFound) {
-            return new Future.immediate(index);
+            return new Future.value(index);
           }
           return dirsToCreate[i].exists().then((e) => e ? i : notFound);
         });
       }
     }
     if (future == null) {
-      return new Future.immediate(notFound);
+      return new Future.value(notFound);
     } else {
       return future;
     }
@@ -100,7 +100,7 @@
         }
       }
       if (future == null) {
-        return new Future.immediate(this);
+        return new Future.value(this);
       } else {
         return future.then((_) => this);
       }
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 4ebaa70..20110af 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -205,8 +205,8 @@
    *  has an [:encoding:] property which can be changed after the
    *  [IOSink] has been created.
    */
-  IOSink<File> openWrite({FileMode mode: FileMode.WRITE,
-                          Encoding encoding: Encoding.UTF_8});
+  IOSink openWrite({FileMode mode: FileMode.WRITE,
+                    Encoding encoding: Encoding.UTF_8});
 
   /**
    * Read the entire file contents as a list of bytes. Returns a
@@ -368,20 +368,26 @@
   List<int> readSync(int bytes);
 
   /**
-   * Reads into an existing List<int> from the file. A maximum of [bytes] bytes
-   * is read into [buffer], starting at position [offset] in the buffer.
+   * Reads into an existing List<int> from the file. If [start] is present, the
+   * bytes will be filled into [buffer] from at index [start], otherwise index
+   * 0. If [end] is present, the [end] - [start] bytes will be read into
+   * [buffer], otherwise up to [buffer.length]. If [end] == [start] nothing
+   * happends.
+   *
    * Returns a [:Future<int>:] that completes with the number of bytes read.
    */
-  Future<int> readList(List<int> buffer, int offset, int bytes);
+  Future<int> readInto(List<int> buffer, [int start, int end]);
 
   /**
-   * Synchronously reads from a file into [buffer].  A maximum of [bytes] bytes
-   * is read into [buffer], starting at position [offset] in the buffer.
-   * Returns the number of bytes read.
+   * Synchronously reads into an existing List<int> from the file. If [start] is
+   * present, the bytes will be filled into [buffer] from at index [start],
+   * otherwise index 0.  If [end] is present, the [end] - [start] bytes will be
+   * read into [buffer], otherwise up to [buffer.length]. If [end] == [start]
+   * nothing happends.
    *
    * Throws a [FileIOException] if the operation fails.
    */
-  int readListSync(List<int> buffer, int offset, int bytes);
+  int readIntoSync(List<int> buffer, [int start, int end]);
 
   /**
    * Writes a single byte to the file. Returns a
@@ -399,21 +405,24 @@
   int writeByteSync(int value);
 
   /**
-   * Writes from a List<int> to the file. [bytes] bytes are written from
-   * [buffer], starting at position [offset] in the buffer. Returns a
-   * [:Future<RandomAccessFile>:] that completes with this
-   * RandomAccessFile when the write completes.
+   * Writes from a [List<int>] to the file. It will read the buffer from index
+   * [start] to index [end]. If [start] is omitted, it'll start from index 0.
+   * If [end] is omitted, it will write to end of [buffer].
+   *
+   * Returns a [:Future<RandomAccessFile>:] that completes with this
+   * [RandomAccessFile] when the write completes.
    */
-  Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes);
+  Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]);
 
   /**
-   * Synchronously writes a List<int> to the file.  [bytes] bytes are
-   * written from [buffer], starting at position [offset] in the
-   * buffer. Returns the number of bytes successfully written.
+   * Synchronously writes from a [List<int>] to the file. It will read the
+   * buffer from index [start] to index [end]. If [start] is omitted, it'll
+   * start from index 0. If [end] is omitted, it will write to the end of
+   * [buffer].
    *
    * Throws a [FileIOException] if the operation fails.
    */
-  int writeListSync(List<int> buffer, int offset, int bytes);
+  void writeFromSync(List<int> buffer, [int start, int end]);
 
   /**
    * Writes a string to the file using the given [Encoding]. Returns a
@@ -425,13 +434,12 @@
 
   /**
    * Synchronously writes a single string to the file using the given
-   * [Encoding]. Returns the number of characters successfully
-   * written.
+   * [Encoding].
    *
    * Throws a [FileIOException] if the operation fails.
    */
-  int writeStringSync(String string,
-                      {Encoding encoding: Encoding.UTF_8});
+  void writeStringSync(String string,
+                       {Encoding encoding: Encoding.UTF_8});
 
   /**
    * Gets the current byte position in the file. Returns a
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 65f7adf..a5ae2f5 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -36,19 +36,24 @@
   }
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _controller.stream.listen(onData,
                                      onError: onError,
                                      onDone: onDone,
-                                     unsubscribeOnError: unsubscribeOnError);
+                                     cancelOnError: cancelOnError);
   }
 
   void _setupController() {
     _controller = new StreamController<List<int>>(
-        onSubscriptionStateChange: _onSubscriptionStateChange,
-        onPauseStateChange: _onPauseStateChange);
+        onListen: _start,
+        onPause: () => _paused = true,
+        onResume: _resume,
+        onCancel: () {
+          _unsubscribed = true;
+          _closeFile();
+        });
   }
 
   Future _closeFile() {
@@ -58,7 +63,7 @@
       _openedFile = null;
       return closeFuture;
     } else {
-      return new Future.immediate(null);
+      return new Future.value();
     }
   }
 
@@ -106,7 +111,7 @@
     if (_path != null) {
       openFuture = new File(_path).open(mode: FileMode.READ);
     } else {
-      openFuture = new Future.immediate(_File._openStdioSync(0));
+      openFuture = new Future.value(_File._openStdioSync(0));
     }
     openFuture
       .then((RandomAccessFile opened) {
@@ -128,23 +133,6 @@
     // Resume reading unless we are already done.
     if (_openedFile != null) _readBlock();
   }
-
-  void _onSubscriptionStateChange() {
-    if (_controller.hasListener) {
-      _start();
-    } else {
-      _unsubscribed = true;
-      _closeFile();
-    }
-  }
-
-  void _onPauseStateChange() {
-    if (_controller.isPaused) {
-      _paused = true;
-    } else {
-      _resume();
-    }
-  }
 }
 
 class _FileStreamConsumer extends StreamConsumer<List<int>> {
@@ -158,11 +146,7 @@
 
   _FileStreamConsumer.fromStdio(int fd) {
     assert(1 <= fd && fd <= 2);
-    _openFuture = new Future.immediate(_File._openStdioSync(fd));
-  }
-
-  Future<File> consume(Stream<List<int>> stream) {
-    return addStream(stream).then((_) => close());
+    _openFuture = new Future.value(_File._openStdioSync(fd));
   }
 
   Future<File> addStream(Stream<List<int>> stream) {
@@ -172,7 +156,7 @@
         _subscription = stream.listen(
           (d) {
             _subscription.pause();
-            openedFile.writeList(d, 0, d.length)
+            openedFile.writeFrom(d, 0, d.length)
               .then((_) => _subscription.resume())
               .catchError((e) {
                 openedFile.close();
@@ -186,7 +170,7 @@
             openedFile.close();
             completer.completeError(e);
           },
-          unsubscribeOnError: true);
+          cancelOnError: true);
       })
       .catchError((e) {
         completer.completeError(e);
@@ -476,15 +460,15 @@
     return new _FileStream(_path);
   }
 
-  IOSink<File> openWrite({FileMode mode: FileMode.WRITE,
-                          Encoding encoding: Encoding.UTF_8}) {
+  IOSink openWrite({FileMode mode: FileMode.WRITE,
+                    Encoding encoding: Encoding.UTF_8}) {
     if (mode != FileMode.WRITE &&
         mode != FileMode.APPEND) {
       throw new FileIOException(
           "Wrong FileMode. Use FileMode.WRITE or FileMode.APPEND");
     }
     var consumer = new _FileStreamConsumer(this, mode);
-    return new IOSink<File>(consumer, encoding: encoding);
+    return new IOSink(consumer, encoding: encoding);
   }
 
   Future<List<int>> readAsBytes() {
@@ -501,7 +485,7 @@
       onError: (e) {
         completer.completeError(e);
       },
-      unsubscribeOnError: true);
+      cancelOnError: true);
     return completer.future;
   }
 
@@ -556,18 +540,18 @@
   Future<File> writeAsBytes(List<int> bytes,
                             {FileMode mode: FileMode.WRITE}) {
     try {
-      IOSink<File> sink = openWrite(mode: mode);
+      IOSink sink = openWrite(mode: mode);
       sink.add(bytes);
       sink.close();
       return sink.done.then((_) => this);;
     } catch (e) {
-      return new Future.immediateError(e);
+      return new Future.error(e);
     }
   }
 
   void writeAsBytesSync(List<int> bytes, {FileMode mode: FileMode.WRITE}) {
     RandomAccessFile opened = openSync(mode: mode);
-    opened.writeListSync(bytes, 0, bytes.length);
+    opened.writeFromSync(bytes, 0, bytes.length);
     opened.closeSync();
   }
 
@@ -715,57 +699,59 @@
     return result;
   }
 
-  Future<int> readList(List<int> buffer, int offset, int bytes) {
+  Future<int> readInto(List<int> buffer, [int start, int end]) {
     _ensureFileService();
-    Completer<int> completer = new Completer<int>();
-    if (buffer is !List || offset is !int || bytes is !int) {
-      // Complete asynchronously so the user has a chance to setup
-      // handlers without getting exceptions when registering the
-      // then handler.
-      Timer.run(() {
-        completer.completeError(new FileIOException(
-            "Invalid arguments to readList for file '$_path'"));
-      });
-      return completer.future;
+    if (buffer is !List ||
+        (start != null && start is !int) ||
+        (end != null && end is !int)) {
+      return new Future.error(new FileIOException(
+          "Invalid arguments to readInto for file '$_path'"));
     };
+    Completer<int> completer = new Completer<int>();
     if (closed) return _completeWithClosedException(completer);
     List request = new List(3);
+    if (start == null) start = 0;
+    if (end == null) end = buffer.length;
     request[0] = _READ_LIST_REQUEST;
     request[1] = _id;
-    request[2] = bytes;
+    request[2] = end - start;
     return _fileService.call(request).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response,
-                                     "readList failed for file '$_path'");
+                                     "readInto failed for file '$_path'");
       }
       var read = response[1];
       var data = response[2];
-      buffer.setRange(offset, read, data);
+      buffer.setRange(start, start + read, data);
       return read;
     });
   }
 
-  static void _checkReadWriteListArguments(int length, int offset, int bytes) {
-    if (offset < 0) throw new RangeError.value(offset);
-    if (bytes < 0) throw new RangeError.value(bytes);
-    if ((offset + bytes) > length) {
-      throw new RangeError.value(offset + bytes);
+  static void _checkReadWriteListArguments(int length, int start, int end) {
+    if (start < 0) throw new RangeError.value(start);
+    if (end < start) throw new RangeError.value(end);
+    if (end > length) {
+      throw new RangeError.value(end);
     }
   }
 
-  external static _readList(int id, List<int> buffer, int offset, int bytes);
+  external static _readInto(int id, List<int> buffer, int start, int end);
 
-  int readListSync(List<int> buffer, int offset, int bytes) {
+  int readIntoSync(List<int> buffer, [int start, int end]) {
     _checkNotClosed();
-    if (buffer is !List || offset is !int || bytes is !int) {
+    if (buffer is !List ||
+        (start != null && start is !int) ||
+        (end != null && end is !int)) {
       throw new FileIOException(
-          "Invalid arguments to readList for file '$_path'");
+          "Invalid arguments to readInto for file '$_path'");
     }
-    if (bytes == 0) return 0;
-    _checkReadWriteListArguments(buffer.length, offset, bytes);
-    var result = _readList(_id, buffer, offset, bytes);
+    if (start == null) start = 0;
+    if (end == null) end = buffer.length;
+    if (end == start) return 0;
+    _checkReadWriteListArguments(buffer.length, start, end);
+    var result = _readInto(_id, buffer, start, end);
     if (result is OSError) {
-      throw new FileIOException("readList failed for file '$_path'",
+      throw new FileIOException("readInto failed for file '$_path'",
                                 result);
     }
     return result;
@@ -814,65 +800,63 @@
     return result;
   }
 
-  Future<RandomAccessFile> writeList(List<int> buffer, int offset, int bytes) {
+  Future<RandomAccessFile> writeFrom(List<int> buffer, [int start, int end]) {
     _ensureFileService();
-    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
-    if (buffer is !List || offset is !int || bytes is !int) {
-      // Complete asynchronously so the user has a chance to setup
-      // handlers without getting exceptions when registering the
-      // then handler.
-      Timer.run(() {
-          completer.completeError(new FileIOException(
-          "Invalid arguments to writeList for file '$_path'"));
-      });
-      return completer.future;
+    if ((buffer is !List && buffer is !ByteData) ||
+        (start != null && start is !int) ||
+        (end != null && end is !int)) {
+      return new Future.error(new FileIOException(
+          "Invalid arguments to writeFrom for file '$_path'"));
     }
+    Completer<RandomAccessFile> completer = new Completer<RandomAccessFile>();
+
     if (closed) return _completeWithClosedException(completer);
 
-    _BufferAndOffset result;
+    _BufferAndStart result;
     try {
-      result = _ensureFastAndSerializableBuffer(buffer, offset, bytes);
+      result = _ensureFastAndSerializableBuffer(buffer, start, end);
     } catch (e) {
-      // Complete asynchronously so the user has a chance to setup
-      // handlers without getting exceptions when registering the
-      // then handler.
-      Timer.run(() => completer.completeError(e));
-      return completer.future;
+      return new Future.error(e);
     }
 
     List request = new List(5);
     request[0] = _WRITE_LIST_REQUEST;
     request[1] = _id;
     request[2] = result.buffer;
-    request[3] = result.offset;
-    request[4] = bytes;
+    request[3] = result.start;
+    request[4] = end - (start - result.start);
     return _fileService.call(request).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response,
-                                     "writeList failed for file '$_path'");
+                                     "writeFrom failed for file '$_path'");
       }
       return this;
     });
   }
 
-  external static _writeList(int id, List<int> buffer, int offset, int bytes);
+  external static _writeFrom(int id, List<int> buffer, int start, int end);
 
-  int writeListSync(List<int> buffer, int offset, int bytes) {
+  void writeFromSync(List<int> buffer, [int start, int end]) {
     _checkNotClosed();
-    if (buffer is !List || offset is !int || bytes is !int) {
+    if (buffer is !List ||
+        (start != null && start is !int) ||
+        (end != null && end is !int)) {
       throw new FileIOException(
-          "Invalid arguments to writeList for file '$_path'");
+          "Invalid arguments to writeFrom for file '$_path'");
     }
-    if (bytes == 0) return 0;
-    _checkReadWriteListArguments(buffer.length, offset, bytes);
-    _BufferAndOffset bufferAndOffset =
-        _ensureFastAndSerializableBuffer(buffer, offset, bytes);
-    var result =
-      _writeList(_id, bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
+    if (start == null) start = 0;
+    if (end == null) end = buffer.length;
+    if (end == start) return;
+    _checkReadWriteListArguments(buffer.length, start, end);
+    _BufferAndStart bufferAndStart =
+        _ensureFastAndSerializableBuffer(buffer, start, end);
+    var result = _writeFrom(_id,
+                            bufferAndStart.buffer,
+                            bufferAndStart.start,
+                            end - (start - bufferAndStart.start));
     if (result is OSError) {
-      throw new FileIOException("writeList failed for file '$_path'", result);
+      throw new FileIOException("writeFrom failed for file '$_path'", result);
     }
-    return result;
   }
 
   Future<RandomAccessFile> writeString(String string,
@@ -886,16 +870,16 @@
       return completer.future;
     }
     var data = _encodeString(string, encoding);
-    return writeList(data, 0, data.length);
+    return writeFrom(data, 0, data.length);
   }
 
-  int writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) {
+  void writeStringSync(String string, {Encoding encoding: Encoding.UTF_8}) {
     if (encoding is! Encoding) {
       throw new FileIOException(
           "Invalid encoding in writeStringSync: $encoding");
     }
     var data = _encodeString(string, encoding);
-    return writeListSync(data, 0, data.length);
+    writeFromSync(data, 0, data.length);
   }
 
   Future<int> position() {
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 72fd67c..21830f2 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -509,6 +509,11 @@
   }
 
   /**
+   * Gets the mime-type, without any parameters.
+   */
+  String get mimeType;
+
+  /**
    * Gets the primary type.
    */
   String get primaryType;
@@ -703,7 +708,7 @@
  * If an unsupported encoding is used an exception will be thrown if
  * using one of the write methods taking a string.
  */
-abstract class HttpResponse implements IOSink<HttpResponse> {
+abstract class HttpResponse implements IOSink {
   // TODO(ajohnsen): Add documentation of how to pipe a file to the response.
   /**
    * Gets and sets the content length of the response. If the size of
@@ -926,12 +931,12 @@
    *
    * The following environment variables are taken into account:
    *
-   *  * http_proxy
-   *  * https_proxy
-   *  * no_proxy
-   *  * HTTP_PROXY
-   *  * HTTPS_PROXY
-   *  * NO_PROXY
+   *     http_proxy
+   *     https_proxy
+   *     no_proxy
+   *     HTTP_PROXY
+   *     HTTPS_PROXY
+   *     NO_PROXY
    *
    * [:http_proxy:] and [:HTTP_PROXY:] specify the proxy server to use for
    * http:// urls. Use the format [:hostname:port:]. If no port is used a
@@ -963,6 +968,12 @@
    *       return HttpClient.findProxyFromEnvironment(
    *           url, {"http_proxy": ..., "no_proxy": ...});
    *     }
+   *
+   * If a proxy requires authentication it is possible to configure
+   * the username and password as well. Use the format
+   * [:username:password@hostname:port:] to include the username and
+   * password. Alternatively the API [addProxyCredentials] can be used
+   * to set credentials for proxies which require authentication.
    */
   static String findProxyFromEnvironment(Uri url,
                                          {Map<String, String> environment}) {
@@ -970,6 +981,34 @@
   }
 
   /**
+   * Sets the function to be called when a proxy is requesting
+   * authentication. Information on the proxy in use and the security
+   * realm for the authentication are passed in the arguments [host],
+   * [port] and [realm].
+   *
+   * The function returns a [Future] which should complete when the
+   * authentication has been resolved. If credentials cannot be
+   * provided the [Future] should complete with [false]. If
+   * credentials are available the function should add these using
+   * [addProxyCredentials] before completing the [Future] with the value
+   * [true].
+   *
+   * If the [Future] completes with [true] the request will be retried
+   * using the updated credentials. Otherwise response processing will
+   * continue normally.
+   */
+  set authenticateProxy(
+      Future<bool> f(String host, int port, String scheme, String realm));
+
+  /**
+   * Add credentials to be used for authorizing HTTP proxies.
+   */
+  void addProxyCredentials(String host,
+                           int port,
+                           String realm,
+                           HttpClientCredentials credentials);
+
+  /**
    * Shutdown the HTTP client. If [force] is [:false:] (the default)
    * the [:HttpClient:] will be kept alive until all active
    * connections are done. If [force] is [:true:] any active
@@ -1012,8 +1051,7 @@
  * If an unsupported encoding is used an exception will be thrown if
  * using one of the write methods taking a string.
  */
-abstract class HttpClientRequest
-    implements IOSink<HttpClientResponse> {
+abstract class HttpClientRequest implements IOSink {
   /**
    * Gets and sets the content length of the request. If the size of
    * the request is not known in advance set content length to -1,
diff --git a/sdk/lib/io/http_body_impl.dart b/sdk/lib/io/http_body_impl.dart
index 4bd9f81..214daa3 100644
--- a/sdk/lib/io/http_body_impl.dart
+++ b/sdk/lib/io/http_body_impl.dart
@@ -47,22 +47,25 @@
         .then((list) {
           dynamic content = list.readBytes();
           String type = "binary";
-          String mimeType = headers.contentType.toString();
+          ContentType contentType = headers.contentType;
+          if (contentType == null) {
+            return new _HttpBody(null, type, content);
+          }
           String asText(Encoding defaultEncoding) {
             var encoding;
-            var charset = headers.contentType.charset;
+            var charset = contentType.charset;
             if (charset != null) encoding = Encoding.fromName(charset);
             if (encoding == null) encoding = defaultEncoding;
             return _decodeString(content, encoding);
           }
-          switch (headers.contentType.primaryType) {
+          switch (contentType.primaryType) {
             case "text":
               type = "text";
               content = asText(Encoding.ASCII);
               break;
 
             case "application":
-              switch (headers.contentType.subType) {
+              switch (contentType.subType) {
                 case "json":
                   content = JSON.parse(asText(Encoding.UTF_8));
                   type = "json";
@@ -76,7 +79,7 @@
             default:
               break;
           }
-          return new _HttpBody(mimeType, type, content);
+          return new _HttpBody(contentType.mimeType, type, content);
         });
   }
 }
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 261f1cd..919761a 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -48,7 +48,7 @@
     if (values != null) {
       int index = values.indexOf(value);
       if (index != -1) {
-        values.removeRange(index, 1);
+        values.removeRange(index, index + 1);
       }
       if (values.length == 0) _headers.remove(name);
     }
@@ -632,6 +632,8 @@
     }
   }
 
+  String get mimeType => '$primaryType/$subType';
+
   String get primaryType => _primaryType;
 
   String get subType => _subType;
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index cea3e11..6477f3a 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -35,13 +35,13 @@
   }
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _stream.listen(onData,
                           onError: onError,
                           onDone: onDone,
-                          unsubscribeOnError: unsubscribeOnError);
+                          cancelOnError: cancelOnError);
   }
 
   // Is completed once all data have been received.
@@ -106,13 +106,13 @@
   }
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _incoming.listen(onData,
                             onError: onError,
                             onDone: onDone,
-                            unsubscribeOnError: unsubscribeOnError);
+                            cancelOnError: cancelOnError);
   }
 
   Map<String, String> get queryParameters {
@@ -215,7 +215,7 @@
     if (followLoops != true) {
       for (var redirect in redirects) {
         if (redirect.location == url) {
-          return new Future.immediateError(
+          return new Future.error(
               new RedirectLoopException(redirects));
         }
       }
@@ -231,9 +231,9 @@
   }
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     var stream = _incoming;
     if (headers.value(HttpHeaders.CONTENT_ENCODING) == "gzip") {
       stream = stream.transform(new ZLibInflater());
@@ -241,7 +241,7 @@
     return stream.listen(onData,
                          onError: onError,
                          onDone: onDone,
-                         unsubscribeOnError: unsubscribeOnError);
+                         cancelOnError: cancelOnError);
   }
 
   Future<Socket> detachSocket() {
@@ -251,6 +251,13 @@
 
   HttpConnectionInfo get connectionInfo => _httpRequest.connectionInfo;
 
+  bool get _shouldAuthenticateProxy {
+    // Only try to authenticate if there is a challenge in the response.
+    List<String> challenge = headers[HttpHeaders.PROXY_AUTHENTICATE];
+    return statusCode == HttpStatus.PROXY_AUTHENTICATION_REQUIRED &&
+        challenge != null && challenge.length == 1;
+  }
+
   bool get _shouldAuthenticate {
     // Only try to authenticate if there is a challenge in the response.
     List<String> challenge = headers[HttpHeaders.WWW_AUTHENTICATE];
@@ -275,7 +282,7 @@
 
       // Fall through to here to perform normal response handling if
       // there is no sensible authorization handling.
-      return new Future.immediate(this);
+      return new Future.value(this);
     }
 
     List<String> challenge = headers[HttpHeaders.WWW_AUTHENTICATE];
@@ -315,8 +322,56 @@
         }
       });
     }
+
     // No credentials were found and the callback was not set.
-    return new Future.immediate(this);
+    return new Future.value(this);
+  }
+
+  Future<HttpClientResponse> _authenticateProxy() {
+    Future<HttpClientResponse> retryWithProxyCredentials(_ProxyCredentials cr) {
+      return fold(null, (x, y) {}).then((_) {
+          return _httpClient._openUrlFromRequest(_httpRequest.method,
+                                                 _httpRequest.uri,
+                                                 _httpRequest)
+              .then((request) => request.close());
+        });
+    }
+
+    List<String> challenge = headers[HttpHeaders.PROXY_AUTHENTICATE];
+    assert(challenge != null || challenge.length == 1);
+    _HeaderValue header =
+        new _HeaderValue.fromString(challenge[0], parameterSeparator: ",");
+    _AuthenticationScheme scheme =
+        new _AuthenticationScheme.fromString(header.value);
+    String realm = header.parameters["realm"];
+
+    // See if any credentials are available.
+    var proxy = _httpRequest._proxy;
+
+    var cr =  _httpClient._findProxyCredentials(proxy);
+    if (cr != null) {
+      return retryWithProxyCredentials(cr);
+    }
+
+    // Ask for more credentials if none found.
+    if (_httpClient._authenticateProxy != null) {
+      Future authComplete = _httpClient._authenticateProxy(proxy.host,
+                                                           proxy.port,
+                                                           "basic",
+                                                           realm);
+      return authComplete.then((credsAvailable) {
+        if (credsAvailable) {
+          var cr =  _httpClient._findProxyCredentials(proxy);
+          return retryWithProxyCredentials(cr);
+        } else {
+          // No credentials available, complete with original response.
+          return this;
+        }
+      });
+    }
+
+    // No credentials were found and the callback was not set.
+    return new Future.value(this);
   }
 }
 
@@ -326,16 +381,21 @@
   // requests and in error handling.
   bool _ignoreBody = false;
   bool _headersWritten = false;
+  bool _asGZip = false;
 
-  IOSink _ioSink;
+  IOSink _headersSink;
+  IOSink _dataSink;
+
   final _HttpOutgoing _outgoing;
 
   final _HttpHeaders headers;
 
   _HttpOutboundMessage(String protocolVersion, _HttpOutgoing outgoing)
       : _outgoing = outgoing,
-        _ioSink = new IOSink(outgoing, encoding: Encoding.ASCII),
-        headers = new _HttpHeaders(protocolVersion);
+        _headersSink = new IOSink(outgoing, encoding: Encoding.ASCII),
+        headers = new _HttpHeaders(protocolVersion) {
+    _dataSink = new IOSink(new _HttpOutboundConsumer(this));
+  }
 
   int get contentLength => headers.contentLength;
   void set contentLength(int contentLength) {
@@ -362,93 +422,44 @@
   }
 
   void write(Object obj) {
-    _writeHeaders();
-    // This comment is copied from runtime/lib/string_buffer_patch.dart.
-    // TODO(srdjan): The following four lines could be replaced by
-    // '$obj', but apparently this is too slow on the Dart VM.
-    String string;
-    if (obj is String) {
-      string = obj;
-    } else {
-      string = obj.toString();
-      if (string is! String) {
-        throw new ArgumentError('toString() did not return a string');
-      }
-    }
-    if (string.isEmpty) return;
-    _ioSink.write(string);
+    _dataSink.write(obj);
   }
 
   void writeAll(Iterable objects, [String separator = ""]) {
-    bool isFirst = true;
-    for (Object obj in objects) {
-      if (isFirst) {
-        isFirst = false;
-      } else {
-        if (!separator.isEmpty) write(separator);
-      }
-      write(obj);
-    }
+    _dataSink.writeAll(objects, separator);
   }
 
   void writeln([Object obj = ""]) {
-    write(obj);
-    write("\n");
+    _dataSink.writeln(obj);
   }
 
   void writeCharCode(int charCode) {
-    write(new String.fromCharCode(charCode));
+    _dataSink.writeCharCode(charCode);
   }
 
   void add(List<int> data) {
-    _writeHeaders();
     if (data.length == 0) return;
-    _ioSink.add(data);
+    _dataSink.add(data);
   }
 
-  void addError(AsyncError error) {
-    _writeHeaders();
-    _ioSink.addError(error);
-  }
-
-  Future<T> consume(Stream<List<int>> stream) {
-    _writeHeaders();
-    return _ioSink.consume(stream);
+  void addError(error) {
+    _dataSink.addError(error);
   }
 
   Future<T> addStream(Stream<List<int>> stream) {
-    _writeHeaders();
-    return _ioSink.writeStream(stream).then((_) => this);
-  }
-
-  Future<T> writeStream(Stream<List<int>> stream) {
-    return addStream(stream);
+    return _dataSink.addStream(stream);
   }
 
   Future close() {
-    // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and
-    // persistentConnection is not guaranteed to be in sync.
-    if (!_headersWritten && !_ignoreBody && headers.contentLength == -1) {
-      // If no body was written, _ignoreBody is false (it's not a HEAD
-      // request) and the content-length is unspecified, set contentLength to 0.
-      headers.chunkedTransferEncoding = false;
-      headers.contentLength = 0;
-    }
-    _writeHeaders();
-    return _ioSink.close();
+    return _dataSink.close();
   }
 
-  Future<T> get done {
-    _writeHeaders();
-    return _ioSink.done;
-  }
+  Future<T> get done => _dataSink.done;
 
   void _writeHeaders() {
     if (_headersWritten) return;
     _headersWritten = true;
-    _ioSink.encoding = Encoding.ASCII;
     headers._synchronize();  // Be sure the 'chunked' option is updated.
-    bool asGZip = false;
     bool isServerSide = this is _HttpResponse;
     if (isServerSide && headers.chunkedTransferEncoding) {
       var response = this;
@@ -461,30 +472,50 @@
               .any((encoding) => encoding.trim().toLowerCase() == "gzip") &&
           contentEncoding == null) {
         headers.set(HttpHeaders.CONTENT_ENCODING, "gzip");
-        asGZip = true;
+        _asGZip = true;
       }
     }
     _writeHeader();
-    _ioSink = new IOSink(new _HttpOutboundConsumer(_ioSink, _consume, asGZip));
-    _ioSink.encoding = encoding;
   }
 
-  Future _consume(IOSink ioSink, Stream<List<int>> stream, bool asGZip) {
+  Future _addStream(Stream<List<int>> stream) {
+    _writeHeaders();
     int contentLength = headers.contentLength;
     if (_ignoreBody) {
-      ioSink.close();
-      return stream.fold(null, (x, y) {}).then((_) => this);
+      stream.fold(null, (x, y) {}).catchError((_) {});
+      return _headersSink.close();
     }
     stream = stream.transform(new _BufferTransformer());
     if (headers.chunkedTransferEncoding) {
-      if (asGZip) {
+      if (_asGZip) {
         stream = stream.transform(new ZLibDeflater(gzip: true, level: 6));
       }
       stream = stream.transform(new _ChunkedTransformer());
     } else if (contentLength >= 0) {
       stream = stream.transform(new _ContentLengthValidator(contentLength));
     }
-    return stream.pipe(ioSink).then((_) => this);
+    return _headersSink.addStream(stream);
+  }
+
+  Future _close() {
+    // TODO(ajohnsen): Currently, contentLength, chunkedTransferEncoding and
+    // persistentConnection is not guaranteed to be in sync.
+    if (!_headersWritten) {
+      if (!_ignoreBody && headers.contentLength == -1) {
+        // If no body was written, _ignoreBody is false (it's not a HEAD
+        // request) and the content-length is unspecified, set contentLength to
+        // 0.
+        headers.chunkedTransferEncoding = false;
+        headers.contentLength = 0;
+      } else if (!_ignoreBody && headers.contentLength > 0) {
+        _headersSink.close().catchError((_) {});
+        return new Future.error(new HttpException(
+            "No content while contentLength was specified to be greater "
+            " than 0: ${headers.contentLength}."));
+      }
+    }
+    _writeHeaders();
+    return _headersSink.close();
   }
 
   void _writeHeader();  // TODO(ajohnsen): Better name.
@@ -492,21 +523,82 @@
 
 
 class _HttpOutboundConsumer implements StreamConsumer {
-  Function _consume;
-  IOSink _ioSink;
-  bool _asGZip;
-  _HttpOutboundConsumer(IOSink this._ioSink,
-                        Function this._consume,
-                        bool this._asGZip);
+  final _HttpOutboundMessage _outbound;
+  StreamController _controller;
+  StreamSubscription _subscription;
+  Completer _closeCompleter = new Completer();
+  Completer _completer;
 
-  Future consume(var stream) => _consume(_ioSink, stream, _asGZip);
+  _HttpOutboundConsumer(_HttpOutboundMessage this._outbound);
+
+  void _onPause() {
+    if (_controller.isPaused) {
+      _subscription.pause();
+    } else {
+      _subscription.resume();
+    }
+  }
+
+  void _onListen() {
+    if (!_controller.hasListener && _subscription != null) {
+      _subscription.cancel();
+    }
+  }
+
+  _ensureController() {
+    if (_controller != null) return;
+    _controller = new StreamController(onPause: _onPause,
+                                       onResume: _onPause,
+                                       onListen: _onListen,
+                                       onCancel: _onListen);
+    _outbound._addStream(_controller.stream)
+        .then((_) {
+                _done();
+                _closeCompleter.complete(_outbound);
+              },
+              onError: (error) {
+                if (!_done(error)) {
+                  _closeCompleter.completeError(error);
+                }
+              });
+  }
+
+  bool _done([error]) {
+    if (_completer == null) return false;
+    var tmp = _completer;
+    _completer = null;
+    if (error != null) {
+      tmp.completeError(error);
+    } else {
+      tmp.complete(_outbound);
+    }
+    return true;
+  }
 
   Future addStream(var stream) {
-    throw new UnimplementedError("_HttpOutboundConsumer.addStream");
+    _ensureController();
+    _completer = new Completer();
+    _subscription = stream.listen(
+        (data) {
+          _controller.add(data);
+        },
+        onDone: () {
+          _done();
+        },
+        onError: (error) {
+          _done(error);
+        },
+        cancelOnError: true);
+    return _completer.future;
   }
 
   Future close() {
-    throw new UnimplementedError("_HttpOutboundConsumer.close");
+    Future closeOutbound() {
+      return _outbound._close().then((_) => _outbound);
+    }
+    if (_controller == null) return closeOutbound();
+    _controller.close();
+    return _closeCompleter.future.then((_) => closeOutbound());
   }
 }
 
@@ -574,8 +666,8 @@
     // Close connection so the socket is 'free'.
     close();
     done.catchError((_) {
-      // Catch any error on done, as they automatically will be propegated to
-      // the websocket.
+      // Catch any error on done, as they automatically will be
+      // propagated to the websocket.
     });
     return future;
   }
@@ -632,7 +724,7 @@
     // Write headers.
     headers._write(buffer);
     writeCRLF();
-    _ioSink.add(buffer.readBytes());
+    _headersSink.add(buffer.readBytes());
   }
 
   String _findReasonPhrase(int statusCode) {
@@ -705,7 +797,7 @@
   final Completer<HttpClientResponse> _responseCompleter
       = new Completer<HttpClientResponse>();
 
-  final bool _usingProxy;
+  final _Proxy _proxy;
 
   Future<HttpClientResponse> _response;
 
@@ -719,7 +811,7 @@
   _HttpClientRequest(_HttpOutgoing outgoing,
                      Uri this.uri,
                      String this.method,
-                     bool this._usingProxy,
+                     _Proxy this._proxy,
                      _HttpClient this._httpClient,
                      _HttpClientConnection this._httpClientConnection)
       : super("1.1", outgoing) {
@@ -731,17 +823,13 @@
 
   Future<HttpClientResponse> get done {
     if (_response == null) {
-      _response = Future.wait([_responseCompleter.future, super.done])
+      _response = Future.wait([_responseCompleter.future,
+                               super.done])
         .then((list) => list[0]);
     }
     return _response;
   }
 
-  Future<HttpClientResponse> consume(Stream<List<int>> stream) {
-    super.consume(stream);
-    return done;
-  }
-
   Future<HttpClientResponse> close() {
     super.close();
     return done;
@@ -774,13 +862,15 @@
       } else {
         // End with exception, too many redirects.
         future = response.fold(null, (x, y) {})
-            .then((_) => new Future.immediateError(
+            .then((_) => new Future.error(
                 new RedirectLimitExceededException(response.redirects)));
       }
+    } else if (response._shouldAuthenticateProxy) {
+      future = response._authenticateProxy();
     } else if (response._shouldAuthenticate) {
       future = response._authenticate();
     } else {
-      future = new Future<HttpClientResponse>.immediate(response);
+      future = new Future<HttpClientResponse>.value(response);
     }
     future.then(
         (v) => _responseCompleter.complete(v),
@@ -789,7 +879,7 @@
         });
   }
 
-  void _onError(AsyncError error) {
+  void _onError(error) {
     _responseCompleter.completeError(error);
   }
 
@@ -802,7 +892,7 @@
     writeSP();
     // Send the path for direct connections and the whole URL for
     // proxy connections.
-    if (!_usingProxy) {
+    if (_proxy.isDirect) {
       String path = uri.path;
       if (path.length == 0) path = "/";
       if (uri.query != "") {
@@ -837,7 +927,7 @@
     // Write headers.
     headers._write(buffer);
     writeCRLF();
-    _ioSink.add(buffer.readBytes());
+    _headersSink.add(buffer.readBytes());
   }
 }
 
@@ -863,7 +953,7 @@
       header.add(hexDigits[length]);
     } else {
       while (length > 0) {
-        header.insertRange(0, 1, hexDigits[length % 16]);
+        header.insert(0, hexDigits[length % 16]);
         length = length >> 4;
       }
     }
@@ -888,11 +978,11 @@
   void handleData(List<int> data, EventSink<List<int>> sink) {
     _bytesWritten += data.length;
     if (_bytesWritten > expectedContentLength) {
-      sink.addError(new AsyncError(new HttpException(
+      sink.addError(new HttpException(
           "Content size exceeds specified contentLength. "
           "$_bytesWritten bytes written while expected "
           "$expectedContentLength. "
-          "[${new String.fromCharCodes(data)}]")));
+          "[${new String.fromCharCodes(data)}]"));
       sink.close();
     } else {
       sink.add(data);
@@ -901,10 +991,10 @@
 
   void handleDone(EventSink<List<int>> sink) {
     if (_bytesWritten < expectedContentLength) {
-      sink.addError(new AsyncError(new HttpException(
+      sink.addError(new HttpException(
           "Content size below specified contentLength. "
           " $_bytesWritten bytes written while expected "
-          "$expectedContentLength.")));
+          "$expectedContentLength."));
     }
     sink.close();
   }
@@ -913,29 +1003,25 @@
 
 // Extends StreamConsumer as this is an internal type, only used to pipe to.
 class _HttpOutgoing implements StreamConsumer<List<int>> {
-  Function _onStream;
-  final Completer _consumeCompleter = new Completer();
+  final Completer _doneCompleter = new Completer();
+  final StreamConsumer _consumer;
 
-  Future onStream(Future callback(Stream<List<int>> stream)) {
-    _onStream = callback;
-    return _consumeCompleter.future;
-  }
-
-  Future consume(Stream<List<int>> stream) {
-    _onStream(stream)
-        .then((_) => _consumeCompleter.complete(),
-              onError: _consumeCompleter.completeError);
-    // Use .then to ensure a Future branch.
-    return _consumeCompleter.future.then((_) => this);
-  }
+  _HttpOutgoing(StreamConsumer this._consumer);
 
   Future addStream(Stream<List<int>> stream) {
-    throw new UnimplementedError("_HttpOutgoing.addStream");
+    return _consumer.addStream(stream)
+        .catchError((error) {
+          _doneCompleter.completeError(error);
+          throw error;
+        });
   }
 
   Future close() {
-    throw new UnimplementedError("_HttpOutgoing.close");
+    _doneCompleter.complete(_consumer);
+    return new Future.value();
   }
+
+  Future get done => _doneCompleter.future;
 }
 
 
@@ -954,7 +1040,6 @@
                         _HttpClient this._httpClient)
       : _httpParser = new _HttpParser.responseParser() {
     _socket.pipe(_httpParser);
-    _socket.done.catchError((e) { destroy(); });
 
     // Set up handlers on the parser here, so we are sure to get 'onDone' from
     // the parser.
@@ -980,23 +1065,35 @@
         });
   }
 
-  _HttpClientRequest send(Uri uri, int port, String method, bool isDirect) {
+  _HttpClientRequest send(Uri uri, int port, String method, _Proxy proxy) {
     // Start with pausing the parser.
     _subscription.pause();
-    var outgoing = new _HttpOutgoing();
+    var outgoing = new _HttpOutgoing(_socket);
     // Create new request object, wrapping the outgoing connection.
     var request = new _HttpClientRequest(outgoing,
                                          uri,
                                          method,
-                                         !isDirect,
+                                         proxy,
                                          _httpClient,
                                          this);
     request.headers.host = uri.domain;
     request.headers.port = port;
     request.headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
+    if (proxy.isAuthenticated) {
+      // If the proxy configuration contains user information use that
+      // for proxy basic authorization.
+      String auth = CryptoUtils.bytesToBase64(
+          _encodeString("${proxy.username}:${proxy.password}"));
+      request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, "Basic $auth");
+    } else if (!proxy.isDirect && _httpClient._proxyCredentials.length > 0) {
+      var cr =  _httpClient._findProxyCredentials(proxy);
+      if (cr != null) {
+        cr.authorize(request);
+      }
+    }
     if (uri.userInfo != null && !uri.userInfo.isEmpty) {
       // If the URL contains user information use that for basic
-      // authorization
+      // authorization.
       String auth =
           CryptoUtils.bytesToBase64(_encodeString(uri.userInfo));
       request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
@@ -1010,56 +1107,52 @@
     // Start sending the request (lazy, delayed until the user provides
     // data).
     _httpParser.responseToMethod = method;
-    _streamFuture = outgoing.onStream((stream) {
-        return _socket.writeStream(stream)
-            .then((s) {
-              // Request sent, set up response completer.
-              _nextResponseCompleter = new Completer();
+    _streamFuture = outgoing.done
+        .then((s) {
+          // Request sent, set up response completer.
+          _nextResponseCompleter = new Completer();
 
-              // Listen for response.
-              _nextResponseCompleter.future
-                  .then((incoming) {
-                    incoming.dataDone.then((_) {
-                      if (incoming.headers.persistentConnection &&
-                          request.persistentConnection) {
-                        // Return connection, now we are done.
-                        _httpClient._returnConnection(this);
-                        _subscription.resume();
-                      } else {
-                        destroy();
-                      }
-                    });
-                    request._onIncoming(incoming);
-                  })
-                  // If we see a state error, we failed to get the 'first'
-                  // element.
-                  // Transform the error to a HttpParserException, for
-                  // consistency.
-                  .catchError((error) {
-                    throw new HttpParserException(
-                        "Connection closed before data was received");
-                  }, test: (error) => error is StateError)
-                  .catchError((error) {
-                    // We are done with the socket.
+          // Listen for response.
+          _nextResponseCompleter.future
+              .then((incoming) {
+                incoming.dataDone.then((_) {
+                  if (incoming.headers.persistentConnection &&
+                      request.persistentConnection) {
+                    // Return connection, now we are done.
+                    _httpClient._returnConnection(this);
+                    _subscription.resume();
+                  } else {
                     destroy();
-                    request._onError(error);
-                  });
+                  }
+                });
+                request._onIncoming(incoming);
+              })
+              // If we see a state error, we failed to get the 'first'
+              // element.
+              // Transform the error to a HttpParserException, for
+              // consistency.
+              .catchError((error) {
+                throw new HttpParserException(
+                    "Connection closed before data was received");
+              }, test: (error) => error is StateError)
+              .catchError((error) {
+                // We are done with the socket.
+                destroy();
+                request._onError(error);
+              });
 
-              // Resume the parser now we have a handler.
-              _subscription.resume();
-              return s;
-            }, onError: (e) {
-              destroy();
-              throw e;
-            });
-    });
+          // Resume the parser now we have a handler.
+          _subscription.resume();
+          return s;
+        }, onError: (e) {
+          destroy();
+        });
     return request;
   }
 
   Future<Socket> detachSocket() {
-    return _streamFuture
-        .then((_) => new _DetachedSocket(_socket, _httpParser.detachIncoming()),
-              onError: (_) {});
+    return _streamFuture.then(
+        (_) => new _DetachedSocket(_socket, _httpParser.detachIncoming()));
   }
 
   void destroy() {
@@ -1071,8 +1164,7 @@
     _httpClient._connectionClosed(this);
     _streamFuture
           // TODO(ajohnsen): Add timeout.
-        .then((_) => _socket.destroy(),
-              onError: (_) {});
+        .then((_) => _socket.destroy());
   }
 
   HttpConnectionInfo get connectionInfo => _HttpConnectionInfo.create(_socket);
@@ -1095,7 +1187,9 @@
   final Set<_HttpClientConnection> _activeConnections
       = new Set<_HttpClientConnection>();
   final List<_Credentials> _credentials = [];
+  final List<_ProxyCredentials> _proxyCredentials = [];
   Function _authenticate;
+  Function _authenticateProxy;
   Function _findProxy = HttpClient.findProxyFromEnvironment;
 
   Future<HttpClientRequest> open(String method,
@@ -1163,6 +1257,18 @@
     _credentials.add(new _Credentials(url, realm, cr));
   }
 
+  set authenticateProxy(
+      Future<bool> f(String host, int port, String scheme, String realm)) {
+    _authenticateProxy = f;
+  }
+
+  void addProxyCredentials(String host,
+                           int port,
+                           String realm,
+                           HttpClientCredentials cr) {
+    _proxyCredentials.add(new _ProxyCredentials(host, port, realm, cr));
+  }
+
   set findProxy(String f(Uri uri)) => _findProxy = f;
 
   Future<HttpClientRequest> _openUrl(String method, Uri uri) {
@@ -1188,7 +1294,7 @@
       try {
         proxyConf = new _ProxyConfiguration(_findProxy(uri));
       } catch (error, stackTrace) {
-        return new Future.immediateError(error, stackTrace);
+        return new Future.error(error, stackTrace);
       }
     }
     return _getConnection(uri.domain, port, proxyConf, isSecure)
@@ -1196,7 +1302,7 @@
           return info.connection.send(uri,
                                       port,
                                       method.toUpperCase(),
-                                      info.proxy.isDirect);
+                                      info.proxy);
         });
   }
 
@@ -1208,7 +1314,7 @@
           request.followRedirects = previous.followRedirects;
           // Allow same number of redirects.
           request.maxRedirects = previous.maxRedirects;
-          // Copy headers
+          // Copy headers.
           for (var header in previous.headers._headers.keys) {
             if (request.headers[header] == null) {
               request.headers.set(header, previous.headers[header]);
@@ -1229,7 +1335,7 @@
     }
     // TODO(ajohnsen): Listen for socket close events.
     if (!_idleConnections.containsKey(connection.key)) {
-      _idleConnections[connection.key] = new Set();
+      _idleConnections[connection.key] = new LinkedHashSet();
     }
     _idleConnections[connection.key].add(connection);
   }
@@ -1254,7 +1360,7 @@
     Iterator<_Proxy> proxies = proxyConf.proxies.iterator;
 
     Future<_ConnnectionInfo> connect(error) {
-      if (!proxies.moveNext()) return new Future.immediateError(error);
+      if (!proxies.moveNext()) return new Future.error(error);
       _Proxy proxy = proxies.current;
       String host = proxy.isDirect ? uriHost: proxy.host;
       int port = proxy.isDirect ? uriPort: proxy.port;
@@ -1266,7 +1372,7 @@
           _idleConnections.remove(key);
         }
         _activeConnections.add(connection);
-        return new Future.immediate(new _ConnnectionInfo(connection, proxy));
+        return new Future.value(new _ConnnectionInfo(connection, proxy));
       }
       return (isSecure && proxy.isDirect
                   ? SecureSocket.connect(host,
@@ -1280,7 +1386,7 @@
           return new _ConnnectionInfo(connection, proxy);
         }, onError: (error) {
           // Continue with next proxy.
-          return connect(error.error);
+          return connect(error);
         });
     }
     return connect(new HttpException("No proxies given"));
@@ -1300,6 +1406,16 @@
     return cr;
   }
 
+  _ProxyCredentials _findProxyCredentials(_Proxy proxy) {
+    // Look for credentials.
+    var it = _proxyCredentials.iterator;
+    while (it.moveNext()) {
+      if (it.current.applies(proxy, _AuthenticationScheme.BASIC)) {
+        return it.current;
+      }
+    }
+  }
+
   void _removeCredentials(_Credentials cr) {
     int index = _credentials.indexOf(cr);
     if (index != -1) {
@@ -1377,39 +1493,35 @@
   _HttpConnection(Socket this._socket, _HttpServer this._httpServer)
       : _httpParser = new _HttpParser.requestParser() {
     _socket.pipe(_httpParser);
-    _socket.done.catchError((e) => destroy());
     _subscription = _httpParser.listen(
         (incoming) {
           // Only handle one incoming request at the time. Keep the
           // stream paused until the request has been send.
           _subscription.pause();
           _state = _ACTIVE;
-          var outgoing = new _HttpOutgoing();
+          var outgoing = new _HttpOutgoing(_socket);
           var response = new _HttpResponse(incoming.headers.protocolVersion,
                                            outgoing);
           var request = new _HttpRequest(response, incoming, _httpServer, this);
-          outgoing.onStream((stream) {
-            return _streamFuture = _socket.writeStream(stream)
-                .then((_) {
-                  if (_state == _DETACHED) return;
-                  if (response.persistentConnection &&
-                      request.persistentConnection &&
-                      incoming.fullBodyRead) {
-                    _state = _IDLE;
-                    // Resume the subscription for incoming requests as the
-                    // request is now processed.
-                    _subscription.resume();
-                  } else {
-                    // Close socket, keep-alive not used or body sent before
-                    // received data was handled.
-                    destroy();
-                  }
-                })
-                .catchError((e) {
+          _streamFuture = outgoing.done
+              .then((_) {
+                if (_state == _DETACHED) return;
+                if (response.persistentConnection &&
+                    request.persistentConnection &&
+                    incoming.fullBodyRead) {
+                  _state = _IDLE;
+                  // Resume the subscription for incoming requests as the
+                  // request is now processed.
+                  _subscription.resume();
+                } else {
+                  // Close socket, keep-alive not used or body sent before
+                  // received data was handled.
                   destroy();
-                  throw e;
-                });
-          });
+                }
+              })
+              .catchError((e) {
+                destroy();
+              });
           response._ignoreBody = request.method == "HEAD";
           response._httpRequest = request;
           _httpServer._handleRequest(request);
@@ -1482,9 +1594,9 @@
       : _closeServer = false;
 
   StreamSubscription<HttpRequest> listen(void onData(HttpRequest event),
-                                         {void onError(AsyncError error),
+                                         {void onError(error),
                                          void onDone(),
-                                         bool unsubscribeOnError}) {
+                                         bool cancelOnError}) {
     _serverSocket.listen(
         (Socket socket) {
           socket.setOption(SocketOption.TCP_NODELAY, true);
@@ -1497,7 +1609,7 @@
     return _controller.stream.listen(onData,
                                      onError: onError,
                                      onDone: onDone,
-                                     unsubscribeOnError: unsubscribeOnError);
+                                     cancelOnError: cancelOnError);
   }
 
   void close() {
@@ -1528,7 +1640,7 @@
     _controller.add(request);
   }
 
-  void _handleError(AsyncError error) {
+  void _handleError(error) {
     if (!closed) _controller.addError(error);
   }
 
@@ -1591,13 +1703,30 @@
       proxy = proxy.trim();
       if (!proxy.isEmpty) {
         if (proxy.startsWith(PROXY_PREFIX)) {
+          String username;
+          String password;
+          // Skip the "PROXY " prefix.
+          proxy = proxy.substring(PROXY_PREFIX.length).trim();
+          // Look for proxy authentication.
+          int at = proxy.indexOf("@");
+          if (at != -1) {
+            String userinfo = proxy.substring(0, at).trim();
+            proxy = proxy.substring(at + 1).trim();
+            int colon = userinfo.indexOf(":");
+            if (colon == -1 || colon == 0 || colon == proxy.length - 1) {
+              throw new HttpException(
+                  "Invalid proxy configuration $configuration");
+            }
+            username = userinfo.substring(0, colon).trim();
+            password = userinfo.substring(colon + 1).trim();
+          }
+          // Look for proxy host and port.
           int colon = proxy.indexOf(":");
           if (colon == -1 || colon == 0 || colon == proxy.length - 1) {
             throw new HttpException(
                 "Invalid proxy configuration $configuration");
           }
-          // Skip the "PROXY " prefix.
-          String host = proxy.substring(PROXY_PREFIX.length, colon).trim();
+          String host = proxy.substring(0, colon).trim();
           String portString = proxy.substring(colon + 1).trim();
           int port;
           try {
@@ -1607,7 +1736,7 @@
                 "Invalid proxy configuration $configuration, "
                 "invalid port '$portString'");
           }
-          proxies.add(new _Proxy(host, port));
+          proxies.add(new _Proxy(host, port, username, password));
         } else if (proxy.trim() == DIRECT_PREFIX) {
           proxies.add(new _Proxy.direct());
         } else {
@@ -1625,11 +1754,17 @@
 
 
 class _Proxy {
-  const _Proxy(this.host, this.port) : isDirect = false;
-  const _Proxy.direct() : host = null, port = null, isDirect = true;
+  const _Proxy(
+      this.host, this.port, this.username, this.password) : isDirect = false;
+  const _Proxy.direct() : host = null, port = null,
+                          username = null, password = null, isDirect = true;
+
+  bool get isAuthenticated => username != null;
 
   final String host;
   final int port;
+  final String username;
+  final String password;
   final bool isDirect;
 }
 
@@ -1662,13 +1797,13 @@
   _DetachedSocket(this._socket, this._incoming);
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _incoming.listen(onData,
                             onError: onError,
                             onDone: onDone,
-                            unsubscribeOnError: unsubscribeOnError);
+                            cancelOnError: cancelOnError);
   }
 
   Encoding get encoding => _socket.encoding;
@@ -1689,20 +1824,12 @@
 
   void add(List<int> bytes) => _socket.add(bytes);
 
-  void addError(AsyncError error) => _socket.addError(error);
-
-  Future<Socket> consume(Stream<List<int>> stream) {
-    return _socket.consume(stream);
-  }
+  void addError(error) => _socket.addError(error);
 
   Future<Socket> addStream(Stream<List<int>> stream) {
     return _socket.addStream(stream);
   }
 
-  Future<Socket> writeStream(Stream<List<int>> stream) {
-    return _socket.writeStream(stream);
-  }
-
   void destroy() => _socket.destroy();
 
   Future close() => _socket.close();
@@ -1776,9 +1903,30 @@
 }
 
 
+class _ProxyCredentials {
+  _ProxyCredentials(this.host, this.port, this.realm, this.credentials);
+
+  _AuthenticationScheme get scheme => credentials.scheme;
+
+  bool applies(_Proxy proxy, _AuthenticationScheme scheme) {
+    return proxy.host == host && proxy.port == port;
+  }
+
+  void authorize(HttpClientRequest request) {
+    credentials.authorizeProxy(this, request);
+  }
+
+  String host;
+  int port;
+  String realm;
+  _HttpClientCredentials credentials;
+}
+
+
 abstract class _HttpClientCredentials implements HttpClientCredentials {
   _AuthenticationScheme get scheme;
   void authorize(_Credentials credentials, HttpClientRequest request);
+  void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request);
 }
 
 
@@ -1790,7 +1938,7 @@
 
   _AuthenticationScheme get scheme => _AuthenticationScheme.BASIC;
 
-  void authorize(_Credentials _, HttpClientRequest request) {
+  String authorization() {
     // There is no mentioning of username/password encoding in RFC
     // 2617. However there is an open draft for adding an additional
     // accept-charset parameter to the WWW-Authenticate and
@@ -1799,7 +1947,15 @@
     // now always use UTF-8 encoding.
     String auth =
         CryptoUtils.bytesToBase64(_encodeString("$username:$password"));
-    request.headers.set(HttpHeaders.AUTHORIZATION, "Basic $auth");
+    return "Basic $auth";
+  }
+
+  void authorize(_Credentials _, HttpClientRequest request) {
+    request.headers.set(HttpHeaders.AUTHORIZATION, authorization());
+  }
+
+  void authorizeProxy(_ProxyCredentials _, HttpClientRequest request) {
+    request.headers.set(HttpHeaders.PROXY_AUTHORIZATION, authorization());
   }
 
   String username;
@@ -1820,6 +1976,12 @@
     throw new UnsupportedError("Digest authentication not yet supported");
   }
 
+  void authorizeProxy(_ProxyCredentials credentials,
+                      HttpClientRequest request) {
+    // TODO(sgjesse): Implement!!!
+    throw new UnsupportedError("Digest authentication not yet supported");
+  }
+
   String username;
   String password;
 }
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index dd55494..3c04684 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -106,8 +106,10 @@
                         List<int> this.carryOverData,
                         Completer oldResumeCompleter) {
     controller = new StreamController<List<int>>(
-        onSubscriptionStateChange: onSubscriptionStateChange,
-        onPauseStateChange: onPauseStateChange);
+        onListen: resume,
+        onPause: pause,
+        onResume: resume,
+        onCancel: () => subscription.cancel());
     if (subscription == null) {
       // Socket was already closed.
       if (carryOverData != null) controller.add(carryOverData);
@@ -123,14 +125,14 @@
   }
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return controller.stream.listen(
         onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: unsubscribeOnError);
+        cancelOnError: cancelOnError);
   }
 
   void resume() {
@@ -156,22 +158,6 @@
       subscription.pause(resumeCompleter.future);
     }
   }
-
-  void onPauseStateChange() {
-    if (controller.isPaused) {
-      pause();
-    } else {
-      resume();
-    }
-  }
-
-  void onSubscriptionStateChange() {
-    if (controller.hasListener) {
-      resume();
-    } else {
-      subscription.cancel();
-    }
-  }
 }
 
 
@@ -209,23 +195,25 @@
 
   _HttpParser._(this._requestParser) {
     _controller = new StreamController<_HttpIncoming>(
-          onSubscriptionStateChange: _updateParsePauseState,
-          onPauseStateChange: _updateParsePauseState);
+          onListen: _updateParsePauseState,
+          onPause: _updateParsePauseState,
+          onResume: _updateParsePauseState,
+          onCancel: _updateParsePauseState);
     _reset();
   }
 
 
   StreamSubscription<_HttpIncoming> listen(void onData(_HttpIncoming event),
-                                           {void onError(AsyncError error),
+                                           {void onError(error),
                                             void onDone(),
-                                            bool unsubscribeOnError}) {
+                                            bool cancelOnError}) {
     return _controller.stream.listen(onData,
                                      onError: onError,
                                      onDone: onDone,
-                                     unsubscribeOnError: unsubscribeOnError);
+                                     cancelOnError: cancelOnError);
   }
 
-  Future<_HttpParser> consume(Stream<List<int>> stream) {
+  Future<_HttpParser> addStream(Stream<List<int>> stream) {
     // Listen to the stream and handle data accordingly. When a
     // _HttpIncoming is created, _dataPause, _dataResume, _dataDone is
     // given to provide a way of controlling the parser.
@@ -236,18 +224,14 @@
         _onData,
         onError: _onError,
         onDone: () {
-          _onDone();
           completer.complete(this);
         });
     return completer.future;
   }
 
-  Future<_HttpParser> addStream(Stream<List<int>> stream) {
-    throw new UnimplementedError("_HttpParser.addStream");
-  }
-
   Future<_HttpParser> close() {
-    throw new UnimplementedError("_HttpParser.close");
+    _onDone();
+    return new Future.value(this);
   }
 
   // From RFC 2616.
@@ -685,7 +669,7 @@
       }
     } catch (e, s) {
       _state = _State.FAILURE;
-      error(new AsyncError(e, s));
+      error(e, s);
     }
 
     _parserCalled = false;
@@ -717,9 +701,8 @@
           !(_state == _State.START && !_requestParser) &&
           !(_state == _State.BODY && !_chunked && _transferLength == -1)) {
         _bodyController.addError(
-            new AsyncError(
-                new HttpParserException(
-                    "Connection closed while receiving data")));
+              new HttpParserException(
+                  "Connection closed while receiving data"));
       }
       _closeIncoming();
       _controller.close();
@@ -728,10 +711,8 @@
     // If the connection is idle the HTTP stream is closed.
     if (_state == _State.START) {
       if (!_requestParser) {
-        error(
-            new AsyncError(
-                new HttpParserException(
-                    "Connection closed before full header was received")));
+        error(new HttpParserException(
+                    "Connection closed before full header was received"));
       }
       _controller.close();
       return;
@@ -746,10 +727,8 @@
       _state = _State.FAILURE;
       // Report the error through the error callback if any. Otherwise
       // throw the error.
-      error(
-          new AsyncError(
-              new HttpParserException(
-                  "Connection closed before full header was received")));
+      error(new HttpParserException(
+                  "Connection closed before full header was received"));
       _controller.close();
       return;
     }
@@ -760,10 +739,8 @@
       _state = _State.FAILURE;
       // Report the error through the error callback if any. Otherwise
       // throw the error.
-      error(
-          new AsyncError(
-              new HttpParserException(
-                  "Connection closed before full body was received")));
+      error(new HttpParserException(
+                  "Connection closed before full body was received"));
     }
     _controller.close();
   }
@@ -882,8 +859,10 @@
     assert(_incoming == null);
     assert(_bodyController == null);
     _bodyController = new StreamController<List<int>>(
-        onSubscriptionStateChange: _bodySubscriptionStateChange,
-        onPauseStateChange: _updateParsePauseState);
+        onListen: _bodySubscriptionStateChange,
+        onPause: _updateParsePauseState,
+        onResume: _updateParsePauseState,
+        onCancel: _bodySubscriptionStateChange);
     _incoming = new _HttpIncoming(
         _headers, transferLength, _bodyController.stream);
     _pauseParsing();  // Needed to handle detaching - don't start on the body!
@@ -935,10 +914,10 @@
     }
   }
 
-  void error(error) {
+  void error(error, [stackTrace]) {
     if (_socketSubscription != null) _socketSubscription.cancel();
     _state = _State.FAILURE;
-    _controller.addError(error);
+    _controller.addError(error, stackTrace);
     _controller.close();
   }
 
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index ecaf427..ac08c0a 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -14,6 +14,7 @@
 
 import 'dart:async';
 import 'dart:collection' show Queue,
+                              LinkedHashSet,
                               DoubleLinkedQueue,
                               DoubleLinkedQueueEntry;
 import 'dart:crypto';
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index df3a7da..8001905 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -7,16 +7,14 @@
 /**
  * Helper class to wrap a [StreamConsumer<List<int>>] and provide
  * utility functions for writing to the StreamConsumer directly. The
- * [IOSink] buffers the input given by [write], [writeAll], [writeln],
- * [writeCharCode] and [add] and will delay a [consume] or
- * [writeStream] until the buffer is flushed.
+ * [IOSink] buffers the input given by all [StringSink] methods and will delay
+ * a [addStream] until the buffer is flushed.
  *
- * When the [IOSink] is bound to a stream (through either [consume]
- * or [writeStream]) any call to the [IOSink] will throw a
- * [StateError].
+ * When the [IOSink] is bound to a stream (through [addStream]) any call
+ * to the [IOSink] will throw a [StateError]. When the [addStream] compeltes,
+ * the [IOSink] will again be open for all calls.
  */
-abstract class IOSink<T>
-    implements StreamConsumer<List<int>>, StringSink, EventSink<List<int>> {
+abstract class IOSink implements StreamSink<List<int>>, StringSink {
   factory IOSink(StreamConsumer<List<int>> target,
                  {Encoding encoding: Encoding.UTF_8})
       => new _IOSinkImpl(target, encoding);
@@ -35,53 +33,40 @@
   /**
    * Writes an error to the consumer.
    */
-  void addError(AsyncError error);
-
-  /**
-   * Provide functionality for piping to the [IOSink].
-   */
-  Future<T> consume(Stream<List<int>> stream);
+  void addError(error);
 
   /**
    * Adds all elements of the given [stream] to `this`.
    */
-  Future<T> addStream(Stream<List<int>> stream);
-
-  /**
-   * Like [consume], but will not close the target when done.
-   *
-   * *Deprecated*: use [addStream] instead.
-   */
-  Future<T> writeStream(Stream<List<int>> stream);
+  Future addStream(Stream<List<int>> stream);
 
   /**
    * Close the target.
    */
-  // TODO(floitsch): Currently the future cannot be typed because it has
-  // hardcoded type Future<HttpClientResponse> in subclass HttpClientRequest.
   Future close();
 
   /**
-   * Get future that will complete when all data has been written to
-   * the IOSink and it has been closed.
+   * Get a future that will complete when all synchronous have completed, or an
+   * error happened. This future is identical to the future returned from close.
    */
-  Future<T> get done;
+  Future get done;
 }
 
 
-class _IOSinkImpl<T> implements IOSink<T> {
+class _IOSinkImpl implements IOSink {
   final StreamConsumer<List<int>> _target;
-
-  Completer _writeStreamCompleter;
+  Completer _doneCompleter = new Completer();
+  Future _doneFuture;
   StreamController<List<int>> _controllerInstance;
-  Future<T> _pipeFuture;
-  StreamSubscription<List<int>> _bindSubscription;
-  bool _paused = true;
+  Completer _controllerCompleter;
+  Encoding _encoding;
+  bool _isClosed = false;
+  bool _isBound = false;
   bool _encodingMutable = true;
 
-  _IOSinkImpl(StreamConsumer<List<int>> this._target, this._encoding);
-
-  Encoding _encoding;
+  _IOSinkImpl(StreamConsumer<List<int>> this._target, this._encoding) {
+    _doneFuture = _doneCompleter.future;
+  }
 
   Encoding get encoding => _encoding;
 
@@ -135,139 +120,103 @@
   }
 
   void add(List<int> data) {
-    if (_isBound) {
-      throw new StateError("IOSink is already bound to a stream");
-    }
     _controller.add(data);
   }
 
-  void addError(AsyncError error) {
-    if (_isBound) {
-      throw new StateError("IOSink is already bound to a stream");
-    }
+  void addError(error) {
     _controller.addError(error);
   }
 
-  Future<T> consume(Stream<List<int>> stream) {
+  Future addStream(Stream<List<int>> stream) {
     if (_isBound) {
       throw new StateError("IOSink is already bound to a stream");
     }
-    return _fillFromStream(stream);
-  }
-
-  Future<T> writeStream(Stream<List<int>> stream) {
-    return addStream(stream);
-  }
-
-  Future<T> addStream(Stream<List<int>> stream) {
-    if (_isBound) {
-      throw new StateError("IOSink is already bound to a stream");
+    _isBound = true;
+    // Wait for any sync operations to complete.
+    Future targetAddStream() {
+      return _target.addStream(stream)
+          .whenComplete(() {
+            _isBound = false;
+          });
     }
-    return _fillFromStream(stream, unbind: true);
+    if (_controllerInstance == null) return targetAddStream();
+    var future = _controllerCompleter.future;
+    _controllerInstance.close();
+    return future.then((_) => targetAddStream());
   }
 
   Future close() {
     if (_isBound) {
-      throw new StateError("IOSink is already bound to a stream");
+      throw new StateError("IOSink is bound to a stream");
     }
-    _controller.close();
-    return _pipeFuture;
+    if (!_isClosed) {
+      _isClosed = true;
+      if (_controllerInstance != null) {
+        _controllerInstance.close();
+      } else {
+        _closeTarget();
+      }
+    }
+    return done;
   }
 
-  Future<T> get done {
-    _controller;
-    return _pipeFuture;
+  void _closeTarget() {
+    _target.close()
+        .then((value) => _completeDone(value: value),
+              onError: (error) => _completeDone(error: error));
   }
 
-  void _completeWriteStreamCompleter([error]) {
-    if (_writeStreamCompleter == null) return;
-    var tmp = _writeStreamCompleter;
-    _writeStreamCompleter = null;
+  Future get done => _doneFuture;
+
+  void _completeDone({value, error}) {
+    if (_doneCompleter == null) return;
+    var tmp = _doneCompleter;
+    _doneCompleter = null;
     if (error == null) {
-      _bindSubscription = null;
-      tmp.complete();
+      tmp.complete(value);
     } else {
       tmp.completeError(error);
     }
   }
 
   StreamController<List<int>> get _controller {
+    if (_isBound) {
+      throw new StateError("IOSink is bound to a stream");
+    }
+    if (_isClosed) {
+      throw new StateError("IOSink is closed");
+    }
     if (_controllerInstance == null) {
-      _controllerInstance = new StreamController<List<int>>(
-          onPauseStateChange: _onPauseStateChange,
-          onSubscriptionStateChange: _onSubscriptionStateChange);
-      var future = _controller.stream.pipe(_target);
-      future.then((_) => _completeWriteStreamCompleter(),
-                  onError: (error) => _completeWriteStreamCompleter(error));
-      _pipeFuture = future.then((value) => value);
+      _controllerInstance = new StreamController<List<int>>();
+      _controllerCompleter = new Completer();
+      _target.addStream(_controller.stream)
+          .then(
+              (_) {
+                if (_isBound) {
+                  // A new stream takes over - forward values to that stream.
+                  var completer = _controllerCompleter;
+                  _controllerCompleter = null;
+                  _controllerInstance = null;
+                  completer.complete();
+                } else {
+                  // No new stream, .close was called. Close _target.
+                  _closeTarget();
+                }
+              },
+              onError: (error) {
+                if (_isBound) {
+                  // A new stream takes over - forward errors to that stream.
+                  var completer = _controllerCompleter;
+                  _controllerCompleter = null;
+                  _controllerInstance = null;
+                  completer.completeError(error);
+                } else {
+                  // No new stream. No need to close target, as it have already
+                  // failed.
+                  _completeDone(error: error);
+                }
+              });
     }
     return _controllerInstance;
   }
-
-  bool get _isBound => _bindSubscription != null;
-
-  void _onPauseStateChange() {
-    _paused = _controller.isPaused;
-    if (_controller.isPaused) {
-      _pause();
-    } else {
-      _resume();
-    }
-  }
-
-  void _pause() {
-    if (_bindSubscription != null) {
-      try {
-        // The subscription can be canceled at this point.
-        _bindSubscription.pause();
-      } catch (e) {
-      }
-    }
-  }
-
-  void _resume() {
-    if (_bindSubscription != null) {
-      try {
-        // The subscription can be canceled at this point.
-        _bindSubscription.resume();
-      } catch (e) {
-      }
-    }
-  }
-
-  void _onSubscriptionStateChange() {
-    if (_controller.hasListener) {
-      _paused = false;
-      _resume();
-    } else {
-      if (_bindSubscription != null) {
-        _bindSubscription.cancel();
-        _bindSubscription = null;
-      }
-    }
-  }
-
-  Future<T> _fillFromStream(Stream<List<int>> stream, {unbind: false}) {
-    _controller;
-    assert(_writeStreamCompleter == null);
-    if (unbind) {
-      _writeStreamCompleter = new Completer<T>();
-    }
-    _bindSubscription = stream.listen(
-        _controller.add,
-        onDone: () {
-          if (unbind) {
-            _completeWriteStreamCompleter();
-          } else {
-            _controller.close();
-          }
-        },
-        onError: _controller.addError);
-    if (_paused) _pause();
-    if (unbind) {
-      return _writeStreamCompleter.future;
-    } else {
-      return _pipeFuture;
-    }
-  }
 }
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 347ae1f..d36d779 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -130,7 +130,7 @@
 
   Future<bool> exists() {
     // TODO(whesse): Replace with asynchronous version.
-    return new Future.immediate(existsSync());
+    return new Future.value(existsSync());
   }
 
   bool existsSync() => FileSystemEntity.isLinkSync(path);
@@ -205,7 +205,7 @@
 
   Future<String> target() {
     // TODO(whesse): Replace with asynchronous version.
-    return new Future.of(targetSync);
+    return new Future.sync(targetSync);
   }
 
   String targetSync() {
diff --git a/sdk/lib/io/mime_multipart_parser.dart b/sdk/lib/io/mime_multipart_parser.dart
index cd12c20..e757c75 100644
--- a/sdk/lib/io/mime_multipart_parser.dart
+++ b/sdk/lib/io/mime_multipart_parser.dart
@@ -49,7 +49,7 @@
     _boundary[1] = _CharCode.LF;
     _boundary[2] = _CharCode.DASH;
     _boundary[3] = _CharCode.DASH;
-    _boundary.setRange(4, charCodes.length, charCodes);
+    _boundary.setRange(4, 4 + charCodes.length, charCodes);
     _state = _START;
     _headerField = new StringBuffer();
     _headerValue = new StringBuffer();
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 1c9fddb..fc2a4aa 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -115,7 +115,7 @@
    * Throws an [UnsupportedError] if the process is
    * non-interactive.
    */
-  IOSink<Process> get stdin;
+  IOSink get stdin;
 
   /**
    * Returns a [:Future:] which completes with the exit code of the process
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index 166b0f2..851b58d 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -64,14 +64,14 @@
   }
 
   StreamSubscription<SecureSocket> listen(void onData(SecureSocket socket),
-                                          {void onError(AsyncError error),
+                                          {void onError(error),
                                            void onDone(),
-                                           bool unsubscribeOnError}) {
+                                           bool cancelOnError}) {
     return _socket.map((rawSocket) => new SecureSocket._(rawSocket))
                   .listen(onData,
                           onError: onError,
                           onDone: onDone,
-                          unsubscribeOnError: unsubscribeOnError);
+                          cancelOnError: cancelOnError);
   }
 
   /**
@@ -107,8 +107,10 @@
                           bool this.requireClientCertificate) {
     _socket = serverSocket;
     _controller = new StreamController<RawSecureSocket>(
-        onPauseStateChange: _onPauseStateChange,
-        onSubscriptionStateChange: _onSubscriptionStateChange);
+        onListen: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange,
+        onCancel: _onSubscriptionStateChange);
   }
 
   /**
@@ -157,13 +159,13 @@
   }
 
   StreamSubscription<RawSecureSocket> listen(void onData(RawSecureSocket s),
-                                             {void onError(AsyncError error),
+                                             {void onError(error),
                                               void onDone(),
-                                              bool unsubscribeOnError}) {
+                                              bool cancelOnError}) {
     return _controller.stream.listen(onData,
                                      onError: onError,
                                      onDone: onDone,
-                                     unsubscribeOnError: unsubscribeOnError);
+                                     cancelOnError: cancelOnError);
   }
 
   /**
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 197e87d..bff54c8 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -245,8 +245,10 @@
       bool this.sendClientCertificate,
       bool this.onBadCertificate(X509Certificate certificate)) {
     _controller = new StreamController<RawSocketEvent>(
-        onPauseStateChange: _onPauseStateChange,
-        onSubscriptionStateChange: _onSubscriptionStateChange);
+        onListen: _onSubscriptionStateChange,
+        onPause: _onPauseStateChange,
+        onResume: _onPauseStateChange,
+        onCancel: _onSubscriptionStateChange);
     _stream = _controller.stream;
     // Throw an ArgumentError if any field is invalid.  After this, all
     // errors will be reported through the future or the stream.
@@ -261,7 +263,7 @@
     if (socket == null) {
       futureSocket = RawSocket.connect(host, requestedPort);
     } else {
-      futureSocket = new Future.immediate(socket);
+      futureSocket = new Future.value(socket);
     }
     futureSocket.then((rawSocket) {
       rawSocket.writeEventsEnabled = false;
@@ -288,9 +290,9 @@
   }
 
   StreamSubscription listen(void onData(RawSocketEvent data),
-                            {void onError(AsyncError error),
+                            {void onError(error),
                              void onDone(),
-                             bool unsubscribeOnError}) {
+                             bool cancelOnError}) {
     if (_writeEventsEnabled) {
       _writeEventsEnabled = false;
       _controller.add(RawSocketEvent.WRITE);
@@ -298,7 +300,7 @@
     return _stream.listen(onData,
                           onError: onError,
                           onDone: onDone,
-                          unsubscribeOnError: unsubscribeOnError);
+                          cancelOnError: cancelOnError);
   }
 
   void _verifyFields() {
@@ -464,17 +466,21 @@
   // up handlers to flush the pipeline when possible.
   int write(List<int> data, [int offset, int bytes]) {
     if (_closedWrite) {
-      _controller.addError(new AsyncError(new SocketIOException(
-          "Writing to a closed socket")));
+      _controller.addError(new SocketIOException("Writing to a closed socket"));
       return 0;
     }
     if (_status != CONNECTED) return 0;
+
+    if (offset == null) offset = 0;
+    if (bytes == null) bytes = data.length - offset;
+
     var buffer = _secureFilter.buffers[WRITE_PLAINTEXT];
     if (bytes > buffer.free) {
       bytes = buffer.free;
     }
     if (bytes > 0) {
-      buffer.data.setRange(buffer.start + buffer.length, bytes, data, offset);
+      int startIndex = buffer.start + buffer.length;
+      buffer.data.setRange(startIndex, startIndex + bytes, data, offset);
       buffer.length += bytes;
     }
     _writeEncryptedData();  // Tries to flush all pipeline stages.
@@ -562,17 +568,14 @@
     _reportError(e, 'Error on underlying RawSocket');
   }
 
-  void _reportError(error, String message) {
+  void _reportError(e, String message) {
     // TODO(whesse): Call _reportError from all internal functions that throw.
-    var e;
-    if (error is AsyncError) {
-      e = error;
-    } else if (error is SocketIOException) {
-      e = new SocketIOException('$message (${error.message})', error.osError);
-    } else if (error is OSError) {
-      e = new SocketIOException(message, error);
+    if (e is SocketIOException) {
+      e = new SocketIOException('$message (${e.message})', e.osError);
+    } else if (e is OSError) {
+      e = new SocketIOException(message, e);
     } else {
-      e = new SocketIOException('$message (${error.toString()})', null);
+      e = new SocketIOException('$message (${e.toString()})', null);
     }
     if (_connectPending) {
       _handshakeComplete.completeError(e);
@@ -660,9 +663,8 @@
         List<int> data = _socket.read(encrypted.free);
         if (data != null) {
           int bytes = data.length;
-          encrypted.data.setRange(encrypted.start + encrypted.length,
-                                  bytes,
-                                  data);
+          int startIndex = encrypted.start + encrypted.length;
+          encrypted.data.setRange(startIndex, startIndex + bytes, data);
           encrypted.length += bytes;
           progress = true;
         }
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index ac3444c..48c8640 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -212,8 +212,7 @@
  * both a [Stream] and a [IOSink] interface, making it ideal for
  * using together with other [Stream]s.
  */
-abstract class Socket implements Stream<List<int>>,
-                                 IOSink<Socket> {
+abstract class Socket implements Stream<List<int>>, IOSink {
   /**
    * Creats a new socket connection to the host and port and returns a [Future]
    * that will complete with either a [Socket] once connected or an error
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 5cad1f0..afa7ea0 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -16,14 +16,14 @@
   _StdStream(Stream<List<int>> this._stream);
 
   StreamSubscription<List<int>> listen(void onData(List<int> event),
-                                       {void onError(AsyncError error),
+                                       {void onError(error),
                                         void onDone(),
-                                        bool unsubscribeOnError}) {
+                                        bool cancelOnError}) {
     return _stream.listen(
         onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: unsubscribeOnError);
+        cancelOnError: cancelOnError);
   }
 }
 
@@ -40,11 +40,9 @@
   void writeln([object = "" ]) => _sink.writeln(object);
   void writeAll(objects, [sep = ""]) => _sink.writeAll(objects, sep);
   void add(List<int> data) => _sink.add(data);
-  void addError(AsyncError error) => _sink.addError(error);
+  void addError(error) => _sink.addError(error);
   void writeCharCode(int charCode) => _sink.writeCharCode(charCode);
-  Future consume(Stream<List<int>> stream) => _sink.consume(stream);
   Future addStream(Stream<List<int>> stream) => _sink.addStream(stream);
-  Future writeStream(Stream<List<int>> stream) => _sink.writeStream(stream);
   Future close() => _sink.close();
   Future get done => _sink.done;
 }
diff --git a/sdk/lib/io/string_transformer.dart b/sdk/lib/io/string_transformer.dart
index 4a70f44..3332879 100644
--- a/sdk/lib/io/string_transformer.dart
+++ b/sdk/lib/io/string_transformer.dart
@@ -315,9 +315,7 @@
   void handleData(String data, EventSink<List<int>> sink) {
     var bytes = _encode(data);
     if (bytes == null) {
-      sink.addError(
-          new AsyncError(
-              new FormatException("Invalid character for encoding")));
+      sink.addError(new FormatException("Invalid character for encoding"));
       sink.close();
     } else {
       sink.add(bytes);
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index bd21220..c7d9e10 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -37,7 +37,7 @@
  * which is supplied through the [:handleData:]. As the protocol is processed,
  * it'll output frame data as either a List<int> or String.
  *
- * Important infomation about usage: Be sure you use unsubscribeOnError, so the
+ * Important infomation about usage: Be sure you use cancelOnError, so the
  * socket will be closed when the processer encounter an error. Not using it
  * will lead to undefined behaviour.
  */
@@ -385,7 +385,7 @@
         response.contentLength = 0;
         response.close();
       });
-      return new Future.immediateError(
+      return new Future.error(
           new WebSocketException("Invalid WebSocket upgrade request"));
     }
 
@@ -547,7 +547,7 @@
           _controller.close();
           if (_writeClosed) _socket.destroy();
         },
-        unsubscribeOnError: true);
+        cancelOnError: true);
 
     _socket.done
         .catchError((error) {
@@ -564,13 +564,13 @@
   }
 
   StreamSubscription listen(void onData(message),
-                            {void onError(AsyncError error),
+                            {void onError(error),
                              void onDone(),
-                             bool unsubscribeOnError}) {
+                             bool cancelOnError}) {
     return _controller.stream.listen(onData,
                                      onError: onError,
                                      onDone: onDone,
-                                     unsubscribeOnError: unsubscribeOnError);
+                                     cancelOnError: cancelOnError);
   }
 
   int get readyState => _readyState;
@@ -671,7 +671,7 @@
     if (mask) {
       header[1] |= 1 << 7;
       var maskBytes = _IOCrypto.getRandomBytes(4);
-      header.setRange(index, 4, maskBytes);
+      header.setRange(index, index + 4, maskBytes);
       index += 4;
       if (data != null) {
         var list = new Uint8List(data.length);
diff --git a/sdk/lib/isolate/isolate_stream.dart b/sdk/lib/isolate/isolate_stream.dart
index 37db4e5..0f0f63f 100644
--- a/sdk/lib/isolate/isolate_stream.dart
+++ b/sdk/lib/isolate/isolate_stream.dart
@@ -77,13 +77,13 @@
   }
 
   StreamSubscription listen(void onData(event),
-                            { void onError(AsyncError error),
+                            { void onError(error),
                               void onDone(),
-                              bool unsubscribeOnError}) {
+                              bool cancelOnError}) {
       return _controller.stream.listen(onData,
                                        onError: onError,
                                        onDone: onDone,
-                                       unsubscribeOnError: unsubscribeOnError);
+                                       cancelOnError: cancelOnError);
   }
 }
 
@@ -114,7 +114,7 @@
    */
   void add(dynamic message);
 
-  void addError(AsyncError errorEvent);
+  void addError(errorEvent);
 
   /** Closing multiple times is allowed. */
   void close();
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 9813a0d..b5b971a 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -34,7 +34,8 @@
    * An immutable map from from library names to mirrors for all
    * libraries known to this mirror system.
    */
-  Map<String, LibraryMirror> get libraries;
+  // TODO(ahe): [libraries] should be Map<Uri, LibraryMirror>.
+  Map<Symbol, LibraryMirror> get libraries;
 
   /**
    * A mirror on the isolate associated with this [MirrorSystem].
@@ -51,6 +52,8 @@
    * A mirror on the [:void:] type.
    */
   TypeMirror get voidType;
+
+  external static String getName(Symbol symbol);
 }
 
 /**
@@ -115,7 +118,7 @@
    * entity, such as 'method' for a method [:void method() {...}:] or
    * 'mylibrary' for a [:#library('mylibrary');:] declaration.
    */
-  String get simpleName;
+  Symbol get simpleName;
 
   /**
    * The fully-qualified name for this Dart language entity.
@@ -128,7 +131,7 @@
    * this is a gray area due to lack of clarity over whether library
    * names are unique.
    */
-  String get qualifiedName;
+  Symbol get qualifiedName;
 
   /**
    * A mirror on the owner of this function.  This is the declaration
@@ -174,16 +177,16 @@
 abstract class ObjectMirror implements Mirror {
   /**
    * Invokes the named function and returns a mirror on the result.
-   * The arguments must be instances of [InstanceMirror], [num], 
-   * [String] or [bool].
+   * The arguments must be instances of [InstanceMirror], [num],
+   * [String], or [bool].
    */
   /* TODO(turnidge): Properly document.
    * TODO(turnidge): Handle ambiguous names.
    * TODO(turnidge): Handle optional & named arguments.
    */
-  Future<InstanceMirror> invokeAsync(String memberName,
+  Future<InstanceMirror> invokeAsync(Symbol memberName,
                                      List<Object> positionalArguments,
-                                     [Map<String,Object> namedArguments]);
+                                     [Map<Symbol, Object> namedArguments]);
 
   /**
    * Invokes a getter and returns a mirror on the result. The getter
@@ -191,17 +194,17 @@
    * method.
    */
   /* TODO(turnidge): Handle ambiguous names.*/
-  Future<InstanceMirror> getFieldAsync(String fieldName);
+  Future<InstanceMirror> getFieldAsync(Symbol fieldName);
 
   /**
    * Invokes a setter and returns a mirror on the result. The setter
    * may be either the implicit setter for a non-final field or a
    * user-defined setter method.
-   * The argument must be an instance of either [InstanceMirror], [num], 
-   * [String] or [bool].
+   * The argument must be an instance of either [InstanceMirror], [num],
+   * [String], or [bool].
    */
   /* TODO(turnidge): Handle ambiguous names.*/
-  Future<InstanceMirror> setFieldAsync(String fieldName, Object value);
+  Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value);
 }
 
 /**
@@ -259,17 +262,17 @@
 
   /**
    * Executes the closure.
-   * The arguments must be instances of [InstanceMirror], [num], 
-   * [String] or [bool]. 
+   * The arguments must be instances of [InstanceMirror], [num],
+   * [String], or [bool].
    */
   Future<InstanceMirror> applyAsync(List<Object> positionalArguments,
-                                    [Map<String,Object> namedArguments]);
+                                    [Map<Symbol, Object> namedArguments]);
 
   /**
    * Looks up the value of a name in the scope of the closure. The
    * result is a mirror on that value.
    */
-  Future<InstanceMirror> findInContext(String name);
+  Future<InstanceMirror> findInContext(Symbol name);
 }
 
 /**
@@ -284,6 +287,7 @@
    * TODO(turnidge): Document where this url comes from.  Will this
    * value be sensible?
    */
+  // TODO(ahe): Change type to [Uri], rename to "uri"?
   String get url;
 
   /**
@@ -293,41 +297,41 @@
    * The members of a library are its top-level classes,
    * functions, variables, getters, and setters.
    */
-  Map<String, Mirror> get members;
+  Map<Symbol, Mirror> get members;
 
   /**
    * An immutable map from names to mirrors for all class
    * declarations in this library.
    */
-  Map<String, ClassMirror> get classes;
+  Map<Symbol, ClassMirror> get classes;
 
   /**
    * An immutable map from names to mirrors for all function, getter,
    * and setter declarations in this library.
    */
-  Map<String, MethodMirror> get functions;
+  Map<Symbol, MethodMirror> get functions;
 
   /**
    * An immutable map from names to mirrors for all getter
    * declarations in this library.
    */
-  Map<String, MethodMirror> get getters;
+  Map<Symbol, MethodMirror> get getters;
 
   /**
    * An immutable map from names to mirrors for all setter
    * declarations in this library.
    */
-  Map<String, MethodMirror> get setters;
+  Map<Symbol, MethodMirror> get setters;
 
   /**
    * An immutable map from names to mirrors for all variable
    * declarations in this library.
    */
-  Map<String, VariableMirror> get variables;
+  Map<Symbol, VariableMirror> get variables;
 }
 
 /**
- * A [TypeMirror] reflects a Dart language class, typedef
+ * A [TypeMirror] reflects a Dart language class, typedef,
  * or type variable.
  */
 abstract class TypeMirror implements DeclarationMirror {
@@ -360,38 +364,38 @@
    *
    * This does not include inherited members.
    */
-  Map<String, Mirror> get members;
+  Map<Symbol, Mirror> get members;
 
   /**
    * An immutable map from names to mirrors for all method,
    * declarations for this type.  This does not include getters and
    * setters.
    */
-  Map<String, MethodMirror> get methods;
+  Map<Symbol, MethodMirror> get methods;
 
   /**
    * An immutable map from names to mirrors for all getter
    * declarations for this type.
    */
-  Map<String, MethodMirror> get getters;
+  Map<Symbol, MethodMirror> get getters;
 
   /**
    * An immutable map from names to mirrors for all setter
    * declarations for this type.
    */
-  Map<String, MethodMirror> get setters;
+  Map<Symbol, MethodMirror> get setters;
 
   /**
    * An immutable map from names to mirrors for all variable
    * declarations for this type.
    */
-  Map<String, VariableMirror> get variables;
+  Map<Symbol, VariableMirror> get variables;
 
   /**
    * An immutable map from names to mirrors for all constructor
    * declarations for this type.
    */
-   Map<String, MethodMirror> get constructors;
+   Map<Symbol, MethodMirror> get constructors;
 
   /**
    * An immutable map from names to mirrors for all type variables for
@@ -399,7 +403,7 @@
    *
    * This map preserves the order of declaration of the type variables.
    */
-   Map<String, TypeVariableMirror> get typeVariables;
+   Map<Symbol, TypeVariableMirror> get typeVariables;
 
   /**
    * An immutable map from names to mirrors for all type arguments for
@@ -407,7 +411,7 @@
    *
    * This map preserves the order of declaration of the type variables.
    */
-  Map<String, TypeMirror> get typeArguments;
+  Map<Symbol, TypeMirror> get typeArguments;
 
   /**
    * Is this the original declaration of this type?
@@ -433,12 +437,13 @@
 
   /**
    * Invokes the named constructor and returns a mirror on the result.
-   * The arguments must be instances of [InstanceMirror], [num], 
+   * The arguments must be instances of [InstanceMirror], [num],
+   * [String], or [bool].
    */
   /* TODO(turnidge): Properly document.*/
-  Future<InstanceMirror> newInstanceAsync(String constructorName,
+  Future<InstanceMirror> newInstanceAsync(Symbol constructorName,
                                           List<Object> positionalArguments,
-                                          [Map<String,Object> namedArguments]);
+                                          [Map<Symbol, Object> namedArguments]);
 
   /**
    * Does this mirror represent a class?
@@ -569,7 +574,7 @@
    * For example, [:'bar':] is the constructor name for constructor
    * [:Foo.bar:] of type [:Foo:].
    */
-  String get constructorName;
+  Symbol get constructorName;
 
   /**
    * Is the reflectee a const constructor?
@@ -641,10 +646,8 @@
 
   /**
    * A mirror on the default value for this parameter, if it exists.
-   *
-   * TODO(turnidge): String may not be a good representation of this
-   * at runtime.
    */
+  // TODO(ahe): This should return an InstanceMirror.
   String get defaultValue;
 }
 
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 570e29c..999864a 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -2,6 +2,7 @@
 
 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;
@@ -3147,6 +3148,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Length> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Length> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Length removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -3167,16 +3176,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Length> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Length> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Length initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Length> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Length fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Length> getRange(int start, int end) =>
@@ -3779,6 +3792,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Number> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Number> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Number removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -3799,16 +3820,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Number> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Number> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Number initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Number> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Number fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Number> getRange(int start, int end) =>
@@ -4642,6 +4667,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<PathSeg> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<PathSeg> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   PathSeg removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -4662,16 +4695,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<PathSeg> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<PathSeg> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [PathSeg initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<PathSeg> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [PathSeg fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<PathSeg> getRange(int start, int end) =>
@@ -5535,6 +5572,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -5555,16 +5600,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [String initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [String fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<String> getRange(int start, int end) =>
@@ -6701,6 +6750,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Transform> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Transform> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Transform removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -6721,16 +6778,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Transform> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Transform> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Transform initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Transform> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Transform fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Transform> getRange(int start, int end) =>
@@ -7228,6 +7289,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<ElementInstance> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<ElementInstance> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   ElementInstance removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7248,16 +7317,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<ElementInstance> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<ElementInstance> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [ElementInstance initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<ElementInstance> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [ElementInstance fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<ElementInstance> getRange(int start, int end) =>
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index e9532a9..64d8154 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -2,6 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
@@ -3408,6 +3409,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Length> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Length> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Length removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -3428,16 +3437,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Length> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Length> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Length initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Length> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Length fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Length> getRange(int start, int end) =>
@@ -4117,6 +4130,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Number> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Number> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Number removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -4137,16 +4158,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Number> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Number> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Number initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Number> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Number fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Number> getRange(int start, int end) =>
@@ -5253,6 +5278,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<PathSeg> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<PathSeg> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   PathSeg removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -5273,16 +5306,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<PathSeg> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<PathSeg> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [PathSeg initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<PathSeg> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [PathSeg fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<PathSeg> getRange(int start, int end) =>
@@ -6243,6 +6280,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   String removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -6263,16 +6308,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<String> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<String> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [String initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<String> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [String fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<String> getRange(int start, int end) =>
@@ -7498,6 +7547,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Transform> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Transform> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Transform removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -7518,16 +7575,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Transform> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Transform> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Transform initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Transform> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Transform fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Transform> getRange(int start, int end) =>
@@ -8079,6 +8140,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<ElementInstance> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<ElementInstance> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   ElementInstance removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -8099,16 +8168,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<ElementInstance> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<ElementInstance> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [ElementInstance initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<ElementInstance> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [ElementInstance fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<ElementInstance> getRange(int start, int end) =>
diff --git a/sdk/lib/utf/utf.dart b/sdk/lib/utf/utf.dart
index 1c8c95c..940ce68 100644
--- a/sdk/lib/utf/utf.dart
+++ b/sdk/lib/utf/utf.dart
@@ -4,6 +4,7 @@
 
 library dart.utf;
 import "dart:async";
+import "dart:collection";
 part "utf_stream.dart";
 part "utf8.dart";
 part "utf16.dart";
@@ -197,7 +198,7 @@
  */
 // TODO(floitsch): Consider removing the extend and switch to implements since
 // that's cheaper to allocate.
-class _ListRange extends Iterable {
+class _ListRange extends IterableBase {
   final List _source;
   final int _offset;
   final int _length;
diff --git a/sdk/lib/utf/utf16.dart b/sdk/lib/utf/utf16.dart
index 9794a81..3518bbb 100644
--- a/sdk/lib/utf/utf16.dart
+++ b/sdk/lib/utf/utf16.dart
@@ -190,7 +190,7 @@
  */
 // TODO(floitsch): Consider removing the extend and switch to implements since
 // that's cheaper to allocate.
-class IterableUtf16Decoder extends Iterable<int> {
+class IterableUtf16Decoder extends IterableBase<int> {
   final _CodeUnitsProvider codeunitsProvider;
   final int replacementCodepoint;
 
diff --git a/sdk/lib/utf/utf32.dart b/sdk/lib/utf/utf32.dart
index 5ddf7a7..acd465c 100644
--- a/sdk/lib/utf/utf32.dart
+++ b/sdk/lib/utf/utf32.dart
@@ -184,7 +184,7 @@
  */
 // TODO(floitsch): Consider removing the extend and switch to implements since
 // that's cheaper to allocate.
-class IterableUtf32Decoder extends Iterable<int> {
+class IterableUtf32Decoder extends IterableBase<int> {
   final Utf32BytesDecoderProvider codeunitsProvider;
 
   IterableUtf32Decoder._(this.codeunitsProvider);
diff --git a/sdk/lib/utf/utf8.dart b/sdk/lib/utf/utf8.dart
index 893cf0f..7543865 100644
--- a/sdk/lib/utf/utf8.dart
+++ b/sdk/lib/utf/utf8.dart
@@ -90,7 +90,7 @@
   int insertAt = 0;
   for (int value in source) {
     if (value < 0 || value > UNICODE_VALID_RANGE_MAX) {
-      encoded.setRange(insertAt, 3, [0xef, 0xbf, 0xbd]);
+      encoded.setRange(insertAt, insertAt + 3, [0xef, 0xbf, 0xbd]);
       insertAt += 3;
     } else if (value <= _UTF8_ONE_BYTE_MAX) {
       encoded[insertAt] = value;
@@ -131,7 +131,7 @@
  */
 // TODO(floitsch): Consider removing the extend and switch to implements since
 // that's cheaper to allocate.
-class IterableUtf8Decoder extends Iterable<int> {
+class IterableUtf8Decoder extends IterableBase<int> {
   final List<int> bytes;
   final int offset;
   final int length;
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 1a36a9f..7dd2c2a 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -2,6 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index 3743a5d..99294d2 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -2,6 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
index 1064ba7..b7eaa46 100644
--- a/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
+++ b/sdk/lib/web_gl/dart2js/web_gl_dart2js.dart
@@ -1,6 +1,7 @@
 library dart.dom.web_gl;
 
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, JSName, Null, Returns, convertDartClosureToJS;
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index 486d0cf..b8c6d3c 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -2,6 +2,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index eee01a0..c1eacb9 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -12,6 +12,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show convertDartClosureToJS, Creates, JavaScriptIndexingBehavior, JSName;
@@ -342,6 +343,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Map> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Map> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Map removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -362,16 +371,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Map> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Map> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Map initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Map> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Map fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Map> getRange(int start, int end) =>
diff --git a/sdk/lib/web_sql/dartium/web_sql_dartium.dart b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
index 2a71887..29dcea9 100644
--- a/sdk/lib/web_sql/dartium/web_sql_dartium.dart
+++ b/sdk/lib/web_sql/dartium/web_sql_dartium.dart
@@ -12,6 +12,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:nativewrappers';
@@ -360,6 +361,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<Map> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<Map> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   Map removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -380,16 +389,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<Map> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Map> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [Map initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<Map> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [Map fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<Map> getRange(int start, int end) =>
diff --git a/tests/co19/co19-compiler.status b/tests/co19/co19-compiler.status
index fa01ccd..6884411 100644
--- a/tests/co19/co19-compiler.status
+++ b/tests/co19/co19-compiler.status
@@ -214,6 +214,25 @@
 
 LibTest/core/int/operator_division_A01_t01: Fail # truncate/ceil/floor/round returns ints, issue 389
 
+LibTest/core/List/List_A01_t02: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A07_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
+
 Language/11_Expressions/06_Lists_A06_t01: Fail # Issue 397
 LibTest/core/Iterable/where_A01_t07: Fail # Issue 397
 LibTest/core/List/addLast_A01_t01: Fail # Issue 397
@@ -244,5 +263,21 @@
 LibTest/core/Set/isSubsetOf_A01_t02: fail # Issue 400
 LibTest/core/List/operator_subscript_A01_t02: Fail # getRange now takes end-argument and returns Iterable. Issue 399
 
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.delayed_A02_t01: Fail # No AsyncError anymore. Issue 407
+
+Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
+
+
 [ $runtime == drt && $compiler == none ]
 *: Skip
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 49253a8..cdf7ed9 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -531,6 +531,40 @@
 LibTest/core/List/getRange_A04_t01: Fail # getRange now takes end-argument and returns Iterable. Issue 399
 LibTest/core/List/operator_subscript_A01_t02: Fail # getRange now takes end-argument and returns Iterable. Issue 399
 
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
+
+LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A01_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A05_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A03_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+LibTest/core/List/setRange_A03_t02: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+
+LibTest/core/List/removeRange_A01_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A03_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A05_t01: Fail # removeRange now takes end-argument. Issue 404
+
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+
 Language/11_Expressions/05_Strings/1_String_Interpolation_A03_t02: Fail # Issue 397
 Language/11_Expressions/05_Strings/1_String_Interpolation_A04_t02: Fail # Issue 397
 Language/11_Expressions/11_Instance_Creation/1_New_A08_t01: Fail # Issue 397
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 91c422c..763f31f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -298,6 +298,19 @@
 LibTest/core/List/operator_subscript_A03_t01: Fail # http://dartbug.com/9228
 LibTest/core/List/operator_subscripted_assignment_A03_t01: Fail # http://dartbug.com/9228
 
+Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A08_t04: Fail, OK # co19 issue 405
+
+
 [ $compiler == dart2js ]
 LibTest/core/int/operator_GT_A01_t01: Fail, OK # co19 issue 200
 LibTest/core/int/operator_LT_A01_t01: Fail, OK # co19 issue 200
@@ -307,7 +320,6 @@
 LibTest/core/List/sort_A01_t06: Slow, Pass # Slow tests that needs extra time to finish.
 
 LibTest/core/List/getRange_A03_t01: Fail, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
-LibTest/core/List/setRange_A05_t01: Fail, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
 
 Language/07_Classes/1_Instance_Methods_A02_t05: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A13_t01: Fail, OK # These tests need to be updated for new optional parameter syntax and semantics, co19 issue 258:
@@ -500,6 +512,41 @@
 LibTest/core/List/getRange_A04_t01: Fail # getRange now takes end-argument and returns Iterable. Issue 399
 LibTest/core/List/operator_subscript_A01_t02: Fail # getRange now takes end-argument and returns Iterable. Issue 399
 
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
+
+LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A01_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A03_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+LibTest/core/List/setRange_A03_t02: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+
+LibTest/core/List/removeRange_A01_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A03_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A05_t01: Fail # removeRange now takes end-argument. Issue 404
+
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+
+[ $compiler == dart2js && $unchecked ]
+LibTest/core/List/setRange_A05_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
 
 # Issues with co19 test suite in checked mode.
 [ $compiler == dart2js && $checked ]
@@ -511,6 +558,10 @@
 LibTest/collection/Queue/Queue.from_A01_t01: Fail # Issue 400
 LibTest/collection/Queue/Queue.from_A01_t02: Fail # Issue 400
 
+LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
 
 
 # Issues with co19 test suite in browsers.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index caf1431..0f7c3ee 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -73,6 +73,22 @@
 
 LibTest/core/int/operator_division_A01_t01: Fail # ~/ returns ints, issue 361
 
+Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t03: Fail, OK # co19 issue 405
+Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail, OK # co19 issue 405
+Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t02: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t04: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A05_t05: Fail, OK # co19 issue 405
+Language/11_Expressions/18_Assignment_A08_t04: Fail, OK # co19 issue 405
+
+
 
 [ $compiler == none && $runtime == vm ]
 Language/13_Libraries_and_Scripts/1_Imports_A02_t21: Crash # Dart issue 6060
@@ -198,6 +214,16 @@
 
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # issue 6085
 
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issues 408
+LibTest/async/Future/asStream_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediate_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/then_A01_t03: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/catchError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/forEach_A03_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A01_t02: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # Future constructors have changed # issue 408
+LibTest/async/Future/asStream_A02_t01: Fail # Future constructors have changed # issue 408
 
 [ $compiler == none && $runtime == vm && $checked ]
 Language/12_Statements/09_Switch_A05_t01: Fail # TODO(vm-team): Please triage this failure.
@@ -429,6 +455,28 @@
 LibTest/core/Set/isSubsetOf_A01_t01: fail # Issue 400
 LibTest/core/Set/isSubsetOf_A01_t02: fail # Issue 400
 
+LibTest/core/Iterable/any_A01_t04: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A01_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t01: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A02_t02: Fail # setRange now takes end-argument. Issue 402
+LibTest/core/List/setRange_A03_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+LibTest/core/List/setRange_A03_t02: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
+
+LibTest/core/List/removeRange_A01_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A03_t01: Fail # removeRange now takes end-argument. Issue 404
+LibTest/core/List/removeRange_A05_t01: Fail # removeRange now takes end-argument. Issue 404
+
+LibTest/core/List/insertRange_A01_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A03_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A04_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A05_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/insertRange_A06_t01: Fail # insertRange is removed. Issue 403
+LibTest/core/List/every_A01_t01: Fail # insertRange is removed. Issue 403
+
+LibTest/async/Completer/completeError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/Future.immediateError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A02_t01: Fail # No AsyncError anymore. Issue 407
+
 [ $compiler == none && $runtime == vm && $checked ]
 LibTest/core/Set/intersection_A01_t01: Fail # issue 390
 LibTest/core/Set/intersection_A01_t02: Fail # issue 390
@@ -441,6 +489,13 @@
 LibTest/core/Match/str_A01_t01: fail # Issue 400
 LibTest/core/RegExp/allMatches_A01_t01: fail # Issue 400
 
+LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
+LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
+
+[ $compiler == none && $runtime == vm && $unchecked ]
+LibTest/core/List/setRange_A05_t01: Fail # setRange now takes end-argument. Issue 402
 
 [ $compiler == none && $arch == simarm ]
 *: Skip
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 394fe0d..c890e85 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -19,7 +19,7 @@
 
   Future<String> localProvider(Uri uri) {
     if (uri.scheme != 'main') return dummy.provider(uri);
-    return new Future<String>.immediate(main);
+    return new Future<String>.value(main);
   }
 
   void localHandler(Uri uri, int begin, int end,
@@ -42,7 +42,7 @@
               localProvider, localHandler, options);
   result.then((String code) {
     onValue(code, errors, warnings);
-  }, onError: (AsyncError e) {
+  }, onError: (e) {
       throw 'Compilation failed';
   });
 }
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 3a4c2fc..9e21cba 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -92,25 +92,25 @@
   final libUri = fileUri('mylib.dart');
 
   provider(uri) {
-    if (uri == scriptUri) return new Future.immediate(srcMain);
+    if (uri == scriptUri) return new Future.value(srcMain);
     if (uri.toString() == libUri.toString()) {
-      return new Future.immediate(srcLibrary);
+      return new Future.value(srcLibrary);
     }
     if (uri.path.endsWith('/core.dart')) {
-      return new Future.immediate(coreLib);
+      return new Future.value(coreLib);
     } else  if (uri.path.endsWith('/io.dart')) {
-      return new Future.immediate(ioLib);
+      return new Future.value(ioLib);
     } else if (uri.path.endsWith('/js_helper.dart')) {
-      return new Future.immediate(helperLib);
+      return new Future.value(helperLib);
     } else if (uri.path.endsWith('/html_dart2js.dart')) {
       // TODO(smok): The file should change to html_dartium at some point.
-      return new Future.immediate(htmlLib);
+      return new Future.value(htmlLib);
     } else if (uri.path.endsWith('/foreign_helper.dart')) {
-      return new Future.immediate(foreignLib);
+      return new Future.value(foreignLib);
     } else if (uri.path.endsWith('/isolate_helper.dart')) {
-      return new Future.immediate(isolateHelperLib);
+      return new Future.value(isolateHelperLib);
     }
-    return new Future.immediate('');
+    return new Future.value('');
   }
 
   handler(uri, begin, end, message, kind) {
diff --git a/tests/compiler/dart2js/declare_once_test.dart b/tests/compiler/dart2js/declare_once_test.dart
new file mode 100644
index 0000000..01fb13e
--- /dev/null
+++ b/tests/compiler/dart2js/declare_once_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test that parameters keep their names in the output.
+
+import "package:expect/expect.dart";
+import 'compiler_helper.dart';
+
+main() {
+  // For a function with only one variable we declare it inline for more
+  // compactness.  Test that we don't also declare it at the start of the
+  // method.
+  var generated = compile(
+      'final List a = const ["bar", "baz"];'
+      'int foo() {'
+      '  for (int i = 0; i < a.length; i++) {'
+      '    print(a[i]);'
+      '  }'
+      '}',
+      entry: 'foo', minify: false);
+  RegExp re = new RegExp(r"var ");
+  Expect.isTrue(re.hasMatch(generated));
+  print(generated);
+  Expect.equals(1, re.allMatches(generated).length);
+}
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 20d6e90..7c4c551 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -37,8 +37,9 @@
       compiler.deferredLoadTask.allDeferredElements.where((e) => e.isClass())
       .toSet();
 
-  var expando =
-      deferredClasses.where((e) => e.name.slowToString() == 'Expando').single;
+  var dateTime =
+      deferredClasses
+          .where((e) => e.name.slowToString() == 'DateTime').single;
 
   var myClass =
       deferredClasses.where((e) => e.name.slowToString() == 'MyClass').single;
@@ -46,7 +47,7 @@
   var deferredLibrary = compiler.libraries['memory:deferred.dart'];
 
   Expect.equals(deferredLibrary, myClass.getLibrary());
-  Expect.equals(compiler.coreLibrary, expando.declaration.getLibrary());
+  Expect.equals(compiler.coreLibrary, dateTime.declaration.getLibrary());
 }
 
 const Map MEMORY_SOURCE_FILES = const {
@@ -71,7 +72,7 @@
   const MyClass();
 
   foo(x) {
-    new Expando();
+    new DateTime.now();
     return (x - 3) ~/ 2;
   }
 }
diff --git a/tests/compiler/dart2js/js_parser_test.dart b/tests/compiler/dart2js/js_parser_test.dart
index 0bfc6bc..1d972f0 100644
--- a/tests/compiler/dart2js/js_parser_test.dart
+++ b/tests/compiler/dart2js/js_parser_test.dart
@@ -71,21 +71,18 @@
   // String literal with escaped quote.
   testExpression(r'var x = "\""');
   // *No clever escapes.
-  testError(r'var x = "\x42"', 'escapes allowed in string literals');
+  testError(r'var x = "\x42"', 'escapes are not allowed in literals');
   // Operator new.
   testExpression('new Foo()');
   // New with dotted access.
   testExpression('new Frobinator.frobinate()');
-  // *We don't handle dot after 'new' because we group 'new' with regular calls
-  // instead of having it together with the dot operator but with opposite
-  // associativity.
-  testError('new Frobinator().frobinate()', "DOT");
-  // The prettyprinter is smarter than we are.
+  testExpression('new Frobinator().frobinate()');
+  // The prettyprinter strips some superfluous parentheses.
   testExpression('(new Frobinator()).frobinate()',
                  'new Frobinator().frobinate()');
   // *We want a bracket on 'new'.
-  testError('new Foo');
-  testError('(new Foo)');
+  testError('new Foo', 'Parentheses are required');
+  testError('(new Foo)', 'Parentheses are required');
   // Bogus operators.
   testError('a +++ b', 'Unknown operator');
   // This isn't perl.  There are rules.
@@ -107,9 +104,24 @@
   testExpression('var new = 42');
   // Bad keyword.
   testError('var typeof = 42', "Expected ALPHA");
-  // Malformed decimal
+  // Malformed decimal/hex.
   testError('var x = 42.', "Unparseable number");
   testError('var x = 1.1.1', "Unparseable number");
+  testError('var x = 0xabcdefga', "Unparseable number");
+  testError('var x = 0xabcdef\$a', "Unparseable number");
+  testError('var x = 0x ', "Unparseable number");
+  // Good hex constants.
+  testExpression('var x = 0xff');
+  testExpression('var x = 0xff + 0xff');
+  testExpression('var x = 0xaF + 0x0123456789abcdefABCDEF');
+  // All sorts of keywords are allowed as property names in ES5.
+  testExpression('x.new = 0');
+  testExpression('x.delete = 0');
+  testExpression('x.for = 0');
+  testExpression('x.instanceof = 0');
+  testExpression('x.in = 0');
+  testExpression('x.void = 0');
+  testExpression('x.continue = 0');
   // More unary.
   testExpression('x = !x');
   testExpression('!x == false');
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 16cccf3..26a33b0 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -32,10 +32,10 @@
       return super.readStringFromUri(resourceUri);
     }
     String source = MEMORY_SOURCE_FILES[resourceUri.path];
-    // TODO(ahe): Return new Future.immediateError(...) ?
+    // TODO(ahe): Return new Future.error(...) ?
     if (source == null) throw 'No such file $resourceUri';
     String resourceName = '$resourceUri';
     this.sourceFiles[resourceName] = new SourceFile(resourceName, source);
-    return new Future.immediate(source);
+    return new Future.value(source);
   }
 }
diff --git a/tests/compiler/dart2js/scanner_test.dart b/tests/compiler/dart2js/scanner_test.dart
index 28c01b0..da8f032 100644
--- a/tests/compiler/dart2js/scanner_test.dart
+++ b/tests/compiler/dart2js/scanner_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import 'dart:collection';
 import 'dart:utf';
 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart';
 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scanner_implementation.dart';
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 181014f..d2c3205 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -6,7 +6,7 @@
 class_test: Fail
 statements_test: Fail
 typed_locals_test: Fail
-no_such_method_test: Fail # Wrong InvocationMirror.memberName.
+no_such_method_test: Fail # Wrong Invocation.memberName.
 
 deferred_semantics_test/none: Fail # TODO(ahe): Multitest cannot use import.
 
diff --git a/tests/compiler/dart2js_extra/for_in_test.dart b/tests/compiler/dart2js_extra/for_in_test.dart
index 39d45d9..eb5de79 100644
--- a/tests/compiler/dart2js_extra/for_in_test.dart
+++ b/tests/compiler/dart2js_extra/for_in_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "dart:collection";
 import "package:expect/expect.dart";
 
 // Test foreach (aka. for-in) functionality.
@@ -25,7 +26,7 @@
   Expect.equals(expect.length, i);
 }
 
-class MyIterable<T> extends Iterable<T> {
+class MyIterable<T> extends IterableBase<T> {
   final List<T> values;
   MyIterable(List<T> values) : this.values = values;
   Iterator get iterator {
diff --git a/tests/compiler/dart2js_extra/no_such_method_test.dart b/tests/compiler/dart2js_extra/no_such_method_test.dart
index dc28e07..a139c02 100644
--- a/tests/compiler/dart2js_extra/no_such_method_test.dart
+++ b/tests/compiler/dart2js_extra/no_such_method_test.dart
@@ -13,7 +13,7 @@
 }
 
 class A {
-  noSuchMethod(InvocationMirror invocation) {
+  noSuchMethod(Invocation invocation) {
     topLevelInfo = new NoSuchMethodInfo(this, invocation.memberName,
                                         invocation.positionalArguments);
     return topLevelInfo;
diff --git a/tests/corelib/apply2_test.dart b/tests/corelib/apply2_test.dart
index e733a24..f2984bf 100644
--- a/tests/corelib/apply2_test.dart
+++ b/tests/corelib/apply2_test.dart
@@ -3,10 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "symbol_map_helper.dart";
 
 apply(Function function, ArgumentDescriptor args) {
   return Function.apply(
-      function, args.positionalArguments, args.namedArguments);
+      function, args.positionalArguments,
+      symbolMapToStringMap(args.namedArguments));
 }
 
 class ArgumentDescriptor {
diff --git a/tests/corelib/apply_test.dart b/tests/corelib/apply_test.dart
index 71e87b9..d872227 100644
--- a/tests/corelib/apply_test.dart
+++ b/tests/corelib/apply_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "symbol_map_helper.dart";
 
 // Testing Function.apply calls correctly.
 // This test is not testing error handling, only that correct parameters
@@ -38,15 +39,17 @@
 
 main() {
   testMap(res, func, map) {
+    map = symbolMapToStringMap(map);
     Expect.equals(res, Function.apply(func, null, map));
     Expect.equals(res, Function.apply(func, [], map));
   }
   testList(res, func, list) {
     Expect.equals(res, Function.apply(func, list));
     Expect.equals(res, Function.apply(func, list, null));
-    Expect.equals(res, Function.apply(func, list, {}));
+    Expect.equals(res, Function.apply(func, list, new Map<Symbol, dynamic>()));
   }
   test(res, func, list, map) {
+    map = symbolMapToStringMap(map);
     Expect.equals(res, Function.apply(func, list, map));
   }
   testList(42, test0, null);
diff --git a/tests/corelib/iterable_expand_test.dart b/tests/corelib/iterable_expand_test.dart
index 5737a9b..9c60541 100644
--- a/tests/corelib/iterable_expand_test.dart
+++ b/tests/corelib/iterable_expand_test.dart
@@ -3,6 +3,21 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import 'dart:collection';
+
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
+
+  get length => list.length;
+  set length(val) { list.length = val; }
+
+  operator [](index) => list[index];
+  operator []=(index, val) => list[index] = val;
+
+  String toString() => "[" + join(", ") + "]";
+}
+
 
 main() {
   test(expectation, iterable) {
@@ -25,6 +40,16 @@
   test([1, 1, 2, 2, 3, 3], [1, 2, 3].expand((x) => [x, x]));
   test([1, 1, 2], [1, 2, 3].expand((x) => [x, x, x].skip(x)));
 
+  test([1], new MyList([1]).expand((x) => [x]));
+  test([1, 2, 3], new MyList([1, 2, 3]).expand((x) => [x]));
+
+  test([], new MyList([1]).expand((x) => []));
+  test([], new MyList([1, 2, 3]).expand((x) => []));
+  test([2], new MyList([1, 2, 3]).expand((x) => x == 2 ? [2] : []));
+
+  test([1, 1, 2, 2, 3, 3], new MyList([1, 2, 3]).expand((x) => [x, x]));
+  test([1, 1, 2], new MyList([1, 2, 3]).expand((x) => [x, x, x].skip(x)));
+
   // if function throws, iteration is stopped.
   Iterable iterable = [1, 2, 3].expand((x) {
     if (x == 2) throw "FAIL";
diff --git a/tests/corelib/iterable_length_test.dart b/tests/corelib/iterable_length_test.dart
index 225d398..20c9663 100644
--- a/tests/corelib/iterable_length_test.dart
+++ b/tests/corelib/iterable_length_test.dart
@@ -2,9 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import "dart:collection";
 import "package:expect/expect.dart";
 
-class A extends Iterable {
+class A extends IterableBase {
   int count;
   A(this.count);
 
diff --git a/tests/corelib/iterable_test.dart b/tests/corelib/iterable_test.dart
index 51e363d..f99bba6 100644
--- a/tests/corelib/iterable_test.dart
+++ b/tests/corelib/iterable_test.dart
@@ -7,7 +7,9 @@
 
 import "package:expect/expect.dart";
 
-class MyIterable implements Iterable {
+import 'dart:collection';
+
+class MyIterable implements IterableBase {
   get iterator => [].iterator;
 }
 
diff --git a/tests/corelib/list_fill_range_test.dart b/tests/corelib/list_fill_range_test.dart
new file mode 100644
index 0000000..cd0e023
--- /dev/null
+++ b/tests/corelib/list_fill_range_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.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int start, int end, [fillValue]) {
+  List copy = list.toList();
+  if (?fillValue) {
+    list.fillRange(start, end, fillValue);
+  } else {
+    list.fillRange(start, end, fillValue);
+  }
+  Expect.equals(copy.length, list.length);
+  for (int i = 0; i < start; i++) {
+    Expect.equals(copy[i], list[i]);
+  }
+  for (int i = start; i < end; i++) {
+    Expect.equals(fillValue, list[i]);
+  }
+  for (int i = end; i < list.length; i++) {
+    Expect.equals(copy[i], list[i]);
+  }
+}
+
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
+  get length => list.length;
+  set length(value) { list.length = value; }
+  operator [](index) => list[index];
+  operator []=(index, val) { list[index] = val; }
+  toString() => list.toString();
+}
+
+main() {
+  test([1, 2, 3], 0, 1);
+  test([1, 2, 3], 0, 1, 99);
+  test([1, 2, 3], 1, 1);
+  test([1, 2, 3], 1, 1, 499);
+  test([1, 2, 3], 3, 3);
+  test([1, 2, 3], 3, 3, 499);
+  test([1, 2, 3].toList(growable: false), 0, 1);
+  test([1, 2, 3].toList(growable: false), 0, 1, 99);
+  test([1, 2, 3].toList(growable: false), 1, 1);
+  test([1, 2, 3].toList(growable: false), 1, 1, 499);
+  test([1, 2, 3].toList(growable: false), 3, 3);
+  test([1, 2, 3].toList(growable: false), 3, 3, 499);
+  test(new MyList([1, 2, 3]), 0, 1);
+  test(new MyList([1, 2, 3]), 0, 1, 99);
+  test(new MyList([1, 2, 3]), 1, 1);
+  test(new MyList([1, 2, 3]), 1, 1, 499);
+  test(new MyList([1, 2, 3]), 3, 3);
+  test(new MyList([1, 2, 3]), 3, 3, 499);
+
+  expectRE(() => test([1, 2, 3], -1, 0));
+  expectRE(() => test([1, 2, 3], 2, 1));
+  expectRE(() => test([1, 2, 3], 0, -1));
+  expectRE(() => test([1, 2, 3], 1, 4));
+  expectRE(() => test(new MyList([1, 2, 3]), -1, 0));
+  expectRE(() => test(new MyList([1, 2, 3]), 2, 1));
+  expectRE(() => test(new MyList([1, 2, 3]), 0, -1));
+  expectRE(() => test(new MyList([1, 2, 3]), 1, 4));
+  expectUE(() => test(const [1, 2, 3], 2, 3));
+  expectUE(() => test(const [1, 2, 3], -1, 0));
+  expectUE(() => test(const [1, 2, 3], 2, 1));
+  expectUE(() => test(const [1, 2, 3], 0, -1));
+  expectUE(() => test(const [1, 2, 3], 1, 4));
+}
+
+void expectRE(Function f) {
+  Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+  Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_insert_all_test.dart b/tests/corelib/list_insert_all_test.dart
new file mode 100644
index 0000000..a1d025a
--- /dev/null
+++ b/tests/corelib/list_insert_all_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int index, Iterable iterable) {
+  List copy = list.toList();
+  list.insertAll(index, iterable);
+  List iterableList = iterable.toList();
+  Expect.equals(copy.length + iterableList.length, list.length);
+  for (int i = 0; i < index; i++) {
+    Expect.equals(copy[i], list[i]);
+  }
+  for (int i = 0; i < iterableList.length; i++) {
+    Expect.equals(iterableList[i], list[i + index]);
+  }
+  for (int i = index + iterableList.length; i < copy.length; i++) {
+    Expect.equals(copy[i], list[i + iterableList.length]);
+  }
+}
+
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
+  get length => list.length;
+  set length(value) { list.length = value; }
+  operator [](index) => list[index];
+  operator []=(index, val) { list[index] = val; }
+  toString() => list.toString();
+}
+
+main() {
+  test([1, 2, 3], 0, [4, 5]);
+  test([1, 2, 3], 1, [4, 5]);
+  test([1, 2, 3], 2, [4, 5]);
+  test([1, 2, 3], 3, [4, 5]);
+  test([1, 2, 3], 2, [4]);
+  test([1, 2, 3], 3, []);
+  test([1, 2, 3], 0, [4, 5].map((x) => x));
+  test([1, 2, 3], 1, [4, 5].map((x) => x));
+  test([1, 2, 3], 2, [4, 5].map((x) => x));
+  test([1, 2, 3], 3, [4, 5].map((x) => x));
+  test([1, 2, 3], 2, [4].map((x) => x));
+  test([1, 2, 3], 3, [].map((x) => x));
+  test([1, 2, 3], 0, const [4, 5]);
+  test([1, 2, 3], 1, const [4, 5]);
+  test([1, 2, 3], 2, const [4, 5]);
+  test([1, 2, 3], 3, const [4 ,5]);
+  test([1, 2, 3], 2, const [4]);
+  test([1, 2, 3], 3, const []);
+  test([1, 2, 3], 0, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 1, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 2, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 3, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 2, new Iterable.generate(1, (x) => x + 4));
+  test([1, 2, 3], 3, new Iterable.generate(0, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 0, [4, 5]);
+  test(new MyList([1, 2, 3]), 1, [4, 5]);
+  test(new MyList([1, 2, 3]), 2, [4]);
+  test(new MyList([1, 2, 3]), 3, []);
+  test(new MyList([1, 2, 3]), 2, [4, 5]);
+  test(new MyList([1, 2, 3]), 3, [4, 5]);
+  test(new MyList([1, 2, 3]), 0, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 1, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 2, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 3, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 2, [4].map((x) => x));
+  test(new MyList([1, 2, 3]), 3, [].map((x) => x));
+
+  expectRE(() => test([1, 2, 3], -1, [4, 5]));
+  expectUE(() => test([1, 2, 3].toList(growable: false), -1, [4, 5]));
+  expectRE(() => test(new MyList([1, 2, 3]), -1, [4, 5]));
+  expectUE(() => test([1, 2, 3].toList(growable: false), 0, [4, 5]));
+}
+
+void expectRE(Function f) {
+  Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+  Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_insert_range_test.dart b/tests/corelib/list_insert_range_test.dart
deleted file mode 100644
index 8670c62..0000000
--- a/tests/corelib/list_insert_range_test.dart
+++ /dev/null
@@ -1,47 +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.
-
-import "package:expect/expect.dart";
-
-main() {
-  var list = [];
-  list.insertRange(-1, 0);
-  Expect.listEquals([], list);
-  list.insertRange(0, 0);
-  Expect.listEquals([], list);
-  list.insertRange(0, 0, 2);
-  Expect.listEquals([], list);
-  list.insertRange(0, 0, 2);
-  Expect.listEquals([], list);
-
-  expectIOORE(() { [1, 2].insertRange(-1, 1); });
-  expectIOORE(() { [1, 2].insertRange(3, 1); });
-  expectIAE(() { [1, 2].insertRange(0, -1); });
-
-  list = []; list.insertRange(0, 3);
-  Expect.listEquals([null, null, null], list);
-
-  list = []; list.insertRange(0, 3, 1);
-  Expect.listEquals([1, 1, 1], list);
-
-  list = [1, 1]; list.insertRange(1, 1, 2);
-  Expect.listEquals([1, 2, 1], list);
-
-  list = [1, 1]; list.insertRange(2, 2, 9);
-  Expect.listEquals([1, 1, 9, 9], list);
-
-  list = [1, 1]; list.insertRange(2, 1);
-  Expect.listEquals([1, 1, null], list);
-
-  list = [1, 1]; list.insertRange(0, 3, 3);
-  Expect.listEquals([3, 3, 3, 1, 1], list);
-}
-
-void expectIOORE(Function f) {
-  Expect.throws(f, (e) => e is RangeError);
-}
-
-void expectIAE(Function f) {
-  Expect.throws(f, (e) => e is ArgumentError);
-}
diff --git a/tests/corelib/list_insert_test.dart b/tests/corelib/list_insert_test.dart
index adfd677..50d088f 100644
--- a/tests/corelib/list_insert_test.dart
+++ b/tests/corelib/list_insert_test.dart
@@ -3,11 +3,23 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:expect/expect.dart';
+import 'dart:collection';
 
-void main() {
-  // Normal modifiable list.
-  var l1 = [0, 1, 2, 3, 4];
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
 
+  get length => list.length;
+  set length(val) { list.length = val; }
+
+  operator [](index) => list[index];
+  operator []=(index, val) => list[index] = val;
+
+  String toString() => "[" + join(", ") + "]";
+}
+
+// l1 must be a modifiable list with 5 elements from 0 to 4.
+void testModifiableList(l1) {
   bool checkedMode = false;
   assert(checkedMode = true);
 
@@ -31,6 +43,12 @@
   Expect.equals(7, l1.length);
   Expect.equals(-1, l1[0]);
   Expect.equals("[-1, 0, 1, 2, 3, 4, 5]", l1.toString());
+}
+
+void main() {
+  // Normal modifiable list.
+  testModifiableList([0, 1, 2, 3, 4]);
+  testModifiableList(new MyList([0, 1, 2, 3, 4]));
 
   // Fixed size list.
   var l2 = new List(5);
diff --git a/tests/corelib/list_remove_range_test.dart b/tests/corelib/list_remove_range_test.dart
index b4fa04f..94032a1 100644
--- a/tests/corelib/list_remove_range_test.dart
+++ b/tests/corelib/list_remove_range_test.dart
@@ -28,14 +28,14 @@
   Expect.listEquals([], list);
 
   list.addAll([3, 4, 5, 6]);
-  list.removeRange(2, 2);
+  list.removeRange(2, 4);
   Expect.listEquals([3, 4], list);
   list.addAll([5, 6]);
 
-  expectIOORE(() { list.removeRange(4, 1); });
+  expectIOORE(() { list.removeRange(4, 5); });
   Expect.listEquals([3, 4, 5, 6], list);
 
-  list.removeRange(1, 2);
+  list.removeRange(1, 3);
   Expect.listEquals([3, 6], list);
 
   testNegativeIndices();
@@ -51,18 +51,14 @@
   Expect.listEquals([1, 2], list);
 
   // A negative length throws an ArgumentError.
-  Expect.throws(() { list.removeRange(0, -1); },
-      (e) => e is ArgumentError);
+  expectIOORE(() { list.removeRange(0, -1); });
   Expect.listEquals([1, 2], list);
 
-  Expect.throws(() { list.removeRange(-1, -1); },
-      (e) => e is ArgumentError);
+  expectIOORE(() { list.removeRange(-1, -1); });
   Expect.listEquals([1, 2], list);
 
-  // A zero length prevails, and does not throw an exception.
-  list.removeRange(-1, 0);
-  Expect.listEquals([1, 2], list);
+  expectIOORE(() { list.removeRange(-1, 0); });
 
-  list.removeRange(4, 0);
+  expectIOORE(() { list.removeRange(4, 4); });
   Expect.listEquals([1, 2], list);
 }
diff --git a/tests/corelib/list_removeat_test.dart b/tests/corelib/list_removeat_test.dart
index d8dbf88..d9c7453 100644
--- a/tests/corelib/list_removeat_test.dart
+++ b/tests/corelib/list_removeat_test.dart
@@ -3,11 +3,23 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import 'dart:collection';
 
-void main() {
-  // Normal modifiable list.
-  var l1 = [0, 1, 2, 3, 4];
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
 
+  get length => list.length;
+  set length(val) { list.length = val; }
+
+  operator [](index) => list[index];
+  operator []=(index, val) => list[index] = val;
+
+  String toString() => "[" + join(", ") + "]";
+}
+
+// l1 must be a modifiable list with 5 elements from 0 to 4.
+void testModifiableList(l1) {
   bool checkedMode = false;
   assert(checkedMode = true);
 
@@ -42,6 +54,12 @@
   Expect.equals(3, l1[1], "l1-2[1]");
   Expect.equals(4, l1[2], "l1-2[2]");
   Expect.equals(3, l1.length, "length-2");
+}
+
+void main() {
+  // Normal modifiable list.
+  testModifiableList([0, 1, 2, 3, 4]);
+  testModifiableList(new MyList([0, 1, 2, 3, 4]));
 
   // Fixed size list.
   var l2 = new List(5);
diff --git a/tests/corelib/list_replace_range_test.dart b/tests/corelib/list_replace_range_test.dart
new file mode 100644
index 0000000..26f016a
--- /dev/null
+++ b/tests/corelib/list_replace_range_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int start, int end, Iterable iterable) {
+  List copy = list.toList();
+  list.replaceRange(start, end, iterable);
+  List iterableList = iterable.toList();
+  Expect.equals(copy.length + iterableList.length - (end - start), list.length);
+  for (int i = 0; i < start; i++) {
+    Expect.equals(copy[i], list[i]);
+  }
+  for (int i = 0; i < iterableList.length; i++) {
+    Expect.equals(iterableList[i], list[i + start]);
+  }
+  int removedLength = end - start;
+  for (int i = end; i < copy.length; i++) {
+    Expect.equals(copy[i], list[i + iterableList.length - removedLength]);
+  }
+}
+
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
+  get length => list.length;
+  set length(value) { list.length = value; }
+  operator [](index) => list[index];
+  operator []=(index, val) { list[index] = val; }
+  toString() => list.toString();
+}
+
+main() {
+  test([1, 2, 3], 0, 1, [4, 5]);
+  test([1, 2, 3], 1, 1, [4, 5]);
+  test([1, 2, 3], 2, 3, [4, 5]);
+  test([1, 2, 3], 3, 3, [4, 5]);
+  test([1, 2, 3], 0, 3, [4, 5]);
+  test([1, 2, 3], 2, 3, [4]);
+  test([1, 2, 3], 0, 3, []);
+  test([1, 2, 3], 0, 1, [4, 5].map((x) => x));
+  test([1, 2, 3], 1, 1, [4, 5].map((x) => x));
+  test([1, 2, 3], 2, 3, [4, 5].map((x) => x));
+  test([1, 2, 3], 3, 3, [4, 5].map((x) => x));
+  test([1, 2, 3], 0, 3, [4, 5].map((x) => x));
+  test([1, 2, 3], 2, 3, [4].map((x) => x));
+  test([1, 2, 3], 0, 3, [].map((x) => x));
+  test([1, 2, 3], 0, 1, const [4, 5]);
+  test([1, 2, 3], 1, 1, const [4, 5]);
+  test([1, 2, 3], 2, 3, const [4, 5]);
+  test([1, 2, 3], 3, 3, const [4, 5]);
+  test([1, 2, 3], 0, 3, const [4, 5]);
+  test([1, 2, 3], 2, 3, const [4]);
+  test([1, 2, 3], 0, 3, const []);
+  test([1, 2, 3], 0, 1, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 1, 1, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 2, 3, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 3, 3, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 0, 3, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 2, 3, new Iterable.generate(2, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 0, 1, [4, 5]);
+  test(new MyList([1, 2, 3]), 1, 1, [4, 5]);
+  test(new MyList([1, 2, 3]), 2, 3, [4, 5]);
+  test(new MyList([1, 2, 3]), 3, 3, [4, 5]);
+  test(new MyList([1, 2, 3]), 0, 3, [4, 5]);
+  test(new MyList([1, 2, 3]), 2, 3, [4]);
+  test(new MyList([1, 2, 3]), 0, 3, []);
+  test(new MyList([1, 2, 3]), 0, 1, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 1, 1, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 2, 3, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 3, 3, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 0, 3, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 2, 3, [4].map((x) => x));
+  test(new MyList([1, 2, 3]), 0, 3, [].map((x) => x));
+  test(new MyList([1, 2, 3]), 0, 1, const [4, 5]);
+  test(new MyList([1, 2, 3]), 1, 1, const [4, 5]);
+  test(new MyList([1, 2, 3]), 2, 3, const [4, 5]);
+  test(new MyList([1, 2, 3]), 3, 3, const [4, 5]);
+  test(new MyList([1, 2, 3]), 0, 3, const [4, 5]);
+  test(new MyList([1, 2, 3]), 2, 3, const [4]);
+  test(new MyList([1, 2, 3]), 0, 3, const []);
+  test(new MyList([1, 2, 3]), 0, 1, new Iterable.generate(2, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 1, 1, new Iterable.generate(2, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 2, 3, new Iterable.generate(2, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 3, 3, new Iterable.generate(2, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 0, 3, new Iterable.generate(2, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 2, 3, new Iterable.generate(2, (x) => x + 4));
+
+  expectRE(() => test([1, 2, 3], -1, 0, []));
+  expectRE(() => test([1, 2, 3], 2, 1, []));
+  expectRE(() => test([1, 2, 3], 0, -1, []));
+  expectRE(() => test([1, 2, 3], 1, 4, []));
+  expectRE(() => test(new MyList([1, 2, 3]), -1, 0, []));
+  expectRE(() => test(new MyList([1, 2, 3]), 2, 1, []));
+  expectRE(() => test(new MyList([1, 2, 3]), 0, -1, []));
+  expectRE(() => test(new MyList([1, 2, 3]), 1, 4, []));
+  expectUE(() => test([1, 2, 3].toList(growable: false), 2, 3, []));
+  expectUE(() => test([1, 2, 3].toList(growable: false), -1, 0, []));
+  expectUE(() => test([1, 2, 3].toList(growable: false), 2, 1, []));
+  expectUE(() => test([1, 2, 3].toList(growable: false), 0, -1, []));
+  expectUE(() => test([1, 2, 3].toList(growable: false), 1, 4, []));
+  expectUE(() => test(const [1, 2, 3], 2, 3, []));
+  expectUE(() => test(const [1, 2, 3], -1, 0, []));
+  expectUE(() => test(const [1, 2, 3], 2, 1, []));
+  expectUE(() => test(const [1, 2, 3], 0, -1, []));
+  expectUE(() => test(const [1, 2, 3], 1, 4, []));
+}
+
+void expectRE(Function f) {
+  Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+  Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_set_all_test.dart b/tests/corelib/list_set_all_test.dart
new file mode 100644
index 0000000..50be8b3
--- /dev/null
+++ b/tests/corelib/list_set_all_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:collection";
+
+test(List list, int index, Iterable iterable) {
+  List copy = list.toList();
+  list.setAll(index, iterable);
+  Expect.equals(copy.length, list.length);
+  for (int i = 0; i < index; i++) {
+    Expect.equals(copy[i], list[i]);
+  }
+  List iterableList = iterable.toList();
+  for (int i = 0; i < iterableList.length; i++) {
+    Expect.equals(iterableList[i], list[i + index]);
+  }
+  for (int i = index + iterableList.length; i < copy.length; i++) {
+    Expect.equals(copy[i], list[i]);
+  }
+}
+
+class MyList extends ListBase {
+  List list;
+  MyList(this.list);
+  get length => list.length;
+  set length(value) { list.length = value; }
+  operator [](index) => list[index];
+  operator []=(index, val) { list[index] = val; }
+  toString() => list.toString();
+}
+
+main() {
+  test([1, 2, 3], 0, [4, 5]);
+  test([1, 2, 3], 1, [4, 5]);
+  test([1, 2, 3], 2, [4]);
+  test([1, 2, 3], 3, []);
+  test([1, 2, 3], 0, [4, 5].map((x) => x));
+  test([1, 2, 3], 1, [4, 5].map((x) => x));
+  test([1, 2, 3], 2, [4].map((x) => x));
+  test([1, 2, 3], 3, [].map((x) => x));
+  test([1, 2, 3], 0, const [4, 5]);
+  test([1, 2, 3], 1, const [4, 5]);
+  test([1, 2, 3], 2, const [4]);
+  test([1, 2, 3], 3, const []);
+  test([1, 2, 3], 0, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 1, new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3], 2, new Iterable.generate(1, (x) => x + 4));
+  test([1, 2, 3], 3, new Iterable.generate(0, (x) => x + 4));
+  test([1, 2, 3].toList(growable: false), 0, [4, 5]);
+  test([1, 2, 3].toList(growable: false), 1, [4, 5]);
+  test([1, 2, 3].toList(growable: false), 2, [4]);
+  test([1, 2, 3].toList(growable: false), 3, []);
+  test([1, 2, 3].toList(growable: false), 0, [4, 5].map((x) => x));
+  test([1, 2, 3].toList(growable: false), 1, [4, 5].map((x) => x));
+  test([1, 2, 3].toList(growable: false), 2, [4].map((x) => x));
+  test([1, 2, 3].toList(growable: false), 3, [].map((x) => x));
+  test([1, 2, 3].toList(growable: false), 0, const [4, 5]);
+  test([1, 2, 3].toList(growable: false), 1, const [4, 5]);
+  test([1, 2, 3].toList(growable: false), 2, const [4]);
+  test([1, 2, 3].toList(growable: false), 3, const []);
+  test([1, 2, 3].toList(growable: false), 0,
+      new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3].toList(growable: false), 1,
+      new Iterable.generate(2, (x) => x + 4));
+  test([1, 2, 3].toList(growable: false), 2,
+      new Iterable.generate(1, (x) => x + 4));
+  test([1, 2, 3].toList(growable: false), 3,
+      new Iterable.generate(0, (x) => x + 4));
+  test(new MyList([1, 2, 3]), 0, [4, 5]);
+  test(new MyList([1, 2, 3]), 1, [4, 5]);
+  test(new MyList([1, 2, 3]), 2, [4]);
+  test(new MyList([1, 2, 3]), 3, []);
+  test(new MyList([1, 2, 3]), 0, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 1, [4, 5].map((x) => x));
+  test(new MyList([1, 2, 3]), 2, [4].map((x) => x));
+  test(new MyList([1, 2, 3]), 3, [].map((x) => x));
+
+  expectRE(() => test([1, 2, 3], -1, [4, 5]));
+  expectRE(() => test([1, 2, 3].toList(growable: false), -1, [4, 5]));
+  expectRE(() => test([1, 2, 3], 1, [4, 5, 6]));
+  expectRE(() => test([1, 2, 3].toList(growable: false), 1, [4, 5, 6]));
+  expectRE(() => test(new MyList([1, 2, 3]), -1, [4, 5]));
+  expectRE(() => test(new MyList([1, 2, 3]), 1, [4, 5, 6]));
+  expectUE(() => test(const [1, 2, 3], 0, [4, 5]));
+  expectUE(() => test(const [1, 2, 3], -1, [4, 5]));
+  expectUE(() => test(const [1, 2, 3], 1, [4, 5, 6]));
+}
+
+void expectRE(Function f) {
+  Expect.throws(f, (e) => e is RangeError);
+}
+
+void expectUE(Function f) {
+  Expect.throws(f, (e) => e is UnsupportedError);
+}
diff --git a/tests/corelib/list_set_range_test.dart b/tests/corelib/list_set_range_test.dart
index a693584..da80052 100644
--- a/tests/corelib/list_set_range_test.dart
+++ b/tests/corelib/list_set_range_test.dart
@@ -27,7 +27,7 @@
   Expect.equals(1, list.length);
   Expect.equals(1, list[0]);
 
-  expectIOORE(() { list.setRange(0, 1, [1, 2], 2); });
+  expectSE(() { list.setRange(0, 1, [1, 2], 2); });
   Expect.equals(1, list.length);
   Expect.equals(1, list[0]);
 
@@ -44,13 +44,13 @@
   list.setRange(0, 4, [1, 2, 3, 4]);
   Expect.listEquals([1, 2, 3, 4], list);
 
-  list.setRange(2, 2, [5, 6, 7, 8]);
+  list.setRange(2, 4, [5, 6, 7, 8]);
   Expect.listEquals([1, 2, 5, 6], list);
 
-  expectIOORE(() { list.setRange(4, 1, [5, 6, 7, 8]); });
+  expectIOORE(() { list.setRange(4, 5, [5, 6, 7, 8]); });
   Expect.listEquals([1, 2, 5, 6], list);
 
-  list.setRange(1, 2, [9, 10, 11, 12]);
+  list.setRange(1, 3, [9, 10, 11, 12]);
   Expect.listEquals([1, 9, 10, 6], list);
 
   testNegativeIndices();
@@ -62,23 +62,29 @@
   Expect.throws(f, (e) => e is RangeError);
 }
 
+void expectSE(Function f) {
+  Expect.throws(f, (e) => e is StateError);
+}
+
+void expectAE(Function f) {
+  Expect.throws(f, (e) => e is ArgumentError);
+}
+
 void testNegativeIndices() {
   var list = [1, 2];
   expectIOORE(() { list.setRange(-1, 1, [1]); });
-  expectIOORE(() { list.setRange(0, 1, [1], -1); });
+  expectAE(() { list.setRange(0, 1, [1], -1); });
 
   // A negative length throws an ArgumentError.
-  Expect.throws(() { list.setRange(0, -1, [1]); },
-      (e) => e is ArgumentError);
+  expectIOORE(() { list.setRange(2, 1, [1]); });
 
-  Expect.throws(() { list.setRange(-1, -1, [1], -1); },
-      (e) => e is ArgumentError);
+  expectAE(() { list.setRange(-1, -2, [1], -1); });
   Expect.listEquals([1, 2], list);
 
-  // A zero length prevails, and does not throw an exception.
-  list.setRange(-1, 0, [1]);
+  expectIOORE(() { list.setRange(-1, -1, [1]); });
   Expect.listEquals([1, 2], list);
 
+  // The skipCount is only used if the length is not 0.
   list.setRange(0, 0, [1], -1);
   Expect.listEquals([1, 2], list);
 }
@@ -87,6 +93,6 @@
   var list = new List<int>(6);
   Expect.listEquals([null, null, null, null, null, null], list);
   list.setRange(0, 3, [1, 2, 3, 4]);
-  list.setRange(3, 3, [1, 2, 3, 4]);
+  list.setRange(3, 6, [1, 2, 3, 4]);
   Expect.listEquals([1, 2, 3, 1, 2, 3], list);
 }
diff --git a/tests/corelib/list_to_string_test.dart b/tests/corelib/list_to_string_test.dart
new file mode 100644
index 0000000..a127c26
--- /dev/null
+++ b/tests/corelib/list_to_string_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.
+
+import "package:expect/expect.dart";
+import 'dart:collection';
+
+class MyList extends ListBase {
+  final list;
+  MyList(this.list);
+
+  get length => list.length;
+  set length(val) { list.length = val; }
+
+  operator [](index) => list[index];
+  operator []=(index, val) => list[index] = val;
+}
+
+main() {
+  Expect.equals("[]", [].toString());
+  Expect.equals("[1]", [1].toString());
+  Expect.equals("[1, 2]", [1, 2].toString());
+  Expect.equals("[]", const [].toString());
+  Expect.equals("[1]", const [1].toString());
+  Expect.equals("[1, 2]", const [1, 2].toString());
+  Expect.equals("[]", new MyList([]).toString());
+  Expect.equals("[1]", new MyList([1]).toString());
+  Expect.equals("[1, 2]", new MyList([1, 2]).toString());
+}
diff --git a/tests/corelib/string_slice_test.dart b/tests/corelib/string_slice_test.dart
deleted file mode 100644
index b003a42..0000000
--- a/tests/corelib/string_slice_test.dart
+++ /dev/null
@@ -1,95 +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.
-
-import "package:expect/expect.dart";
-
-// Short string.
-var s = "0123456789";
-// Long string.
-var l = "$s$s$s$s$s$s$s$s$s$s";
-// Very long string.
-var v = "$l$l$l$l$l$l$l$l$l$l";
-
-
-testSliceSuccess() {
-  // Test different ways to get the same slice from a string.
-  testSlice(String string, int start, int end) {
-    int length = string.length;
-    String expect = string.substring(start, end);
-    Expect.equals(expect, string.slice(start, end), "#${length}[$start:$end]");
-    if (start < length) {
-      // If start == length, there is no negative representation of the position.
-      Expect.equals(expect, string.slice(start - length, end),
-                    "#${length}[${start - length}:$end]");
-    }
-    if (end < length) {
-      Expect.equals(expect, string.slice(start, end - length),
-                    "#${length}[$start:${end - length}]");
-      Expect.equals(expect, string.slice(start - length, end - length),
-                    "#${length}[${start-length}:${end-length}]");
-    } else {
-      Expect.equals(expect, string.slice(start),
-                    "#${length}[$start]");
-      if (start < length) {
-        Expect.equals(expect, string.slice(start - length),
-                      "#${length}[${start-length}]");
-        if (start == 0) {
-          Expect.equals(string, string.slice(), "#$length[:]");
-        }
-      }
-    }
-  }
-
-  testSliceCombinations(String string) {
-    int length = string.length;
-    List<int> positions = [0, 1, string.length >> 1, length - 1, length];
-    for (int i = 0; i < positions.length; i++) {
-      for (int j = i; j < positions.length; j++) {
-        testSlice(string, positions[i], positions[j]);
-      }
-    }
-  }
-
-  testSliceCombinations(s);
-  testSliceCombinations(l);
-  testSliceCombinations(v);
-}
-
-testSliceError() {
-  function expectRangeError(void thunk()) {
-    Expect.throws(thunk, (e) => e is RangeError);
-  };
-  function expectArgumentError(void thunk()) {
-    Expect.throws(thunk, (e) => e is ArgumentError);
-  };
-  function badType(void thunk()) {
-    bool checkedMode = false;
-    assert(checkedMode = true);
-    Expect.throws(thunk,
-                  (e) => checkedMode ? e is TypeError : e is ArgumentError);
-  }
-
-  // Invalid start:
-  expectRangeError(() => s.slice(11));
-  expectRangeError(() => s.slice(-11));
-  // Invalid end:
-  expectRangeError(() => s.slice(0, 11));
-  expectRangeError(() => s.slice(0, -11));
-  // Non-int:
-  badType(() => s.slice(1.5));
-  badType(() => s.slice(0, 1.5));
-  badType(() => s.slice("1"));
-  badType(() => s.slice(0, "1"));
-  // Bad order:
-  expectArgumentError(() => s.slice(5, 4));
-  expectArgumentError(() => s.slice(-5, 4));
-  expectArgumentError(() => s.slice(5, -6));
-  expectArgumentError(() => s.slice(-5, -6));
-}
-
-
-main() {
-  testSliceSuccess();
-  testSliceError();
-}
diff --git a/tests/corelib/symbol_map_helper.dart b/tests/corelib/symbol_map_helper.dart
new file mode 100644
index 0000000..da9e7e5
--- /dev/null
+++ b/tests/corelib/symbol_map_helper.dart
@@ -0,0 +1,15 @@
+// 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.test.symbol_map_helper;
+
+// TODO(ahe): Update map literals to avoid this method.
+Map<Symbol, dynamic> symbolMapToStringMap(Map<String, dynamic> map) {
+  if (map == null) return null;
+  Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
+  map.forEach((name, value) {
+    result[new Symbol(name)] = value;
+  });
+  return result;
+}
diff --git a/tests/corelib/symbol_test.dart b/tests/corelib/symbol_test.dart
index b3604c4..a160244 100644
--- a/tests/corelib/symbol_test.dart
+++ b/tests/corelib/symbol_test.dart
@@ -83,4 +83,8 @@
   if (new Symbol('fisk').hashCode != x.hashCode) {
     throw "non-const Symbol's hashCode not equal to its const equivalent";
   }
+
+  if (new Symbol('') != const Symbol('')) {
+    throw 'empty Symbol not equals to itself';
+  }
 }
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 449a0b8..f953129 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -608,8 +608,6 @@
 
     testUnsupported('removeRange', () => getQueryAll().removeRange(0, 1));
 
-    testUnsupported('insertangeRange', () => getQueryAll().insertRange(0, 1));
-
     testUnsupported('clear', () => getQueryAll().clear());
 
     testUnsupported('removeLast', () => getQueryAll().removeLast());
diff --git a/tests/html/fileapi_test.dart b/tests/html/fileapi_test.dart
index 697f176..47f0695 100644
--- a/tests/html/fileapi_test.dart
+++ b/tests/html/fileapi_test.dart
@@ -44,8 +44,8 @@
       test('directoryDoesntExist', () {
         return fs.root.getDirectory(
             'directory2')
-              .catchError((e) {
-                expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+              .catchError((error) {
+                expect(error.code, equals(FileError.NOT_FOUND_ERR));
               }, test: (e) => e is FileError);
         });
 
@@ -66,8 +66,8 @@
       test('fileDoesntExist', () {
         return fs.root.getFile(
             'file2')
-          .catchError((e) {
-            expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+          .catchError((error) {
+            expect(error.code, equals(FileError.NOT_FOUND_ERR));
           }, test: (e) => e is FileError);
       });
 
@@ -99,7 +99,7 @@
           return fs.root.createDirectory(
               'directory3')
             .then((DirectoryEntry dir) {
-              return new Future.immediate(new FileAndDir(file, dir));
+              return new Future.value(new FileAndDir(file, dir));
             });
         });
   }
@@ -152,8 +152,8 @@
             expect(entry.name, 'movedFile');
             expect(entry.fullPath, '/directory3/movedFile');
             return fs.root.getFile('file4');
-          }).catchError((e) {
-            expect(e.error.code, equals(FileError.NOT_FOUND_ERR));
+          }).catchError((error) {
+            expect(error.code, equals(FileError.NOT_FOUND_ERR));
           }, test: (e) => e is FileError);
       });
 
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index 27b11a8..cac79de 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -110,7 +110,7 @@
     test('Web Database', () {
       // Skip if not supported.
       if (!SqlDatabase.supported) {
-        return new Future.immediate(null);
+        return new Future.value();
       }
 
       final tableName = 'test_table';
diff --git a/tests/html/xhr_test.dart b/tests/html/xhr_test.dart
index 6214581..0087b74 100644
--- a/tests/html/xhr_test.dart
+++ b/tests/html/xhr_test.dart
@@ -86,8 +86,8 @@
     test('XHR.request No file', () {
       HttpRequest.request('NonExistingFile').then(
         (_) { fail('Request should not have succeeded.'); },
-        onError: expectAsync1((e) {
-          var xhr = e.error.target;
+        onError: expectAsync1((error) {
+          var xhr = error.target;
           expect(xhr.readyState, equals(HttpRequest.DONE));
           validate404(xhr);
         }));
@@ -116,8 +116,8 @@
     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;
+        onError: expectAsync1((error) {
+          var xhr = error.target;
           expect(xhr.readyState, equals(HttpRequest.DONE));
           validate404(xhr);
         }));
@@ -137,8 +137,8 @@
     test('XHR.getString No file', () {
       HttpRequest.getString('NonExistingFile').then(
         (_) { fail('Succeeded for non-existing file.'); },
-        onError: expectAsync1((e) {
-          validate404(e.error.target);
+        onError: expectAsync1((error) {
+          validate404(error.target);
         }));
     });
 
diff --git a/tests/isolate/global_error_handler_stream2_test.dart b/tests/isolate/global_error_handler_stream2_test.dart
index ef079d0..f349589 100644
--- a/tests/isolate/global_error_handler_stream2_test.dart
+++ b/tests/isolate/global_error_handler_stream2_test.dart
@@ -21,9 +21,6 @@
 
 bool globalErrorHandler(IsolateUnhandledException e) {
   var source = e.source;
-  if (source is AsyncError) {
-    source = source.error;
-  }
   return source is RuntimeError && source.message == "ignore exception";
 }
 
diff --git a/tests/language/factory2_test.dart b/tests/language/factory2_test.dart
index 80c0cc0..882ec7b 100644
--- a/tests/language/factory2_test.dart
+++ b/tests/language/factory2_test.dart
@@ -2,7 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-abstract class Link<T> extends Iterable<T> {
+import "dart:collection";
+
+abstract class Link<T> extends IterableBase<T> {
   // does not match constructor for LinkFactory
   factory Link(T head, [Link<T> tail]) = LinkFactory<T>; /// static type warning
   Link<T> prepend(T element);
diff --git a/tests/language/factory3_test.dart b/tests/language/factory3_test.dart
index 403633b..c6c61ab 100644
--- a/tests/language/factory3_test.dart
+++ b/tests/language/factory3_test.dart
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 // VMOptions=--enable_checked_mode
 
-abstract class Link<T> extends Iterable<T> {
+import "dart:collection";
+
+abstract class Link<T> extends IterableBase<T> {
   factory Link(T head, [Link<T> tail]) = LinkEntry<T>;
   Link<T> prepend(T element);
 }
diff --git a/tests/language/full_stacktrace1_test.dart b/tests/language/full_stacktrace1_test.dart
index 4bef00e..945ca70 100644
--- a/tests/language/full_stacktrace1_test.dart
+++ b/tests/language/full_stacktrace1_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 
 void func1() {
-  throw new Exception("Test peanut gallery request for Full stacktrace");
+  throw new Exception("Test full stacktrace");
 }
 void func2() {
   func1();
@@ -14,34 +14,14 @@
   try {
     func2();
   } on Object catch(e, s) {
-    print(e);
-
-    var full_trace = s.fullStackTrace;
-    Expect.isTrue(full_trace.contains("func1"));
-    Expect.isTrue(full_trace.contains("func2"));
-    Expect.isTrue(full_trace.contains("func3"));
-    Expect.isTrue(full_trace.contains("func4"));
-    Expect.isTrue(full_trace.contains("func5"));
-    Expect.isTrue(full_trace.contains("func6"));
-    Expect.isTrue(full_trace.contains("main"));
-
-    var trace = s.stackTrace;
-    Expect.isTrue(trace.contains("func1"));
-    Expect.isTrue(trace.contains("func2"));
-    Expect.isTrue(trace.contains("func3"));
-
-    Expect.isFalse(trace.contains("func4"));
-    Expect.isFalse(trace.contains("func5"));
-    Expect.isFalse(trace.contains("func6"));
-    Expect.isFalse(trace.contains("main"));
-
-    print(s);
-
-    print("Full stack trace");
-    print(full_trace);
-
-    print("Stack trace");
-    print(trace);
+    var fullTrace = s.toString();
+    Expect.isTrue(fullTrace.contains("func1"));
+    Expect.isTrue(fullTrace.contains("func2"));
+    Expect.isTrue(fullTrace.contains("func3"));
+    Expect.isTrue(fullTrace.contains("func4"));
+    Expect.isTrue(fullTrace.contains("func5"));
+    Expect.isTrue(fullTrace.contains("func6"));
+    Expect.isTrue(fullTrace.contains("main"));
   }
 }
 int func4() {
diff --git a/tests/language/full_stacktrace2_test.dart b/tests/language/full_stacktrace2_test.dart
index 7f45706..a98f5a6 100644
--- a/tests/language/full_stacktrace2_test.dart
+++ b/tests/language/full_stacktrace2_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 
 void func1() {
-  throw new Exception("Test peanut gallery request for Full stacktrace");
+  throw new Exception("Test full stacktrace");
 }
 void func2() {
   func1();
@@ -14,36 +14,15 @@
   try {
     func2();
   } on Object catch(e, s) {
-    print(e);
-
-    var full_trace = s.fullStackTrace;
-    Expect.isTrue(full_trace.contains("func1"));
-    Expect.isTrue(full_trace.contains("func2"));
-    Expect.isTrue(full_trace.contains("func3"));
-    Expect.isTrue(full_trace.contains("func4"));
-    Expect.isTrue(full_trace.contains("func5"));
-    Expect.isTrue(full_trace.contains("func6"));
-    Expect.isTrue(full_trace.contains("func7"));
-    Expect.isTrue(full_trace.contains("main"));
-
-    var trace = s.stackTrace;
-    Expect.isTrue(trace.contains("func1"));
-    Expect.isTrue(trace.contains("func2"));
-    Expect.isTrue(trace.contains("func3"));
-
-    Expect.isFalse(trace.contains("func4"));
-    Expect.isFalse(trace.contains("func5"));
-    Expect.isFalse(trace.contains("func6"));
-    Expect.isFalse(trace.contains("func7"));
-    Expect.isFalse(trace.contains("main"));
-
-    print(s);
-
-    print("Full stack trace");
-    print(full_trace);
-
-    print("Stack trace");
-    print(trace);
+    var fullTrace = s.toString();
+    Expect.isTrue(fullTrace.contains("func1"));
+    Expect.isTrue(fullTrace.contains("func2"));
+    Expect.isTrue(fullTrace.contains("func3"));
+    Expect.isTrue(fullTrace.contains("func4"));
+    Expect.isTrue(fullTrace.contains("func5"));
+    Expect.isTrue(fullTrace.contains("func6"));
+    Expect.isTrue(fullTrace.contains("func7"));
+    Expect.isTrue(fullTrace.contains("main"));
 
     throw;  // This is a rethrow.
   }
@@ -56,36 +35,15 @@
   try {
     func4();
   } on Object catch(e, s) {
-
-    var full_trace = s.fullStackTrace;
-    print(full_trace);
-    Expect.isTrue(full_trace.contains("func1"));
-    Expect.isTrue(full_trace.contains("func2"));
-    Expect.isTrue(full_trace.contains("func3"));
-    Expect.isTrue(full_trace.contains("func4"));
-    Expect.isTrue(full_trace.contains("func5"));
-    Expect.isTrue(full_trace.contains("func6"));
-    Expect.isTrue(full_trace.contains("func7"));
-    Expect.isTrue(full_trace.contains("main"));
-
-    var trace = s.stackTrace;
-    Expect.isTrue(trace.contains("func1"));
-    Expect.isTrue(trace.contains("func2"));
-    Expect.isTrue(trace.contains("func3"));
-    Expect.isTrue(trace.contains("func4"));
-    Expect.isTrue(trace.contains("func5"));
-
-    Expect.isFalse(trace.contains("func6"));
-    Expect.isFalse(trace.contains("func7"));
-    Expect.isFalse(trace.contains("main"));
-
-    print(s);
-
-    print("Full stack trace");
-    print(full_trace);
-
-    print("Stack trace");
-    print(trace);
+    var fullTrace = s.toString();
+    Expect.isTrue(fullTrace.contains("func1"));
+    Expect.isTrue(fullTrace.contains("func2"));
+    Expect.isTrue(fullTrace.contains("func3"));
+    Expect.isTrue(fullTrace.contains("func4"));
+    Expect.isTrue(fullTrace.contains("func5"));
+    Expect.isTrue(fullTrace.contains("func6"));
+    Expect.isTrue(fullTrace.contains("func7"));
+    Expect.isTrue(fullTrace.contains("main"));
   }
   return 1;
 }
diff --git a/tests/language/full_stacktrace3_test.dart b/tests/language/full_stacktrace3_test.dart
index 4bacd04..553f86a 100644
--- a/tests/language/full_stacktrace3_test.dart
+++ b/tests/language/full_stacktrace3_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 
 void func1() {
-  throw new Exception("Test peanut gallery request for Full stacktrace");
+  throw new Exception("Test full stacktrace");
 }
 void func2() {
   func1();
@@ -14,35 +14,15 @@
   try {
     func2();
   } on Object catch(e, s) {
-    print(e);
-    var full_trace = s.fullStackTrace;
-    Expect.isTrue(full_trace.contains("func1"));
-    Expect.isTrue(full_trace.contains("func2"));
-    Expect.isTrue(full_trace.contains("func3"));
-    Expect.isTrue(full_trace.contains("func4"));
-    Expect.isTrue(full_trace.contains("func5"));
-    Expect.isTrue(full_trace.contains("func6"));
-    Expect.isTrue(full_trace.contains("func7"));
-    Expect.isTrue(full_trace.contains("main"));
-
-    var trace = s.stackTrace;
-    Expect.isTrue(trace.contains("func1"));
-    Expect.isTrue(trace.contains("func2"));
-    Expect.isTrue(trace.contains("func3"));
-
-    Expect.isFalse(trace.contains("func4"));
-    Expect.isFalse(trace.contains("func5"));
-    Expect.isFalse(trace.contains("func6"));
-    Expect.isFalse(trace.contains("func7"));
-    Expect.isFalse(trace.contains("main"));
-
-    print(s);
-
-    print("Full stack trace");
-    print(full_trace);
-
-    print("Stack trace");
-    print(trace);
+    var fullTrace = s.toString();
+    Expect.isTrue(fullTrace.contains("func1"));
+    Expect.isTrue(fullTrace.contains("func2"));
+    Expect.isTrue(fullTrace.contains("func3"));
+    Expect.isTrue(fullTrace.contains("func4"));
+    Expect.isTrue(fullTrace.contains("func5"));
+    Expect.isTrue(fullTrace.contains("func6"));
+    Expect.isTrue(fullTrace.contains("func7"));
+    Expect.isTrue(fullTrace.contains("main"));
     throw new Exception("This is not a rethrow");
   }
 }
@@ -54,35 +34,15 @@
   try {
     func4();
   } on Object catch(e, s) {
-    var full_trace = s.fullStackTrace;
-    Expect.isFalse(full_trace.contains("func1"));
-    Expect.isFalse(full_trace.contains("func2"));
-    Expect.isTrue(full_trace.contains("func3"));
-    Expect.isTrue(full_trace.contains("func4"));
-    Expect.isTrue(full_trace.contains("func5"));
-    Expect.isTrue(full_trace.contains("func6"));
-    Expect.isTrue(full_trace.contains("func7"));
-    Expect.isTrue(full_trace.contains("main"));
-
-    var trace = s.stackTrace;
-    Expect.isFalse(trace.contains("func1"));
-    Expect.isFalse(trace.contains("func2"));
-
-    Expect.isTrue(trace.contains("func3"));
-    Expect.isTrue(trace.contains("func4"));
-    Expect.isTrue(trace.contains("func5"));
-
-    Expect.isFalse(trace.contains("func6"));
-    Expect.isFalse(trace.contains("func7"));
-    Expect.isFalse(trace.contains("main"));
-
-    print(s);
-
-    print("Full stack trace");
-    print(full_trace);
-
-    print("Stack trace");
-    print(trace);
+    var fullTrace = s.toString();
+    Expect.isFalse(fullTrace.contains("func1"));
+    Expect.isFalse(fullTrace.contains("func2"));
+    Expect.isTrue(fullTrace.contains("func3"));
+    Expect.isTrue(fullTrace.contains("func4"));
+    Expect.isTrue(fullTrace.contains("func5"));
+    Expect.isTrue(fullTrace.contains("func6"));
+    Expect.isTrue(fullTrace.contains("func7"));
+    Expect.isTrue(fullTrace.contains("main"));
   }
   return 1;
 }
diff --git a/tests/language/invocation_mirror_invoke_on_test.dart b/tests/language/invocation_mirror_invoke_on_test.dart
index 030fee6..4f84915 100644
--- a/tests/language/invocation_mirror_invoke_on_test.dart
+++ b/tests/language/invocation_mirror_invoke_on_test.dart
@@ -4,7 +4,7 @@
 
 import "package:expect/expect.dart";
 
-// Testing InvocationMirror.invokeOn method; test of issue 7227.
+// Testing Invocation.invokeOn method; test of issue 7227.
 
 var reachedSetX = 0;
 var reachedGetX = 0;
diff --git a/tests/language/invocation_mirror_test.dart b/tests/language/invocation_mirror_test.dart
index 5c5a91b..d1bb2aa 100644
--- a/tests/language/invocation_mirror_test.dart
+++ b/tests/language/invocation_mirror_test.dart
@@ -4,14 +4,14 @@
 
 import "package:expect/expect.dart";
 
-// InvocationMirror and noSuchMethod testing.
+// Invocation and noSuchMethod testing.
 
 /** Class with noSuchMethod that returns the mirror */
 class N {
   // Storage for the last argument to noSuchMethod.
   // Needed for setters, which don't evaluate to the return value.
   var last;
-  noSuchMethod(InvocationMirror m) => last = m;
+  noSuchMethod(Invocation m) => last = m;
 
   flif(int x) { Expect.fail("never get here"); }
   flaf([int x]) { Expect.fail("never get here"); }
@@ -28,14 +28,14 @@
 }
 
 /**
- * Checks the data of an InvocationMirror.
+ * Checks the data of an Invocation.
  *
  * Call without optionals for getters, with only positional for setters,
  * and with both optionals for everything else.
  */
-testInvocationMirror(InvocationMirror im, String name,
+testInvocationMirror(Invocation im, String name,
                      [List positional, Map named]) {
-  Expect.isTrue(im is InvocationMirror, "is InvocationMirror");
+  Expect.isTrue(im is Invocation, "is Invocation");
   Expect.equals(name, im.memberName, "name");
   if (named == null) {
     Expect.isTrue(im.isAccessor, "$name:isAccessor");
@@ -152,7 +152,7 @@
 }
 
 class M extends N {
-  noSuchMethod(InvocationMirror m) { throw "never get here"; }
+  noSuchMethod(Invocation m) { throw "never get here"; }
 
   testSuperCalls() {
     // Missing property/method access.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index ff16206..360ffc3 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -26,10 +26,13 @@
 class_literal_test/27: Fail # Class literals are expression now; delete this test.
 class_literal_test/28: Fail # Class literals are expression now; delete this test.
 class_literal_test/29: Fail # Class literals are expression now; delete this test.
-full_stacktrace1_test: Skip # Stack trace interface is not implemented yet.
-full_stacktrace2_test: Skip # Stack trace interface is not implemented yet.
-full_stacktrace3_test: Skip # Stack trace interface is not implemented yet.
-stacktrace_test: Skip # Stack trace interface is not implemented yet.
+
+# Fails due to inlining. Not all expected frames are in the trace.
+full_stacktrace1_test: Pass, Fail  # issue 9895
+full_stacktrace2_test: Pass, Fail  # issue 9895
+full_stacktrace3_test: Pass, Fail  # issue 9895
+# Stack traces may or may not end in a newline depending on the JS enging.
+stacktrace_test: Pass, Fail # Assumes stack trace string ends in newline.
 
 # VM specific tests that should not be run by dart2js.
 *vm_test: Skip
diff --git a/tests/language/list_test.dart b/tests/language/list_test.dart
index a0a12ec..d3afdf8 100644
--- a/tests/language/list_test.dart
+++ b/tests/language/list_test.dart
@@ -54,17 +54,17 @@
 
     Expect.throws(() {
       List a = new List(4);
-      a.setRange(1, 1, a, null);
+      a.setRange(1, 2, a, null);
     });
 
     Expect.throws(() {
       List a = new List(4);
-      a.setRange(1, 1, const [1, 2, 3, 4], null);
+      a.setRange(1, 2, const [1, 2, 3, 4], null);
     });
 
     Expect.throws(() {
       List a = new List(4);
-      a.setRange(10, 1, a, 1);
+      a.setRange(10, 11, a, 1);
     }, (e) => e is RangeError);
 
     a = new List(4);
diff --git a/tests/language/no_such_method2_test.dart b/tests/language/no_such_method2_test.dart
index bd0b6a8..5b1e9fa 100644
--- a/tests/language/no_such_method2_test.dart
+++ b/tests/language/no_such_method2_test.dart
@@ -7,7 +7,7 @@
 // Regression test for https://code.google.com/p/dart/issues/detail?id=7697.
 // dart2js used to optimize [noSuchMethod] based on the user-provided
 // argument, and forget that the runtime might call it with its own
-// [InvocationMirror] implementation.
+// [Invocation] implementation.
 
 class Hey {
   foo() => noSuchMethod(new FakeInvocationMirror());
@@ -21,7 +21,7 @@
   noSuchMethod(x) => x.isGetter;
 }
 
-class FakeInvocationMirror implements InvocationMirror {
+class FakeInvocationMirror implements Invocation {
   final bool isGetter = false;
 }
 
diff --git a/tests/language/no_such_method_test.dart b/tests/language/no_such_method_test.dart
index 5e154d2..39f1417 100644
--- a/tests/language/no_such_method_test.dart
+++ b/tests/language/no_such_method_test.dart
@@ -18,7 +18,7 @@
     return (10 * a) + b;
   }
 
-  noSuchMethod(InvocationMirror im) {
+  noSuchMethod(Invocation im) {
     Expect.equals("moo", getName(im));
     Expect.equals(0, im.positionalArguments.length);
     Expect.equals(1, im.namedArguments.length);
diff --git a/tests/language/overridden_no_such_method.dart b/tests/language/overridden_no_such_method.dart
index 127a53d..97433e3 100644
--- a/tests/language/overridden_no_such_method.dart
+++ b/tests/language/overridden_no_such_method.dart
@@ -13,7 +13,7 @@
 
   OverriddenNoSuchMethod() {}
 
-  noSuchMethod(InvocationMirror mirror) {
+  noSuchMethod(Invocation mirror) {
     Expect.equals("foo", getName(mirror));
     // 'foo' was called with two parameters (not counting receiver).
     List args = mirror.positionalArguments;
diff --git a/tests/language/stack_trace_test.dart b/tests/language/stack_trace_test.dart
index 665313f..2f584a6 100644
--- a/tests/language/stack_trace_test.dart
+++ b/tests/language/stack_trace_test.dart
@@ -18,7 +18,7 @@
     } on MyException catch (exception, stacktrace) {
       i = 50;
       print(exception.message_);
-      Expect.equals((stacktrace != null), true);
+      Expect.isNotNull(stacktrace);
       print(stacktrace);
     }
     try {
@@ -28,7 +28,7 @@
     } on MyException catch (exception, stacktrace) {
       i = 50;
       print(exception.message_);
-      Expect.equals((stacktrace != null), true);
+      Expect.isNotNull(stacktrace);
       print(stacktrace);
     }
     try {
@@ -38,7 +38,7 @@
     } on MyException catch (exception, stacktrace) {
       i = 50;
       print(exception.message_);
-      Expect.equals((stacktrace != null), true);
+      Expect.isNotNull(stacktrace);
       print(stacktrace);
     } finally {
       i = i + 800;
diff --git a/tests/language/store_to_load_forwarding_phis_vm_test.dart b/tests/language/store_to_load_forwarding_phis_vm_test.dart
index 13654a6..72ee9b3 100644
--- a/tests/language/store_to_load_forwarding_phis_vm_test.dart
+++ b/tests/language/store_to_load_forwarding_phis_vm_test.dart
@@ -22,7 +22,7 @@
 
 foo(obj) {
   var a = obj.foo;
-  return new Future.immediate(null).then((val) { });
+  return new Future.value().then((val) { });
 }
 
 main() {
diff --git a/tests/language/super_call4_test.dart b/tests/language/super_call4_test.dart
index 4d68a19..079b8d2 100644
--- a/tests/language/super_call4_test.dart
+++ b/tests/language/super_call4_test.dart
@@ -10,7 +10,7 @@
 class C {
   E e = new E();
 
-  bool noSuchMethod(InvocationMirror im) {
+  bool noSuchMethod(Invocation im) {
     if (im.memberName == 'foo') {
       return im.positionalArguments.isEmpty &&
              im.namedArguments.isEmpty &&
@@ -36,7 +36,7 @@
 }
 
 class D extends C {
-  bool noSuchMethod(InvocationMirror im) {
+  bool noSuchMethod(Invocation im) {
     return false;
   }
   test1() {
diff --git a/tests/language/super_getter_setter_test.dart b/tests/language/super_getter_setter_test.dart
index ea923e8..ac50bbb 100644
--- a/tests/language/super_getter_setter_test.dart
+++ b/tests/language/super_getter_setter_test.dart
@@ -30,7 +30,7 @@
   operator[](index) => indexField[index];
   operator[]=(index, value) { indexField[index] = value; }
 
-  noSuchMethod(InvocationMirror im) {
+  noSuchMethod(Invocation im) {
     if (im.memberName.startsWith('missingSetter')) {
       Expect.isTrue(im.isSetter);
       missingSetterField = im.positionalArguments[0];
diff --git a/tests/language/super_operator_index5_test.dart b/tests/language/super_operator_index5_test.dart
index 6842709..1342852 100644
--- a/tests/language/super_operator_index5_test.dart
+++ b/tests/language/super_operator_index5_test.dart
@@ -10,7 +10,7 @@
   var indexField = new List(2);
   operator[](index) => indexField[index];
 
-  noSuchMethod(InvocationMirror im) {
+  noSuchMethod(Invocation im) {
     if (im.memberName == '[]=') {
       Expect.equals(2, im.positionalArguments.length);
       indexField[im.positionalArguments[0]] = im.positionalArguments[1];
diff --git a/tests/language/super_operator_index6_test.dart b/tests/language/super_operator_index6_test.dart
index 9fb942f..57e3951 100644
--- a/tests/language/super_operator_index6_test.dart
+++ b/tests/language/super_operator_index6_test.dart
@@ -10,7 +10,7 @@
   var indexField = new List(2);
   operator[]=(index, value) { indexField[index] = value; }
 
-  noSuchMethod(InvocationMirror im) {
+  noSuchMethod(Invocation im) {
     if (im.memberName == '[]') {
       Expect.equals(1, im.positionalArguments.length);
       return indexField[im.positionalArguments[0]];
diff --git a/tests/language/super_operator_index7_test.dart b/tests/language/super_operator_index7_test.dart
index b77b06f..fb0b78a 100644
--- a/tests/language/super_operator_index7_test.dart
+++ b/tests/language/super_operator_index7_test.dart
@@ -9,7 +9,7 @@
 class A {
   var indexField = new List(2);
 
-  noSuchMethod(InvocationMirror im) {
+  noSuchMethod(Invocation im) {
     if (im.memberName == '[]=') {
       Expect.equals(2, im.positionalArguments.length);
       indexField[im.positionalArguments[0]] = im.positionalArguments[1];
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index bfa469b..7309143 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -1,3 +1,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.
+
+[ $compiler == dartc ]
+lib/core/core: Fail
diff --git a/tests/lib/async/event_helper.dart b/tests/lib/async/event_helper.dart
index db5189c..eeafcc6 100644
--- a/tests/lib/async/event_helper.dart
+++ b/tests/lib/async/event_helper.dart
@@ -29,7 +29,7 @@
 }
 
 class ErrorEvent implements Event {
-  final AsyncError error;
+  final error;
 
   ErrorEvent(this.error);
 
@@ -40,10 +40,10 @@
   bool operator==(Object other) {
     if (other is! ErrorEvent) return false;
     ErrorEvent otherEvent = other;
-    return error.error == other.error.error;
+    return error == other.error;
   }
 
-  String toString() => "ErrorEvent: ${error.error}";
+  String toString() => "ErrorEvent: ${error}";
 }
 
 class DoneEvent implements Event {
@@ -70,14 +70,14 @@
 
   /** Capture events from a stream into a new [Events] object. */
   factory Events.capture(Stream stream,
-                         { bool unsubscribeOnError: false }) = CaptureEvents;
+                         { bool cancelOnError: false }) = CaptureEvents;
 
   // EventSink interface.
   void add(var value) {
     events.add(new DataEvent(value));
   }
 
-  void addError(AsyncError error) {
+  void addError(error) {
     events.add(new ErrorEvent(error));
   }
 
@@ -86,7 +86,7 @@
   }
 
   // Error helper for creating errors manually..
-  void error(var value) { addError(new AsyncError(value, null)); }
+  void error(var value) { addError(value); }
 
   /** Replay the captured events on a sink. */
   void replay(EventSink sink) {
@@ -134,21 +134,21 @@
 class CaptureEvents extends Events {
   StreamSubscription subscription;
   Completer onDoneSignal;
-  bool unsubscribeOnError = false;
+  bool cancelOnError = false;
 
   CaptureEvents(Stream stream,
-                { bool unsubscribeOnError: false })
+                { bool cancelOnError: false })
       : onDoneSignal = new Completer() {
-    this.unsubscribeOnError = unsubscribeOnError;
+    this.cancelOnError = cancelOnError;
     subscription = stream.listen(add,
                                  onError: addError,
                                  onDone: close,
-                                 unsubscribeOnError: unsubscribeOnError);
+                                 cancelOnError: cancelOnError);
   }
 
-  void addError(AsyncError error) {
+  void addError(error) {
     super.addError(error);
-    if (unsubscribeOnError) onDoneSignal.complete(null);
+    if (cancelOnError) onDoneSignal.complete(null);
   }
 
   void close() {
diff --git a/tests/lib/async/future_constructor_test.dart b/tests/lib/async/future_constructor_test.dart
new file mode 100644
index 0000000..64d946c
--- /dev/null
+++ b/tests/lib/async/future_constructor_test.dart
@@ -0,0 +1,38 @@
+// 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 future_test;
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+
+main() {
+  compare(func) {
+    // Compare the results of the following two futures.
+    Future f1 = new Future(func);
+    Future f2 = new Future.value().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, e2);
+                      });
+            });
+  }
+  Future val = new Future.value(42);
+  Future err1 = new Future.error("Error")..catchError((_){});
+  compare(() => 42);
+  compare(() => val);
+  compare(() { throw "Flif"; });
+  compare(() => err1);
+  bool hasExecuted = false;
+  compare(() {
+    hasExecuted = true;
+    return 499;
+  });
+  Expect.isFalse(hasExecuted);
+}
+
diff --git a/tests/lib/async/future_delayed_error_test.dart b/tests/lib/async/future_delayed_error_test.dart
index 8d444c2..be16cf0 100644
--- a/tests/lib/async/future_delayed_error_test.dart
+++ b/tests/lib/async/future_delayed_error_test.dart
@@ -12,10 +12,10 @@
   // An open ReceivePort keeps the VM running. If the error-handler below is not
   // executed then the test will fail with a timeout.
   var port = new ReceivePort();
-  var future = new Future.immediateError("error");
-  future.catchError((e) {
+  var future = new Future.error("error");
+  future.catchError((error) {
     port.close();
-    Expect.equals(e.error, "error");
+    Expect.equals(error, "error");
   });
 }
 
@@ -27,9 +27,9 @@
 
 testDelayedError() {
   var port = new ReceivePort();
-  completedFuture.catchError((e) {
+  completedFuture.catchError((error) {
     port.close();
-    Expect.equals(e.error, "foobar");
+    Expect.equals(error, "foobar");
   });
 }
 
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 6feffe1..078ee4a 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -10,8 +10,8 @@
 
 const Duration MS = const Duration(milliseconds: 1);
 
-testImmediate() {
-  final future = new Future<String>.immediate("42");
+testValue() {
+  final future = new Future<String>.value("42");
   var port = new ReceivePort();
   future.then((x) {
     Expect.equals("42", x);
@@ -19,29 +19,37 @@
   });
 }
 
-testOf() {
+testSync() {
   compare(func) {
     // Compare the results of the following two futures.
-    Future f1 = new Future.of(func);
-    Future f2 = new Future.immediate(null).then((_) => func());
+    Future f1 = new Future.sync(func);
+    Future f2 = new Future.value().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);
+                         Expect.equals(e1, e2);
                       });
             });
   }
-  Future val = new Future.immediate(42);
-  Future err1 = new Future.immediateError("Error")..catchError((_){});
-  Future err2 = new Future.immediateError(new AsyncError("AsyncError"))..catchError((_){});
+  Future val = new Future.value(42);
+  Future err1 = new Future.error("Error")..catchError((_){});
+  try {
+    throw new List(0);
+  } catch (e, st) {
+    Future err2 = new Future.error(e, st)..catchError((_){});
+  }
   compare(() => 42);
   compare(() => val);
   compare(() { throw "Flif"; });
-  compare(() { throw new AsyncError("AsyncFlif"); });
   compare(() => err1);
-  compare(() => err2);
+  bool hasExecuted = false;
+  compare(() {
+    hasExecuted = true;
+    return 499;
+  });
+  Expect.isTrue(hasExecuted);
 }
 
 testNeverComplete() {
@@ -127,8 +135,8 @@
   var port = new ReceivePort();
   future
       .then((v) { throw "Value not expected"; })
-      .catchError((e) {
-        Expect.equals(e.error, ex);
+      .catchError((error) {
+        Expect.equals(error, ex);
         port.close();
       }, test: (e) => e == ex);
   completer.completeError(ex);
@@ -140,7 +148,7 @@
   final ex = new Exception();
 
   var ex2;
-  var done = future.catchError((e) { ex2 = e.error; });
+  var done = future.catchError((error) { ex2 = error; });
 
   Expect.isFalse(completer.isCompleted);
   completer.completeError(ex);
@@ -240,7 +248,7 @@
 testFutureAsStreamCompleteImmediate() {
   bool gotValue = false;
   var port = new ReceivePort();
-  new Future.immediate("value").asStream().listen(
+  new Future.value("value").asStream().listen(
       (data) {
         Expect.isFalse(gotValue);
         gotValue = true;
@@ -263,7 +271,7 @@
       onError: (error) {
         Expect.isFalse(gotError);
         gotError = true;
-        Expect.equals("error", error.error);
+        Expect.equals("error", error);
       },
       onDone: () {
         Expect.isTrue(gotError);
@@ -316,8 +324,8 @@
   var completer = new Completer();
   Future future = completer.future;
   Future later = future.whenComplete(countDown);
-  later.catchError((AsyncError e) {
-    Expect.equals("error", e.error);
+  later.catchError((error) {
+    Expect.equals("error", error);
     countDown();
   });
   completer.completeError("error");
@@ -335,8 +343,8 @@
     countDown();
     throw "new error";
   });
-  later.catchError((AsyncError e) {
-    Expect.equals("new error", e.error);
+  later.catchError((error) {
+    Expect.equals("new error", error);
     countDown();
   });
   completer.complete(42);
@@ -354,8 +362,8 @@
     countDown();
     throw "new error";
   });
-  later.catchError((AsyncError e) {
-    Expect.equals("new error", e.error);
+  later.catchError((error) {
+    Expect.equals("new error", error);
     countDown();
   });
   completer.completeError("error");
@@ -422,8 +430,8 @@
     return completer2.future;
   }).then((v) {
     Expect.fail("should fail async");
-  }, onError: (AsyncError e) {
-    Expect.equals("Fail", e.error);
+  }, onError: (error) {
+    Expect.equals("Fail", error);
     countDown(1);
   });
 
@@ -448,8 +456,8 @@
     return completer2.future;
   }).then((v) {
     Expect.fail("should fail async");
-  }, onError: (AsyncError e) {
-    Expect.equals("Error", e.error);
+  }, onError: (error) {
+    Expect.equals("Error", error);
     countDown(1);
   });
 
@@ -474,8 +482,8 @@
     return completer2.future;
   }).then((v) {
     Expect.fail("should fail async");
-  }, onError: (AsyncError e) {
-    Expect.equals("Fail", e.error);
+  }, onError: (error) {
+    Expect.equals("Fail", error);
     countDown(1);
   });
 
@@ -485,12 +493,12 @@
 testFutureThenThrowsAsync() {
   final completer = new Completer<int>();
   final future = completer.future;
-  AsyncError error = new AsyncError(42, "st");
+  int error = 42;
 
   var port = new ReceivePort();
   future.then((v) {
     throw error;
-  }).catchError((AsyncError e) {
+  }).catchError((e) {
     Expect.identical(error, e);
     port.close();
   });
@@ -500,12 +508,12 @@
 testFutureCatchThrowsAsync() {
   final completer = new Completer<int>();
   final future = completer.future;
-  AsyncError error = new AsyncError(42, "st");
+  int error = 42;
 
   var port = new ReceivePort();
-  future.catchError((AsyncError e) {
+  future.catchError((e) {
     throw error;
-  }).catchError((AsyncError e) {
+  }).catchError((e) {
     Expect.identical(error, e);
     port.close();
   });
@@ -515,13 +523,13 @@
 testFutureCatchRethrowsAsync() {
   final completer = new Completer<int>();
   final future = completer.future;
-  AsyncError error;
+  var error;
 
   var port = new ReceivePort();
-  future.catchError((AsyncError e) {
+  future.catchError((e) {
     error = e;
     throw e;
-  }).catchError((AsyncError e) {
+  }).catchError((e) {
     Expect.identical(error, e);
     port.close();
   });
@@ -531,25 +539,25 @@
 testFutureWhenThrowsAsync() {
   final completer = new Completer<int>();
   final future = completer.future;
-  AsyncError error = new AsyncError(42, "st");
+  var error = 42;
 
   var port = new ReceivePort();
   future.whenComplete(() {
     throw error;
-  }).catchError((AsyncError e) {
+  }).catchError((e) {
     Expect.identical(error, e);
     port.close();
   });
   completer.complete(0);
 }
 
-testCompleteWithAsyncError() {
+testCompleteWithError() {
   final completer = new Completer<int>();
   final future = completer.future;
-  AsyncError error = new AsyncError(42, "st");
+  var error = 42;
 
   var port = new ReceivePort();
-  future.catchError((AsyncError e) {
+  future.catchError((e) {
     Expect.identical(error, e);
     port.close();
   });
@@ -562,7 +570,7 @@
   final future = completer.future;
   var port = new ReceivePort();
 
-  future.then((v) => new Future.immediate(v * 2))
+  future.then((v) => new Future.value(v * 2))
         .then((v) {
           Expect.equals(42, v);
           port.close();
@@ -598,24 +606,24 @@
   final future = completer.future;
   var port = new ReceivePort();
 
-  future.then((v) => new Future.immediateError("Fehler"))
-        .then((v) { Expect.fail("unreachable!"); }, onError: (e) {
-          Expect.equals("Fehler", e.error);
+  future.then((v) => new Future.error("Fehler"))
+        .then((v) { Expect.fail("unreachable!"); }, onError: (error) {
+          Expect.equals("Fehler", error);
           port.close();
         });
   completer.complete(21);
 }
 
 main() {
-  testImmediate();
-  testOf();
+  testValue();
+  testSync();
   testNeverComplete();
 
   testComplete();
   testCompleteWithSuccessHandlerBeforeComplete();
   testCompleteWithSuccessHandlerAfterComplete();
   testCompleteManySuccessHandlers();
-  testCompleteWithAsyncError();
+  testCompleteWithError();
 
   testException();
   testExceptionHandler();
diff --git a/tests/lib/async/futures_test.dart b/tests/lib/async/futures_test.dart
index 7ae1d7e..446d93b 100644
--- a/tests/lib/async/futures_test.dart
+++ b/tests/lib/async/futures_test.dart
@@ -53,8 +53,8 @@
 
   return Future.wait(futures).then((_) {
     throw 'incorrect error';
-  }).catchError((e) {
-    Expect.equals('correct error', e.error);
+  }).catchError((error) {
+    Expect.equals('correct error', error);
   });
 }
 
@@ -69,8 +69,8 @@
 
   return Future.wait(futures).then((_) {
     throw 'incorrect error 2';
-  }).catchError((e) {
-    Expect.equals('correct error', e.error);
+  }).catchError((error) {
+    Expect.equals('correct error', error);
   });
 }
 
@@ -84,7 +84,7 @@
   var seen = <int>[];
   return Future.forEach([1, 2, 3, 4, 5], (n) {
     seen.add(n);
-    return new Future.immediate(null);
+    return new Future.value();
   }).then((_) => Expect.listEquals([1, 2, 3, 4, 5], seen));
 }
 
@@ -93,11 +93,11 @@
   return Future.forEach([1, 2, 3, 4, 5], (n) {
     if (n == 4) throw 'correct exception';
     seen.add(n);
-    return new Future.immediate(null);
+    return new Future.value();
   }).then((_) {
     throw 'incorrect exception';
-  }).catchError((e) {
-    Expect.equals('correct exception', e.error);
+  }).catchError((error) {
+    Expect.equals('correct exception', error);
   });
 }
 
diff --git a/tests/lib/async/slow_consumer2_test.dart b/tests/lib/async/slow_consumer2_test.dart
index d4865c4..2108870 100644
--- a/tests/lib/async/slow_consumer2_test.dart
+++ b/tests/lib/async/slow_consumer2_test.dart
@@ -58,7 +58,7 @@
   }
 
   Future close() {
-    return new Future.immediate(finalCount);
+    return new Future.value(finalCount);
   }
 }
 
@@ -70,7 +70,9 @@
   StreamController controller;
 
   DataProvider(int this.bytesPerSecond, int this.targetCount, this.chunkSize) {
-    controller = new StreamController(onPauseStateChange: onPauseStateChange);
+    controller = new StreamController(
+      onPause: onPauseStateChange,
+      onResume: onPauseStateChange);
     Timer.run(send);
   }
 
diff --git a/tests/lib/async/slow_consumer3_test.dart b/tests/lib/async/slow_consumer3_test.dart
index 18842c0..5bb3f99 100644
--- a/tests/lib/async/slow_consumer3_test.dart
+++ b/tests/lib/async/slow_consumer3_test.dart
@@ -58,7 +58,7 @@
   }
 
   Future close() {
-    return new Future.immediate(finalCount);
+    return new Future.value(finalCount);
   }
 }
 
diff --git a/tests/lib/async/slow_consumer_test.dart b/tests/lib/async/slow_consumer_test.dart
index c07f8ac..a20ad6d 100644
--- a/tests/lib/async/slow_consumer_test.dart
+++ b/tests/lib/async/slow_consumer_test.dart
@@ -15,7 +15,7 @@
 const int GB = KB * KB * KB;
 
 class SlowConsumer extends StreamConsumer {
-  var current = new Future.immediate(0);
+  var current = new Future.value(0);
   final int bytesPerSecond;
   int finalCount;
 
@@ -55,7 +55,7 @@
   }
 
   Future close() {
-    return new Future.immediate(finalCount);
+    return new Future.value(finalCount);
   }
 }
 
@@ -68,7 +68,9 @@
   Timer pendingSend;
 
   DataProvider(int this.bytesPerSecond, int this.targetCount, this.chunkSize) {
-    controller = new StreamController(onPauseStateChange: onPauseStateChange);
+    controller = new StreamController(
+      onPause: onPauseStateChange,
+      onResume: onPauseStateChange);
     Timer.run(send);
   }
 
diff --git a/tests/lib/async/stream_controller_async_test.dart b/tests/lib/async/stream_controller_async_test.dart
index dca28e1..6949900 100644
--- a/tests/lib/async/stream_controller_async_test.dart
+++ b/tests/lib/async/stream_controller_async_test.dart
@@ -14,8 +14,8 @@
 testController() {
   // Test fold
   test("StreamController.fold", () {
-    StreamController c = new StreamController.broadcast();
-    Stream stream = c.stream;
+    StreamController c = new StreamController();
+    Stream stream = c.stream.asBroadcastStream();
     stream.fold(0, (a,b) => a + b)
      .then(expectAsync1((int v) {
         Expect.equals(42, v);
@@ -26,10 +26,10 @@
   });
 
   test("StreamController.fold throws", () {
-    StreamController c = new StreamController.broadcast();
-    Stream stream = c.stream;
+    StreamController c = new StreamController();
+    Stream stream = c.stream.asBroadcastStream();
     stream.fold(0, (a,b) { throw "Fnyf!"; })
-     .catchError(expectAsync1((e) { Expect.equals("Fnyf!", e.error); }));
+     .catchError(expectAsync1((error) { Expect.equals("Fnyf!", error); }));
     c.add(42);
   });
 }
@@ -49,7 +49,7 @@
     StreamController c = new StreamController();
     Stream stream = c.stream;
     stream.fold(0, (a,b) { throw "Fnyf!"; })
-            .catchError(expectAsync1((e) { Expect.equals("Fnyf!", e.error); }));
+            .catchError(expectAsync1((e) { Expect.equals("Fnyf!", e); }));
     c.add(42);
   });
 
@@ -177,8 +177,8 @@
 
   test("singleWhere 2", () {
     StreamController c = new StreamController();
-    Future f = c.stream.singleWhere((x) => (x % 3) == 0);  // Matches both 9 and 87..
-    f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+    Future f = c.stream.singleWhere((x) => (x % 3) == 0);  // Matches 9 and 87..
+    f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
     sentEvents.replay(c);
   });
 
@@ -192,7 +192,7 @@
   test("first empty", () {
     StreamController c = new StreamController();
     Future f = c.stream.first;
-    f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+    f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
     Events emptyEvents = new Events()..close();
     emptyEvents.replay(c);
   });
@@ -200,7 +200,7 @@
   test("first error", () {
     StreamController c = new StreamController();
     Future f = c.stream.first;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..error("error")..close();
     errorEvents.replay(c);
   });
@@ -208,7 +208,7 @@
   test("first error 2", () {
     StreamController c = new StreamController();
     Future f = c.stream.first;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..error("error")..error("error2")..close();
     errorEvents.replay(c);
   });
@@ -223,7 +223,7 @@
   test("last empty", () {
     StreamController c = new StreamController();
     Future f = c.stream.last;
-    f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+    f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
     Events emptyEvents = new Events()..close();
     emptyEvents.replay(c);
   });
@@ -231,7 +231,7 @@
   test("last error", () {
     StreamController c = new StreamController();
     Future f = c.stream.last;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..error("error")..close();
     errorEvents.replay(c);
   });
@@ -239,7 +239,7 @@
   test("last error 2", () {
     StreamController c = new StreamController();
     Future f = c.stream.last;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..error("error")..error("error2")..close();
     errorEvents.replay(c);
   });
@@ -254,7 +254,7 @@
   test("elementAt 2", () {
     StreamController c = new StreamController();
     Future f = c.stream.elementAt(20);
-    f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+    f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
     sentEvents.replay(c);
   });
 }
@@ -369,15 +369,18 @@
   });
 }
 
+class TestError { const TestError(); }
+
 testRethrow() {
-  AsyncError error = new AsyncError("UNIQUE", "UNIQUE");
+  TestError error = const TestError();
+  
 
   testStream(name, streamValueTransform) {
     test("rethrow-$name-value", () {
       StreamController c = new StreamController();
       Stream s = streamValueTransform(c.stream, (v) { throw error; });
       s.listen((_) { Expect.fail("unexpected value"); }, onError: expectAsync1(
-          (AsyncError e) { Expect.identical(error, e); }));
+          (e) { Expect.identical(error, e); }));
       c.add(null);
       c.close();
     });
@@ -388,7 +391,7 @@
       StreamController c = new StreamController();
       Stream s = streamErrorTransform(c.stream, (e) { throw error; });
       s.listen((_) { Expect.fail("unexpected value"); }, onError: expectAsync1(
-          (AsyncError e) { Expect.identical(error, e); }));
+          (e) { Expect.identical(error, e); }));
       c.addError(null);
       c.close();
     });
diff --git a/tests/lib/async/stream_controller_test.dart b/tests/lib/async/stream_controller_test.dart
index 7eba3c1..e3a6da2 100644
--- a/tests/lib/async/stream_controller_test.dart
+++ b/tests/lib/async/stream_controller_test.dart
@@ -11,76 +11,84 @@
 
 testMultiController() {
   // Test normal flow.
-  var c = new StreamController.broadcast();
+  var c = new StreamController();
   Events expectedEvents = new Events()
       ..add(42)
       ..add("dibs")
       ..error("error!")
       ..error("error too!")
       ..close();
-  Events actualEvents = new Events.capture(c.stream);
+  Events actualEvents = new Events.capture(c.stream.asBroadcastStream());
   expectedEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test automatic unsubscription on error.
-  c = new StreamController.broadcast();
+  c = new StreamController();
   expectedEvents = new Events()..add(42)..error("error");
-  actualEvents = new Events.capture(c.stream, unsubscribeOnError: true);
+  actualEvents = new Events.capture(c.stream.asBroadcastStream(),
+                                    cancelOnError: true);
   Events sentEvents =
       new Events()..add(42)..error("error")..add("Are you there?");
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test manual unsubscription.
-  c = new StreamController.broadcast();
+  c = new StreamController();
   expectedEvents = new Events()..add(42)..error("error")..add(37);
-  actualEvents = new Events.capture(c.stream, unsubscribeOnError: false);
+  actualEvents = new Events.capture(c.stream.asBroadcastStream(),
+                                    cancelOnError: false);
   expectedEvents.replay(c);
   actualEvents.subscription.cancel();
   c.add("Are you there");  // Not sent to actualEvents.
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test filter.
-  c = new StreamController.broadcast();
+  c = new StreamController();
   expectedEvents = new Events()
     ..add("a string")..add("another string")..close();
   sentEvents = new Events()
     ..add("a string")..add(42)..add("another string")..close();
-  actualEvents = new Events.capture(c.stream.where((v) => v is String));
+  actualEvents = new Events.capture(c.stream
+    .asBroadcastStream()
+    .where((v) => v is String));
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test map.
-  c = new StreamController.broadcast();
+  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.map((v) => "$v$v"));
+  actualEvents = new Events.capture(c.stream
+    .asBroadcastStream()
+    .map((v) => "$v$v"));
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test handleError.
-  c = new StreamController.broadcast();
+  c = new StreamController();
   expectedEvents = new Events()..add("ab")..error("[foo]");
   sentEvents = new Events()..add("ab")..error("foo")..add("ab")..close();
-  actualEvents = new Events.capture(c.stream.handleError((v) {
-        if (v.error is String) {
-          throw new AsyncError("[${v.error}]",
-                                "other stack");
+  actualEvents = new Events.capture(c.stream
+    .asBroadcastStream()
+    .handleError((error) {
+        if (error is String) {
+          // TODO(floitsch): this test originally changed the stacktrace.
+          throw "[${error}]";
         }
-      }), unsubscribeOnError: true);
+      }), cancelOnError: true);
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // reduce is tested asynchronously and therefore not in this file.
 
   // Test expand
-  c = new StreamController.broadcast();
+  c = new StreamController();
   sentEvents = new Events()..add(3)..add(2)..add(4)..close();
   expectedEvents = new Events()..add(1)..add(2)..add(3)
                                ..add(1)..add(2)
                                ..add(1)..add(2)..add(3)..add(4)
                                ..close();
-  actualEvents = new Events.capture(c.stream.expand((v) {
+  actualEvents = new Events.capture(c.stream.asBroadcastStream().expand((v) {
     var l = [];
     for (int i = 0; i < v; i++) l.add(i + 1);
     return l;
@@ -89,14 +97,14 @@
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test transform.
-  c = new StreamController.broadcast();
+  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(
+  actualEvents = new Events.capture(c.stream.asBroadcastStream().transform(
       new StreamTransformer(
-          handleData: (v, s) { s.addError(new AsyncError(v)); },
-          handleError: (e, s) { s.add(e.error); },
+          handleData: (v, s) { s.addError(v); },
+          handleError: (e, s) { s.add(e); },
           handleDone: (s) {
 
             s.add("foo");
@@ -108,7 +116,7 @@
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test multiple filters.
-  c = new StreamController.broadcast();
+  c = new StreamController();
   sentEvents = new Events()..add(42)
                            ..add("snugglefluffy")
                            ..add(7)
@@ -117,20 +125,20 @@
                            ..close();
   expectedEvents = new Events()..add(42)..error("not FormatException");
   actualEvents = new Events.capture(
-      c.stream.where((v) => v is String)
+      c.stream.asBroadcastStream().where((v) => v is String)
        .map((v) => int.parse(v))
-       .handleError((v) {
-          if (v.error is! FormatException) throw v;
+       .handleError((error) {
+          if (error is! FormatException) throw error;
         })
        .where((v) => v > 10),
-      unsubscribeOnError: true);
+      cancelOnError: true);
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
   // Test subscription changes while firing.
-  c = new StreamController.broadcast();
+  c = new StreamController();
   var sink = c.sink;
-  var stream = c.stream;
+  var stream = c.stream.asBroadcastStream();
   var counter = 0;
   var subscription = stream.listen(null);
   subscription.onData((data) {
@@ -169,7 +177,7 @@
   // Test automatic unsubscription on error.
   c = new StreamController();
   expectedEvents = new Events()..add(42)..error("error");
-  actualEvents = new Events.capture(c.stream, unsubscribeOnError: true);
+  actualEvents = new Events.capture(c.stream, cancelOnError: true);
   Events sentEvents =
       new Events()..add(42)..error("error")..add("Are you there?");
   sentEvents.replay(c);
@@ -178,7 +186,7 @@
   // Test manual unsubscription.
   c = new StreamController();
   expectedEvents = new Events()..add(42)..error("error")..add(37);
-  actualEvents = new Events.capture(c.stream, unsubscribeOnError: false);
+  actualEvents = new Events.capture(c.stream, cancelOnError: false);
   expectedEvents.replay(c);
   actualEvents.subscription.cancel();
   c.add("Are you there");  // Not sent to actualEvents.
@@ -206,12 +214,12 @@
   c = new StreamController();
   expectedEvents = new Events()..add("ab")..error("[foo]");
   sentEvents = new Events()..add("ab")..error("foo")..add("ab")..close();
-  actualEvents = new Events.capture(c.stream.handleError((v) {
-        if (v.error is String) {
-          throw new AsyncError("[${v.error}]",
-                                "other stack");
+  actualEvents = new Events.capture(c.stream.handleError((error) {
+        if (error is String) {
+          // TODO(floitsch): this error originally changed the stack trace.
+          throw "[${error}]";
         }
-      }), unsubscribeOnError: true);
+      }), cancelOnError: true);
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
@@ -262,8 +270,8 @@
     Future<bool> contains = c.stream.contains("b");
     contains.then((var c) {
       Expect.fail("no value expected");
-    }).catchError((AsyncError e) {
-      Expect.equals("FAIL", e.error);
+    }).catchError((error) {
+      Expect.equals("FAIL", error);
     });
     sentEvents.replay(c);
   }
@@ -275,8 +283,8 @@
       new Events()..error("a")..add(42)..error("b")..add("foo")..close();
   actualEvents = new Events.capture(c.stream.transform(
       new StreamTransformer(
-          handleData: (v, s) { s.addError(new AsyncError(v)); },
-          handleError: (e, s) { s.add(e.error); },
+          handleData: (v, s) { s.addError(v); },
+          handleError: (e, s) { s.add(e); },
           handleDone: (s) {
             s.add("foo");
             s.close();
@@ -296,11 +304,11 @@
   actualEvents = new Events.capture(
       c.stream.where((v) => v is String)
        .map((v) => int.parse(v))
-       .handleError((v) {
-          if (v.error is! FormatException) throw v;
+       .handleError((error) {
+          if (error is! FormatException) throw error;
         })
        .where((v) => v > 10),
-      unsubscribeOnError: true);
+      cancelOnError: true);
   sentEvents.replay(c);
   Expect.listEquals(expectedEvents.events, actualEvents.events);
 
@@ -387,16 +395,14 @@
 }
 
 testClosed() {
-  for (StreamController c in [new StreamController(),
-                              new StreamController.broadcast()]) {
-    Expect.isFalse(c.isClosed);
-    c.add(42);
-    Expect.isFalse(c.isClosed);
-    c.addError("bad");
-    Expect.isFalse(c.isClosed);
-    c.close();
-    Expect.isTrue(c.isClosed);
-  }
+  StreamController c = new StreamController();
+  Expect.isFalse(c.isClosed);
+  c.add(42);
+  Expect.isFalse(c.isClosed);
+  c.addError("bad");
+  Expect.isFalse(c.isClosed);
+  c.close();
+  Expect.isTrue(c.isClosed);
 }
 
 main() {
diff --git a/tests/lib/async/stream_event_transform_test.dart b/tests/lib/async/stream_event_transform_test.dart
index 78c79cd..87f114c 100644
--- a/tests/lib/async/stream_event_transform_test.dart
+++ b/tests/lib/async/stream_event_transform_test.dart
@@ -10,15 +10,15 @@
 import 'event_helper.dart';
 
 void handleData(int data, EventSink<int> sink) {
-  sink.addError(new AsyncError("$data"));
+  sink.addError("$data");
   sink.add(data + 1);
 }
 
-void handleError(AsyncError e, EventSink<int> sink) {
-  String value = e.error;
+void handleError(error, EventSink<int> sink) {
+  String value = error;
   int data = int.parse(value);
   sink.add(data);
-  sink.addError(new AsyncError("${data + 1}"));
+  sink.addError("${data + 1}");
 }
 
 void handleDone(EventSink<int> sink) {
@@ -28,15 +28,14 @@
 
 class EventTransformer extends StreamEventTransformer<int,int> {
   void handleData(int data, EventSink<int> sink) {
-    sink.addError(new AsyncError("$data"));
+    sink.addError("$data");
     sink.add(data + 1);
   }
 
-  void handleError(AsyncError e, EventSink<int> sink) {
-    String value = e.error;
+  void handleError(String value, EventSink<int> sink) {
     int data = int.parse(value);
     sink.add(data);
-    sink.addError(new AsyncError("${data + 1}"));
+    sink.addError("${data + 1}");
   }
 
   void handleDone(EventSink<int> sink) {
diff --git a/tests/lib/async/stream_single_test.dart b/tests/lib/async/stream_single_test.dart
index 3bc889a..fe0b384 100644
--- a/tests/lib/async/stream_single_test.dart
+++ b/tests/lib/async/stream_single_test.dart
@@ -22,14 +22,14 @@
   test("single empty", () {
     StreamController c = new StreamController();
     Future f = c.stream.single;
-    f.catchError(expectAsync1((e) { Expect.isTrue(e.error is StateError); }));
+    f.catchError(expectAsync1((error) { Expect.isTrue(error is StateError); }));
     new Events.fromIterable([]).replay(c);
   });
 
   test("single error", () {
     StreamController c = new StreamController();
     Future f = c.stream.single;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..error("error")..close();
     errorEvents.replay(c);
   });
@@ -37,7 +37,7 @@
   test("single error 2", () {
     StreamController c = new StreamController();
     Future f = c.stream.single;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..error("error")..error("error2")..close();
     errorEvents.replay(c);
   });
@@ -45,7 +45,7 @@
   test("single error 3", () {
     StreamController c = new StreamController();
     Future f = c.stream.single;
-    f.catchError(expectAsync1((e) { Expect.equals("error", e.error); }));
+    f.catchError(expectAsync1((error) { Expect.equals("error", error); }));
     Events errorEvents = new Events()..add(499)..error("error")..close();
     errorEvents.replay(c);
   });
diff --git a/tests/lib/async/stream_single_to_multi_subscriber_test.dart b/tests/lib/async/stream_single_to_multi_subscriber_test.dart
index 8424cb2..1f4d693 100644
--- a/tests/lib/async/stream_single_to_multi_subscriber_test.dart
+++ b/tests/lib/async/stream_single_to_multi_subscriber_test.dart
@@ -37,7 +37,7 @@
   });
 
   test("tomulti no-op", () {
-    StreamController c = new StreamController<int>.broadcast();
+    StreamController c = new StreamController<int>();
     Stream<int> multi = c.stream.asBroadcastStream();
     Events expected = new Events.fromIterable([1, 2, 3, 4, 5]);
     Events actual1 = new Events.capture(multi);
diff --git a/tests/lib/async/stream_state_helper.dart b/tests/lib/async/stream_state_helper.dart
index b982d9d..dbc645a 100644
--- a/tests/lib/async/stream_state_helper.dart
+++ b/tests/lib/async/stream_state_helper.dart
@@ -10,21 +10,23 @@
 
 class StreamProtocolTest {
   StreamController _controller;
+  Stream _controllerStream;
   StreamSubscription _subscription;
   List<Event> _expectations = new List<Event>();
   int _nextExpectationIndex = 0;
   Function _onComplete;
 
   StreamProtocolTest([bool broadcast = false]) {
+    _controller = new StreamController(
+          onListen: _onSubcription,
+          onPause: _onPause,
+          onResume: _onPause,
+          onCancel: _onSubcription);
+    // TODO(lrn): Make it work with multiple subscribers too.
     if (broadcast) {
-     _controller = new StreamController.broadcast(
-          onPauseStateChange: _onPause,
-          onSubscriptionStateChange: _onSubcription);
-     // TODO(lrn): Make it work with multiple subscribers too.
+      _controllerStream = _controller.stream.asBroadcastStream();
     } else {
-     _controller = new StreamController(
-          onPauseStateChange: _onPause,
-          onSubscriptionStateChange: _onSubcription);
+      _controllerStream = _controller.stream;
     }
     _onComplete = expectAsync0((){
       _onComplete = null;  // Being null marks the test to be complete.
@@ -36,15 +38,15 @@
   void error(var error) { _controller.addError(error); }
   void close() { _controller.close(); }
 
-  void subscribe({bool unsubscribeOnError : false}) {
+  void subscribe({bool cancelOnError : false}) {
     // TODO(lrn): Handle more subscriptions (e.g., a subscription-id
     // per subscription, and an id on event _expectations).
     if (_subscription != null) throw new StateError("Already subscribed");
-    _subscription = _controller.stream.listen(_onData,
-                                              onError: _onError,
-                                              onDone: _onDone,
-                                              unsubscribeOnError:
-                                                  unsubscribeOnError);
+    _subscription = _controllerStream.listen(_onData,
+                                             onError: _onError,
+                                             onDone: _onDone,
+                                             cancelOnError:
+                                                 cancelOnError);
   }
 
   void pause([Future resumeSignal]) {
@@ -73,11 +75,11 @@
     });
   }
 
-  void _onError(AsyncError error) {
+  void _onError(error) {
     _withNextExpectation((Event expect) {
       if (!expect.matchError(error)) {
         _fail("Expected: $expect\n"
-              "Found   : [Data: ${error.error}]");
+              "Found   : [Data: ${error}]");
       }
     });
   }
@@ -190,7 +192,7 @@
     if (_action != null) _action();
     return true;
   }
-  bool matchError(AsyncError e) {
+  bool matchError(e) {
     if (!_testError(e)) return false;
     if (_action != null) _action();
     return true;
@@ -233,7 +235,7 @@
 class ErrorEvent extends Event {
   final error;
   ErrorEvent(this.error, void action()) : super(action);
-  bool _testError(AsyncError error) => this.error == error.error;
+  bool _testError(error) => this.error == error;
   String toString() => "[Error: $error]";
 }
 
@@ -270,8 +272,8 @@
     _actual = "*[Data $data]";
     return true;
   }
-  bool _testError(AsyncError error) {
-    _actual = "*[Error ${error.error}]";
+  bool _testError(error) {
+    _actual = "*[Error ${error}]";
     return true;
   }
   bool _testDone() {
diff --git a/tests/lib/async/stream_state_nonzero_timer_test.dart b/tests/lib/async/stream_state_nonzero_timer_test.dart
index d05f9fa..868f760 100644
--- a/tests/lib/async/stream_state_nonzero_timer_test.dart
+++ b/tests/lib/async/stream_state_nonzero_timer_test.dart
@@ -15,7 +15,8 @@
 
 main() {
   mainTest(false);
-  mainTest(true);
+  // TODO(floitsch): reenable?
+  // mainTest(true);
 }
 
 mainTest(bool broadcast) {
diff --git a/tests/lib/async/stream_state_test.dart b/tests/lib/async/stream_state_test.dart
index f27697b..d6d873f 100644
--- a/tests/lib/async/stream_state_test.dart
+++ b/tests/lib/async/stream_state_test.dart
@@ -12,7 +12,8 @@
 
 main() {
   mainTest(false);
-  mainTest(true);
+  // TODO(floitsch): reenable?
+  // mainTest(true);
 }
 
 mainTest(bool broadcast) {
@@ -58,7 +59,7 @@
      ..expectData(42)
      ..expectError("bad")
      ..expectSubscription(false, !broadcast);
-    t..subscribe(unsubscribeOnError: true)
+    t..subscribe(cancelOnError: true)
      ..add(42)
      ..error("bad")
      ..add(43)
@@ -73,7 +74,7 @@
      ..expectData(43)
      ..expectDone()
      ..expectSubscription(false, false);
-    t..subscribe(unsubscribeOnError: false)
+    t..subscribe(cancelOnError: false)
      ..add(42)
      ..error("bad")
      ..add(43)
diff --git a/tests/lib/async/stream_subscription_as_future_test.dart b/tests/lib/async/stream_subscription_as_future_test.dart
new file mode 100644
index 0000000..5be8f79
--- /dev/null
+++ b/tests/lib/async/stream_subscription_as_future_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the Stream.single method.
+library stream_single_test;
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import '../../../pkg/unittest/lib/unittest.dart';
+
+main() {
+  test("subscription.asStream success", () {
+    Stream stream = new Stream.fromIterable([1, 2, 3]);
+    var output = [];
+    var subscription = stream.listen((x) { output.add(x); });
+    subscription.asFuture(output).then(expectAsync1((o) {
+      Expect.listEquals([1, 2, 3], o);
+    }));
+  });
+
+  test("subscription.asStream success2", () {
+    StreamController controller = new StreamController();
+    [1, 2, 3].forEach(controller.add);
+    controller.close();
+    Stream stream = controller.stream;
+    var output = [];
+    var subscription = stream.listen((x) { output.add(x); });
+    subscription.asFuture(output).then(expectAsync1((o) {
+      Expect.listEquals([1, 2, 3], o);
+    }));
+  });
+
+  test("subscription.asStream success 3", () {
+    Stream stream = new Stream.fromIterable([1, 2, 3]).map((x) => x);
+    var output = [];
+    var subscription = stream.listen((x) { output.add(x); });
+    subscription.asFuture(output).then(expectAsync1((o) {
+      Expect.listEquals([1, 2, 3], o);
+    }));
+  });
+
+  test("subscription.asStream failure", () {
+    StreamController controller = new StreamController();
+    [1, 2, 3].forEach(controller.add);
+    controller.addError("foo");
+    controller.close();
+    Stream stream = controller.stream;
+    var output = [];
+    var subscription = stream.listen((x) { output.add(x); });
+    subscription.asFuture(output).catchError(expectAsync1((error) {
+      Expect.equals(error, "foo");
+    }));
+  });
+
+  test("subscription.asStream failure2", () {
+    Stream stream = new Stream.fromIterable([1, 2, 3, 4])
+      .map((x) {
+        if (x == 4) throw "foo";
+        return x;
+      });
+    var output = [];
+    var subscription = stream.listen((x) { output.add(x); });
+    subscription.asFuture(output).catchError(expectAsync1((error) {
+      Expect.equals(error, "foo");
+    }));
+  });
+}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 33c57ac..5c2c79f 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// TODO(rmacnak): Move the existing mirror tests here (a place for 
+// TODO(rmacnak): Move the existing mirror tests here (a place for
 // cross-implementation tests).
 
 library MirrorsTest;
@@ -11,48 +11,50 @@
 
 var topLevelField;
 
-class Class {
+class Class<T> {
   Class() { this.field = "default value"; }
   Class.withInitialValue(this.field);
   var field;
   static var staticField;
 }
 
+typedef Typedef();
+
 testFieldAccess(mirrors) {
   var instance = new Class();
 
-  var libMirror = mirrors.libraries["MirrorsTest"];
-  var classMirror = libMirror.classes["Class"];
+  var libMirror = mirrors.libraries[const Symbol("MirrorsTest")];
+  var classMirror = libMirror.classes[const Symbol("Class")];
   var instMirror = reflect(instance);
 
-  libMirror.setFieldAsync('topLevelField', 42);
-  var future = libMirror.getFieldAsync('topLevelField');
+  libMirror.setFieldAsync(new Symbol('topLevelField'), 42);
+  var future = libMirror.getFieldAsync(new Symbol('topLevelField'));
   future.then(expectAsync1((resultMirror) {
     expect(resultMirror.reflectee, equals(42));
-    expect(topLevelField, equals(42));   
-  }));
-  
-  classMirror.setFieldAsync('staticField', 43);
-  future = classMirror.getFieldAsync('staticField');
-  future.then(expectAsync1((resultMirror) {
-    expect(resultMirror.reflectee, equals(43));
-    expect(Class.staticField, equals(43)); 
+    expect(topLevelField, equals(42));
   }));
 
-  instMirror.setFieldAsync('field', 44);
-  future = instMirror.getFieldAsync('field');
+  classMirror.setFieldAsync(new Symbol('staticField'), 43);
+  future = classMirror.getFieldAsync(new Symbol('staticField'));
+  future.then(expectAsync1((resultMirror) {
+    expect(resultMirror.reflectee, equals(43));
+    expect(Class.staticField, equals(43));
+  }));
+
+  instMirror.setFieldAsync(new Symbol('field'), 44);
+  future = instMirror.getFieldAsync(new Symbol('field'));
   future.then(expectAsync1((resultMirror) {
     expect(resultMirror.reflectee, equals(44));
-    expect(instance.field, equals(44)); 
+    expect(instance.field, equals(44));
   }));
 }
 
 testClosureMirrors(mirrors) {
   var closure = (x, y, z) { return x + y + z; };
-  
+
   var mirror = reflect(closure);
   expect(mirror is ClosureMirror, equals(true));
-  
+
   var funcMirror = mirror.function;
   expect(funcMirror is MethodMirror, equals(true));
   expect(funcMirror.parameters.length, equals(3));
@@ -64,17 +66,17 @@
 }
 
 testInvokeConstructor(mirrors) {
-  var libMirror = mirrors.libraries["MirrorsTest"];
-  var classMirror = libMirror.classes["Class"];
-  
-  var future = classMirror.newInstanceAsync('', []);
+  var libMirror = mirrors.libraries[const Symbol("MirrorsTest")];
+  var classMirror = libMirror.classes[const Symbol("Class")];
+
+  var future = classMirror.newInstanceAsync(new Symbol(''), []);
   future.then(expectAsync1((resultMirror) {
     var instance = resultMirror.reflectee;
     expect(instance is Class, equals(true));
     expect(instance.field, equals("default value"));
   }));
 
-  future = classMirror.newInstanceAsync('withInitialValue', [45]);
+  future = classMirror.newInstanceAsync(new Symbol('withInitialValue'), [45]);
   future.then(expectAsync1((resultMirror) {
     var instance = resultMirror.reflectee;
     expect(instance is Class, equals(true));
@@ -82,11 +84,42 @@
   }));
 }
 
+testNames(mirrors) {
+  var libMirror = mirrors.libraries[const Symbol('MirrorsTest')];
+  var classMirror = libMirror.classes[const Symbol('Class')];
+  var typedefMirror = libMirror.members[const Symbol('Typedef')];
+  var methodMirror = libMirror.functions[const Symbol('testNames')];
+  var variableMirror = classMirror.variables[const Symbol('field')];
+
+  expect(libMirror.simpleName, equals(const Symbol('MirrorsTest')));
+  expect(libMirror.qualifiedName, equals(const Symbol('MirrorsTest')));
+
+  expect(classMirror.simpleName, equals(const Symbol('Class')));
+  expect(classMirror.qualifiedName, equals(const Symbol('MirrorsTest.Class')));
+
+  TypeVariableMirror typeVariable = classMirror.typeVariables.values.single;
+  expect(typeVariable.simpleName, equals(const Symbol('T')));
+  expect(typeVariable.qualifiedName,
+         equals(const Symbol('MirrorsTest.Class.T')));
+
+  expect(typedefMirror.simpleName, equals(const Symbol('Typedef')));
+  expect(typedefMirror.qualifiedName,
+         equals(const Symbol('MirrorsTest.Typedef')));
+
+  expect(methodMirror.simpleName, equals(const Symbol('testNames')));
+  expect(methodMirror.qualifiedName,
+         equals(const Symbol('MirrorsTest.testNames')));
+
+  expect(variableMirror.simpleName, equals(const Symbol('field')));
+  expect(variableMirror.qualifiedName,
+         equals(const Symbol('MirrorsTest.Class.field')));
+}
+
 main() {
   var mirrors = currentMirrorSystem();
 
   test("Test field access", () { testFieldAccess(mirrors); });
   test("Test closure mirrors", () { testClosureMirrors(mirrors); });
   test("Test invoke constructor", () { testInvokeConstructor(mirrors); });
+  test("Test simple and qualifiedName", () { testNames(mirrors); });
 }
-
diff --git a/tests/standalone/debugger/debug_lib.dart b/tests/standalone/debugger/debug_lib.dart
index bc1f246..9fa6349 100644
--- a/tests/standalone/debugger/debug_lib.dart
+++ b/tests/standalone/debugger/debug_lib.dart
@@ -6,6 +6,7 @@
 
 library DartDebugger;
 
+import "dart:async";
 import "dart:io";
 import "dart:math";
 import "dart:utf";
@@ -458,11 +459,16 @@
           },
           onError: (e) {
             print("Error '$e' detected in input stream from debug target");
+            var trace = getAttachedStackTrace(e);
+            if (trace != null) print("StackTrace: $trace");
             close(killDebugee: true);
           });
       },
-      onError: (asyncErr) {
-        error("Error while connecting to debugee: $asyncErr");
+      onError: (e) {
+        String msg = "Error while connecting to debugee: $e";
+        var trace = getAttachedStackTrace(e);
+        if (trace != null) msg += "\nStackTrace: $trace";
+        error(msg);
         close(killDebugee: true);
       });
   }
@@ -518,6 +524,8 @@
     onError: (e) {
       if (++retries >= 3) { 
         print('unable to find unused port: $e');
+        var trace = getAttachedStackTrace(e);
+        if (trace != null) print("StackTrace: $trace");
         return -1; 
       } else {
         // Retry with another random port.
diff --git a/tests/standalone/float_array_test.dart b/tests/standalone/float_array_test.dart
index d8c9ebb..562b91e 100644
--- a/tests/standalone/float_array_test.dart
+++ b/tests/standalone/float_array_test.dart
@@ -41,7 +41,7 @@
   }
 
   // 4.0e40 is larger than the largest representable float.
-  floatArray.setRange(1, 2, const [8.0, 4.0e40]);
+  floatArray.setRange(1, 3, const [8.0, 4.0e40]);
   Expect.equals(20, floatArray[0]);
   Expect.equals(8, floatArray[1]);
   Expect.equals(double.INFINITY, floatArray[2]);
@@ -59,7 +59,7 @@
   });
 
   Expect.throws(() {
-    floatArray.setRange(3, 1, list);
+    floatArray.setRange(3, 4, list);
   });
 }
 
@@ -125,7 +125,7 @@
   }
 
   // Unlike Float32Array we can properly represent 4.0e40
-  floatArray.setRange(1, 2, const [8.0, 4.0e40]);
+  floatArray.setRange(1, 3, const [8.0, 4.0e40]);
   Expect.equals(20, floatArray[0]);
   Expect.equals(8, floatArray[1]);
   Expect.equals(4.0e40, floatArray[2]);
@@ -143,7 +143,7 @@
   });
 
   Expect.throws(() {
-    floatArray.setRange(3, 1, list);
+    floatArray.setRange(3, 4, list);
   });
 }
 
diff --git a/tests/standalone/io/dart_std_io_pipe_test.dart b/tests/standalone/io/dart_std_io_pipe_test.dart
index bdbffeb..e3dfec0 100644
--- a/tests/standalone/io/dart_std_io_pipe_test.dart
+++ b/tests/standalone/io/dart_std_io_pipe_test.dart
@@ -25,7 +25,7 @@
   RandomAccessFile pipeOut  = new File(fileName).openSync();
   int length = pipeOut.lengthSync();
   List data = new List<int>(length);
-  pipeOut.readListSync(data, 0, length);
+  pipeOut.readIntoSync(data, 0, length);
   Expect.equals(content, new String.fromCharCodes(data));
   pipeOut.closeSync();
 }
@@ -93,7 +93,7 @@
   });
   future.catchError((error) {
     dir.deleteSync(recursive: true);
-    Expect.fail(error.error.toString());
+    Expect.fail(error.toString());
   });
 }
 
diff --git a/tests/standalone/io/directory_error_test.dart b/tests/standalone/io/directory_error_test.dart
index 33418ef..123954c 100644
--- a/tests/standalone/io/directory_error_test.dart
+++ b/tests/standalone/io/directory_error_test.dart
@@ -35,8 +35,8 @@
   Expect.throws(() => inNonExistent.createSync(),
                 (e) => checkCreateInNonExistentFileException(e));
 
-  inNonExistent.create().catchError((e) {
-    checkCreateInNonExistentFileException(e.error);
+  inNonExistent.create().catchError((error) {
+    checkCreateInNonExistentFileException(error);
     done();
   });
 }
@@ -62,8 +62,8 @@
   Expect.throws(() => nonExistent.createTempSync(),
                 (e) => checkCreateTempInNonExistentFileException(e));
 
-  nonExistent.createTemp().catchError((e) {
-    checkCreateTempInNonExistentFileException(e.error);
+  nonExistent.createTemp().catchError((error) {
+    checkCreateTempInNonExistentFileException(error);
     done();
   });
 }
@@ -84,8 +84,8 @@
   Expect.throws(() => nonExistent.deleteSync(),
                 (e) => checkDeleteNonExistentFileException(e));
 
-  nonExistent.delete().catchError((e) {
-    checkDeleteNonExistentFileException(e.error);
+  nonExistent.delete().catchError((error) {
+    checkDeleteNonExistentFileException(error);
     done();
   });
 }
@@ -107,8 +107,8 @@
   Expect.throws(() => nonExistent.deleteSync(recursive: true),
                 (e) => checkDeleteRecursivelyNonExistentFileException(e));
 
-  nonExistent.delete(recursive: true).catchError((e) {
-    checkDeleteRecursivelyNonExistentFileException(e.error);
+  nonExistent.delete(recursive: true).catchError((error) {
+    checkDeleteRecursivelyNonExistentFileException(error);
     done();
   });
 }
@@ -130,9 +130,8 @@
 }
 
 
-bool checkAsyncListNonExistentFileException(e) {
-  Expect.isTrue(e is AsyncError);
-  return checkListNonExistentFileException(e.error);
+bool checkAsyncListNonExistentFileException(error) {
+  return checkListNonExistentFileException(error);
 }
 
 
@@ -155,8 +154,8 @@
                 (e) => e is DirectoryIOException);
   var renameDone = nonExistent.rename(newPath);
   renameDone.then((ignore) => Expect.fail('rename non existent'))
-            .catchError((e) {
-              Expect.isTrue(e.error is DirectoryIOException);
+            .catchError((error) {
+              Expect.isTrue(error is DirectoryIOException);
             done();
   });
 }
@@ -171,8 +170,8 @@
                 (e) => e is DirectoryIOException);
   var renameDone = d.rename(newPath);
   renameDone.then((ignore) => Expect.fail('rename file as directory'))
-            .catchError((e) {
-              Expect.isTrue(e.error is DirectoryIOException);
+            .catchError((error) {
+              Expect.isTrue(error is DirectoryIOException);
               done();
             });
 }
@@ -187,8 +186,8 @@
                 (e) => e is DirectoryIOException);
   var renameDone = temp1.rename(fileName);
   renameDone.then((ignore) => Expect.fail('rename dir overwrite file'))
-            .catchError((e) {
-              Expect.isTrue(e.error is DirectoryIOException);
+            .catchError((error) {
+              Expect.isTrue(error is DirectoryIOException);
               temp1.deleteSync(recursive: true);
               done();
             });
diff --git a/tests/standalone/io/directory_fuzz_test.dart b/tests/standalone/io/directory_fuzz_test.dart
index c1dadef..dda9fe3 100644
--- a/tests/standalone/io/directory_fuzz_test.dart
+++ b/tests/standalone/io/directory_fuzz_test.dart
@@ -51,7 +51,7 @@
     futures.add(doItAsync(() {
       return d.exists().then((res) {
         if (!res) return d.delete(recursive: true);
-        return new Future.immediate(true);
+        return new Future.value(true);
       });
     }));
     typeMapping.forEach((k2, v2) {
diff --git a/tests/standalone/io/directory_test.dart b/tests/standalone/io/directory_test.dart
index decf05d..d9ca0de 100644
--- a/tests/standalone/io/directory_test.dart
+++ b/tests/standalone/io/directory_test.dart
@@ -89,9 +89,8 @@
     setupListerHandlers(Stream<FileSystemEntity> stream) {
       stream.listen(
           (_) => Expect.fail("Listing of non-existing directory should fail"),
-          onError: (e) {
-            Expect.isTrue(e is AsyncError);
-            Expect.isTrue(e.error is DirectoryIOException);
+          onError: (error) {
+            Expect.isTrue(error is DirectoryIOException);
           });
     }
     new Directory("").createTemp().then((d) {
@@ -109,9 +108,8 @@
       setupListHandlers(Stream<FileSystemEntity> stream) {
         stream.listen(
           (_) => Expect.fail("Listing of non-existing directory should fail"),
-          onError: (e) {
-            Expect.isTrue(e is AsyncError);
-            Expect.isTrue(e.error is DirectoryIOException);
+          onError: (error) {
+            Expect.isTrue(error is DirectoryIOException);
             if (++errors == 2) {
               d.delete(recursive: true).then((_) {
                 port.close();
@@ -141,8 +139,8 @@
     setupFutureHandlers(future) {
       future.then((ignore) {
         Expect.fail("Deletion of non-existing directory should fail");
-      }).catchError((e) {
-        Expect.isTrue(e.error is DirectoryIOException);
+      }).catchError((error) {
+        Expect.isTrue(error is DirectoryIOException);
       });
     }
 
@@ -169,8 +167,8 @@
           }
           var long = new Directory("${buffer.toString()}");
           var errors = 0;
-          onError(e) {
-            Expect.isTrue(e.error is DirectoryIOException);
+          onError(error) {
+            Expect.isTrue(error is DirectoryIOException);
             if (++errors == 2) {
               d.delete(recursive: true).then((ignore) => port.close());
             }
@@ -555,8 +553,8 @@
     file.create().then((_) {
       subDir.create()
         .then((_) { Expect.fail("dir create should fail on existing file"); })
-        .catchError((e) {
-          Expect.isTrue(e.error is DirectoryIOException);
+        .catchError((error) {
+          Expect.isTrue(error is DirectoryIOException);
           temp.delete(recursive: true).then((_) {
             port.close();
           });
diff --git a/tests/standalone/io/echo_server_stream_test.dart b/tests/standalone/io/echo_server_stream_test.dart
index dfd264d..4c00422 100644
--- a/tests/standalone/io/echo_server_stream_test.dart
+++ b/tests/standalone/io/echo_server_stream_test.dart
@@ -57,7 +57,10 @@
     }
 
     void errorHandler(e) {
-      Expect.fail("Socket error $e");
+      String msg = "Socket error $e";
+      var trace = getAttachedStackTrace(e);
+      if (trace != null) msg += "\nStackTrace: $trace";
+      Expect.fail(msg);
     }
 
     void connectHandler() {
@@ -115,7 +118,7 @@
       int bytesRead;
       bytesRead = data.length;
       if (bytesRead > 0) {
-        buffer.setRange(offset, data.length, data);
+        buffer.setRange(offset, offset + data.length, data);
         offset += bytesRead;
         for (int i = 0; i < offset; i++) {
           Expect.equals(EchoServerGame.FIRSTCHAR + i, buffer[i]);
@@ -128,7 +131,10 @@
     }
 
     void errorHandler(e) {
-      Expect.fail("Socket error $e");
+      String msg = "Socket error $e";
+      var trace = getAttachedStackTrace(e);
+      if (trace != null) msg += "\nStackTrace: $trace";
+      Expect.fail(msg);
     }
 
     connection.listen(dataReceived, onError: errorHandler);
diff --git a/tests/standalone/io/file_error_test.dart b/tests/standalone/io/file_error_test.dart
index e1741fd..16c0e24 100644
--- a/tests/standalone/io/file_error_test.dart
+++ b/tests/standalone/io/file_error_test.dart
@@ -53,8 +53,8 @@
 
   var openFuture = file.open(mode: FileMode.READ);
   openFuture.then((raf) => Expect.fail("Unreachable code"))
-            .catchError((e) {
-              checkOpenNonExistentFileException(e.error);
+            .catchError((error) {
+              checkOpenNonExistentFileException(error);
               p.toSendPort().send(null);
             });
 }
@@ -75,8 +75,8 @@
 
   var delete = file.delete();
   delete.then((ignore) => Expect.fail("Unreachable code"))
-        .catchError((e) {
-          checkDeleteNonExistentFileException(e.error);
+        .catchError((error) {
+          checkDeleteNonExistentFileException(error);
           p.toSendPort().send(null);
         });
 }
@@ -97,8 +97,8 @@
 
   var lenFuture = file.length();
   lenFuture.then((len) => Expect.fail("Unreachable code"))
-           .catchError((e) {
-             checkLengthNonExistentFileException(e.error);
+           .catchError((error) {
+             checkLengthNonExistentFileException(error);
              p.toSendPort().send(null);
            });
 }
@@ -134,8 +134,8 @@
 
   var create = file.create();
   create.then((ignore) => Expect.fail("Unreachable code"))
-  .catchError((e) {
-    checkCreateInNonExistentDirectoryException(e.error);
+  .catchError((error) {
+    checkCreateInNonExistentDirectoryException(error);
     p.toSendPort().send(null);
   });
 }
@@ -165,8 +165,8 @@
 
   var fullPathFuture = file.fullPath();
   fullPathFuture.then((path) => Expect.fail("Unreachable code $path"))
-  .catchError((e) {
-    checkFullPathOnNonExistentDirectoryException(e.error);
+  .catchError((error) {
+    checkFullPathOnNonExistentDirectoryException(error);
     p.toSendPort().send(null);
   });
 }
@@ -197,8 +197,8 @@
 
   var dirFuture = file.directory();
   dirFuture.then((directory) => Expect.fail("Unreachable code"))
-  .catchError((e) {
-    checkDirectoryInNonExistentDirectoryException(e.error);
+  .catchError((error) {
+    checkDirectoryInNonExistentDirectoryException(error);
     p.toSendPort().send(null);
   });
 }
@@ -218,8 +218,8 @@
 
   var readAsBytesFuture = file.readAsBytes();
   readAsBytesFuture.then((data) => Expect.fail("Unreachable code"))
-  .catchError((e) {
-    checkOpenNonExistentFileException(e.error);
+  .catchError((error) {
+    checkOpenNonExistentFileException(error);
     p.toSendPort().send(null);
   });
 }
@@ -239,8 +239,8 @@
 
   var readAsStringFuture = file.readAsString(encoding: Encoding.ASCII);
   readAsStringFuture.then((data) => Expect.fail("Unreachable code"))
-  .catchError((e) {
-    checkOpenNonExistentFileException(e.error);
+  .catchError((error) {
+    checkOpenNonExistentFileException(error);
     p.toSendPort().send(null);
   });
 }
@@ -260,8 +260,8 @@
 
   var readAsLinesFuture = file.readAsLines(encoding: Encoding.ASCII);
   readAsLinesFuture.then((data) => Expect.fail("Unreachable code"))
-  .catchError((e) {
-    checkOpenNonExistentFileException(e.error);
+  .catchError((error) {
+    checkOpenNonExistentFileException(error);
     p.toSendPort().send(null);
   });
 }
@@ -300,25 +300,25 @@
                   (e) => checkWriteReadOnlyFileException(e));
 
     var writeByteFuture = openedFile.writeByte(0);
-    writeByteFuture.catchError((e) {
-      checkWriteReadOnlyFileException(e.error);
+    writeByteFuture.catchError((error) {
+      checkWriteReadOnlyFileException(error);
       openedFile.close().then((ignore) => port.send(null));
     });
   });
 }
 
-testWriteListToReadOnlyFile() {
+testWriteFromToReadOnlyFile() {
   createTestFile((file, port) {
     var openedFile = file.openSync(mode: FileMode.READ);
 
     List data = [0, 1, 2, 3];
     // Writing to read only file should throw an exception.
-    Expect.throws(() => openedFile.writeListSync(data, 0, data.length),
+    Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
                   (e) => checkWriteReadOnlyFileException(e));
 
-    var writeListFuture = openedFile.writeList(data, 0, data.length);
-    writeListFuture.catchError((e) {
-      checkWriteReadOnlyFileException(e.error);
+    var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
+    writeFromFuture.catchError((error) {
+      checkWriteReadOnlyFileException(error);
       openedFile.close().then((ignore) => port.send(null));
     });
   });
@@ -337,8 +337,8 @@
 
     var truncateFuture = openedFile.truncate(0);
     truncateFuture.then((ignore) => Expect.fail("Unreachable code"))
-    .catchError((e) {
-      checkWriteReadOnlyFileException(e.error);
+    .catchError((error) {
+      checkWriteReadOnlyFileException(error);
       openedFile.close().then((ignore) => port.send(null));
     });
   });
@@ -361,9 +361,9 @@
                   (e) => checkFileClosedException(e));
     Expect.throws(() => openedFile.writeByteSync(0),
                   (e) => checkFileClosedException(e));
-    Expect.throws(() => openedFile.writeListSync(data, 0, data.length),
+    Expect.throws(() => openedFile.writeFromSync(data, 0, data.length),
                   (e) => checkFileClosedException(e));
-    Expect.throws(() => openedFile.readListSync(data, 0, data.length),
+    Expect.throws(() => openedFile.readIntoSync(data, 0, data.length),
                   (e) => checkFileClosedException(e));
     Expect.throws(() => openedFile.writeStringSync("Hello"),
                   (e) => checkFileClosedException(e));
@@ -380,8 +380,8 @@
 
     var errorCount = 0;
 
-    _errorHandler(e) {
-      checkFileClosedException(e.error);
+    _errorHandler(error) {
+      checkFileClosedException(error);
       if (--errorCount == 0) {
         port.send(null);
       }
@@ -395,12 +395,12 @@
     writeByteFuture.then((ignore) => Expect.fail("Unreachable code"))
     .catchError(_errorHandler);
     errorCount++;
-    var readListFuture = openedFile.readList(data, 0, data.length);
-    readListFuture.then((bytesRead) => Expect.fail("Unreachable code"))
+    var readIntoFuture = openedFile.readInto(data, 0, data.length);
+    readIntoFuture.then((bytesRead) => Expect.fail("Unreachable code"))
     .catchError(_errorHandler);
     errorCount++;
-    var writeListFuture = openedFile.writeList(data, 0, data.length);
-    writeListFuture.then((ignore) => Expect.fail("Unreachable code"))
+    var writeFromFuture = openedFile.writeFrom(data, 0, data.length);
+    writeFromFuture.then((ignore) => Expect.fail("Unreachable code"))
     .catchError(_errorHandler);
     errorCount++;
     var writeStringFuture = openedFile.writeString("Hello");
@@ -436,8 +436,8 @@
     openedFile.close().then((ignore) {
       var closeFuture = openedFile.close();
       closeFuture.then((ignore) => null)
-      .catchError((e) {
-        Expect.isTrue(e.error is FileIOException);
+      .catchError((error) {
+        Expect.isTrue(error is FileIOException);
         port.send(null);
       });
     });
@@ -486,7 +486,7 @@
   testReadAsTextNonExistent();
   testReadAsLinesNonExistent();
   testWriteByteToReadOnlyFile();
-  testWriteListToReadOnlyFile();
+  testWriteFromToReadOnlyFile();
   testTruncateReadOnlyFile();
   testOperateOnClosedFile();
   testRepeatedlyCloseFile();
diff --git a/tests/standalone/io/file_fuzz_test.dart b/tests/standalone/io/file_fuzz_test.dart
index b210bff..3013a01 100644
--- a/tests/standalone/io/file_fuzz_test.dart
+++ b/tests/standalone/io/file_fuzz_test.dart
@@ -80,8 +80,8 @@
       doItSync(() => opened.writeStringSync(p[0], p[1]));
     }
     for (var p in typePermutations(3)) {
-      doItSync(() => opened.readListSync(p[0], p[1], p[2]));
-      doItSync(() => opened.writeListSync(p[0], p[1], p[2]));
+      doItSync(() => opened.readIntoSync(p[0], p[1], p[2]));
+      doItSync(() => opened.writeFromSync(p[0], p[1], p[2]));
     }
     opened.closeSync();
   }
@@ -108,8 +108,8 @@
       futures.add(doItAsync(() => opened.writeString(p[0], p[1])));
     }
     for (var p in typePermutations(3)) {
-      futures.add(doItAsync(() => opened.readList(p[0], p[1], p[2])));
-      futures.add(doItAsync(() => opened.writeList(p[0], p[1], p[2])));
+      futures.add(doItAsync(() => opened.readInto(p[0], p[1], p[2])));
+      futures.add(doItAsync(() => opened.writeFrom(p[0], p[1], p[2])));
     }
   }
   Future.wait(futures).then((ignore) {
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
index 1406290..5f7f73f 100644
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ b/tests/standalone/io/file_invalid_arguments_test.dart
@@ -22,10 +22,10 @@
   var readFuture = file.read(arg);
   readFuture.then((bytes) {
     Expect.fail('exception expected');
-  }).catchError((e) {
+  }).catchError((error) {
     errors++;
-    Expect.isTrue(e.error is FileIOException);
-    Expect.isTrue(e.error.toString().contains('Invalid arguments'));
+    Expect.isTrue(error is FileIOException);
+    Expect.isTrue(error.toString().contains('Invalid arguments'));
     file.close().then((ignore) {
       Expect.equals(1, errors);
       port.close();
@@ -33,12 +33,12 @@
   });
 }
 
-void testReadListInvalidArgs(buffer, offset, length) {
+void testReadIntoInvalidArgs(buffer, start, end) {
   var port = new ReceivePort();
   String filename = getFilename("tests/vm/data/fixed_length_file");
   var file = (new File(filename)).openSync();
   try {
-    file.readListSync(buffer, offset, length);
+    file.readIntoSync(buffer, start, end);
     Expect.fail('exception expected');
   } catch (e) {
     Expect.isTrue(e is FileIOException);
@@ -46,13 +46,13 @@
   }
 
   var errors = 0;
-  var readListFuture = file.readList(buffer, offset, length);
-  readListFuture.then((bytes) {
+  var readIntoFuture = file.readInto(buffer, start, end);
+  readIntoFuture.then((bytes) {
     Expect.fail('exception expected');
-  }).catchError((e) {
+  }).catchError((error) {
     errors++;
-    Expect.isTrue(e.error is FileIOException);
-    Expect.isTrue(e.error.toString().contains('Invalid arguments'));
+    Expect.isTrue(error is FileIOException);
+    Expect.isTrue(error.toString().contains('Invalid arguments'));
     file.close().then((ignore) {
       Expect.equals(1, errors);
       port.close();
@@ -75,33 +75,33 @@
   var writeByteFuture = file.writeByte(value);
   writeByteFuture.then((ignore) {
     Expect.fail('exception expected');
-  }).catchError((s) {
-    Expect.isTrue(s.error is FileIOException);
-    Expect.isTrue(s.error.toString().contains('Invalid argument'));
+  }).catchError((error) {
+    Expect.isTrue(error is FileIOException);
+    Expect.isTrue(error.toString().contains('Invalid argument'));
     file.close().then((ignore) {
       port.close();
     });
   });
 }
 
-void testWriteListInvalidArgs(buffer, offset, bytes) {
+void testWriteFromInvalidArgs(buffer, start, end) {
   var port = new ReceivePort();
   String filename = getFilename("tests/vm/data/fixed_length_file");
   var file = (new File("${filename}_out")).openSync(mode: FileMode.WRITE);
   try {
-    file.writeListSync(buffer, offset, bytes);
+    file.writeFromSync(buffer, start, end);
     Expect.fail('exception expected');
   } catch (e) {
     Expect.isTrue(e is FileIOException);
     Expect.isTrue(e.toString().contains('Invalid arguments'));
   }
 
-  var writeListFuture = file.writeList(buffer, offset, bytes);
-  writeListFuture.then((ignore) {
+  var writeFromFuture = file.writeFrom(buffer, start, end);
+  writeFromFuture.then((ignore) {
     Expect.fail('exception expected');
-  }).catchError((s) {
-    Expect.isTrue(s.error is FileIOException);
-    Expect.isTrue(s.error.toString().contains('Invalid arguments'));
+  }).catchError((error) {
+    Expect.isTrue(error is FileIOException);
+    Expect.isTrue(error.toString().contains('Invalid arguments'));
     file.close().then((ignore) {
       port.close();
     });
@@ -122,8 +122,8 @@
   var writeStringFuture = file.writeString(string, encoding: encoding);
   writeStringFuture.then((ignore) {
     Expect.fail('exception expected');
-  }).catchError((s) {
-    Expect.isTrue(s.error is FileIOException);
+  }).catchError((error) {
+    Expect.isTrue(error is FileIOException);
     file.close().then((ignore) {
       port.close();
     });
@@ -136,12 +136,12 @@
 
 main() {
   testReadInvalidArgs('asdf');
-  testReadListInvalidArgs(12, 0, 1);
-  testReadListInvalidArgs(new List(10), '0', 1);
-  testReadListInvalidArgs(new List(10), 0, '1');
+  testReadIntoInvalidArgs(12, 0, 1);
+  testReadIntoInvalidArgs(new List(10), '0', 1);
+  testReadIntoInvalidArgs(new List(10), 0, '1');
   testWriteByteInvalidArgs('asdf');
-  testWriteListInvalidArgs(12, 0, 1);
-  testWriteListInvalidArgs(new List(10), '0', 1);
-  testWriteListInvalidArgs(new List(10), 0, '1');
+  testWriteFromInvalidArgs(12, 0, 1);
+  testWriteFromInvalidArgs(new List(10), '0', 1);
+  testWriteFromInvalidArgs(new List(10), 0, '1');
   testWriteStringInvalidArgs("Hello, world", 42);
 }
diff --git a/tests/standalone/io/file_system_delete_test.dart b/tests/standalone/io/file_system_delete_test.dart
index 84847bf..cf1d801 100644
--- a/tests/standalone/io/file_system_delete_test.dart
+++ b/tests/standalone/io/file_system_delete_test.dart
@@ -7,7 +7,7 @@
 import "dart:io";
 
 Future throws(callback()) {
-  return new Future.immediate(null)
+  return new Future.value()
     .then((_) => callback())
     .then((_) { throw "Expected error"; },
           onError: (_) {});
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index a4dc4ec..9ca0fe4 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -152,10 +152,12 @@
           }
           position += d.length;
         },
-        onError: (e) {
+        onError: (error) {
           print('Error on input in testReadWriteStreamLargeFile');
-          print('with error $e');
-          throw e;
+          print('with error $error');
+          var trace = getAttachedStackTrace(error);
+          if (trace != null) print("StackTrace: $trace");
+          throw error;
         },
         onDone: () {
           Expect.equals(expectedLength, position);
@@ -167,6 +169,8 @@
               .catchError((e) {
                 print('Exception while deleting ReadWriteStreamLargeFile file');
                 print('Exception $e');
+                var trace = getAttachedStackTrace(e);
+                if (trace != null) print("StackTrace: $trace");
               });
         });
     });
@@ -203,9 +207,9 @@
     File file = new File(filename);
     file.open(mode: READ).then((RandomAccessFile file) {
       List<int> buffer = new List<int>(10);
-      file.readList(buffer, 0, 5).then((bytes_read) {
+      file.readInto(buffer, 0, 5).then((bytes_read) {
         Expect.equals(5, bytes_read);
-        file.readList(buffer, 5, 5).then((bytes_read) {
+        file.readInto(buffer, 5, 10).then((bytes_read) {
           Expect.equals(5, bytes_read);
           Expect.equals(47, buffer[0]);  // represents '/' in the file.
           Expect.equals(47, buffer[1]);  // represents '/' in the file.
@@ -229,9 +233,9 @@
     RandomAccessFile raf = (new File(filename)).openSync();
     List<int> buffer = new List<int>(42);
     int bytes_read = 0;
-    bytes_read = raf.readListSync(buffer, 0, 12);
+    bytes_read = raf.readIntoSync(buffer, 0, 12);
     Expect.equals(12, bytes_read);
-    bytes_read = raf.readListSync(buffer, 12, 30);
+    bytes_read = raf.readIntoSync(buffer, 12, 42);
     Expect.equals(30, bytes_read);
     Expect.equals(47, buffer[0]);  // represents '/' in the file.
     Expect.equals(47, buffer[1]);  // represents '/' in the file.
@@ -265,7 +269,7 @@
     final File file = new File(inFilename);
     file.open(mode: READ).then((openedFile) {
       List<int> buffer1 = new List<int>(42);
-      openedFile.readList(buffer1, 0, 42).then((bytes_read) {
+      openedFile.readInto(buffer1, 0, 42).then((bytes_read) {
         Expect.equals(42, bytes_read);
         openedFile.close().then((ignore) {
           // Write the contents of the file just read into another file.
@@ -278,12 +282,12 @@
                 Expect.fail("Not a full path");
               }
               file2.open(mode: WRITE).then((openedFile2) {
-                openedFile2.writeList(buffer1, 0, bytes_read).then((ignore) {
+                openedFile2.writeFrom(buffer1, 0, bytes_read).then((ignore) {
                   openedFile2.close().then((ignore) {
                     List<int> buffer2 = new List<int>(bytes_read);
                     final File file3 = new File(outFilename);
                     file3.open(mode: READ).then((openedFile3) {
-                      openedFile3.readList(buffer2, 0, 42).then((bytes_read) {
+                      openedFile3.readInto(buffer2, 0, 42).then((bytes_read) {
                         Expect.equals(42, bytes_read);
                         openedFile3.close().then((ignore) {
                           // Now compare the two buffers to check if they
@@ -322,17 +326,17 @@
     Expect.isTrue(new File(filename).existsSync());
     List<int> buffer = content.codeUnits;
     RandomAccessFile openedFile = file.openSync(mode: WRITE);
-    openedFile.writeListSync(buffer, 0, buffer.length);
+    openedFile.writeFromSync(buffer, 0, buffer.length);
     openedFile.closeSync();
     // Reopen the file in write mode to ensure that we overwrite the content.
     openedFile = (new File(filename)).openSync(mode: WRITE);
-    openedFile.writeListSync(buffer, 0, buffer.length);
+    openedFile.writeFromSync(buffer, 0, buffer.length);
     Expect.equals(content.length, openedFile.lengthSync());
     openedFile.closeSync();
     // Open the file in append mode and ensure that we do not overwrite
     // the existing content.
     openedFile = (new File(filename)).openSync(mode: APPEND);
-    openedFile.writeListSync(buffer, 0, buffer.length);
+    openedFile.writeFromSync(buffer, 0, buffer.length);
     Expect.equals(content.length * 2, openedFile.lengthSync());
     openedFile.closeSync();
     file.deleteSync();
@@ -405,7 +409,7 @@
     List<int> buffer1 = new List<int>(42);
     int bytes_read = 0;
     int bytes_written = 0;
-    bytes_read = file.readListSync(buffer1, 0, 42);
+    bytes_read = file.readIntoSync(buffer1, 0, 42);
     Expect.equals(42, bytes_read);
     file.closeSync();
     // Write the contents of the file just read into another file.
@@ -418,12 +422,50 @@
     }
     Expect.isTrue(new File(path).existsSync());
     RandomAccessFile openedFile = outFile.openSync(mode: WRITE);
-    openedFile.writeListSync(buffer1, 0, bytes_read);
+    openedFile.writeFromSync(buffer1, 0, bytes_read);
     openedFile.closeSync();
     // Now read the contents of the file just written.
     List<int> buffer2 = new List<int>(bytes_read);
     openedFile = (new File(outFilename)).openSync();
-    bytes_read = openedFile.readListSync(buffer2, 0, 42);
+    bytes_read = openedFile.readIntoSync(buffer2, 0, 42);
+    Expect.equals(42, bytes_read);
+    openedFile.closeSync();
+    // Now compare the two buffers to check if they are identical.
+    Expect.equals(buffer1.length, buffer2.length);
+    for (int i = 0; i < buffer1.length; i++) {
+      Expect.equals(buffer1[i],  buffer2[i]);
+    }
+    // Delete the output file.
+    outFile.deleteSync();
+    Expect.isFalse(outFile.existsSync());
+  }
+
+  static void testReadWriteNoArgsSync() {
+    // Read a file.
+    String inFilename = getFilename("tests/vm/data/fixed_length_file");
+    RandomAccessFile file = (new File(inFilename)).openSync();
+    List<int> buffer1 = new List<int>(42);
+    int bytes_read = 0;
+    int bytes_written = 0;
+    bytes_read = file.readIntoSync(buffer1);
+    Expect.equals(42, bytes_read);
+    file.closeSync();
+    // Write the contents of the file just read into another file.
+    String outFilename = tempDirectory.path + "/out_read_write_sync";
+    File outFile = new File(outFilename);
+    outFile.createSync();
+    String path = outFile.fullPathSync();
+    if (path[0] != '/' && path[0] != '\\' && path[1] != ':') {
+      Expect.fail("Not a full path");
+    }
+    Expect.isTrue(new File(path).existsSync());
+    RandomAccessFile openedFile = outFile.openSync(mode: WRITE);
+    openedFile.writeFromSync(buffer1);
+    openedFile.closeSync();
+    // Now read the contents of the file just written.
+    List<int> buffer2 = new List<int>(bytes_read);
+    openedFile = (new File(outFilename)).openSync();
+    bytes_read = openedFile.readIntoSync(buffer2, 0);
     Expect.equals(42, bytes_read);
     openedFile.closeSync();
     // Now compare the two buffers to check if they are identical.
@@ -471,18 +513,18 @@
     file.create().then((ignore) {
       file.open(mode: WRITE).then((RandomAccessFile openedFile) {
         // Write bytes from 0 to 7.
-        openedFile.writeList([0], 0, 1);
-        openedFile.writeList(const [1], 0, 1);
-        openedFile.writeList(new MyListOfOneElement(2), 0, 1);
+        openedFile.writeFrom([0], 0, 1);
+        openedFile.writeFrom(const [1], 0, 1);
+        openedFile.writeFrom(new MyListOfOneElement(2), 0, 1);
         var x = 12345678901234567890123456789012345678901234567890;
         var y = 12345678901234567890123456789012345678901234567893;
-        openedFile.writeList([y - x], 0, 1);
-        openedFile.writeList([260], 0, 1);  // 260 = 256 + 4 = 0x104.
-        openedFile.writeList(const [261], 0, 1);
-        openedFile.writeList(new MyListOfOneElement(262), 0, 1);
+        openedFile.writeFrom([y - x], 0, 1);
+        openedFile.writeFrom([260], 0, 1);  // 260 = 256 + 4 = 0x104.
+        openedFile.writeFrom(const [261], 0, 1);
+        openedFile.writeFrom(new MyListOfOneElement(262), 0, 1);
         x = 12345678901234567890123456789012345678901234567890;
         y = 12345678901234567890123456789012345678901234568153;
-        openedFile.writeList([y - x], 0, 1).then((ignore) {
+        openedFile.writeFrom([y - x], 0, 1).then((ignore) {
           openedFile.close().then((ignore) {
             // Check the written bytes.
             final File file2 = new File(fileName);
@@ -490,7 +532,7 @@
             var length = openedFile2.lengthSync();
             Expect.equals(8, length);
             List data = new List(length);
-            openedFile2.readListSync(data, 0, length);
+            openedFile2.readIntoSync(data, 0, length);
             for (var i = 0; i < data.length; i++) {
               Expect.equals(i, data[i]);
             }
@@ -594,10 +636,10 @@
     input.position().then((position) {
       Expect.equals(0, position);
       List<int> buffer = new List<int>(100);
-      input.readList(buffer, 0, 12).then((bytes_read) {
+      input.readInto(buffer, 0, 12).then((bytes_read) {
         input.position().then((position) {
           Expect.equals(12, position);
-          input.readList(buffer, 12, 6).then((bytes_read) {
+          input.readInto(buffer, 12, 18).then((bytes_read) {
             input.position().then((position) {
               Expect.equals(18, position);
               input.setPosition(8).then((ignore) {
@@ -618,9 +660,9 @@
     RandomAccessFile input = (new File(filename)).openSync();
     Expect.equals(0, input.positionSync());
     List<int> buffer = new List<int>(100);
-    input.readListSync(buffer, 0, 12);
+    input.readIntoSync(buffer, 0, 12);
     Expect.equals(12, input.positionSync());
-    input.readListSync(buffer, 12, 6);
+    input.readIntoSync(buffer, 12, 18);
     Expect.equals(18, input.positionSync());
     input.setPositionSync(8);
     Expect.equals(8, input.positionSync());
@@ -631,7 +673,7 @@
     File file = new File(tempDirectory.path + "/out_truncate");
     List buffer = const [65, 65, 65, 65, 65, 65, 65, 65, 65, 65];
     file.open(mode: WRITE).then((RandomAccessFile openedFile) {
-      openedFile.writeList(buffer, 0, 10).then((ignore) {
+      openedFile.writeFrom(buffer, 0, 10).then((ignore) {
         openedFile.length().then((length) {
           Expect.equals(10, length);
           openedFile.truncate(5).then((ignore) {
@@ -657,7 +699,7 @@
     File file = new File(tempDirectory.path + "/out_truncate_sync");
     List buffer = const [65, 65, 65, 65, 65, 65, 65, 65, 65, 65];
     RandomAccessFile openedFile = file.openSync(mode: WRITE);
-    openedFile.writeListSync(buffer, 0, 10);
+    openedFile.writeFromSync(buffer, 0, 10);
     Expect.equals(10, openedFile.lengthSync());
     openedFile.truncateSync(5);
     Expect.equals(5, openedFile.lengthSync());
@@ -705,7 +747,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(100);
-      openedFile.readListSync(buffer, 0, 10);
+      openedFile.readIntoSync(buffer, 0, 10);
     } on FileIOException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -716,7 +758,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(100);
-      openedFile.writeListSync(buffer, 0, 10);
+      openedFile.writeFromSync(buffer, 0, 10);
     } on FileIOException catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -782,7 +824,7 @@
     RandomAccessFile openedFile = file.openSync(mode: WRITE);
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.readListSync(buffer, 0, 12);
+      openedFile.readIntoSync(buffer, 0, 12);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -793,7 +835,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.readListSync(buffer, 6, 6);
+      openedFile.readIntoSync(buffer, 6, 12);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -804,7 +846,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.readListSync(buffer, -1, 1);
+      openedFile.readIntoSync(buffer, -1, 1);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -815,7 +857,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.readListSync(buffer, 0, -1);
+      openedFile.readIntoSync(buffer, 0, -1);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -826,7 +868,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.writeListSync(buffer, 0, 12);
+      openedFile.writeFromSync(buffer, 0, 12);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -837,7 +879,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.writeListSync(buffer, 6, 6);
+      openedFile.writeFromSync(buffer, 6, 12);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -848,7 +890,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.writeListSync(buffer, -1, 1);
+      openedFile.writeFromSync(buffer, -1, 1);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -859,7 +901,7 @@
     exceptionCaught = false;
     try {
       List<int> buffer = new List<int>(10);
-      openedFile.writeListSync(buffer, 0, -1);
+      openedFile.writeFromSync(buffer, 0, -1);
     } on RangeError catch (ex) {
       exceptionCaught = true;
     } on Exception catch (ex) {
@@ -1218,6 +1260,7 @@
     createTempDirectory(() {
       testReadWrite();
       testReadWriteSync();
+      testReadWriteNoArgsSync();
       testReadWriteStream();
       testReadEmptyFileSync();
       testReadEmptyFile();
diff --git a/tests/standalone/io/file_typed_data_test.dart b/tests/standalone/io/file_typed_data_test.dart
index 027c191..2c00cef 100644
--- a/tests/standalone/io/file_typed_data_test.dart
+++ b/tests/standalone/io/file_typed_data_test.dart
@@ -10,18 +10,18 @@
 import 'dart:isolate';
 import 'dart:typeddata';
 
-void testWriteUint8ListAndView() {
+void testWriteInt8ListAndView() {
   ReceivePort port = new ReceivePort();
-  Uint8List list = new Uint8List(8);
+  Int8List list = new Int8List(8);
   for (int i = 0; i < 8; i++) list[i] = i;
-  var view = new Uint8List.view(list.buffer, 2, 4);
+  var view = new Int8List.view(list.buffer, 2, 4);
 
   new Directory('').createTemp().then((temp) {
     var file = new File("${temp.path}/test");
     file.open(mode: FileMode.WRITE).then((raf) {
-      return raf.writeList(list, 0, 8);
+      return raf.writeFrom(list, 0, 8);
     }).then((raf) {
-      return raf.writeList(view, 0, 4);
+      return raf.writeFrom(view, 0, 4);
     }).then((raf) {
       return raf.close();
     }).then((_) {
@@ -37,6 +37,254 @@
 }
 
 
+void testWriteUint8ListAndView() {
+  ReceivePort port = new ReceivePort();
+  Uint8List list = new Uint8List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Uint8List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      Expect.listEquals(expected, content);
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteUint8ClampedListAndView() {
+  ReceivePort port = new ReceivePort();
+  Uint8ClampedList list = new Uint8ClampedList(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Uint8ClampedList.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      Expect.listEquals(expected, content);
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteInt16ListAndView() {
+  ReceivePort port = new ReceivePort();
+  var list = new Int16List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Int16List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      var typed_data_content = new Uint8List(content.length);
+      for (int i = 0; i < content.length; i++) {
+        typed_data_content[i] = content[i];
+      }
+      Expect.listEquals(expected, new Int16List.view(typed_data_content));
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteUint16ListAndView() {
+  ReceivePort port = new ReceivePort();
+  var list = new Uint16List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Uint16List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      var typed_data_content = new Uint8List(content.length);
+      for (int i = 0; i < content.length; i++) {
+        typed_data_content[i] = content[i];
+      }
+      Expect.listEquals(expected, new Uint16List.view(typed_data_content));
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteInt32ListAndView() {
+  ReceivePort port = new ReceivePort();
+  var list = new Int32List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Int32List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      var typed_data_content = new Uint8List(content.length);
+      for (int i = 0; i < content.length; i++) {
+        typed_data_content[i] = content[i];
+      }
+      Expect.listEquals(expected, new Int32List.view(typed_data_content));
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteUint32ListAndView() {
+  ReceivePort port = new ReceivePort();
+  var list = new Uint32List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Uint32List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      var typed_data_content = new Uint8List(content.length);
+      for (int i = 0; i < content.length; i++) {
+        typed_data_content[i] = content[i];
+      }
+      Expect.listEquals(expected, new Uint32List.view(typed_data_content));
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteInt64ListAndView() {
+  ReceivePort port = new ReceivePort();
+  var list = new Int64List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Int64List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+        //      return raf.writeList(view, 0, 4);
+        //}).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      //expected.addAll(view);
+      var content = file.readAsBytesSync();
+      var typed_data_content = new Uint8List(content.length);
+      for (int i = 0; i < content.length; i++) {
+        typed_data_content[i] = content[i];
+      }
+      Expect.listEquals(expected, new Int64List.view(typed_data_content));
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
+void testWriteUint64ListAndView() {
+  ReceivePort port = new ReceivePort();
+  var list = new Uint64List(8);
+  for (int i = 0; i < 8; i++) list[i] = i;
+  var view = new Uint64List.view(list.buffer, 2, 4);
+
+  new Directory('').createTemp().then((temp) {
+    var file = new File("${temp.path}/test");
+    file.open(mode: FileMode.WRITE).then((raf) {
+      return raf.writeFrom(list, 0, 8);
+    }).then((raf) {
+      return raf.writeFrom(view, 0, 4);
+    }).then((raf) {
+      return raf.close();
+    }).then((_) {
+      var expected = [];
+      expected.addAll(list);
+      expected.addAll(view);
+      var content = file.readAsBytesSync();
+      var typed_data_content = new Uint8List(content.length);
+      for (int i = 0; i < content.length; i++) {
+        typed_data_content[i] = content[i];
+      }
+      Expect.listEquals(expected, new Uint64List.view(typed_data_content));
+      temp.deleteSync(recursive: true);
+      port.close();
+    });
+  });
+}
+
+
 main() {
+  testWriteInt8ListAndView();
   testWriteUint8ListAndView();
+  testWriteUint8ClampedListAndView();
+  testWriteInt16ListAndView();
+  testWriteUint16ListAndView();
+  testWriteInt32ListAndView();
+  testWriteUint32ListAndView();
+  testWriteInt64ListAndView();
+  testWriteUint64ListAndView();
 }
diff --git a/tests/standalone/io/http_10_test.dart b/tests/standalone/io/http_10_test.dart
index 0c79981..9250a36 100644
--- a/tests/standalone/io/http_10_test.dart
+++ b/tests/standalone/io/http_10_test.dart
@@ -8,6 +8,7 @@
 // VMOptions=--short_socket_read --short_socket_write
 
 import "package:expect/expect.dart";
+import "dart:async";
 import "dart:isolate";
 import "dart:io";
 
@@ -25,14 +26,19 @@
           Expect.equals("1.0", request.protocolVersion);
           response.done
               .then((_) => Expect.fail("Unexpected response completion"))
-              .catchError((e) => Expect.isTrue(e.error is HttpException));
+              .catchError((error) => Expect.isTrue(error is HttpException));
           response.write("Z");
           response.write("Z");
           response.close();
           Expect.throws(() => response.write("x"),
                         (e) => e is StateError);
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
 
     int count = 0;
     makeRequest() {
@@ -77,7 +83,12 @@
             response.close();
           });
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
 
     int count = 0;
     makeRequest() {
@@ -124,7 +135,12 @@
           response.write("Z");
           response.close();
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
 
     Socket.connect("127.0.0.1", server.port).then((socket) {
       void sendRequest() {
@@ -174,7 +190,12 @@
           response.write("Z");
           response.close();
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
 
     int count = 0;
     makeRequest() {
diff --git a/tests/standalone/io/http_auth_test.dart b/tests/standalone/io/http_auth_test.dart
index bd5e2c0..ef400f4 100644
--- a/tests/standalone/io/http_auth_test.dart
+++ b/tests/standalone/io/http_auth_test.dart
@@ -220,7 +220,7 @@
         Uri.parse("http://127.0.0.1/basic"),
         "test",
         new HttpClientBasicCredentials("test", "test"));
-    return new Future.immediate(true);
+    return new Future.value(true);
   };
 
   HttpClientConnection conn =
@@ -243,7 +243,7 @@
         Uri.parse("http://127.0.0.1/digest"),
         "test",
         new HttpClientDigestCredentials("test", "test"));
-    return new Future.immediate(true);
+    return new Future.value(true);
   };
 
   HttpClientConnection conn =
diff --git a/tests/standalone/io/http_body_test.dart b/tests/standalone/io/http_body_test.dart
index c25406e..ae0d128 100644
--- a/tests/standalone/io/http_body_test.dart
+++ b/tests/standalone/io/http_body_test.dart
@@ -98,13 +98,20 @@
             Expect.equals(type, body.type);
             switch (type) {
               case "text":
+                Expect.equals(body.mimeType, "text/plain");
                 Expect.equals(expectedBody, body.body);
                 break;
 
               case "json":
+                Expect.equals(body.mimeType, "application/json");
                 Expect.mapEquals(expectedBody, body.body);
                 break;
 
+              case "binary":
+                Expect.equals(body.mimeType, null);
+                Expect.listEquals(expectedBody, body.body);
+                break;
+
               default:
                 Expect.fail("bad body type");
             }
@@ -116,8 +123,10 @@
       var client = new HttpClient();
       client.post("127.0.0.1", server.port, "/")
           .then((request) {
-            request.headers.contentType =
-                new ContentType.fromString(mimeType);
+            if (mimeType != null) {
+              request.headers.contentType =
+                  new ContentType.fromString(mimeType);
+            }
             request.add(content);
             return request.close();
           })
@@ -152,6 +161,8 @@
        null,
        "json",
        true);
+
+  test(null, "body".codeUnits, "body".codeUnits, "binary");
 }
 
 
diff --git a/tests/standalone/io/http_content_length_test.dart b/tests/standalone/io/http_content_length_test.dart
index c42b8d3..4efd9af 100644
--- a/tests/standalone/io/http_content_length_test.dart
+++ b/tests/standalone/io/http_content_length_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "dart:async";
 import "dart:isolate";
 import "dart:io";
 
@@ -19,8 +20,8 @@
             .then((_) {
               Expect.fail("Unexpected successful response completion");
             })
-            .catchError((e) {
-              Expect.isTrue(e.error is HttpException);
+            .catchError((error) {
+              Expect.isTrue(error is HttpException);
             });
           // write with content length 0 closes the connection and
           // reports an error.
@@ -35,7 +36,10 @@
                         (e) => e is StateError);
         },
         onError: (e) {
-          Expect.fail("Unexpected server error $e");
+          String msg = "Unexpected server error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
         });
 
     int count = 0;
@@ -61,8 +65,11 @@
                 });
           })
           .catchError((e) {
-            Expect.fail("Unexpected error $e");
-          });
+            String msg = "Unexpected error $e";
+            var trace = getAttachedStackTrace(e);
+            if (trace != null) msg += "\nStackTrace: $trace";
+            Expect.fail(msg);
+         });
     }
   });
 }
@@ -92,8 +99,8 @@
                     .then((_) {
                       Expect.fail("Unexpected successful response completion");
                     })
-                    .catchError((e) {
-                      Expect.isTrue(e.error is HttpException, "[$e]");
+                    .catchError((error) {
+                      Expect.isTrue(error is HttpException, "[$error]");
                       if (++serverCount == totalConnections) {
                         server.close();
                       }
@@ -103,7 +110,12 @@
                               (e) => e is StateError);
               });
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
 
     int clientCount = 0;
     HttpClient client = new HttpClient();
@@ -168,7 +180,12 @@
                               (e) => e is StateError);
               });
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
 
     int count = 0;
     HttpClient client = new HttpClient();
@@ -201,7 +218,12 @@
                   }
                 });
           })
-          .catchError((e) => Expect.fail("Unexpected error $e"));
+          .catchError((e) {
+            String msg = "Unexpected error $e";
+            var trace = getAttachedStackTrace(e);
+            if (trace != null) msg += "\nStackTrace: $trace";
+            Expect.fail(msg);
+          });
     }
   });
 }
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index 3f2d0cf..e3dc5ba 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -4,8 +4,10 @@
 
 import "package:expect/expect.dart";
 import "dart:async";
+import 'dart:crypto';
 import "dart:io";
 import "dart:uri";
+import 'dart:utf';
 
 class Server {
   HttpServer server;
@@ -48,8 +50,10 @@
             },
             onDone: () {
               String path = request.uri.path.substring(1);
-              String content = "$path$path$path";
-              Expect.equals(content, body.toString());
+              if (path != "A") {
+                String content = "$path$path$path";
+                Expect.equals(content, body.toString());
+              }
               response.write(request.uri.path);
               response.close();
             });
@@ -76,9 +80,21 @@
   HttpServer server;
   HttpClient client;
   int requestCount = 0;
+  String username;
+  String password;
 
   ProxyServer() : client = new HttpClient();
 
+  authenticationRequired(request) {
+    request.fold(null, (x, y) {}).then((_) {
+      var response = request.response;
+      response.headers.set(HttpHeaders.PROXY_AUTHENTICATE,
+                           "Basic, realm=realm");
+      response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED;
+      response.close();
+    });
+  }
+
   Future<ProxyServer> start() {
     var x = new Completer();
     HttpServer.bind().then((s) {
@@ -86,6 +102,25 @@
       x.complete(this);
       server.listen((HttpRequest request) {
         requestCount++;
+        if (username != null && password != null) {
+          if (request.headers[HttpHeaders.PROXY_AUTHORIZATION] == null) {
+            authenticationRequired(request);
+            return;
+          } else {
+            Expect.equals(
+                1, request.headers[HttpHeaders.PROXY_AUTHORIZATION].length);
+            String authorization =
+              request.headers[HttpHeaders.PROXY_AUTHORIZATION][0];
+            List<String> tokens = authorization.split(" ");
+            Expect.equals("Basic", tokens[0]);
+            String auth =
+                CryptoUtils.bytesToBase64(encodeUtf8("$username:$password"));
+            if (auth != tokens[1]) {
+              authenticationRequired(request);
+              return;
+            }
+          }
+        }
         // Open the connection from the proxy.
         client.openUrl(request.method, request.uri)
           .then((HttpClientRequest clientRequest) {
@@ -362,10 +397,151 @@
   });
 }
 
+
+int testProxyAuthenticateCount = 0;
+void testProxyAuthenticate() {
+  setupProxyServer().then((proxyServer) {
+  proxyServer.username = "test";
+  proxyServer.password = "test";
+  setupServer(1).then((server) {
+  setupServer(1, secure: true).then((secureServer) {
+    HttpClient client = new HttpClient();
+
+    Completer step1 = new Completer();
+    Completer step2 = new Completer();
+
+    // Test with no authentication.
+    client.findProxy = (Uri uri) {
+      return "PROXY localhost:${proxyServer.port}";
+    };
+
+    const int loopCount = 2;
+    for (int i = 0; i < loopCount; i++) {
+      test(bool secure) {
+        String url = secure
+            ? "https://localhost:${secureServer.port}/$i"
+            : "http://127.0.0.1:${server.port}/$i";
+
+        client.postUrl(Uri.parse(url))
+          .then((HttpClientRequest clientRequest) {
+            String content = "$i$i$i";
+            clientRequest.write(content);
+            return clientRequest.close();
+          })
+          .then((HttpClientResponse response) {
+            response.listen((_) {}, onDone: () {
+              testProxyAuthenticateCount++;
+              Expect.equals(HttpStatus.PROXY_AUTHENTICATION_REQUIRED,
+                            response.statusCode);
+              if (testProxyAuthenticateCount == loopCount * 2) {
+                Expect.equals(0, server.requestCount);
+                Expect.equals(0, secureServer.requestCount);
+                step1.complete(null);
+              }
+            });
+          });
+      }
+
+      test(false);
+      test(true);
+    }
+
+    step1.future.then((_) {
+      testProxyAuthenticateCount = 0;
+      client.findProxy = (Uri uri) {
+        return "PROXY test:test@localhost:${proxyServer.port}";
+      };
+
+      for (int i = 0; i < loopCount; i++) {
+        test(bool secure) {
+          String url = secure
+              ? "https://localhost:${secureServer.port}/$i"
+              : "http://127.0.0.1:${server.port}/$i";
+
+          client.postUrl(Uri.parse(url))
+            .then((HttpClientRequest clientRequest) {
+              String content = "$i$i$i";
+              clientRequest.write(content);
+              return clientRequest.close();
+            })
+            .then((HttpClientResponse response) {
+              response.listen((_) {}, onDone: () {
+                testProxyAuthenticateCount++;
+                Expect.equals(HttpStatus.OK, response.statusCode);
+                if (testProxyAuthenticateCount == loopCount * 2) {
+                  Expect.equals(loopCount, server.requestCount);
+                  Expect.equals(loopCount, secureServer.requestCount);
+                  step2.complete(null);
+                }
+              });
+            });
+        }
+
+        test(false);
+        test(true);
+      }
+    });
+
+    step2.future.then((_) {
+      testProxyAuthenticateCount = 0;
+      client.findProxy = (Uri uri) {
+        return "PROXY localhost:${proxyServer.port}";
+      };
+
+      client.authenticateProxy = (host, port, scheme, realm) {
+        client.addProxyCredentials(
+            "localhost",
+            proxyServer.port,
+            "realm",
+            new HttpClientBasicCredentials("test", "test"));
+        return new Future.value(true);
+      };
+
+      for (int i = 0; i < loopCount; i++) {
+        test(bool secure) {
+          String url = secure
+              ? "https://localhost:${secureServer.port}/A"
+              : "http://127.0.0.1:${server.port}/A";
+
+          client.postUrl(Uri.parse(url))
+            .then((HttpClientRequest clientRequest) {
+              String content = "$i$i$i";
+              clientRequest.write(content);
+              return clientRequest.close();
+            })
+            .then((HttpClientResponse response) {
+              response.listen((_) {}, onDone: () {
+                testProxyAuthenticateCount++;
+                Expect.equals(HttpStatus.OK, response.statusCode);
+                if (testProxyAuthenticateCount == loopCount * 2) {
+                  Expect.equals(loopCount * 2, server.requestCount);
+                  Expect.equals(loopCount * 2, secureServer.requestCount);
+                  proxyServer.shutdown();
+                  server.shutdown();
+                  secureServer.shutdown();
+                  client.close();
+                }
+              });
+            });
+        }
+        test(false);
+        test(true);
+      }
+    });
+
+  });
+  });
+  });
+}
+
 int testRealProxyDoneCount = 0;
 void testRealProxy() {
   setupServer(1).then((server) {
     HttpClient client = new HttpClient();
+     client.addProxyCredentials("localhost",
+                                8080,
+                                "test",
+                                new HttpClientBasicCredentials("test", "test"));
 
     List<String> proxy =
         ["PROXY localhost:8080",
@@ -389,8 +565,45 @@
         })
         .then((HttpClientResponse response) {
           response.listen((_) {}, onDone: () {
-            testRealProxyDoneCount++;
-            if (testRealProxyDoneCount == proxy.length) {
+            if (++testRealProxyDoneCount == proxy.length) {
+              Expect.equals(proxy.length, server.requestCount);
+              server.shutdown();
+              client.close();
+            }
+          });
+        });
+    }
+  });
+}
+
+int testRealProxyAuthDoneCount = 0;
+void testRealProxyAuth() {
+  setupServer(1).then((server) {
+    HttpClient client = new HttpClient();
+
+    List<String> proxy =
+        ["PROXY test:test@localhost:8080",
+         "PROXY test:test@localhost:8080; PROXY hede.hule.hest:8080",
+         "PROXY hede.hule.hest:8080; PROXY test:test@localhost:8080",
+         "PROXY test:test@localhost:8080; DIRECT"];
+
+    client.findProxy = (Uri uri) {
+      // Pick the proxy configuration based on the request path.
+      int index = int.parse(uri.path.substring(1));
+      return proxy[index];
+    };
+
+    for (int i = 0; i < proxy.length; i++) {
+      client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/$i"))
+        .then((HttpClientRequest clientRequest) {
+          String content = "$i$i$i";
+          clientRequest.contentLength = content.length;
+          clientRequest.write(content);
+          return clientRequest.close();
+        })
+        .then((HttpClientResponse response) {
+          response.listen((_) {}, onDone: () {
+            if (++testRealProxyAuthDoneCount == proxy.length) {
               Expect.equals(proxy.length, server.requestCount);
               server.shutdown();
               client.close();
@@ -415,7 +628,9 @@
   testProxy();
   testProxyChain();
   testProxyFromEnviroment();
+  testProxyAuthenticate();
   // This test is not normally run. It can be used for locally testing
   // with a real proxy server (e.g. Apache).
   //testRealProxy();
+  //testRealProxyAuth();
 }
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index f146083..adcd6c3 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -329,8 +329,8 @@
 
     client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/1"))
       .then((HttpClientRequest request) => request.close())
-      .catchError((e) {
-        Expect.equals(5, e.error.redirects.length);
+      .catchError((error) {
+        Expect.equals(5, error.redirects.length);
         server.close();
         client.close();
       }, test: (e) => e is RedirectLimitExceededException);
@@ -344,8 +344,8 @@
     int redirectCount = 0;
     client.getUrl(Uri.parse("http://127.0.0.1:${server.port}/A"))
       .then((HttpClientRequest request) => request.close())
-      .catchError((e) {
-        Expect.equals(2, e.error.redirects.length);
+      .catchError((error) {
+        Expect.equals(2, error.redirects.length);
         server.close();
         client.close();
       }, test: (e) => e is RedirectLoopException);
diff --git a/tests/standalone/io/http_server_early_client_close_test.dart b/tests/standalone/io/http_server_early_client_close_test.dart
index 5a58899..aade9d2 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -39,17 +39,17 @@
           calledOnRequest = true;
           request.listen(
               (_) {},
-              onError: (e) {
+              onError: (error) {
                 Expect.isFalse(calledOnError);
-                Expect.equals(exception, e.error.message);
+                Expect.equals(exception, error.message);
                 calledOnError = true;
                 port.close();
                 c.complete(null);
               });
         },
-        onError: (e) {
+        onError: (error) {
           Expect.isFalse(calledOnError);
-          Expect.equals(exception, e.error.message);
+          Expect.equals(exception, error.message);
           Expect.equals(expectRequest, calledOnRequest);
           calledOnError = true;
           port.close();
diff --git a/tests/standalone/io/http_server_early_server_close_test.dart b/tests/standalone/io/http_server_early_server_close_test.dart
index d5de5d9..2a1c3db 100644
--- a/tests/standalone/io/http_server_early_server_close_test.dart
+++ b/tests/standalone/io/http_server_early_server_close_test.dart
@@ -13,7 +13,10 @@
       server.listen((HttpRequest request) {
             Timer.run(server.close);
           }, onError: (e) {
-            Expect.fail("No server errors expected: $e");
+            String msg = "No server errors expected: $e";
+            var trace = getAttachedStackTrace(e);
+            if (trace != null) msg += "\nStackTrace: $trace";
+            Expect.fail(msg);
           });
       return server.port;
     });
diff --git a/tests/standalone/io/http_server_response_test.dart b/tests/standalone/io/http_server_response_test.dart
index 51ad60d..ac019c8 100644
--- a/tests/standalone/io/http_server_response_test.dart
+++ b/tests/standalone/io/http_server_response_test.dart
@@ -33,7 +33,7 @@
               client.close();
             },
             onError: (error) {
-              Expect.isTrue(error.error is HttpParserException);
+              Expect.isTrue(error is HttpParserException);
             });
       })
       .catchError((error) {
@@ -50,13 +50,28 @@
       server.close();
     });
   });
+
+  testServerRequest((server, request) {
+    new File("__not_exitsing_file_").openRead().pipe(request.response)
+        .catchError((e) {
+          server.close();
+        });
+  });
+
+  testServerRequest((server, request) {
+    request.response.done.then((_) {
+      server.close();
+    });
+    request.response.contentLength = 0;
+    request.response.close();
+  });
 }
 
 void testResponseAddStream() {
   int bytes = new File(new Options().script).lengthSync();
 
   testServerRequest((server, request) {
-    request.response.writeStream(new File(new Options().script).openRead())
+    request.response.addStream(new File(new Options().script).openRead())
         .then((response) {
           response.close();
           response.done.then((_) => server.close());
@@ -64,9 +79,9 @@
   }, bytes: bytes);
 
   testServerRequest((server, request) {
-    request.response.writeStream(new File(new Options().script).openRead())
+    request.response.addStream(new File(new Options().script).openRead())
         .then((response) {
-          request.response.writeStream(new File(new Options().script).openRead())
+          request.response.addStream(new File(new Options().script).openRead())
               .then((response) {
                 response.close();
                 response.done.then((_) => server.close());
@@ -76,13 +91,27 @@
 
   testServerRequest((server, request) {
     var controller = new StreamController();
-    request.response.writeStream(controller.stream)
+    request.response.addStream(controller.stream)
         .then((response) {
           response.close();
           response.done.then((_) => server.close());
         });
     controller.close();
   }, bytes: 0);
+
+  testServerRequest((server, request) {
+    request.response.addStream(new File("__not_exitsing_file_").openRead())
+        .catchError((e) {
+          server.close();
+        });
+  });
+
+  testServerRequest((server, request) {
+    new File("__not_exitsing_file_").openRead().pipe(request.response)
+        .catchError((e) {
+          server.close();
+        });
+  });
 }
 
 void testBadResponseAdd() {
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index 4724467..bd8362e 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "dart:async";
 import "dart:io";
 import "dart:isolate";
 
@@ -29,8 +30,11 @@
             onDone();
           });
       })
-      .catchError((error) {
-        Expect.fail("Unexpected error in Http Client: $error");
+      .catchError((e) {
+        String msg = "Unexpected error in Http Client: $e";
+        var trace = getAttachedStackTrace(e);
+        if (trace != null) msg += "\nStackTrace: $trace";
+        Expect.fail(msg);
       });
   }
 
diff --git a/tests/standalone/io/https_server_test.dart b/tests/standalone/io/https_server_test.dart
index 490152e..fbefbeb 100644
--- a/tests/standalone/io/https_server_test.dart
+++ b/tests/standalone/io/https_server_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
+import "dart:async";
 import "dart:io";
 import "dart:uri";
 import "dart:isolate";
@@ -43,8 +44,11 @@
                 onDone();
               });
         })
-        .catchError((error) {
-          Expect.fail("Unexpected error in Https client: $error");
+        .catchError((e) {
+          String msg = "Unexpected error in Https client: $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
         });
     });
   }
diff --git a/tests/standalone/io/io_sink_test.dart b/tests/standalone/io/io_sink_test.dart
new file mode 100644
index 0000000..1c96448
--- /dev/null
+++ b/tests/standalone/io/io_sink_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import "dart:async";
+import "dart:io";
+import "dart:isolate";
+
+class TestConsumer implements StreamConsumer {
+  final List expected;
+  final List received = [];
+
+  var closePort;
+
+  int addStreamCount = 0;
+  int expcetedAddStreamCount;
+
+  TestConsumer(this.expected,
+               {close: true,
+                this.expcetedAddStreamCount: -1}) {
+    if (close) closePort = new ReceivePort();
+  }
+
+  Future addStream(Stream stream) {
+    addStreamCount++;
+    return stream.fold(
+        received,
+        (list, value) {
+          list.addAll(value);
+          return list;
+        })
+        .then((_) {});
+  }
+
+  Future close() {
+    return new Future.value()
+      .then((_) {
+        if (closePort != null) closePort.close();
+        Expect.listEquals(expected, received);
+        if (expcetedAddStreamCount >= 0) {
+          Expect.equals(expcetedAddStreamCount, addStreamCount);
+        }
+      });
+  }
+}
+
+void testClose() {
+  var sink = new IOSink(new TestConsumer([], expcetedAddStreamCount: 0));
+  sink.close();
+}
+
+void testAddClose() {
+  var sink = new IOSink(new TestConsumer([0]));
+  sink.add([0]);
+  sink.close();
+
+  sink = new IOSink(new TestConsumer([0, 1, 2]));
+  sink.add([0]);
+  sink.add([1]);
+  sink.add([2]);
+  sink.close();
+}
+
+void testAddStreamClose() {
+  {
+    var sink = new IOSink(new TestConsumer([0]));
+    var controller = new StreamController();
+    sink.addStream(controller.stream)
+        .then((_) {
+          sink.close();
+        });
+    controller.add([0]);
+    controller.close();
+  }
+  {
+    var sink = new IOSink(new TestConsumer([0, 1, 2]));
+    var controller = new StreamController();
+    sink.addStream(controller.stream)
+        .then((_) {
+          sink.close();
+        });
+    controller.add([0]);
+    controller.add([1]);
+    controller.add([2]);
+    controller.close();
+  }
+}
+
+void testAddStreamAddClose() {
+  {
+    var sink = new IOSink(new TestConsumer([0, 1]));
+    var controller = new StreamController();
+    sink.addStream(controller.stream)
+        .then((_) {
+          sink.add([1]);
+          sink.close();
+        });
+    controller.add([0]);
+    controller.close();
+  }
+}
+
+void main() {
+  testClose();
+  testAddClose();
+  testAddStreamClose();
+  testAddStreamAddClose();
+}
diff --git a/tests/standalone/io/process_start_exception_test.dart b/tests/standalone/io/process_start_exception_test.dart
index f7a0a66..a1f891e 100644
--- a/tests/standalone/io/process_start_exception_test.dart
+++ b/tests/standalone/io/process_start_exception_test.dart
@@ -13,9 +13,9 @@
       Process.start("__path_to_something_that_should_not_exist__",
                     const []);
   processFuture.then((p) => Expect.fail('got process despite start error'))
-  .catchError((e) {
-    Expect.isTrue(e.error is ProcessException);
-    Expect.equals(2, e.error.errorCode, e.error.toString());
+  .catchError((error) {
+    Expect.isTrue(error is ProcessException);
+    Expect.equals(2, error.errorCode, error.toString());
   });
 }
 
@@ -25,9 +25,9 @@
                   const []);
 
   processFuture.then((result) => Expect.fail("exit handler called"))
-  .catchError((e) {
-    Expect.isTrue(e.error is ProcessException);
-    Expect.equals(2, e.error.errorCode, e.error.toString());
+  .catchError((error) {
+    Expect.isTrue(error is ProcessException);
+    Expect.equals(2, error.errorCode, error.toString());
   });
 }
 
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index 3b3079c..cc8a86e 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -42,16 +42,16 @@
   // Bind to a unknown DNS name.
   RawSecureServerSocket.bind("ko.faar.__hest__", 0, 5, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
-  }).catchError((e) {
-    Expect.isTrue(e.error is SocketIOException);
+  }).catchError((error) {
+    Expect.isTrue(error is SocketIOException);
     port.toSendPort().send(1);
   });
 
   // Bind to an unavaliable IP-address.
   RawSecureServerSocket.bind("8.8.8.8", 0, 5, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
-  }).catchError((e) {
-    Expect.isTrue(e.error is SocketIOException);
+  }).catchError((error) {
+    Expect.isTrue(error is SocketIOException);
     port.toSendPort().send(1);
   });
 
@@ -70,9 +70,9 @@
       t.close();
       port.toSendPort().send(1);
     })
-    .catchError((e) {
+    .catchError((error) {
       Expect.notEquals('windows', Platform.operatingSystem);
-      Expect.isTrue(e.error is SocketIOException);
+      Expect.isTrue(error is SocketIOException);
       s.close();
       port.toSendPort().send(1);
     });
@@ -101,16 +101,14 @@
       .then((clientEnd) {
         Expect.fail("No client connection expected.");
       })
-      .catchError((e) {
-        Expect.isTrue(e is AsyncError);
-        Expect.isTrue(e.error is SocketIOException);
+      .catchError((error) {
+        Expect.isTrue(error is SocketIOException);
       });
     server.listen((serverEnd) {
       Expect.fail("No server connection expected.");
     },
-    onError: (e) {
-      Expect.isTrue(e is AsyncError);
-      Expect.isTrue(e.error is SocketIOException);
+    onError: (error) {
+      Expect.isTrue(error is SocketIOException);
       clientEndFuture.then((_) => port.close());
     });
   });
@@ -173,7 +171,7 @@
             Expect.isTrue(client.available() > 0);
             var buffer = client.read();
             if (buffer != null) {
-              data.setRange(bytesRead, buffer.length, buffer);
+              data.setRange(bytesRead, bytesRead + buffer.length, buffer);
               bytesRead += buffer.length;
               for (var value in buffer) {
                 Expect.isTrue(value is int);
@@ -220,7 +218,8 @@
             Expect.isTrue(socket.available() > 0);
             var buffer = socket.read();
             if (buffer != null) {
-              dataReceived.setRange(bytesRead, buffer.length, buffer);
+              int endIndex = bytesRead + buffer.length;
+              dataReceived.setRange(bytesRead, endIndex, buffer);
               bytesRead += buffer.length;
             }
             break;
diff --git a/tests/standalone/io/raw_secure_socket_pause_test.dart b/tests/standalone/io/raw_secure_socket_pause_test.dart
index d703112..cfd93cb 100644
--- a/tests/standalone/io/raw_secure_socket_pause_test.dart
+++ b/tests/standalone/io/raw_secure_socket_pause_test.dart
@@ -100,8 +100,11 @@
               default: throw "Unexpected event $event";
             }
           },
-          onError: (AsyncError a) {
-            Expect.fail("onError handler of RawSecureSocket stream hit: $a");
+          onError: (e) {
+            String msg = "onError handler of RawSecureSocket stream hit: $e";
+            var trace = getAttachedStackTrace(e);
+            if (trace != null) msg += "\nStackTrace: $trace";
+            Expect.fail(msg);
           });
     });
   });
diff --git a/tests/standalone/io/raw_secure_socket_test.dart b/tests/standalone/io/raw_secure_socket_test.dart
index 02254b4..33b092f 100644
--- a/tests/standalone/io/raw_secure_socket_test.dart
+++ b/tests/standalone/io/raw_secure_socket_test.dart
@@ -71,8 +71,11 @@
               default: throw "Unexpected event $event";
             }
           },
-          onError: (AsyncError a) {
-            Expect.fail("onError handler of RawSecureSocket stream hit: $a");
+          onError: (e) {
+            String msg = "onError handler of RawSecureSocket stream hit $e";
+            var trace = getAttachedStackTrace(e);
+            if (trace != null) msg += "\nStackTrace: $trace";
+            Expect.fail(msg);
           });
     });
   });
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index b619668..23fc6a5 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -34,16 +34,16 @@
   // Bind to a unknown DNS name.
   RawServerSocket.bind("ko.faar.__hest__")
       .then((_) { Expect.fail("Failure expected"); } )
-      .catchError((e) {
-        Expect.isTrue(e.error is SocketIOException);
+      .catchError((error) {
+        Expect.isTrue(error is SocketIOException);
         port.toSendPort().send(1);
       });
 
   // Bind to an unavaliable IP-address.
   RawServerSocket.bind("8.8.8.8")
       .then((_) { Expect.fail("Failure expected"); } )
-      .catchError((e) {
-        Expect.isTrue(e.error is SocketIOException);
+      .catchError((error) {
+        Expect.isTrue(error is SocketIOException);
         port.toSendPort().send(1);
       });
 
@@ -59,9 +59,9 @@
               Expect.equals(s.port, t.port);
               port.toSendPort().send(1);
             })
-            .catchError((e) {
+            .catchError((error) {
               Expect.notEquals('windows', Platform.operatingSystem);
-              Expect.isTrue(e.error is SocketIOException);
+              Expect.isTrue(error is SocketIOException);
               port.toSendPort().send(1);
             });
       });
@@ -166,7 +166,7 @@
             Expect.isTrue(bytesWritten == 0);
             Expect.isTrue(client.available() > 0);
             var buffer = client.read();
-            data.setRange(bytesRead, buffer.length, buffer);
+            data.setRange(bytesRead, bytesRead + buffer.length, buffer);
             bytesRead += buffer.length;
             if (bytesRead == data.length) {
               verifyTestData(data);
@@ -202,7 +202,7 @@
           case RawSocketEvent.READ:
             Expect.isTrue(socket.available() > 0);
             var buffer = socket.read();
-            data.setRange(bytesRead, buffer.length, buffer);
+            data.setRange(bytesRead, bytesRead + buffer.length, buffer);
             bytesRead += buffer.length;
             break;
           case RawSocketEvent.WRITE:
diff --git a/tests/standalone/io/read_into_const_list_test.dart b/tests/standalone/io/read_into_const_list_test.dart
index e1ed587..5bc1c6b 100644
--- a/tests/standalone/io/read_into_const_list_test.dart
+++ b/tests/standalone/io/read_into_const_list_test.dart
@@ -20,7 +20,7 @@
   File file = new File(filename);
   file.open().then((input) {
       try {
-        input.readListSync(a, 0, 1);
+        input.readIntoSync(a, 0, 1);
         Expect.fail("no exception thrown");
       } catch (e) {
         Expect.isTrue(e is UnsupportedError);
diff --git a/tests/standalone/io/secure_no_builtin_roots_database_test.dart b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
index 078ba70..8c647d0 100644
--- a/tests/standalone/io/secure_no_builtin_roots_database_test.dart
+++ b/tests/standalone/io/secure_no_builtin_roots_database_test.dart
@@ -15,8 +15,7 @@
       .then((request) => request.close())
       .then((response) => Expect.fail("Unexpected successful connection"))
       .catchError((error) {
-        Expect.isTrue(error is AsyncError);
-        Expect.isTrue(error.error is SocketIOException);
+        Expect.isTrue(error is SocketIOException);
         keepAlive.close();
         client.close();
       });
diff --git a/tests/standalone/io/secure_no_builtin_roots_test.dart b/tests/standalone/io/secure_no_builtin_roots_test.dart
index a93404c..c411e62 100644
--- a/tests/standalone/io/secure_no_builtin_roots_test.dart
+++ b/tests/standalone/io/secure_no_builtin_roots_test.dart
@@ -15,8 +15,7 @@
       .then((request) => request.close())
       .then((response) => Expect.fail("Unexpected successful connection"))
       .catchError((error) {
-        Expect.isTrue(error is AsyncError);
-        Expect.isTrue(error.error is SocketIOException);
+        Expect.isTrue(error is SocketIOException);
         keepAlive.close();
         client.close();
       });
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index da71e0d..dbe0355 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -42,16 +42,16 @@
   // Bind to a unknown DNS name.
   SecureServerSocket.bind("ko.faar.__hest__", 0, 5, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
-  }).catchError((e) {
-    Expect.isTrue(e.error is SocketIOException);
+  }).catchError((error) {
+    Expect.isTrue(error is SocketIOException);
     port.toSendPort().send(1);
   });
 
   // Bind to an unavaliable IP-address.
   SecureServerSocket.bind("8.8.8.8", 0, 5, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
-  }).catchError((e) {
-    Expect.isTrue(e.error is SocketIOException);
+  }).catchError((error) {
+    Expect.isTrue(error is SocketIOException);
     port.toSendPort().send(1);
   });
 
@@ -69,9 +69,9 @@
       s.close();
       t.close();
       port.toSendPort().send(1);
-    }).catchError((e) {
+    }).catchError((error) {
       Expect.notEquals('windows', Platform.operatingSystem);
-      Expect.isTrue(e.error is SocketIOException);
+      Expect.isTrue(error is SocketIOException);
       s.close();
       port.toSendPort().send(1);
     });
@@ -100,16 +100,14 @@
       .then((clientEnd) {
         Expect.fail("No client connection expected.");
       })
-      .catchError((e) {
-        Expect.isTrue(e is AsyncError);
-        Expect.isTrue(e.error is SocketIOException);
+      .catchError((error) {
+        Expect.isTrue(error is SocketIOException);
       });
     server.listen((serverEnd) {
       Expect.fail("No server connection expected.");
     },
-    onError: (e) {
-      Expect.isTrue(e is AsyncError);
-      Expect.isTrue(e.error is SocketIOException);
+    onError: (error) {
+      Expect.isTrue(error is SocketIOException);
       clientEndFuture.then((_) => port.close());
     });
   });
@@ -167,7 +165,7 @@
       client.listen(
         (buffer) {
           Expect.isTrue(bytesWritten == 0);
-          data.setRange(bytesRead, buffer.length, buffer);
+          data.setRange(bytesRead, bytesRead + buffer.length, buffer);
           bytesRead += buffer.length;
           if (bytesRead == data.length) {
             verifyTestData(data);
@@ -189,7 +187,7 @@
       socket.close();  // Can also be delayed.
       socket.listen(
         (List<int> buffer) {
-          dataReceived.setRange(bytesRead, buffer.length, buffer);
+          dataReceived.setRange(bytesRead, bytesRead + buffer.length, buffer);
           bytesRead += buffer.length;
         },
         onDone: () {
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index 09a5852..61e5af8 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -56,7 +56,12 @@
           Expect.equals(9, body[body.length - 1]);
           server.close();
         },
-        onError: (e) => Expect.fail("Unexpected error $e"));
+        onError: (e) {
+          String msg = "Unexpected error $e";
+          var trace = getAttachedStackTrace(e);
+          if (trace != null) msg += "\nStackTrace: $trace";
+          Expect.fail(msg);
+        });
     });
   });
 }
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index c82f3fb..81c1b14 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -164,7 +164,7 @@
         client.listen(
             (data) => Expect.fail("Unexpected data"),
             onError: (error) {
-              Expect.isTrue(error.error is SocketIOException);
+              Expect.isTrue(error is SocketIOException);
               errors++;
             },
             onDone: () {
@@ -184,7 +184,7 @@
               Expect.fail("Expected error");
             },
             onError: (error) {
-              Expect.isTrue(error.error is SocketIOException);
+              Expect.isTrue(error is SocketIOException);
               port.close();
             });
       });
diff --git a/tests/standalone/io/socket_many_connections_test.dart b/tests/standalone/io/socket_many_connections_test.dart
index b10ad71..c6c557e 100644
--- a/tests/standalone/io/socket_many_connections_test.dart
+++ b/tests/standalone/io/socket_many_connections_test.dart
@@ -80,7 +80,10 @@
     }
 
     void errorHandler(e) {
-      print("Socket error $e");
+      String msg = "Socket error $e";
+      var trace = getAttachedStackTrace(e);
+      if (trace != null) msg += "\nStackTrace: $trace";
+      print(msg);
       connection.close();
     }
 
diff --git a/tests/standalone/io/socket_test.dart b/tests/standalone/io/socket_test.dart
index a405c05..1385b67 100644
--- a/tests/standalone/io/socket_test.dart
+++ b/tests/standalone/io/socket_test.dart
@@ -34,16 +34,16 @@
   // Bind to a unknown DNS name.
   ServerSocket.bind("ko.faar.__hest__")
       .then((_) { Expect.fail("Failure expected"); } )
-      .catchError((e) {
-        Expect.isTrue(e.error is SocketIOException);
+      .catchError((error) {
+        Expect.isTrue(error is SocketIOException);
         port.toSendPort().send(1);
       });
 
   // Bind to an unavaliable IP-address.
   ServerSocket.bind("8.8.8.8")
       .then((_) { Expect.fail("Failure expected"); } )
-      .catchError((e) {
-        Expect.isTrue(e.error is SocketIOException);
+      .catchError((error) {
+        Expect.isTrue(error is SocketIOException);
         port.toSendPort().send(1);
       });
 
@@ -59,9 +59,9 @@
               Expect.equals(s.port, t.port);
               port.toSendPort().send(1);
             })
-            .catchError((e) {
+            .catchError((error) {
               Expect.notEquals('windows', Platform.operatingSystem);
-              Expect.isTrue(e.error is SocketIOException);
+              Expect.isTrue(error is SocketIOException);
               port.toSendPort().send(1);
             });
       });
diff --git a/tests/standalone/io/stdout_stderr_test.dart b/tests/standalone/io/stdout_stderr_test.dart
index 4775891..ccd1550 100644
--- a/tests/standalone/io/stdout_stderr_test.dart
+++ b/tests/standalone/io/stdout_stderr_test.dart
@@ -17,16 +17,18 @@
   sink.add([101, 108, 108, 111, 10]);
 
   var controller = new StreamController();
-  sink.writeStream(controller.stream);
+  var future = sink.addStream(controller.stream);
   controller.add([72, 101, 108]);
   controller.add([108, 111, 10]);
   controller.close();
 
-  controller = new StreamController();
-  controller.stream.pipe(sink);
-  controller.add([72, 101, 108]);
-  controller.add([108, 111, 10]);
-  controller.close();
+  future.then((_) {
+    controller = new StreamController();
+    controller.stream.pipe(sink);
+    controller.add([72, 101, 108]);
+    controller.add([108, 111, 10]);
+    controller.close();
+  });
 }
 
 main() {
diff --git a/tests/standalone/io/stream_pipe_test.dart b/tests/standalone/io/stream_pipe_test.dart
index c029e0b..75f7981 100644
--- a/tests/standalone/io/stream_pipe_test.dart
+++ b/tests/standalone/io/stream_pipe_test.dart
@@ -39,9 +39,9 @@
   var data2 = new List<int>(count);
   if (file1Offset != 0) file1.setPositionSync(file1Offset);
   if (file2Offset != 0) file2.setPositionSync(file2Offset);
-  var read1 = file1.readListSync(data1, 0, count);
+  var read1 = file1.readIntoSync(data1, 0, count);
   Expect.equals(count, read1);
-  var read2 = file2.readListSync(data2, 0, count);
+  var read2 = file2.readIntoSync(data2, 0, count);
   Expect.equals(count, read2);
   for (var i = 0; i < count; i++) {
     if (data1[i] != data2[i]) {
@@ -100,7 +100,7 @@
   var dstFile = new File(dstFileName);
   dstFile.createSync();
   var output = dstFile.openWrite();
-  output.writeStream(srcStream).then((_) {
+  output.addStream(srcStream).then((_) {
     output.add([32]);
     output.close();
     output.done.then((_) {
@@ -114,7 +114,7 @@
                                        count: srcLength));
       dst.setPositionSync(srcLength);
       var data = new List<int>(1);
-      var read2 = dst.readListSync(data, 0, 1);
+      var read2 = dst.readIntoSync(data, 0, 1);
       Expect.equals(32, data[0]);
       src.closeSync();
       dst.closeSync();
@@ -143,9 +143,9 @@
   var dstFile = new File(dstFileName);
   dstFile.createSync();
   var output = dstFile.openWrite();
-  output.writeStream(srcStream).then((_) {
+  output.addStream(srcStream).then((_) {
     var srcStream2 = srcFile.openRead();
-    output.writeStream(srcStream2).then((_) {
+    output.addStream(srcStream2).then((_) {
       output.close();
       output.done.then((_) {
         var src = srcFile.openSync();
diff --git a/tests/standalone/io/string_transformer_test.dart b/tests/standalone/io/string_transformer_test.dart
index a15633d..a7dd544 100644
--- a/tests/standalone/io/string_transformer_test.dart
+++ b/tests/standalone/io/string_transformer_test.dart
@@ -197,9 +197,9 @@
       onDone: () {
         Expect.equals(1, errors);
       },
-      onError: (e) {
+      onError: (error) {
         errors++;
-        Expect.isTrue(e.error is TestException);
+        Expect.isTrue(error is TestException);
       });
   controller.addError(new TestException());
   controller.close();
@@ -222,7 +222,7 @@
       Expect.fail("data not expected");
     },
     onError: (error) {
-      Expect.isTrue(error.error is FormatException);
+      Expect.isTrue(error is FormatException);
     });
 
 }
diff --git a/tests/standalone/io/testing_server.dart b/tests/standalone/io/testing_server.dart
index 79ab136..79f0175 100644
--- a/tests/standalone/io/testing_server.dart
+++ b/tests/standalone/io/testing_server.dart
@@ -13,7 +13,10 @@
   void onConnection(Socket connection);  // Abstract.
 
   void errorHandlerServer(e) {
-    Expect.fail("Server socket error $e");
+    String msg = "Server socket error $e";
+    var trace = getAttachedStackTrace(e);
+    if (trace != null) msg += "\nStackTrace: $trace";
+    Expect.fail(msg);
   }
 
   void dispatch(message, SendPort replyTo) {
diff --git a/tests/standalone/io/web_socket_protocol_processor_test.dart b/tests/standalone/io/web_socket_protocol_processor_test.dart
index 54a7c12..eb15db0 100644
--- a/tests/standalone/io/web_socket_protocol_processor_test.dart
+++ b/tests/standalone/io/web_socket_protocol_processor_test.dart
@@ -51,7 +51,10 @@
   }
 
   void onError(e) {
-    Expect.fail("Unexpected error $e");
+    String msg = "Unexpected error $e";
+    var trace = getAttachedStackTrace(e);
+    if (trace != null) msg += "\nStackTrace: $trace";
+    Expect.fail(msg);
   }
 
 }
@@ -90,7 +93,7 @@
       frame[frameIndex++] = count >> ((7 - i) * 8) & 0xFF;
     }
   }
-  frame.setRange(frameIndex, count, data, offset);
+  frame.setRange(frameIndex, frameIndex + count, data, offset);
   return frame;
 }
 
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index f17fa0f..b67e5bf 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -4,6 +4,10 @@
 
 package/invalid_uri_test: Fail, OK # Fails intentionally
 
+[ $runtime == vm ]
+io/test_runner_test: Fail # Fails because checked-in dart executable is not up to date.
+io/skipping_dart2js_compilations_test: Fail # Fails because checked-in dart executable is not up to date.
+
 [ $runtime == vm && ( $system == windows ) ]
 io/raw_socket_test: Pass, Fail # Issue 8901
 io/http_shutdown_test: Pass, Fail # Issue  9101
diff --git a/tests/standalone/typed_data_test.dart b/tests/standalone/typed_data_test.dart
index 62c4425..11e3366 100644
--- a/tests/standalone/typed_data_test.dart
+++ b/tests/standalone/typed_data_test.dart
@@ -161,7 +161,7 @@
     Expect.equals(20 + i, list[i]);
   }
 
-  typed_data.setRange(1, 2, const [8, 9]);
+  typed_data.setRange(1, 3, const [8, 9]);
   Expect.equals(20, typed_data[0]);
   Expect.equals(8, typed_data[1]);
   Expect.equals(9, typed_data[2]);
@@ -182,7 +182,7 @@
   });
 
   Expect.throws(() {
-    typed_data.setRange(3, 1, list);
+    typed_data.setRange(3, 4, list);
   });
 }
 
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index c4d6603..87f1b4e 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -61,7 +61,9 @@
                   class JSNumber {}
                   class JSNull {}
                   class JSBool {}
-                  var getInterceptor;""";
+                  getInterceptor(o){}
+                  getDispatchProperty(o) {}
+                  setDispatchProperty(o, v) {}""";
     } else if (uri.path.endsWith('js_helper.dart')) {
       source = 'library jshelper; class JSInvocationMirror {} '
                'class ConstantMap {} class TypeImpl {}';
@@ -95,7 +97,7 @@
     if (code == null) {
       throw 'Compilation failed';
     }
-  }, onError: (AsyncError e) {
+  }, onError: (e) {
       throw 'Compilation failed';
   });
 }
diff --git a/tests/utils/recursive_import_test.dart b/tests/utils/recursive_import_test.dart
index 2c707e7..b6e95f3 100644
--- a/tests/utils/recursive_import_test.dart
+++ b/tests/utils/recursive_import_test.dart
@@ -114,7 +114,7 @@
     // first time.
     Expect.equals(2 * (count - 1), warningCount);
     Expect.equals(1, errorCount);
-  }, onError: (AsyncError e) {
+  }, onError: (e) {
       throw 'Compilation failed';
   });
 }
diff --git a/tools/VERSION b/tools/VERSION
index 971672e..08711a3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 4
-BUILD 6
-PATCH 1
+BUILD 7
+PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 3de5b93..44163fe 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -223,7 +223,9 @@
     # TODO(kasperl): Consider running peg and css tests too.
     extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
     extras_flags = flags
-    if system == 'linux' and runtime == 'd8':
+    if (system == 'linux'
+        and runtime == 'd8'
+        and not '--host-checked' in extras_flags):
       # Run the extra tests in checked mode, but only on linux/d8.
       # Other systems have less resources and tend to time out.
       extras_flags = extras_flags + ['--host-checked']
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 942b57c..be09394 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -50,11 +50,14 @@
 # ....util/
 # ......analyzer/
 # ........dart_analyzer.jar
+# ......dartanalyzer/
+# ........dartanalyzer.jar
 # ........(third-party libraries for dart_analyzer)
 # ......pub/
 # ......(more will come here)
 
 
+import glob
 import optparse
 import os
 import re
@@ -113,7 +116,7 @@
 
 def CopyDartScripts(home, sdk_root):
   # TODO(dgrove) - add pub once issue 6619 is fixed
-  for executable in ['dart2js', 'dartdoc']:
+  for executable in ['dart2js', 'dartanalyzer', 'dartdoc']:
     CopyShellScript(os.path.join(home, 'sdk', 'bin', executable),
                     os.path.join(sdk_root, 'bin'))
 
@@ -262,6 +265,16 @@
     src_file = join(ANALYZER_HOME, 'util', 'analyzer', jarToCopy)
     copyfile(src_file, dest_file)
 
+  # Create and copy dartanalyzer into 'util'
+  DARTANALYZER_SRC = join(HOME, build_dir, 'dartanalyzer')
+  DARTANALYZER_DEST = join(UTIL, 'dartanalyzer')
+  os.makedirs(DARTANALYZER_DEST)
+  
+  jarFiles = glob.glob(join(DARTANALYZER_SRC, '*.jar'))
+  
+  for jarFile in jarFiles:
+    copyfile(jarFile, join(DARTANALYZER_DEST, os.path.basename(jarFile)))
+  
   # Create and populate util/pub.
   copytree(join(HOME, 'utils', 'pub'), join(UTIL, 'pub'),
            ignore=ignore_patterns('.svn', 'sdk'))
diff --git a/tools/ddbg.dart b/tools/ddbg.dart
index e79e294..4174700 100644
--- a/tools/ddbg.dart
+++ b/tools/ddbg.dart
@@ -575,6 +575,7 @@
         },
         onError: (err) {
           print("Error in debug connection: $err");
+          // TODO(floitsch): do we want to print the stack trace?
           quitShell();
         });
     stdinSubscription = stdin.transform(new StringDecoder())
diff --git a/tools/dom/docs/lib/docs.dart b/tools/dom/docs/lib/docs.dart
index 1b38913..8856b73 100644
--- a/tools/dom/docs/lib/docs.dart
+++ b/tools/dom/docs/lib/docs.dart
@@ -64,7 +64,7 @@
 }
 
 Future<bool> _exportJsonToFile(Map convertedJson, Path jsonPath) {
-  return new Future.of(() {
+  return new Future.sync(() {
     final jsonFile = new File.fromPath(jsonPath);
     var writeJson = prettySerialize(convertedJson);
 
@@ -106,7 +106,8 @@
 
         // Remove interface name from Dom Name.
         if (memberDomName.indexOf('.') >= 0) {
-          memberDomName = memberDomName.slice(memberDomName.indexOf('.') + 1);
+          memberDomName =
+              memberDomName.substring(memberDomName.indexOf('.') + 1);
         }
 
         if (!memberComment.isEmpty) {
diff --git a/tools/dom/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
index 6af0d7d..914b7ca 100755
--- a/tools/dom/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -132,7 +132,7 @@
   _logger.info('Flush...')
   emitters.Flush()
 
-  monitored.FinishMonitoring()
+  monitored.FinishMonitoring(dart2js_output_dir)
 
 def GenerateSingleFile(library_path, output_dir, generated_output_dir=None):
   library_dir = os.path.dirname(library_path)
diff --git a/tools/dom/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
index 60565a1..f61f33d 100755
--- a/tools/dom/scripts/databasebuilder.py
+++ b/tools/dom/scripts/databasebuilder.py
@@ -83,6 +83,7 @@
     self._database = database
     self._imported_interfaces = []
     self._impl_stmts = []
+    self.conditionals_met = set()
 
   def _resolve_type_defs(self, idl_file):
     type_def_map = {}
@@ -473,11 +474,15 @@
     conditional = node.ext_attrs['Conditional']
     if conditional.find('&') != -1:
       for condition in conditional.split('&'):
+        condition = condition.strip()
+        self.conditionals_met.add(condition)
         if not enabled(condition):
           return False
       return True
 
     for condition in conditional.split('|'):
+      condition = condition.strip()
+      self.conditionals_met.add(condition)
       if enabled(condition):
         return True
     return False
diff --git a/tools/dom/scripts/fremontcutbuilder.py b/tools/dom/scripts/fremontcutbuilder.py
index bb82b26..6ccfefb 100755
--- a/tools/dom/scripts/fremontcutbuilder.py
+++ b/tools/dom/scripts/fremontcutbuilder.py
@@ -10,86 +10,79 @@
 import os.path
 import sys
 
-# TODO(antonm): most probably should go away or be autogenerated on IDLs roll.
-DEFAULT_FEATURE_DEFINES = [
-    # Enabled Chrome WebKit build.
-    'ENABLE_3D_PLUGIN',
-    'ENABLE_3D_RENDERING',
-    'ENABLE_ACCELERATED_2D_CANVAS',
+FEATURE_DISABLED = [
     'ENABLE_BATTERY_STATUS',
+    'ENABLE_CSS3_CONDITIONAL_RULES',
+    'ENABLE_CSS_DEVICE_ADAPTATION',
+    'ENABLE_CUSTOM_SCHEME_HANDLER',
+    'ENABLE_ENCRYPTED_MEDIA_V2',
+    'ENABLE_INSPECTOR', # Internal DevTools API.
+    'ENABLE_MEDIA_CAPTURE', # Only enabled on Android.
+    'ENABLE_MICRODATA',
+    'ENABLE_ORIENTATION_EVENTS', # Only enabled on Android.
+    'ENABLE_PROXIMITY_EVENTS',
+    'ENABLE_SPEECH_SYNTHESIS',
+    'ENABLE_WEBVTT_REGIONS',
+    'ENABLE_XHR_TIMEOUT',
+]
+
+FEATURE_DEFINES = [
     'ENABLE_BLOB',
-    'ENABLE_BLOB_SLICE',
     'ENABLE_CALENDAR_PICKER',
-    'ENABLE_CHANNEL_MESSAGING',
+    'ENABLE_CANVAS_PATH',
+    'ENABLE_CANVAS_PROXY',
     'ENABLE_CSS_FILTERS',
-    'ENABLE_CSS_IMAGE_SET',
+    'ENABLE_CSS_REGIONS',
     'ENABLE_CSS_SHADERS',
-    'ENABLE_DART',
-    'ENABLE_DATA_TRANSFER_ITEMS',
+    'ENABLE_CUSTOM_ELEMENTS',
     'ENABLE_DATALIST_ELEMENT',
-    'ENABLE_DETAILS',
     'ENABLE_DETAILS_ELEMENT',
     'ENABLE_DEVICE_ORIENTATION',
+    'ENABLE_DIALOG_ELEMENT',
     'ENABLE_DIRECTORY_UPLOAD',
     'ENABLE_DOWNLOAD_ATTRIBUTE',
     'ENABLE_ENCRYPTED_MEDIA',
     'ENABLE_FILE_SYSTEM',
     'ENABLE_FILTERS',
-    'ENABLE_FULLSCREEN_API',
+    'ENABLE_FONT_LOAD_EVENTS',
     'ENABLE_GAMEPAD',
     'ENABLE_GEOLOCATION',
-    'ENABLE_GESTURE_EVENTS',
-    'ENABLE_INDEXED_DATABASE',
     'ENABLE_INPUT_SPEECH',
-    'ENABLE_INPUT_TYPE_COLOR',
-    'ENABLE_INPUT_TYPE_DATE',
     'ENABLE_JAVASCRIPT_DEBUGGER',
-    'ENABLE_JAVASCRIPT_I18N_API',
     'ENABLE_LEGACY_NOTIFICATIONS',
-    'ENABLE_LINK_PREFETCH',
-    'ENABLE_MEDIA_SOURCE',
     'ENABLE_MEDIA_STATISTICS',
     'ENABLE_MEDIA_STREAM',
     'ENABLE_METER_ELEMENT',
-    'ENABLE_METER_TAG',
-    'ENABLE_MHTML',
+    'ENABLE_NAVIGATOR_CONTENT_UTILS',
     'ENABLE_NOTIFICATIONS',
-    'ENABLE_OVERFLOW_SCROLLING',
     'ENABLE_PAGE_POPUP',
-    'ENABLE_PAGE_VISIBILITY_API',
+    'ENABLE_PERFORMANCE_TIMELINE',
     'ENABLE_POINTER_LOCK',
     'ENABLE_PROGRESS_ELEMENT',
-    'ENABLE_PROGRESS_TAG',
     'ENABLE_QUOTA',
-    'ENABLE_REGISTER_PROTOCOL_HANDLER',
     'ENABLE_REQUEST_ANIMATION_FRAME',
-    'ENABLE_RUBY',
-    'ENABLE_SANDBOX',
+    'ENABLE_REQUEST_AUTOCOMPLETE',
+    'ENABLE_RESOURCE_TIMING',
     'ENABLE_SCRIPTED_SPEECH',
     'ENABLE_SHADOW_DOM',
     'ENABLE_SHARED_WORKERS',
-    'ENABLE_SMOOTH_SCROLLING',
     'ENABLE_SQL_DATABASE',
     'ENABLE_STYLE_SCOPED',
     'ENABLE_SVG',
     'ENABLE_SVG_FONTS',
     'ENABLE_TOUCH_EVENTS',
-    'ENABLE_V8_SCRIPT_DEBUG_SERVER',
+    'ENABLE_USER_TIMING',
     'ENABLE_VIDEO',
     'ENABLE_VIDEO_TRACK',
-    'ENABLE_VIEWPORT',
-    'ENABLE_WEBGL',
     'ENABLE_WEB_AUDIO',
-    'ENABLE_WEB_INTENTS',
+    'ENABLE_WEBGL',
     'ENABLE_WEB_SOCKETS',
     'ENABLE_WEB_TIMING',
     'ENABLE_WORKERS',
-    'ENABLE_XHR_RESPONSE_BLOB',
     'ENABLE_XSLT',
 ]
 
-def build_database(idl_files, database_dir, feature_defines=None,
-                   parallel=False):
+def build_database(idl_files, database_dir, parallel=False):
   """This code reconstructs the FremontCut IDL database from W3C,
   WebKit and Dart IDL files."""
   current_dir = os.path.dirname(__file__)
@@ -109,13 +102,11 @@
   # TODO(vsm): Reconcile what is exposed here and inside WebKit code
   # generation.  We need to recheck this periodically for now.
   webkit_defines = [ 'LANGUAGE_DART', 'LANGUAGE_JAVASCRIPT' ]
-  if feature_defines is None:
-      feature_defines = DEFAULT_FEATURE_DEFINES
 
   webkit_options = databasebuilder.DatabaseBuilderOptions(
       idl_syntax=idlparser.WEBKIT_SYNTAX,
       # TODO(vsm): What else should we define as on when processing IDL?
-      idl_defines=webkit_defines + feature_defines,
+      idl_defines=webkit_defines + FEATURE_DEFINES,
       source='WebKit',
       source_attributes={'revision': webkit_revision})
 
@@ -142,6 +133,20 @@
   # Cleanup:
   builder.normalize_annotations(['WebKit', 'Dart'])
 
+  conditionals_met = set(
+      'ENABLE_' + conditional for conditional in builder.conditionals_met)
+  known_conditionals = set(FEATURE_DEFINES + FEATURE_DISABLED)
+
+  unused_conditionals = known_conditionals - conditionals_met
+  if unused_conditionals:
+    raise Exception('There are some unused conditionals %s' %
+        sorted(unused_conditionals))
+
+  unknown_conditionals = conditionals_met - known_conditionals
+  if unknown_conditionals:
+    raise Exception('There are some unknown conditionals %s' %
+        sorted(unknown_conditionals))
+
   db.Save()
   return db
 
@@ -159,8 +164,15 @@
   if not os.path.exists(webcore_dir):
     raise RuntimeError('directory not found: %s' % webcore_dir)
 
+  DIRS_TO_IGNORE = [
+      'bindings', # Various test IDLs
+      'testing', # IDLs to expose testing APIs
+      'networkinfo', # Not yet used in Blink yet
+      'vibration', # Not yet used in Blink yet
+  ]
+
   def visitor(arg, dir_name, names):
-    if os.path.basename(dir_name) in ['bindings', 'testing']:
+    if os.path.basename(dir_name) in DIRS_TO_IGNORE:
       names[:] = [] # Do not go underneath
     for name in names:
       file_name = os.path.join(dir_name, name)
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 1ab6c53..630a034 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -101,7 +101,7 @@
 
     # DOMWindow aliased with global scope.
     'Window': '@*DOMWindow',
-})
+}, dart2jsOnly=True)
 
 def IsRegisteredType(type_name):
   return type_name in _idl_type_registry
@@ -528,7 +528,7 @@
 
     # Should be either a DOMString, an Array of DOMStrings or null.
     'IDBAny get IDBObjectStore.keyPath': None,
-})
+}, dart2jsOnly=True)
 
 def FindConversion(idl_type, direction, interface, member):
   table = dart2js_conversions
@@ -696,7 +696,7 @@
     'XMLHttpRequest.response': [
       "@Creates('ArrayBuffer|Blob|Document|=Object|=List|String|num')",
     ],
-})
+}, dart2jsOnly=True)
 
 _indexed_db_annotations = [
   "@SupportedBrowser(SupportedBrowser.CHROME)",
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index 7f64f1b..0f06390 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -113,10 +113,6 @@
   '*.webkitfullscreenchange': ('fullscreenChange', 'Event'),
   '*.webkitfullscreenerror': ('fullscreenError', 'Event'),
   'AudioContext.complete': ('complete', 'Event'),
-  'BatteryManager.chargingchange': ('chargingChange', 'Event'),
-  'BatteryManager.chargingtimechange': ('chargingTimeChange', 'Event'),
-  'BatteryManager.dischargingtimechange': ('dischargingTimeChange', 'Event'),
-  'BatteryManager.levelchange': ('levelChange', 'Event'),
   'DOMApplicationCache.cached': ('cached', 'Event'),
   'DOMApplicationCache.checking': ('checking', 'Event'),
   'DOMApplicationCache.downloading': ('downloading', 'Event'),
diff --git a/tools/dom/scripts/monitored.py b/tools/dom/scripts/monitored.py
index 06dc4dd..9d0c8da 100644
--- a/tools/dom/scripts/monitored.py
+++ b/tools/dom/scripts/monitored.py
@@ -8,21 +8,24 @@
 _monitored_values = []
 
 
-def FinishMonitoring():
+def FinishMonitoring(includeDart2jsOnly):
   for value in _monitored_values:
+    if value._dart2jsOnly and not includeDart2jsOnly:
+      continue
     value.CheckUsage()
 
 class MonitoredCollection(object):
-  def __init__(self, name):
+  def __init__(self, name, dart2jsOnly):
     self.name = name
     self._used_keys = set()
+    self._dart2jsOnly = dart2jsOnly
     _monitored_values.append(self)
 
 class Dict(MonitoredCollection):
   """Wrapper for a dict that reports unused keys."""
 
-  def __init__(self, name, map):
-    super(Dict, self).__init__(name)
+  def __init__(self, name, map, dart2jsOnly=False):
+    super(Dict, self).__init__(name, dart2jsOnly)
     self._map = map
 
   def __getitem__(self, key):
@@ -52,8 +55,8 @@
 class Set(MonitoredCollection):
   """Wrapper for a set that reports unused keys."""
 
-  def __init__(self, name, a_set):
-    super(Set, self).__init__(name)
+  def __init__(self, name, a_set, dart2jsOnly=False):
+    super(Set, self).__init__(name, dart2jsOnly)
     self._set = a_set
 
   def __contains__(self, key):
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 4d813a4..3cb9d4b 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -74,7 +74,7 @@
     'Window.open',
     'Window.requestAnimationFrame',
     # 'WorkerContext.indexedDB', # Workers
-    ])
+    ], dart2jsOnly=True)
 
 _js_custom_constructors = monitored.Set('systemhtml._js_custom_constructors', [
     'AudioContext',
@@ -84,7 +84,7 @@
     'RTCPeerConnection',
     'RTCSessionDescription',
     'SpeechRecognition',
-    ])
+    ], dart2jsOnly=True)
 
 # Classes that offer only static methods, and therefore we should suppress
 # constructor creation.
diff --git a/tools/dom/src/EventStreamProvider.dart b/tools/dom/src/EventStreamProvider.dart
index f5a9407..788b179 100644
--- a/tools/dom/src/EventStreamProvider.dart
+++ b/tools/dom/src/EventStreamProvider.dart
@@ -19,9 +19,9 @@
   bool get isBroadcast => true;
 
   StreamSubscription<T> listen(void onData(T event),
-      { void onError(AsyncError error),
-      void onDone(),
-      bool unsubscribeOnError}) {
+      { void onError(error),
+        void onDone(),
+        bool cancelOnError}) {
 
     return new _EventStreamSubscription<T>(
         this._target, this._eventType, onData, this._useCapture);
@@ -63,7 +63,7 @@
   }
 
   /// Has no effect.
-  void onError(void handleError(AsyncError error)) {}
+  void onError(void handleError(error)) {}
 
   /// Has no effect.
   void onDone(void handleDone()) {}
@@ -97,6 +97,12 @@
       _target.$dom_removeEventListener(_eventType, _onData, _useCapture);
     }
   }
+
+  Future asFuture([var futureValue]) {
+    // We just need a future that will never succeed or fail.
+    Completer completer = new Completer();
+    return completer.future;
+  }
 }
 
 
diff --git a/tools/dom/src/KeyboardEventStream.dart b/tools/dom/src/KeyboardEventStream.dart
index 48dbdba..6f08c70 100644
--- a/tools/dom/src/KeyboardEventStream.dart
+++ b/tools/dom/src/KeyboardEventStream.dart
@@ -28,7 +28,7 @@
   static final int _ROMAN_ALPHABET_OFFSET = "a".codeUnits[0] - "A".codeUnits[0];
 
   /** Controller to produce KeyEvents for the stream. */
-  final StreamController _controller = new StreamController.broadcast();
+  final StreamController _controller = new StreamController();
 
   static const _EVENT_TYPE = 'KeyEvent';
 
diff --git a/tools/dom/src/ModelTreeObserver.dart b/tools/dom/src/ModelTreeObserver.dart
index f055795..8e0bb41a 100644
--- a/tools/dom/src/ModelTreeObserver.dart
+++ b/tools/dom/src/ModelTreeObserver.dart
@@ -79,14 +79,14 @@
     // Catch and report them a global exceptions.
     try {
       if (node._hasLocalModel != true && node._model != model &&
-          node._modelChangedStream != null) {
+          node._modelChangedStreams != null &&
+          !node._modelChangedStreams.isEmpty) {
         node._model = model;
-        node._modelChangedStream.add(node);
+        node._modelChangedStreams.toList()
+          .forEach((controller) => controller.add(node));
       }
-    } on AsyncError catch (e) {
-      e.throwDelayed();
     } catch (e, s) {
-      new AsyncError(e, s).throwDelayed();
+      new Future.error(e, s);
     }
     for (var child = node.$dom_firstChild; child != null;
         child = child.nextNode) {
diff --git a/tools/dom/src/WrappedList.dart b/tools/dom/src/WrappedList.dart
index c20cfd5..7a4ec30 100644
--- a/tools/dom/src/WrappedList.dart
+++ b/tools/dom/src/WrappedList.dart
@@ -104,6 +104,12 @@
 
   void insert(int index, E element) => _list.insert(index, element);
 
+  void insertAll(int index, Iterable<E> iterable) =>
+      _list.insertAll(index, iterable);
+
+  void setAll(int index, Iterable<E> iterable) =>
+      _list.setAll(index, iterable);
+
   E removeAt(int index) => _list.removeAt(index);
 
   E removeLast() => _list.removeLast();
@@ -112,14 +118,18 @@
 
   Iterable<E> getRange(int start, int end) => _list.getRange(start, end);
 
-  void setRange(int start, int length, List<E> from, [int startFrom]) {
-    _list.setRange(start, length, from, startFrom);
+  void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+    _list.setRange(start, end, iterable, skipCount);
   }
 
-  void removeRange(int start, int length) { _list.removeRange(start, length); }
+  void removeRange(int start, int end) { _list.removeRange(start, end); }
 
-  void insertRange(int start, int length, [E fill]) {
-    _list.insertRange(start, length, fill);
+  void replaceRange(int start, int end, Iterable<E> iterable) {
+    _list.replaceRange(start, end, iterable);
+  }
+
+  void fillRange(int start, int end, [E fillValue]) {
+    _list.fillRange(start, end, fillValue);
   }
 
   Map<int, E> asMap() => _list.asMap();
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 4ab1438..d3055a3 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -11,6 +11,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
diff --git a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
index eedcc3c..2f001d2 100644
--- a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
@@ -6,6 +6,7 @@
 
 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 a229e0a..9016bcc 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
diff --git a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
index 4d1ccdf..4b24fa5 100644
--- a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
@@ -5,6 +5,7 @@
 library dart.dom.web_gl;
 
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show Creates, JSName, Null, Returns, convertDartClosureToJS;
diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
index 6a599c1..6e50a6e05 100644
--- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
@@ -16,6 +16,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html';
 import 'dart:html_common';
 import 'dart:_js_helper' show convertDartClosureToJS, Creates, JavaScriptIndexingBehavior, JSName;
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 72e2df7..eb2d73c 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -10,6 +10,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:_collection-dev';
 import 'dart:html_common';
 import 'dart:indexed_db';
 import 'dart:isolate';
diff --git a/tools/dom/templates/html/dartium/svg_dartium.darttemplate b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
index 13f2891..863fc5f 100644
--- a/tools/dom/templates/html/dartium/svg_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/svg_dartium.darttemplate
@@ -5,6 +5,7 @@
 
 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 5c1f4dd..919ef20 100644
--- a/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_audio_dartium.darttemplate
@@ -5,6 +5,7 @@
 
 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_gl_dartium.darttemplate b/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
index fb6d6b0..18615a1 100644
--- a/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_gl_dartium.darttemplate
@@ -5,6 +5,7 @@
 
 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_sql_dartium.darttemplate b/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
index bfb9155..b78b476 100644
--- a/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/web_sql_dartium.darttemplate
@@ -16,6 +16,7 @@
 
 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_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 13eaa30..9fd0d99 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -166,8 +166,16 @@
     return _childElements.fold(initialValue, combine);
   }
 
-  void setRange(int start, int rangeLength, List from,
-                [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
+    throw new UnimplementedError();
+  }
+
+  void replaceRange(int start, int end, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void fillRange(int start, int end, [Element fillValue]) {
     throw new UnimplementedError();
   }
 
@@ -188,11 +196,7 @@
     _childElements.retainWhere(test);
   }
 
-  void removeRange(int start, int rangeLength) {
-    throw new UnimplementedError();
-  }
-
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void removeRange(int start, int end) {
     throw new UnimplementedError();
   }
 
@@ -225,6 +229,14 @@
     }
   }
 
+  void insertAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void setAll(int index, Iterable<Element> iterable) {
+    throw new UnimplementedError();
+  }
+
   void clear() {
     // It is unclear if we want to keep non element nodes?
     _element.text = '';
@@ -309,16 +321,12 @@
     throw new UnsupportedError('');
   }
 
-  void setRange(int start, int rangeLength, List from,
-                [int startFrom = 0]) {
+  void setRange(int start, int end, Iterable<Element> iterable,
+                [int skipCount = 0]) {
     throw new UnsupportedError('');
   }
 
-  void removeRange(int start, int rangeLength) {
-    throw new UnsupportedError('');
-  }
-
-  void insertRange(int start, int rangeLength, [initialValue = null]) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError('');
   }
 
diff --git a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
index 19447c2..c4fec21 100644
--- a/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Geolocation.darttemplate
@@ -54,21 +54,20 @@
     int watchId;
     var controller;
     controller = new StreamController<Geoposition>(
-      onSubscriptionStateChange: () {
-        if (controller.hasListener) {
-          assert(watchId == null);
-          watchId = $dom_watchPosition(
-              (position) {
-                controller.add(_ensurePosition(position));
-              },
-              (error) {
-                controller.addError(error);
-              },
-              options);
-        } else {
-          assert(watchId != null);
-          $dom_clearWatch(watchId);
-        }
+      onListen: () {
+        assert(watchId == null);
+        watchId = $dom_watchPosition(
+            (position) {
+              controller.add(_ensurePosition(position));
+            },
+            (error) {
+              controller.addError(error);
+            },
+            options);
+      },
+      onCancel: () {
+        assert(watchId != null);
+        $dom_clearWatch(watchId);
       });
 
     return controller.stream;
diff --git a/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate b/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
index 3464b5b..164cefa 100644
--- a/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBCursor.darttemplate
@@ -10,7 +10,7 @@
    try {
       return _completeRequest($dom_delete());
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -19,7 +19,7 @@
    try {
       return _completeRequest($dom_update(value));
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
diff --git a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
index 01031d6..b64989c 100644
--- a/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBFactory.darttemplate
@@ -24,7 +24,7 @@
       {int version, void onUpgradeNeeded(VersionChangeEvent),
       void onBlocked(Event)}) {
     if ((version == null) != (onUpgradeNeeded == null)) {
-      return new Future.immediateError(new ArgumentError(
+      return new Future.error(new ArgumentError(
           'version and onUpgradeNeeded must be specified together'));
     }
     try {
@@ -43,7 +43,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -58,7 +58,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -71,7 +71,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
diff --git a/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate b/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
index 08c5d07..f184d02 100644
--- a/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBIndex.darttemplate
@@ -16,7 +16,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -27,7 +27,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -38,7 +38,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
diff --git a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
index 5343411..4251ff5 100644
--- a/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
+++ b/tools/dom/templates/html/impl/impl_IDBObjectStore.darttemplate
@@ -17,7 +17,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -26,7 +26,7 @@
     try {
       return _completeRequest($dom_clear());
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -35,7 +35,7 @@
     try {
       return _completeRequest($dom_delete(key_OR_keyRange));
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -50,7 +50,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -65,7 +65,7 @@
       }
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
@@ -76,7 +76,7 @@
 
       return _completeRequest(request);
     } catch (e, stacktrace) {
-      return new Future.immediateError(e, stacktrace);
+      return new Future.error(e, stacktrace);
     }
   }
 
diff --git a/tools/dom/templates/html/impl/impl_Node.darttemplate b/tools/dom/templates/html/impl/impl_Node.darttemplate
index cb664d6..af16447 100644
--- a/tools/dom/templates/html/impl/impl_Node.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Node.darttemplate
@@ -82,6 +82,14 @@
     }
   }
 
+  void insertAll(int index, Iterable<Node> iterable) {
+    throw new UnimplementedError();
+  }
+
+  void setAll(int index, Iterable<Node> iterable) {
+    throw new UnimplementedError();
+  }
+
   Node removeLast() {
     final result = last;
     if (result != null) {
@@ -152,23 +160,28 @@
   }
 
   // FIXME: implement these.
-  void setRange(int start, int rangeLength, List<Node> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<Node> iterable,
+                [int skipCount = 0]) {
     throw new UnsupportedError(
         "Cannot setRange on immutable List.");
   }
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError(
         "Cannot removeRange on immutable List.");
   }
-  void insertRange(int start, int rangeLength, [Node initialValue]) {
-    throw new UnsupportedError(
-        "Cannot insertRange on immutable List.");
-  }
 
   Iterable<Node> getRange(int start, int end) {
     throw new UnimplementedError("NodeList.getRange");
   }
 
+  void replaceRange(int start, int end, Iterable<Node> iterable) {
+    throw new UnimplementedError("NodeList.replaceRange");
+  }
+
+  void fillRange(int start, int end, [Node fillValue]) {
+    throw new UnimplementedError("NodeList.fillRange");
+  }
+
   List<Node> sublist(int start, [int end]) {
     if (end == null) end == length;
     return Lists.getRange(this, start, end, <Node>[]);
@@ -269,7 +282,7 @@
 $endif
   var _model;
   bool _hasLocalModel;
-  StreamController<Node> _modelChangedStream;
+  Set<StreamController<Node>> _modelChangedStreams;
 
   /**
    * The data model which is inherited through the tree.
@@ -286,7 +299,7 @@
   @Experimental
   get model {
     // If we have a change handler then we've cached the model locally.
-    if (_modelChangedStream != null) {
+    if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
       return _model;
     }
     // Otherwise start looking up the tree.
@@ -306,8 +319,8 @@
     _ModelTreeObserver.initialize();
 
     if (changed) {
-      if (_modelChangedStream != null) {
-        _modelChangedStream.add(this);
+      if (_modelChangedStreams != null && !_modelChangedStreams.isEmpty) {
+        _modelChangedStreams.toList().forEach((stream) => stream.add(this));
       }
       // Propagate new model to all descendants.
       _ModelTreeObserver.propagateModel(this, value, false);
@@ -336,12 +349,14 @@
    * Get a stream of models, whenever the model changes.
    */
   Stream<Node> get onModelChanged {
-    if (_modelChangedStream == null) {
-      // Ensure the model is cached locally to minimize change notifications.
-      _model = model;
-      _modelChangedStream = new StreamController.broadcast();
+    if (_modelChangedStreams == null) {
+      _modelChangedStreams = new Set<StreamController<Node>>();
     }
-    return _modelChangedStream.stream;
+    var controller;
+    controller = new StreamController(
+        onListen: () { _modelChangedStreams.add(controller); },
+        onCancel: () { _modelChangedStreams.remove(controller); });
+    return controller.stream;
   }
 
   /**
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index 2d9493d..7d86600 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -315,7 +315,7 @@
   const _BeforeUnloadEventStreamProvider(this._eventType);
 
   Stream<BeforeUnloadEvent> forTarget(EventTarget e, {bool useCapture: false}) {
-    var controller = new StreamController.broadcast();
+    var controller = new StreamController();
     var stream = new _EventStream(e, _eventType, useCapture);
     stream.listen((event) {
       var wrapped = new _BeforeUnloadEvent(event);
diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate
index 8b85dab..8baaa09 100644
--- a/tools/dom/templates/immutable_list_mixin.darttemplate
+++ b/tools/dom/templates/immutable_list_mixin.darttemplate
@@ -143,6 +143,14 @@
     throw new UnsupportedError("Cannot add to immutable List.");
   }
 
+  void insertAll(int index, Iterable<$E> iterable) {
+    throw new UnsupportedError("Cannot add to immutable List.");
+  }
+
+  void setAll(int index, Iterable<$E> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
   $E removeAt(int pos) {
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
@@ -163,16 +171,20 @@
     throw new UnsupportedError("Cannot remove from immutable List.");
   }
 
-  void setRange(int start, int rangeLength, List<$E> from, [int startFrom]) {
+  void setRange(int start, int end, Iterable<$E> iterable, [int skipCount]) {
     throw new UnsupportedError("Cannot setRange on immutable List.");
   }
 
-  void removeRange(int start, int rangeLength) {
+  void removeRange(int start, int end) {
     throw new UnsupportedError("Cannot removeRange on immutable List.");
   }
 
-  void insertRange(int start, int rangeLength, [$E initialValue]) {
-    throw new UnsupportedError("Cannot insertRange on immutable List.");
+  void replaceRange(int start, int end, Iterable<$E> iterable) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
+  }
+
+  void fillRange(int start, int end, [$E fillValue]) {
+    throw new UnsupportedError("Cannot modify an immutable List.");
   }
 
   Iterable<$E> getRange(int start, int end) =>
diff --git a/tools/release/version.dart b/tools/release/version.dart
index 74e1e66..99b44bd 100644
--- a/tools/release/version.dart
+++ b/tools/release/version.dart
@@ -149,7 +149,7 @@
 
   Future<int> getRevision() {
     if (repositoryType == RepositoryType.UNKNOWN) {
-      return new Future.immediate(0);
+      return new Future.value(0);
     }
     var isSvn = repositoryType == RepositoryType.SVN;
     var command = isSvn ? "svn" : "git";
diff --git a/tools/testing/dart/drt_updater.dart b/tools/testing/dart/drt_updater.dart
index abb1fe7..67e1716 100644
--- a/tools/testing/dart/drt_updater.dart
+++ b/tools/testing/dart/drt_updater.dart
@@ -30,6 +30,7 @@
       _updatingProcess = Process.run('python', _getUpdateCommand);
       _updatingProcess.then(_onUpdatedHandler).catchError((e) {
         print("Error starting $script process: $e");
+        // TODO(floitsch): should we print the stacktrace?
         return false;
       });
     }
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index feffa4c..cc1e414 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -142,7 +142,7 @@
         }
       },
       onError: (e) {
-        DebugLogger.error('HttpServer: an error occured: $e');
+        DebugLogger.error('HttpServer: an error occured', e);
       });
       _serverList.add(httpServer);
     });
@@ -186,7 +186,7 @@
     response.headers.set("Access-Control-Allow-Origin", "*");
     request.pipe(response).catchError((e) {
       DebugLogger.warning(
-          'HttpServer: error while closing the response stream: $e');
+          'HttpServer: error while closing the response stream', e);
     });
   }
 
@@ -196,12 +196,11 @@
         websocket.send(data);
         websocket.close();
       }, onError: (e) {
-        DebugLogger.warning(
-            'HttpServer: error while echoing to WebSocket: $e');
+        DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
       });
     }).catchError((e) {
       DebugLogger.warning(
-          'HttpServer: error while transforming to WebSocket: $e');
+          'HttpServer: error while transforming to WebSocket', e);
     });
   }
 
@@ -286,7 +285,7 @@
     response.close();
     response.done.catchError((e) {
       DebugLogger.warning(
-          'HttpServer: error while closing the response stream: $e');
+          'HttpServer: error while closing the response stream', e);
     });
   }
 
@@ -336,7 +335,7 @@
     }
     file.openRead().pipe(response).catchError((e) {
       DebugLogger.warning(
-          'HttpServer: error while closing the response stream: $e');
+          'HttpServer: error while closing the response stream', e);
     });
   }
 
@@ -352,7 +351,7 @@
     response.close();
     response.done.catchError((e) {
       DebugLogger.warning(
-          'HttpServer: error while closing the response stream: $e');
+          'HttpServer: error while closing the response stream', e);
     });
   }
 }
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 5eac74a..659fef5 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -344,8 +344,8 @@
 
   void allDone() {
     if (_printSummary) {
-      print('\n=== Failure summary:\n');
       if (!_failureSummary.isEmpty) {
+        print('\n=== Failure summary:\n');
         for (String line in _failureSummary) {
           print(line);
         }
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 5dd8e19..231cdb5 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -984,6 +984,7 @@
           timeoutTimer = new Timer(new Duration(seconds: testCase.timeout),
                                    timeoutHandler);
         }).catchError((e) {
+          // TODO(floitsch): should we try to report the stacktrace?
           print("Process error:");
           print("  Command: $command");
           print("  Error: $e");
@@ -1243,6 +1244,7 @@
       });
       callback();
     }).catchError((e) {
+      // TODO(floitsch): should we try to report the stacktrace?
       print("Process error:");
       print("  Command: $_executable ${_batchArguments.join(' ')}");
       print("  Error: $e");
@@ -1414,6 +1416,7 @@
           }
         });
       }).catchError((e) {
+      // TODO(floitsch): should we try to report the stacktrace?
         print("Error starting process:");
         print("  Command: $cmd ${arg.join(' ')}");
         print("  Error: $e");
@@ -1479,6 +1482,7 @@
             stdoutStringStream.listen(seleniumServerHandler);
             stderrStringStream.listen(seleniumServerHandler);
           }).catchError((e) {
+            // TODO(floitsch): should we try to report the stacktrace?
             print("Process error:");
             print("  Command: java -jar $file");
             print("  Error: $e");
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 6381a12..3a3de41 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -79,7 +79,7 @@
     _pending++;
     var handledTaskFuture = task.catchError((e) {
       if (!wasCompleted) {
-        _completer.completeError(e.error, e.stackTrace);
+        _completer.completeError(e);
         wasCompleted = true;
       }
     }).then((_) {
@@ -1094,7 +1094,7 @@
     }
     if (executable.endsWith('.dart')) {
       // Run the compiler script via the Dart VM.
-      args.insertRange(0, 1, executable);
+      args.insert(0, executable);
       executable = dartShellFileName;
     }
     if (['dart2js', 'dart2dart'].contains(configuration['compiler'])) {
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index dc79246..4ab769c 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -5,6 +5,7 @@
 library utils;
 
 import 'dart:io';
+import 'dart:async';
 import 'dart:utf' as utf;
 
 class DebugLogger {
@@ -27,15 +28,28 @@
     }
   }
 
-  static void info(String msg) {
+  static String _formatErrorMessage(String msg, error) {
+    if (error == null) return msg;
+    msg += ": $error";
+    // TODO(floitsch): once the dart-executable that is bundled
+    // with the Dart sources is updated, uncomment the following
+    // lines.
+    // var trace = getAttachedStackTrace(error);
+    // if (trace != null) msg += "\nStackTrace: $trace";
+    return msg;
+  }
+  static void info(String msg, [error]) {
+    msg = _formatErrorMessage(msg, error);
     _print("Info: $msg");
   }
 
-  static void warning(String msg) {
+  static void warning(String msg, [error]) {
+    msg = _formatErrorMessage(msg, error);
     _print("Warning: $msg");
   }
 
-  static void error(String msg) {
+  static void error(String msg, [error]) {
+    msg = _formatErrorMessage(msg, error);
     _print("Error: $msg");
   }
 
diff --git a/tools/version.dart b/tools/version.dart
index eb10ac7..6972667 100644
--- a/tools/version.dart
+++ b/tools/version.dart
@@ -4,6 +4,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:io";
+import "dart:async" show getAttachedStackTrace;
 import "release/version.dart";
 
 void main() {
@@ -14,6 +15,8 @@
     print(currentVersion);
   }).catchError((e) {
     print("Could not create version number, failed with: $e");
+    var trace = getAttachedStackTrace(e);
+    if (trace != null) print("StackTrace: $trace");
     return true;
   });
 }
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index b7783b4..233f9be 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -155,6 +155,8 @@
       .then((_) => print(apidoc.status))
       .catchError((e) {
         print('Error: generation failed: ${e}');
+        var trace = getAttachedStackTrace(e);
+        if (trace != null) print("StackTrace: $trace");
         apidoc.cleanup();
         exit(1);
       })
diff --git a/utils/apidoc/mdn/extract.dart b/utils/apidoc/mdn/extract.dart
index 65d753b..2e2d766 100644
--- a/utils/apidoc/mdn/extract.dart
+++ b/utils/apidoc/mdn/extract.dart
@@ -1,3 +1,8 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:collection";
 import 'dart:html';
 import 'dart:json' as json;
 
@@ -477,7 +482,7 @@
   }
 }
 
-class PostOrderTraversal extends Iterable<Node> {
+class PostOrderTraversal extends IterableBase<Node> {
   final Node _node;
   PostOrderTraversal(this._node);
 
diff --git a/utils/lib/file_system_vm.dart b/utils/lib/file_system_vm.dart
index 7c09b70..d84d081 100644
--- a/utils/lib/file_system_vm.dart
+++ b/utils/lib/file_system_vm.dart
@@ -21,7 +21,7 @@
     var file = (new File(filename)).openSync();
     var length = file.lengthSync();
     var buffer = new List<int>(length);
-    var bytes = file.readListSync(buffer, 0, length);
+    var bytes = file.readIntoSync(buffer, 0, length);
     file.closeSync();
     return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
   }
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index 1948ba1..8fa94df 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -83,18 +83,18 @@
         return location;
       }).then((location) => client.get(location))
         .then(handleJsonSuccess);
-    }).catchError((asyncError) {
-      if (asyncError.error is! PubHttpException) throw asyncError;
-      var url = asyncError.error.response.request.url;
+    }).catchError((error) {
+      if (error is! PubHttpException) throw error;
+      var url = error.response.request.url;
       if (urisEqual(url, cloudStorageUrl)) {
         // TODO(nweiz): the response may have XML-formatted information about
         // the error. Try to parse that out once we have an easily-accessible
         // XML parser.
         throw 'Failed to upload the package.';
       } else if (urisEqual(Uri.parse(url.origin), Uri.parse(server.origin))) {
-        handleJsonError(asyncError.error.response);
+        handleJsonError(error.response);
       } else {
-        throw asyncError;
+        throw error;
       }
     });
   }
diff --git a/utils/pub/command_uploader.dart b/utils/pub/command_uploader.dart
index 673a4bd..5bb05f2 100644
--- a/utils/pub/command_uploader.dart
+++ b/utils/pub/command_uploader.dart
@@ -59,7 +59,7 @@
       exit(exit_codes.USAGE);
     }
 
-    return new Future.of(() {
+    return new Future.sync(() {
       var package = commandOptions['package'];
       if (package != null) return package;
       return new Entrypoint(path.current, cache).root.name;
@@ -76,9 +76,8 @@
           return client.delete(url);
         }
       });
-    }).then(handleJsonSuccess).catchError((asyncError) {
-      if (asyncError.error is! PubHttpException) throw asyncError;
-      handleJsonError(asyncError.error.response);
-    });
+    }).then(handleJsonSuccess)
+      .catchError((error) => handleJsonError(error.response),
+                  test: (e) => e is PubHttpException);
   }
 }
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index db6ad47..fe058c4 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -71,7 +71,7 @@
     if (pendingOrCompleted != null) return pendingOrCompleted;
 
     var packageDir = path.join(packagesDir, id.name);
-    var future = new Future.of(() {
+    var future = new Future.sync(() {
       ensureDir(path.dirname(packageDir));
 
       if (entryExists(packageDir)) {
@@ -102,7 +102,7 @@
   /// directory, respecting the [LockFile] if present. Returns a [Future] that
   /// completes when all dependencies are installed.
   Future installDependencies() {
-    return new Future.of(() {
+    return new Future.sync(() {
       return resolveVersions(cache.sources, root, loadLockFile());
     }).then(_installDependencies);
   }
@@ -119,7 +119,7 @@
   /// other dependencies as specified by the [LockFile] if possible. Returns a
   /// [Future] that completes when all dependencies are installed.
   Future updateDependencies(List<String> dependencies) {
-    return new Future.of(() {
+    return new Future.sync(() {
       var solver = new VersionSolver(cache.sources, root, loadLockFile());
       for (var dependency in dependencies) {
         solver.useLatestVersion(dependency);
@@ -131,10 +131,10 @@
   /// Removes the old packages directory, installs all dependencies listed in
   /// [packageVersions], and writes a [LockFile].
   Future _installDependencies(List<PackageId> packageVersions) {
-    return new Future.of(() {
+    return new Future.sync(() {
       cleanDir(packagesDir);
       return Future.wait(packageVersions.map((id) {
-        if (id.isRoot) return new Future.immediate(id);
+        if (id.isRoot) return new Future.value(id);
         return install(id);
       }).toList());
     }).then((ids) {
@@ -148,13 +148,13 @@
   /// reached packages. This should only be called after the lockfile has been
   /// successfully generated.
   Future<List<Pubspec>> walkDependencies() {
-    return new Future.of(() {
+    return new Future.sync(() {
       var lockFile = loadLockFile();
       var group = new FutureGroup<Pubspec>();
       var visited = new Set<String>();
 
       // Include the root package in the results.
-      group.add(new Future.immediate(root.pubspec));
+      group.add(new Future.value(root.pubspec));
 
       visitPackage(Pubspec pubspec) {
         for (var ref in pubspec.dependencies) {
@@ -166,7 +166,7 @@
           visited.add(ref.name);
           var future;
           if (ref.name == root.name) {
-            future = new Future<Pubspec>.immediate(root.pubspec);
+            future = new Future<Pubspec>.value(root.pubspec);
           } else {
             future = cache.describe(id);
           }
diff --git a/utils/pub/error_group.dart b/utils/pub/error_group.dart
index b5f8f8e..694638c 100644
--- a/utils/pub/error_group.dart
+++ b/utils/pub/error_group.dart
@@ -103,7 +103,7 @@
   ///
   /// If all members of [this] have already completed successfully or with an
   /// error, it's a [StateError] to try to signal an error.
-  void signalError(AsyncError error) {
+  void signalError(var error) {
     if (_isDone) {
       throw new StateError("Can't signal errors on a complete ErrorGroup.");
     }
@@ -113,7 +113,7 @@
 
   /// Signal an error internally. This is just like [signalError], but instead
   /// of throwing an error if [this] is complete, it just does nothing.
-  void _signalError(AsyncError error) {
+  void _signalError(var error) {
     if (_isDone) return;
 
     var caught = false;
@@ -181,12 +181,12 @@
     _completer.future.catchError((_) {});
   }
 
-  Future then(onValue(value), {onError(AsyncError asyncError)}) {
+  Future then(onValue(value), {onError(error)}) {
     _hasListeners = true;
     return _completer.future.then(onValue, onError: onError);
   }
 
-  Future catchError(onError(AsyncError asyncError), {bool test(Object error)}) {
+  Future catchError(onError(error), {bool test(Object error)}) {
     _hasListeners = true;
     return _completer.future.catchError(onError, test: test);
   }
@@ -203,8 +203,8 @@
 
   /// Signal that an error from [_group] should be propagated through [this],
   /// unless it's already complete.
-  void _signalError(AsyncError error) {
-    if (!_isDone) _completer.completeError(error.error, error.stackTrace);
+  void _signalError(var error) {
+    if (!_isDone) _completer.completeError(error);
     _isDone = true;
   }
 }
@@ -225,6 +225,10 @@
   /// The underlying [StreamController] for [this].
   final StreamController _controller;
 
+  /// The controller's [Stream]. May be different than `_controller.stream` if
+  /// the wrapped stream is a broadcasting stream.
+  Stream _stream;
+
   /// The [StreamSubscription] that connects the wrapped [Stream] to
   /// [_controller].
   StreamSubscription _subscription;
@@ -235,9 +239,10 @@
   /// Creates a new [_ErrorGroupFuture] that's a child of [_group] and wraps
   /// [inner].
   _ErrorGroupStream(this._group, Stream inner)
-    : _controller = inner.isBroadcast ?
-          new StreamController.broadcast() :
-          new StreamController() {
+    : _controller = new StreamController() {
+    this._stream = inner.isBroadcast
+        ? _controller.stream.asBroadcastStream()
+        : _controller.stream;
     _subscription = inner.listen((v) {
       _controller.add(v);
     }, onError: (e) {
@@ -250,22 +255,22 @@
   }
 
   StreamSubscription listen(void onData(value),
-      {void onError(AsyncError error), void onDone(),
-       bool unsubscribeOnError}) {
-    return _controller.stream.listen(onData,
+      {void onError(var error), void onDone(),
+       bool cancelOnError}) {
+    return _stream.listen(onData,
         onError: onError,
         onDone: onDone,
-        unsubscribeOnError: true);
+        cancelOnError: true);
   }
 
   /// Signal that an error from [_group] should be propagated through [this],
   /// unless it's already complete.
-  void _signalError(AsyncError e) {
+  void _signalError(var e) {
     if (_isDone) return;
     _subscription.cancel();
     // Call these asynchronously to work around issue 7913.
-    new Future.immediate(null).then((_) {
-      _controller.addError(e.error, e.stackTrace);
+    new Future.value().then((_) {
+      _controller.addError(e);
       _controller.close();
     });
   }
diff --git a/utils/pub/git.dart b/utils/pub/git.dart
index 53ecbe7..8d996229 100644
--- a/utils/pub/git.dart
+++ b/utils/pub/git.dart
@@ -13,7 +13,7 @@
 /// Tests whether or not the git command-line app is available for use.
 Future<bool> get isInstalled {
   if (_isGitInstalledCache != null) {
-    return new Future.immediate(_isGitInstalledCache);
+    return new Future.value(_isGitInstalledCache);
   }
 
   return _gitCommand.then((git) => git != null);
@@ -44,7 +44,7 @@
 /// found on the user's PATH.
 Future<String> get _gitCommand {
   if (_gitCommandCache != null) {
-    return new Future.immediate(_gitCommandCache);
+    return new Future.value(_gitCommandCache);
   }
 
   return _tryGitCommand("git").then((success) {
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index cea2bac..c98616d 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -123,7 +123,7 @@
   /// future that completes once this is finished and throws an exception if it
   /// fails.
   Future _ensureRepoCache(PackageId id) {
-    return new Future.of(() {
+    return new Future.sync(() {
       var path = _repoCachePath(id);
       if (!entryExists(path)) return _clone(_getUrl(id), path, mirror: true);
       return git.run(["fetch"], workingDir: path).then((result) => null);
@@ -143,12 +143,12 @@
   /// the working tree, but instead makes the repository a local mirror of the
   /// remote repository. See the manpage for `git clone` for more information.
   Future _clone(String from, String to, {bool mirror: false}) {
-    return new Future.of(() {
+    return new Future.sync(() {
       // Git on Windows does not seem to automatically create the destination
       // directory.
       ensureDir(to);
       var args = ["clone", from, to];
-      if (mirror) args.insertRange(1, 1, "--mirror");
+      if (mirror) args.insert(1, "--mirror");
       return git.run(args);
     }).then((result) => null);
   }
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index 0ed4e0c..5a4106e 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -63,7 +63,7 @@
 
   /// Downloads a package from the site and unpacks it.
   Future<bool> install(PackageId id, String destPath) {
-    return new Future.of(() {
+    return new Future.sync(() {
       var url = _makeVersionUrl(id, (server, package, version) =>
           "$server/packages/$package/versions/$version.tar.gz");
       log.io("Install package from $url.");
@@ -98,7 +98,7 @@
       return '%${match[0].codeUnitAt(0)}';
     });
 
-    return new Future.immediate(
+    return new Future.value(
         path.join(systemCacheRoot, urlDir, "${parsed.first}-${id.version}"));
   }
 
@@ -130,23 +130,23 @@
   /// When an error occurs trying to read something about [package] from [url],
   /// this tries to translate into a more user friendly error message. Always
   /// throws an error, either the original one or a better one.
-  void _throwFriendlyError(AsyncError asyncError, package, url) {
-    if (asyncError.error is PubHttpException &&
-        asyncError.error.response.statusCode == 404) {
+  void _throwFriendlyError(error, package, url) {
+    if (error is PubHttpException &&
+        error.response.statusCode == 404) {
       throw 'Could not find package "$package" at $url.';
     }
 
-    if (asyncError.error is TimeoutException) {
+    if (error is TimeoutException) {
       throw 'Timed out trying to find package "$package" at $url.';
     }
 
-    if (asyncError.error is io.SocketIOException) {
+    if (error is io.SocketIOException) {
       throw 'Got socket error trying to find package "$package" at $url.\n'
-          '${asyncError.error.osError}';
+          '${error.osError}';
     }
 
     // Otherwise re-throw the original exception.
-    throw asyncError;
+    throw error;
   }
 
 }
diff --git a/utils/pub/http.dart b/utils/pub/http.dart
index dadc4b1..8df0575 100644
--- a/utils/pub/http.dart
+++ b/utils/pub/http.dart
@@ -61,21 +61,21 @@
       return http.Response.fromStream(streamedResponse).then((response) {
         throw new PubHttpException(response);
       });
-    }).catchError((asyncError) {
-      if (asyncError.error is SocketIOException &&
-          asyncError.error.osError != null) {
-        if (asyncError.error.osError.errorCode == 8 ||
-            asyncError.error.osError.errorCode == -2 ||
-            asyncError.error.osError.errorCode == -5 ||
-            asyncError.error.osError.errorCode == 11001 ||
-            asyncError.error.osError.errorCode == 11004) {
+    }).catchError((error) {
+      if (error is SocketIOException &&
+          error.osError != null) {
+        if (error.osError.errorCode == 8 ||
+            error.osError.errorCode == -2 ||
+            error.osError.errorCode == -5 ||
+            error.osError.errorCode == 11001 ||
+            error.osError.errorCode == 11004) {
           throw 'Could not resolve URL "${request.url.origin}".';
-        } else if (asyncError.error.osError.errorCode == -12276) {
+        } else if (error.osError.errorCode == -12276) {
           throw 'Unable to validate SSL certificate for '
               '"${request.url.origin}".';
         }
       }
-      throw asyncError;
+      throw error;
     }), HTTP_TIMEOUT, 'fetching URL "${request.url}"');
   }
 
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 8523d34..32c4574 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -69,7 +69,7 @@
 String writeBinaryFile(String file, List<int> contents) {
   log.io("Writing ${contents.length} bytes to binary file $file.");
   new File(file).openSync(mode: FileMode.WRITE)
-      ..writeListSync(contents, 0, contents.length)
+      ..writeFromSync(contents)
       ..closeSync();
   log.fine("Wrote text file $file.");
   return file;
@@ -284,10 +284,12 @@
 
 /// A sink that writes to standard output. Errors piped to this stream will be
 /// surfaced to the top-level error handler.
+// TODO: Unrequired wrapper, stdout is now an EventSink<List<int>>.
 final EventSink<List<int>> stdoutSink = _wrapStdio(stdout, "stdout");
 
 /// A sink that writes to standard error. Errors piped to this stream will be
 /// surfaced to the top-level error handler.
+// TODO: Unrequired wrapper, stdout is now an EventSink<List<int>>.
 final EventSink<List<int>> stderrSink = _wrapStdio(stderr, "stderr");
 
 /// Wrap the standard output or error [stream] in a [EventSink]. Any errors are
@@ -297,7 +299,7 @@
   pair.last.catchError((e) {
     // This log may or may not work, depending on how the stream failed. Not
     // much we can do about that.
-    log.error("Error writing to $name: $e");
+    log.error("Error writing to $name", e);
     exit(exit_codes.IO);
   });
   return pair.first;
@@ -341,17 +343,17 @@
 /// true.
 ///
 /// When an error occurs on [stream], that error is passed to [sink]. If
-/// [unsubscribeOnError] is true, [Future] will be completed successfully and no
+/// [cancelOnError] is true, [Future] will be completed successfully and no
 /// more data or errors will be piped from [stream] to [sink]. If
-/// [unsubscribeOnError] and [closeSink] are both true, [sink] will then be
+/// [cancelOnError] and [closeSink] are both true, [sink] will then be
 /// closed.
 Future store(Stream stream, EventSink sink,
-    {bool unsubscribeOnError: true, closeSink: true}) {
+    {bool cancelOnError: true, closeSink: true}) {
   var completer = new Completer();
   stream.listen(sink.add,
       onError: (e) {
         sink.addError(e);
-        if (unsubscribeOnError) {
+        if (cancelOnError) {
           completer.complete();
           if (closeSink) sink.close();
         }
@@ -359,7 +361,7 @@
       onDone: () {
         if (closeSink) sink.close();
         completer.complete();
-      }, unsubscribeOnError: unsubscribeOnError);
+      }, cancelOnError: cancelOnError);
   return completer.future;
 }
 
@@ -548,9 +550,9 @@
 /// Returns a future that completes to the value that the future returned from
 /// [fn] completes to.
 Future withTempDir(Future fn(String path)) {
-  return new Future.of(() {
+  return new Future.sync(() {
     var tempDir = createTempDir();
-    return new Future.of(() => fn(tempDir))
+    return new Future.sync(() => fn(tempDir))
         .whenComplete(() => deleteEntry(tempDir));
   });
 }
@@ -668,7 +670,7 @@
     }).catchError((e) {
       // We don't have to worry about double-signaling here, since the store()
       // above will only be reached if startProcess succeeds.
-      controller.addError(e.error, e.stackTrace);
+      controller.addError(e);
       controller.close();
     });
     return new ByteStream(controller.stream);
@@ -705,7 +707,7 @@
   }).catchError((e) {
     // We don't have to worry about double-signaling here, since the store()
     // above will only be reached if everything succeeds.
-    controller.addError(e.error, e.stackTrace);
+    controller.addError(e);
     controller.close();
   });
   return new ByteStream(controller.stream);
diff --git a/utils/pub/log.dart b/utils/pub/log.dart
index ec3fee9..891ba7d 100644
--- a/utils/pub/log.dart
+++ b/utils/pub/log.dart
@@ -57,7 +57,16 @@
 }
 
 /// Logs [message] at [Level.ERROR].
-void error(message) => write(Level.ERROR, message);
+void error(message, [error]) {
+  if (error != null) {
+    message = "$message: $error";
+    var trace = getAttachedStackTrace(error);
+    if (trace != null) {
+      message = "$message\nStackTrace: $trace";
+    }
+  }
+  write(Level.ERROR, message);
+}
 
 /// Logs [message] at [Level.WARNING].
 void warning(message) => write(Level.WARNING, message);
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index 85bfed7..e4b8ee0 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -82,21 +82,21 @@
       // Be sure to save the credentials even when an error happens.
       _saveCredentials(cache, client.credentials);
     });
-  }).catchError((asyncError) {
-    if (asyncError.error is ExpirationException) {
+  }).catchError((error) {
+    if (error is ExpirationException) {
       log.error("Pub's authorization to upload packages has expired and "
           "can't be automatically refreshed.");
       return withClient(cache, fn);
-    } else if (asyncError.error is AuthorizationException) {
+    } else if (error is AuthorizationException) {
       var message = "OAuth2 authorization failed";
-      if (asyncError.error.description != null) {
-        message = "$message (${asyncError.error.description})";
+      if (error.description != null) {
+        message = "$message (${error.description})";
       }
       log.error("$message.");
       clearCredentials(cache);
       return withClient(cache, fn);
     } else {
-      throw asyncError;
+      throw error;
     }
   });
 }
@@ -104,7 +104,7 @@
 /// Gets a new OAuth2 client. If saved credentials are available, those are
 /// used; otherwise, the user is prompted to authorize the pub client.
 Future<Client> _getClient(SystemCache cache) {
-  return new Future.of(() {
+  return new Future.sync(() {
     var credentials = _loadCredentials(cache);
     if (credentials == null) return _authorize();
 
diff --git a/utils/pub/path_source.dart b/utils/pub/path_source.dart
index e849b6f..e4d1f02 100644
--- a/utils/pub/path_source.dart
+++ b/utils/pub/path_source.dart
@@ -25,7 +25,7 @@
   final shouldCache = false;
 
   Future<Pubspec> describe(PackageId id) {
-    return new Future.of(() {
+    return new Future.sync(() {
       _validatePath(id.name, id.description);
       return new Pubspec.load(id.name, id.description["path"],
           systemCache.sources);
@@ -40,7 +40,7 @@
   }
 
   Future<bool> install(PackageId id, String destination) {
-    return new Future.of(() {
+    return new Future.sync(() {
       try {
         _validatePath(id.name, id.description);
       } on FormatException catch(err) {
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index 811c198..9af9c27 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -145,7 +145,7 @@
 /// Checks that pub is running on a supported platform. If it isn't, it prints
 /// an error message and exits. Completes when the validation is done.
 Future validatePlatform() {
-  return new Future.of(() {
+  return new Future.sync(() {
     if (Platform.operatingSystem != 'windows') return;
 
     return runProcess('ver', []).then((result) {
@@ -236,7 +236,9 @@
       exit(exit_codes.USAGE);
     }
 
-    handleError(error, trace) {
+    handleError(error) {
+      var trace = getAttachedStackTrace(error);
+
       // This is basically the top-level exception handler so that we don't
       // spew a stack trace on our users.
       var message;
@@ -265,7 +267,7 @@
       exit(_chooseExitCode(error));
     }
 
-    new Future.of(() {
+    new Future.sync(() {
       if (requiresEntrypoint) {
         // TODO(rnystrom): Will eventually need better logic to walk up
         // subdirectories until we hit one that looks package-like. For now,
@@ -277,8 +279,7 @@
       if (commandFuture == null) return true;
 
       return commandFuture;
-    }).whenComplete(() => cache_.deleteTempDir()).catchError((asyncError) {
-      var e = asyncError.error;
+    }).whenComplete(() => cache_.deleteTempDir()).catchError((e) {
       if (e is PubspecNotFoundException && e.name == null) {
         e = 'Could not find a file named "pubspec.yaml" in the directory '
           '${path.current}.';
@@ -287,7 +288,7 @@
           '${path.basename(path.current)}").';
       }
 
-      handleError(e, asyncError.stackTrace);
+      handleError(e);
     }).then((_) {
       // Explicitly exit on success to ensure that any dangling dart:io handles
       // don't cause the process to never terminate.
diff --git a/utils/pub/safe_http_server.dart b/utils/pub/safe_http_server.dart
index 8843e48..79417bc 100644
--- a/utils/pub/safe_http_server.dart
+++ b/utils/pub/safe_http_server.dart
@@ -42,23 +42,22 @@
   HttpConnectionsInfo connectionsInfo() => _inner.connectionsInfo();
 
   StreamSubscription<HttpRequest> listen(void onData(HttpRequest value),
-      {void onError(AsyncError error), void onDone(),
-      bool unsubscribeOnError: false}) {
+      {void onError(error), void onDone(),
+      bool cancelOnError: false}) {
     var subscription;
     subscription = super.listen((request) {
       onData(new _HttpRequestWrapper(request));
-    }, onError: (e) {
-      var error = e.error;
+    }, onError: (error) {
       // Ignore socket error 104, which is caused by a request being cancelled
       // before it writes any headers. There's no reason to care about such
       // requests.
       if (error is SocketIOException && error.osError.errorCode == 104) return;
       // Ignore any parsing errors, which come from malformed requests.
       if (error is HttpParserException) return;
-      // Manually handle unsubscribeOnError so the above (ignored) errors don't
+      // Manually handle cancelOnError so the above (ignored) errors don't
       // cause unsubscription.
-      if (unsubscribeOnError) subscription.cancel();
-      if (onError != null) onError(e);
+      if (cancelOnError) subscription.cancel();
+      if (onError != null) onError(error);
     }, onDone: onDone);
     return subscription;
   }
@@ -132,12 +131,8 @@
   Future<Socket> detachSocket() => _inner.detachSocket();
   HttpConnectionInfo get connectionInfo => _inner.connectionInfo;
   void add(List<int> data) => _inner.add(data);
-  Future<HttpResponse> consume(Stream<List<int>> stream) =>
-    _inner.consume(stream);
   Future<HttpResponse> addStream(Stream<List<int>> stream) =>
     _inner.addStream(stream);
-  Future<HttpResponse> writeStream(Stream<List<int>> stream) =>
-    _inner.writeStream(stream);
   Future close() => _inner.close();
   void write(Object obj) => _inner.write(obj);
   void writeAll(Iterable objects) => _inner.writeAll(objects);
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index adb9571..b5e5d53 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -154,7 +154,7 @@
   ///
   /// This doesn't need to be implemented if [shouldCache] is false.
   Future<String> systemCacheDirectory(PackageId id) {
-    return new Future.immediateError(
+    return new Future.error(
         "systemCacheDirectory() must be implemented if shouldCache is true.");
   }
 
@@ -206,7 +206,7 @@
   /// [descriptionsEqual].
   ///
   /// By default, this just returns [id].
-  Future<PackageId> resolveId(PackageId id) => new Future.immediate(id);
+  Future<PackageId> resolveId(PackageId id) => new Future.value(id);
   
   /// Returns the [Package]s that have been installed in the system cache.
   List<Package> getCachedPackages() {
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index 47c27fc..5e80e57 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -59,7 +59,7 @@
       if (completed) return;
 
       completed = true;
-      _completer.completeError(e.error, e.stackTrace);
+      _completer.completeError(e);
     }));
 
     return task;
@@ -156,7 +156,7 @@
 /// to [completer].
 void chainToCompleter(Future future, Completer completer) {
   future.then((value) => completer.complete(value),
-      onError: (e) => completer.completeError(e.error, e.stackTrace));
+      onError: (e) => completer.completeError(e));
 }
 
 // TODO(nweiz): remove this when issue 7964 is fixed.
@@ -169,23 +169,24 @@
     subscription.cancel();
     completer.complete(value);
   }, onError: (e) {
-    completer.completeError(e.error, e.stackTrace);
+    completer.completeError(e);
   }, onDone: () {
     completer.completeError(new StateError("No elements"));
-  }, unsubscribeOnError: true);
+  }, cancelOnError: true);
   return completer.future;
 }
 
 /// Returns a wrapped version of [stream] along with a [StreamSubscription] that
 /// can be used to control the wrapped stream.
 Pair<Stream, StreamSubscription> streamWithSubscription(Stream stream) {
-  var controller = stream.isBroadcast ?
-      new StreamController.broadcast() :
-      new StreamController();
+  var controller = new StreamController();
+  var controllerStream = stream.isBroadcast ?
+      controller.stream.asBroadcastStream() :
+      controller.stream;
   var subscription = stream.listen(controller.add,
       onError: controller.addError,
       onDone: controller.close);
-  return new Pair<Stream, StreamSubscription>(controller.stream, subscription);
+  return new Pair<Stream, StreamSubscription>(controllerStream, subscription);
 }
 
 // TODO(nweiz): remove this when issue 7787 is fixed.
@@ -248,7 +249,7 @@
 Future<Iterable> futureWhere(Iterable iter, test(value)) {
   return Future.wait(iter.map((e) {
     var result = test(e);
-    if (result is! Future) result = new Future.immediate(result);
+    if (result is! Future) result = new Future.value(result);
     return result.then((result) => new Pair(e, result));
   }))
       .then((pairs) => pairs.where((pair) => pair.last))
@@ -342,7 +343,7 @@
   if (object is Iterable) {
     return Future.wait(object.map(awaitObject).toList());
   }
-  if (object is! Map) return new Future.immediate(object);
+  if (object is! Map) return new Future.value(object);
 
   var pairs = <Future<Pair>>[];
   object.forEach((key, value) {
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
index 1998c47..45a8fba 100644
--- a/utils/pub/validator/compiled_dartdoc.dart
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -20,7 +20,7 @@
     : super(entrypoint);
 
   Future validate() {
-    return new Future.of(() {
+    return new Future.sync(() {
       for (var entry in listDir(entrypoint.root.dir, recursive: true)) {
         if (path.basename(entry) != "nav.json") continue;
         var dir = path.dirname(entry);
diff --git a/utils/pub/validator/dependency.dart b/utils/pub/validator/dependency.dart
index d66059d..711e82d 100644
--- a/utils/pub/validator/dependency.dart
+++ b/utils/pub/validator/dependency.dart
@@ -31,12 +31,12 @@
                 'package.\n'
             'Pub enables "package:${entrypoint.root.name}" imports '
                 'implicitly.');
-        return new Future.immediate(null);
+        return new Future.value();
       }
 
       if (dependency.constraint.isAny) _warnAboutConstraint(dependency);
 
-      return new Future.immediate(null);
+      return new Future.value();
     });
   }
 
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
index 5d6628d..216f2bf 100644
--- a/utils/pub/validator/directory.dart
+++ b/utils/pub/validator/directory.dart
@@ -21,7 +21,7 @@
   static final _PLURAL_NAMES = ["tools", "tests", "docs", "examples"];
 
   Future validate() {
-    return new Future.of(() {
+    return new Future.sync(() {
       for (var dir in listDir(entrypoint.root.dir)) {
         if (!dirExists(dir)) continue;
 
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index 7ff06fc..2e72738 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -23,7 +23,7 @@
     : super(entrypoint);
 
   Future validate() {
-    return new Future.of(() {
+    return new Future.sync(() {
       var libDir = path.join(entrypoint.root.dir, "lib");
 
       if (!dirExists(libDir)) {
diff --git a/utils/pub/validator/license.dart b/utils/pub/validator/license.dart
index ffcbd10..50d1bfe 100644
--- a/utils/pub/validator/license.dart
+++ b/utils/pub/validator/license.dart
@@ -19,7 +19,7 @@
     : super(entrypoint);
 
   Future validate() {
-    return new Future.of(() {
+    return new Future.sync(() {
       var licenseLike = new RegExp(
           r"^([a-zA-Z0-9]+[-_])?(LICENSE|COPYING)(\..*)?$");
       if (listDir(entrypoint.root.dir)
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index 412d6c3..542d9fd 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -28,7 +28,7 @@
     : super(entrypoint);
 
   Future validate() {
-    return new Future.of(() {
+    return new Future.sync(() {
       _checkName(entrypoint.root.name, 'Package name "${entrypoint.root.name}"',
           isPackage: true);
 
diff --git a/utils/pub/validator/pubspec_field.dart b/utils/pub/validator/pubspec_field.dart
index e87f38b..03a1b8e 100644
--- a/utils/pub/validator/pubspec_field.dart
+++ b/utils/pub/validator/pubspec_field.dart
@@ -56,6 +56,6 @@
       errors.add('Your pubspec.yaml is missing a "version" field.');
     }
 
-    return new Future.immediate(null);
+    return new Future.value();
   }
 }
diff --git a/utils/pub/validator/utf8_readme.dart b/utils/pub/validator/utf8_readme.dart
index 8bf52a9..cbb85c4 100644
--- a/utils/pub/validator/utf8_readme.dart
+++ b/utils/pub/validator/utf8_readme.dart
@@ -20,7 +20,7 @@
     : super(entrypoint);
 
   Future validate() {
-    return new Future.of(() {
+    return new Future.sync(() {
       var readme = entrypoint.root.readmePath;
       if (readme == null) return;
       var bytes = readBinaryFile(readme);
diff --git a/utils/pub/version_solver.dart b/utils/pub/version_solver.dart
index 5b055d8..36569ba 100644
--- a/utils/pub/version_solver.dart
+++ b/utils/pub/version_solver.dart
@@ -97,7 +97,7 @@
     Future processNextWorkItem(_) {
       while (true) {
         // Stop if we are done.
-        if (_work.isEmpty) return new Future.immediate(buildResults());
+        if (_work.isEmpty) return new Future.value(buildResults());
 
         // If we appear to be stuck in a loop, then we probably have an unstable
         // graph, bail. We guess this based on a rough heuristic that it should
@@ -284,8 +284,7 @@
       Version version) {
     // If there is no version, it means no package, so no dependencies.
     if (version == null) {
-      return new Future<Map<String, PackageRef>>.immediate(
-          <String, PackageRef>{});
+      return new Future<Map<String, PackageRef>>.value(<String, PackageRef>{});
     }
 
     var id = new PackageId(package, source, version, description);
@@ -475,7 +474,7 @@
   Future<Pubspec> load(PackageId id) {
     // Complete immediately if it's already cached.
     if (_pubspecs.containsKey(id)) {
-      return new Future<Pubspec>.immediate(_pubspecs[id]);
+      return new Future<Pubspec>.value(_pubspecs[id]);
     }
 
     return id.describe().then((pubspec) {
diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
index 1efd7d1d..2fbc3cd 100644
--- a/utils/tests/pub/command_line_config.dart
+++ b/utils/tests/pub/command_line_config.dart
@@ -5,7 +5,7 @@
 library command_line_config;
 
 import 'dart:io';
-import 'dart:math';
+import 'dart:math' as math;
 
 import 'package:pathos/path.dart' as path;
 import 'package:unittest/unittest.dart';
@@ -92,7 +92,7 @@
     if (stack.length == 0) return;
 
     // Figure out the longest path so we know how much to pad.
-    int longest = stack.map((frame) => frame.location.length).reduce(max);
+    int longest = stack.map((frame) => frame.location.length).reduce(math.max);
 
     // Print out the stack trace nicely formatted.
     for (var frame in stack) {
diff --git a/utils/tests/pub/error_group_test.dart b/utils/tests/pub/error_group_test.dart
index e7aa477..3460ddd 100644
--- a/utils/tests/pub/error_group_test.dart
+++ b/utils/tests/pub/error_group_test.dart
@@ -28,15 +28,15 @@
 
     test('should pass signaled errors to .done', () {
       expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
     });
 
     test("shouldn't allow additional futures or streams once an error has been "
         "signaled", () {
       expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
 
-      expect(() => errorGroup.registerFuture(new Future.immediate(null)),
+      expect(() => errorGroup.registerFuture(new Future.value()),
           throwsStateError);
       expect(() => errorGroup.registerStream(new StreamController().stream),
           throwsStateError);
@@ -63,7 +63,7 @@
         "been called", () {
       completer.complete('value');
 
-      expect(() => errorGroup.registerFuture(new Future.immediate(null)),
+      expect(() => errorGroup.registerFuture(new Future.value()),
           throwsStateError);
       expect(() => errorGroup.registerStream(new StreamController().stream),
           throwsStateError);
@@ -87,7 +87,7 @@
         'and should ignore a subsequent value from that future', () {
       expect(future, throwsFormatException);
       // errorGroup shouldn't top-level the exception
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
       completer.complete('value');
     });
 
@@ -95,7 +95,7 @@
         'and should ignore a subsequent exception from that future', () {
       expect(future, throwsFormatException);
       // errorGroup shouldn't top-level the exception
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
       completer.completeError(new ArgumentError());
     });
 
@@ -103,7 +103,7 @@
         'future has a listener', () {
       expect(future, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
     });
 
     test("should complete .done if the future receives a value even if the "
@@ -131,7 +131,7 @@
         "a listener",
         () {
       expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
 
       // A listener added afterwards should receive the exception
       expect(errorGroup.done.catchError((_) {
@@ -192,7 +192,7 @@
 
       expect(future1.then((_) {
         // shouldn't cause a top-level exception
-        errorGroup.signalError(new AsyncError(new FormatException()));
+        errorGroup.signalError(new FormatException());
       }), completes);
     });
   });
@@ -203,8 +203,8 @@
 
     setUp(() {
       errorGroup = new ErrorGroup();
-      controller = new StreamController.broadcast();
-      stream = errorGroup.registerStream(controller.stream);
+      controller = new StreamController();
+      stream = errorGroup.registerStream(controller.stream.asBroadcastStream());
     });
 
     test('should pass through values from the stream', () {
@@ -219,21 +219,21 @@
         'listener', () {
       expect(stream.first, throwsFormatException);
       // errorGroup shouldn't top-level the exception
-      controller.addError(new AsyncError(new FormatException()));
+      controller.addError(new FormatException());
     });
 
     test('should notify the error group of an exception from the stream even '
         'if it has a listener', () {
       expect(stream.first, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
-      controller.addError(new AsyncError(new FormatException()));
+      controller.addError(new FormatException());
     });
 
     test('should pass a signaled exception to the stream if it has a listener '
         'and should unsubscribe that stream', () {
       expect(stream.first, throwsFormatException);
       // errorGroup shouldn't top-level the exception
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
 
       expect(stream.first.catchError((_) {
         controller.add('value');
@@ -245,46 +245,21 @@
         'stream has a listener', () {
       expect(stream.first, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
     });
 
-    test("should complete .done when the stream is done even if the stream "
-        "doesn't have a listener", () {
+    test("should see one value and complete .done when the stream is done even "
+         "if the stream doesn't have a listener", () {
       expect(errorGroup.done, completes);
       controller.add('value');
       controller.close();
 
-      // A listener added afterwards should see an empty stream, since it's not
-      // single-subscription
+      // Now that broadcast controllers have been removed a listener should
+      // see the value that has been put into the controller.
       expect(errorGroup.done.then((_) => stream.toList()),
-          completion(isEmpty));
+          completion(equals(['value'])));
     });
 
-    test("should pipe an exception from the stream to .done if the stream "
-        "doesn't have a listener", () {
-      expect(errorGroup.done, throwsFormatException);
-      controller.addError(new AsyncError(new FormatException()));
-
-      // A listener added afterwards should see an empty stream, since it's not
-      // single-subscription
-      expect(errorGroup.done.catchError((_) {
-        controller.add('value'); // should be ignored
-        return stream.toList();
-      }), completion(isEmpty));
-    });
-
-    test("should pass a signaled exception to .done if the stream doesn't "
-        "have a listener",
-        () {
-      expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
-
-      // A listener added afterwards should receive the exception
-      expect(errorGroup.done.catchError((_) {
-        controller.add('value'); // should be ignored
-        return stream.toList();
-      }), completion(isEmpty));
-    });
   });
 
   group('with a single single-subscription stream', () {
@@ -311,7 +286,7 @@
     test("should pipe an exception from the stream to .done if the stream "
         "doesn't have a listener", () {
       expect(errorGroup.done, throwsFormatException);
-      controller.addError(new AsyncError(new FormatException()));
+      controller.addError(new FormatException());
 
       // A listener added afterwards should receive the exception
       expect(errorGroup.done.catchError((_) {
@@ -324,7 +299,7 @@
         "have a listener",
         () {
       expect(errorGroup.done, throwsFormatException);
-      errorGroup.signalError(new AsyncError(new FormatException()));
+      errorGroup.signalError(new FormatException());
 
       // A listener added afterwards should receive the exception
       expect(errorGroup.done.catchError((_) {
@@ -342,10 +317,10 @@
 
     setUp(() {
       errorGroup = new ErrorGroup();
-      controller1 = new StreamController.broadcast();
-      controller2 = new StreamController.broadcast();
-      stream1 = errorGroup.registerStream(controller1.stream);
-      stream2 = errorGroup.registerStream(controller2.stream);
+      controller1 = new StreamController();
+      controller2 = new StreamController();
+      stream1 = errorGroup.registerStream(controller1.stream.asBroadcastStream());
+      stream2 = errorGroup.registerStream(controller2.stream.asBroadcastStream());
     });
 
     test("should pipe exceptions from one stream to the other and to .done",
@@ -354,7 +329,7 @@
       expect(stream2.first, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
 
-      controller1.addError(new AsyncError(new FormatException()));
+      controller1.addError(new FormatException());
     });
 
     test("each future should be able to emit values independently", () {
@@ -373,7 +348,7 @@
 
       expect(stream1.toList().then((_) {
         // shouldn't cause a top-level exception
-        controller2.addError(new AsyncError(new FormatException()));
+        controller2.addError(new FormatException());
       }), completes);
     });
 
@@ -384,7 +359,7 @@
 
       expect(stream1.toList().then((_) {
         // shouldn't cause a top-level exception
-        errorGroup.signalError(new AsyncError(new FormatException()));
+        errorGroup.signalError(new FormatException());
       }), completes);
     });
   });
@@ -397,8 +372,8 @@
 
     setUp(() {
       errorGroup = new ErrorGroup();
-      controller = new StreamController.broadcast();
-      stream = errorGroup.registerStream(controller.stream);
+      controller = new StreamController();
+      stream = errorGroup.registerStream(controller.stream.asBroadcastStream());
       completer = new Completer();
       future = errorGroup.registerFuture(completer.future);
     });
@@ -408,7 +383,7 @@
       expect(future, throwsFormatException);
       expect(errorGroup.done, throwsFormatException);
 
-      controller.addError(new AsyncError(new FormatException()));
+      controller.addError(new FormatException());
     });
 
     test("should pipe exceptions from the future to the stream", () {
@@ -436,7 +411,7 @@
 
       expect(future.then((_) {
         // shouldn't cause a top-level exception
-        controller.addError(new AsyncError(new FormatException()));
+        controller.addError(new FormatException());
       }), completes);
     });
 
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 3ba46a4..ba04998 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -119,7 +119,7 @@
 /// Closes [_server]. Returns a [Future] that will complete after the [_server]
 /// is closed.
 Future _closeServer() {
-  if (_server == null) return new Future.immediate(null);
+  if (_server == null) return new Future.value();
   _server.close();
   _server = null;
   _portCompleterCache = null;
@@ -356,7 +356,7 @@
       '--trace'];
   dartArgs.addAll(args);
 
-  if (tokenEndpoint == null) tokenEndpoint = new Future.immediate(null);
+  if (tokenEndpoint == null) tokenEndpoint = new Future.value();
   var optionsFuture = tokenEndpoint.then((tokenEndpoint) {
     var options = new ProcessOptions();
     options.workingDirectory = pathInSandbox(appPath);
@@ -588,7 +588,7 @@
   return schedule(() {
     var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath));
 
-    return new Future.of(() {
+    return new Future.sync(() {
       var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache));
       return validator.validate().then((_) {
         return new Pair(validator.errors, validator.warnings);
diff --git a/utils/tests/pub/validator/dependency_test.dart b/utils/tests/pub/validator/dependency_test.dart
index de4d08e..4001330 100644
--- a/utils/tests/pub/validator/dependency_test.dart
+++ b/utils/tests/pub/validator/dependency_test.dart
@@ -38,9 +38,9 @@
     expect(request.url.path, equals("/packages/foo.json"));
 
     if (hostedVersions == null) {
-      return new Future.immediate(new http.Response("not found", 404));
+      return new Future.value(new http.Response("not found", 404));
     } else {
-      return new Future.immediate(new http.Response(json.stringify({
+      return new Future.value(new http.Response(json.stringify({
         "name": "foo",
         "uploaders": ["nweiz@google.com"],
         "versions": hostedVersions
diff --git a/utils/tests/pub/validator/size_test.dart b/utils/tests/pub/validator/size_test.dart
index 47c7d1e..3dd1e21 100644
--- a/utils/tests/pub/validator/size_test.dart
+++ b/utils/tests/pub/validator/size_test.dart
@@ -16,7 +16,7 @@
 
 Function size(int size) {
   return (entrypoint) =>
-      new SizeValidator(entrypoint, new Future.immediate(size));
+      new SizeValidator(entrypoint, new Future.value(size));
 }
 
 main() {
diff --git a/utils/tests/pub/version_solver_test.dart b/utils/tests/pub/version_solver_test.dart
index 94a7c58..845f597 100644
--- a/utils/tests/pub/version_solver_test.dart
+++ b/utils/tests/pub/version_solver_test.dart
@@ -481,11 +481,11 @@
       : _packages = <String, Map<Version, Package>>{};
 
   Future<List<Version>> getVersions(String name, String description) {
-    return new Future.of(() => _packages[description].keys.toList());
+    return new Future.sync(() => _packages[description].keys.toList());
   }
 
   Future<Pubspec> describe(PackageId id) {
-    return new Future.of(() => _packages[id.name][id.version].pubspec);
+    return new Future.sync(() => _packages[id.name][id.version].pubspec);
   }
 
   Future<bool> install(PackageId id, String path) {
diff --git a/utils/tests/string_encoding/benchmark_runner.dart b/utils/tests/string_encoding/benchmark_runner.dart
index 0463030..f29c4f9 100644
--- a/utils/tests/string_encoding/benchmark_runner.dart
+++ b/utils/tests/string_encoding/benchmark_runner.dart
@@ -168,17 +168,16 @@
   }
 
   String _leftAlign(String s, int width) {
-    List<int> outCodes = [];
-    outCodes.insertRange(0, width, spaceChar);
+    List<int> outCodes = new List<int>.filled(width, spaceChar);
     outCodes.setRange(0, Math.min(width, s.length), s.codeUnits);
     return new String.fromCharCodes(outCodes);
   }
 
   String _rightAlign(String s, int width) {
-    List<int> outCodes = [];
-    outCodes.insertRange(0, width, spaceChar);
-    outCodes.setRange(Math.max(0, width - s.length), Math.min(width, s.length),
-        s.codeUnits);
+    List<int> outCodes = new List<int>.filled(width, spaceChar);
+    int fromIndex = Math.max(0, width - s.length);
+    int length = Math.min(width, s.length);
+    outCodes.setRange(fromIndex, fromIndex + length, s.codeUnits);
     return new String.fromCharCodes(outCodes);
   }