Version 0.5.4.0 .

svn merge -r 22222:22342 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@22349 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/dart.gyp b/dart.gyp
index 1abc0ef..c4b0ddc 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -110,7 +110,6 @@
       'target_name': 'dart2js',
       'type': 'none',
       'dependencies': [
-        'third_party/v8/src/d8.gyp:d8',
         'utils/compiler/compiler.gyp:dart2js',
       ],
     },
@@ -150,7 +149,6 @@
       'target_name': 'dart2js_bot',
       'type': 'none',
       'dependencies': [
-        'third_party/v8/src/d8.gyp:d8',
         'create_sdk',
         'packages',
       ],
diff --git a/pkg/http/test/safe_http_server.dart b/pkg/http/test/safe_http_server.dart
index b6e1c83..25d57ee 100644
--- a/pkg/http/test/safe_http_server.dart
+++ b/pkg/http/test/safe_http_server.dart
@@ -21,9 +21,9 @@
 class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
   final HttpServer _inner;
 
-  static Future<SafeHttpServer> bind([String host = "127.0.0.1",
+  static Future<SafeHttpServer> bind([String host = "localhost",
       int port = 0, int backlog = 0]) {
-    return HttpServer.bind(host, port, backlog)
+    return HttpServer.bind(host, port, backlog: backlog)
         .then((server) => new SafeHttpServer(server));
   }
 
diff --git a/pkg/scheduled_test/lib/scheduled_server.dart b/pkg/scheduled_test/lib/scheduled_server.dart
index cb17268..1e4e633 100644
--- a/pkg/scheduled_test/lib/scheduled_server.dart
+++ b/pkg/scheduled_test/lib/scheduled_server.dart
@@ -48,7 +48,7 @@
 
     var scheduledServer;
     scheduledServer = new ScheduledServer._(schedule(() {
-      return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
+      return SafeHttpServer.bind("localhost", 0).then((server) {
         server.listen(scheduledServer._handleRequest,
             onError: (e) => currentSchedule.signalError(e));
         currentSchedule.onComplete.schedule(server.close);
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 b6e1c83..25d57ee 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
@@ -21,9 +21,9 @@
 class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
   final HttpServer _inner;
 
-  static Future<SafeHttpServer> bind([String host = "127.0.0.1",
+  static Future<SafeHttpServer> bind([String host = "localhost",
       int port = 0, int backlog = 0]) {
-    return HttpServer.bind(host, port, backlog)
+    return HttpServer.bind(host, port, backlog: backlog)
         .then((server) => new SafeHttpServer(server));
   }
 
diff --git a/pkg/scheduled_test/lib/src/utils.dart b/pkg/scheduled_test/lib/src/utils.dart
index 6e4c636..4bd4505 100644
--- a/pkg/scheduled_test/lib/src/utils.dart
+++ b/pkg/scheduled_test/lib/src/utils.dart
@@ -35,6 +35,7 @@
 /// Prepends each line in [text] with [prefix]. If [firstPrefix] is passed, the
 /// first line is prefixed with that instead.
 String prefixLines(String text, {String prefix: '| ', String firstPrefix}) {
+  if (text == null) return '';
   var lines = text.split('\n');
   if (firstPrefix == null) {
     return lines.map((line) => '$prefix$line').join('\n');
diff --git a/pkg/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index f05b469..cb7d656 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -85,7 +85,7 @@
       throw new FormatException("Couldn't parse stack trace line '$frame'.");
     }
 
-    var uri = new Uri.fromString(match[2]);
+    var uri = Uri.parse(match[2]);
     var member = match[1].replaceAll("<anonymous closure>", "<fn>");
     return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member);
   }
diff --git a/pkg/stack_trace/test/frame_test.dart b/pkg/stack_trace/test/frame_test.dart
index 02bec68..826bad7 100644
--- a/pkg/stack_trace/test/frame_test.dart
+++ b/pkg/stack_trace/test/frame_test.dart
@@ -31,8 +31,7 @@
   test('parses a stack frame correctly', () {
     var frame = new Frame.parse("#1      Foo._bar "
         "(file:///home/nweiz/code/stuff.dart:42:21)");
-    expect(frame.uri,
-        equals(new Uri.fromString("file:///home/nweiz/code/stuff.dart")));
+    expect(frame.uri, equals(Uri.parse("file:///home/nweiz/code/stuff.dart")));
     expect(frame.line, equals(42));
     expect(frame.column, equals(21));
     expect(frame.member, equals('Foo._bar'));
diff --git a/pkg/stack_trace/test/trace_test.dart b/pkg/stack_trace/test/trace_test.dart
index cbbf90b..d3fa56e 100644
--- a/pkg/stack_trace/test/trace_test.dart
+++ b/pkg/stack_trace/test/trace_test.dart
@@ -41,10 +41,10 @@
 ''');
 
     expect(trace.frames[0].uri,
-        equals(new Uri.fromString("file:///home/nweiz/code/stuff.dart")));
-    expect(trace.frames[1].uri, equals(new Uri.fromString("dart:async")));
+        equals(Uri.parse("file:///home/nweiz/code/stuff.dart")));
+    expect(trace.frames[1].uri, equals(Uri.parse("dart:async")));
     expect(trace.frames[2].uri,
-        equals(new Uri.fromString("http://pub.dartlang.org/thing.dart")));
+        equals(Uri.parse("http://pub.dartlang.org/thing.dart")));
   });
 
   test('parses a real stack trace correctly', () {
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
index a423651..2193603 100644
--- a/runtime/bin/filter.cc
+++ b/runtime/bin/filter.cc
@@ -166,9 +166,10 @@
 
 Dart_Handle Filter::SetFilterPointerNativeField(Dart_Handle filter,
                                                 Filter* filter_pointer) {
-  return Dart_SetNativeInstanceField(filter,
-                                     kFilterPointerNativeField,
-                                     (intptr_t)filter_pointer);
+  return Dart_SetNativeInstanceField(
+      filter,
+      kFilterPointerNativeField,
+      reinterpret_cast<intptr_t>(filter_pointer));
 }
 
 
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index ddaf345..38bc31a 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -41,7 +41,7 @@
   V(Process_Exit, 1)                                                           \
   V(Process_Sleep, 1)                                                          \
   V(Process_Pid, 1)                                                            \
-  V(ServerSocket_CreateBindListen, 4)                                          \
+  V(ServerSocket_CreateBindListen, 5)                                          \
   V(ServerSocket_Accept, 2)                                                    \
   V(Socket_CreateConnect, 3)                                                   \
   V(Socket_Available, 1)                                                       \
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 851104a..1134889 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -383,12 +383,15 @@
   Dart_Handle result = GetSockAddr(host_obj, &addr);
   Dart_Handle port_obj = Dart_GetNativeArgument(args, 2);
   Dart_Handle backlog_obj = Dart_GetNativeArgument(args, 3);
+  Dart_Handle v6_only_obj = Dart_GetNativeArgument(args, 4);
+  bool v6_only = DartUtils::GetBooleanValue(v6_only_obj);
   int64_t port = 0;
   int64_t backlog = 0;
   if (!Dart_IsError(result) &&
       DartUtils::GetInt64Value(port_obj, &port) &&
       DartUtils::GetInt64Value(backlog_obj, &backlog)) {
-    intptr_t socket = ServerSocket::CreateBindListen(addr, port, backlog);
+    intptr_t socket = ServerSocket::CreateBindListen(
+        addr, port, backlog, v6_only);
     OSError error;
     Dart_TypedDataReleaseData(host_obj);
     if (socket >= 0) {
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 99a0078..5c191a0 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -176,7 +176,8 @@
   //   -5: invalid bindAddress
   static intptr_t CreateBindListen(RawAddr addr,
                                    intptr_t port,
-                                   intptr_t backlog);
+                                   intptr_t backlog,
+                                   bool v6_only = false);
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index e4b99bd..8bb8f07 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -195,7 +195,8 @@
 
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
-                                        intptr_t backlog) {
+                                        intptr_t backlog,
+                                        bool v6_only) {
   intptr_t fd;
 
   fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
@@ -208,7 +209,7 @@
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
   if (addr.ss.ss_family == AF_INET6) {
-    optval = 0;
+    optval = v6_only ? 1 : 0;
     TEMP_FAILURE_RETRY(
         setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
   }
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index e881f5d..cfc9b12 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -207,7 +207,8 @@
 
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
-                                        intptr_t backlog) {
+                                        intptr_t backlog,
+                                        bool v6_only) {
   intptr_t fd;
 
   fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
@@ -220,7 +221,7 @@
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
   if (addr.ss.ss_family == AF_INET6) {
-    optval = 0;
+    optval = v6_only ? 1 : 0;
     TEMP_FAILURE_RETRY(
         setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
   }
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index bf17056..94363fb 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -207,7 +207,8 @@
 
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
-                                        intptr_t backlog) {
+                                        intptr_t backlog,
+                                        bool v6_only) {
   intptr_t fd;
 
   fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
@@ -220,7 +221,7 @@
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
   if (addr.ss.ss_family == AF_INET6) {
-    optval = 0;
+    optval = v6_only ? 1 : 0;
     VOID_TEMP_FAILURE_RETRY(
         setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
   }
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 1515403..d10f3ae 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class RawServerSocket  {
-  /* patch */ static Future<RawServerSocket> bind([address = "127.0.0.1",
-                                                   int port = 0,
-                                                   int backlog = 0]) {
-    return _RawServerSocket.bind(address, port, backlog);
+  /* patch */ static Future<RawServerSocket> bind(address,
+                                                  int port,
+                                                  {int backlog: 0,
+                                                   bool v6Only: false}) {
+    return _RawServerSocket.bind(address, port, backlog, v6Only);
   }
 }
 
@@ -36,7 +37,7 @@
   }
 
   /* patch */ static Future<List<InternetAddress>> lookup(
-      String host, {InternetAddressType type: InternetAddressType.IP_V4}) {
+      String host, {InternetAddressType type: InternetAddressType.ANY}) {
     return _NativeSocket.lookup(host, type: type);
   }
 }
@@ -158,7 +159,7 @@
   static SendPort socketService;
 
   static Future<List<InternetAddress>> lookup(
-      String host, {InternetAddressType type: InternetAddressType.IP_V4}) {
+      String host, {InternetAddressType type: InternetAddressType.ANY}) {
     ensureSocketService();
     return socketService.call([HOST_NAME_LOOKUP, host, type._value])
         .then((response) {
@@ -215,7 +216,8 @@
 
   static Future<_NativeSocket> bind(host,
                                     int port,
-                                    int backlog) {
+                                    int backlog,
+                                    bool v6Only) {
     return new Future.value(host)
         .then((host) {
           if (host is _InternetAddress) return host;
@@ -232,7 +234,8 @@
           socket.address = address;
           var result = socket.nativeCreateBindListen(address._sockaddr_storage,
                                                      port,
-                                                     backlog);
+                                                     backlog,
+                                                     v6Only);
           if (result is OSError) {
             throw new SocketIOException(
                 "Failed to create server socket", result);
@@ -526,7 +529,7 @@
       native "Socket_WriteList";
   nativeCreateConnect(List<int> addr,
                       int port) native "Socket_CreateConnect";
-  nativeCreateBindListen(List<int> addr, int port, int backlog)
+  nativeCreateBindListen(List<int> addr, int port, int backlog, bool v6Only)
       native "ServerSocket_CreateBindListen";
   nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
   int nativeGetPort() native "Socket_GetPort";
@@ -545,11 +548,12 @@
 
   static Future<_RawServerSocket> bind(address,
                                        int port,
-                                       int backlog) {
+                                       int backlog,
+                                       bool v6Only) {
     if (port < 0 || port > 0xFFFF)
       throw new ArgumentError("Invalid port $port");
     if (backlog < 0) throw new ArgumentError("Invalid backlog $backlog");
-    return _NativeSocket.bind(address, port, backlog)
+    return _NativeSocket.bind(address, port, backlog, v6Only)
         .then((socket) => new _RawServerSocket(socket));
   }
 
@@ -602,6 +606,7 @@
       close();
     }
   }
+
   void _onPauseStateChange() {
     if (_controller.isPaused) {
       _pause();
@@ -737,10 +742,11 @@
 
 
 patch class ServerSocket {
-  /* patch */ static Future<ServerSocket> bind([address = "127.0.0.1",
-                                                int port = 0,
-                                                int backlog = 0]) {
-    return _ServerSocket.bind(address, port, backlog);
+  /* patch */ static Future<ServerSocket> bind(address,
+                                               int port,
+                                               {int backlog: 0,
+                                                bool v6Only: false}) {
+    return _ServerSocket.bind(address, port, backlog, v6Only);
   }
 }
 
@@ -750,8 +756,9 @@
 
   static Future<_ServerSocket> bind(address,
                                     int port,
-                                    int backlog) {
-    return _RawServerSocket.bind(address, port, backlog)
+                                    int backlog,
+                                    bool v6Only) {
+    return _RawServerSocket.bind(address, port, backlog, v6Only)
         .then((socket) => new _ServerSocket(socket));
   }
 
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 12b76d8..e8b0d47 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -239,7 +239,8 @@
 
 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
-                                        intptr_t backlog) {
+                                        intptr_t backlog,
+                                        bool v6_only) {
   SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, IPPROTO_TCP);
   if (s == INVALID_SOCKET) {
     return -1;
@@ -259,7 +260,7 @@
   }
 
   if (addr.ss.ss_family == AF_INET6) {
-    optval = false;
+    optval = v6_only;
     setsockopt(s,
                IPPROTO_IPV6,
                IPV6_V6ONLY,
diff --git a/runtime/embedders/openglui/build_skia.sh b/runtime/embedders/openglui/build_skia.sh
index 9eca1dc..5190f10 100755
--- a/runtime/embedders/openglui/build_skia.sh
+++ b/runtime/embedders/openglui/build_skia.sh
@@ -72,7 +72,7 @@
   if [ ${CLEAN} != 0 ] ; then
     ../android/bin/android_make -d $TARGET_ARCH -j clean
   else
-    env -i BUILDTYPE=$BUILD ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" ../android/bin/android_make BUILDTYPE=$BUILD -d $TARGET_ARCH -j --debug=j
+    env -i BUILDTYPE=$BUILD ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT}" PATH="${PATH}:${DART_DIR}/third_party/gsutil" ../android/bin/android_make BUILDTYPE=$BUILD -d $TARGET_ARCH -j --debug=j
   fi
 
 else
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index 8ee9dd3..55d3626 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -221,6 +221,32 @@
   int operator ~() native "Smi_bitNegate";
   int _shrFromInt(int other) native "Smi_shrFromInt";
   int _shlFromInt(int other) native "Smi_shlFromInt";
+
+  String toString() {
+    if (this == 0) return "0";
+    var reversed = new List();
+    var val = this < 0 ? -this : this;
+    while (val > 0) {
+      reversed.add((val % 10) + 0x30);
+      val = val ~/ 10;
+    }
+    final int numDigits = reversed.length;
+    List digits;
+    int i;
+    if (this < 0) {
+      digits = new List(numDigits + 1);
+      digits[0] = 0x2D;  // '-'.
+      i = 1;
+    } else {
+      digits = new List(numDigits);
+      i = 0;
+    }
+    int ri = reversed.length - 1;
+    for (; i < digits.length; i++, ri--) {
+      digits[i] = reversed[ri];
+    }
+    return _StringBase.createFromCharCodes(digits);
+  }
 }
 
 // Represents integers that cannot be represented by Smi but fit into 64bits.
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 9a06b24..761541a 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -19,7 +19,6 @@
     args.SetAt(0, list);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
-  // TODO(srdjan): Check that parameterized type is an int.
 
   Array& a = Array::Handle();
   intptr_t array_len;
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 2d148ec..f20f8b0 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -27,9 +27,13 @@
    *  [codePoints].
    */
   static String createFromCharCodes(Iterable<int> charCodes) {
-    if (charCodes is! _ObjectArray && charCodes is! _GrowableObjectArray) {
+    // TODO(srdjan): Also skip copying of typed arrays.
+    if (charCodes is! _ObjectArray &&
+        charCodes is! _GrowableObjectArray &&
+        charCodes is! _ImmutableArray) {
       charCodes = new List<int>.from(charCodes, growable: false);
     }
+
     return _createFromCodePoints(charCodes);
   }
 
@@ -314,7 +318,7 @@
    */
   static String _interpolate(List values) {
     int numValues = values.length;
-    var stringList = new List(numValues);
+    _ObjectArray stringList = new List(numValues);
     for (int i = 0; i < numValues; i++) {
       stringList[i] = values[i].toString();
     }
@@ -428,7 +432,7 @@
     return _concatAll(stringsArray);
   }
 
-  static String _concatAll(List<String> strings)
+  static String _concatAll(_ObjectArray<String> strings)
       native "Strings_concatAll";
 }
 
diff --git a/runtime/tests/vm/dart/inline_stack_frame_test.dart b/runtime/tests/vm/dart/inline_stack_frame_test.dart
index f8592ac..62fa819 100644
--- a/runtime/tests/vm/dart/inline_stack_frame_test.dart
+++ b/runtime/tests/vm/dart/inline_stack_frame_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// VMOptions=--optimization_counter_threshold=10
+
 import "package:expect/expect.dart";
 
 // This test tries to verify that we produce the correct stack trace when
@@ -50,7 +52,7 @@
     return result;
   }
   int func5(var i) {
-    if (i >= 1030) throw "show me inlined functions";
+    if (i >= 520) throw "show me inlined functions";
     return i;
   }
 }
@@ -64,7 +66,7 @@
   Expect.isTrue(result.contains("Test.func3"));
   Expect.isTrue(result.contains("Test.func4"));
   Expect.isTrue(result.contains("Test.func"));
-  for (var i = 0; i <= 200; i++) {
+  for (var i = 0; i <= 10; i++) {
     result = x.func1(i);
   }
   Expect.isTrue(result.contains("show me inlined functions"));
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 26005da..529a615 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -61,8 +61,9 @@
 # Tests missing code generation support.
 cc/Dart2JSCompileAll: Skip
 cc/CorelibCompileAll: Skip
-# Tests needing Dart execution.
-dart/*: Skip
+dart/byte_array_test: Skip
+dart/byte_array_optimized_test: Skip
+dart/inline_stack_frame_test: Skip
 
 [ $arch == mips ]
 *: Skip
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 49d0db2..d55fab9 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -100,10 +100,14 @@
 
 
 uint32_t Address::encoding3() const {
-  ASSERT(kind_ == Immediate);
-  uint32_t offset = encoding_ & kOffset12Mask;
-  ASSERT(offset < 256);
-  return (encoding_ & ~kOffset12Mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
+  if (kind_ == Immediate) {
+    uint32_t offset = encoding_ & kOffset12Mask;
+    ASSERT(offset < 256);
+    return (encoding_ & ~kOffset12Mask) | B22 |
+           ((offset & 0xf0) << 4) | (offset & 0xf);
+  }
+  ASSERT(kind_ == IndexRegister);
+  return encoding_;
 }
 
 
@@ -192,7 +196,6 @@
   ASSERT(rd != kNoRegister);
   ASSERT(cond != kNoCondition);
   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
-                     B22  |
                      mode |
                      (static_cast<int32_t>(rd) << kRdShift) |
                      ad.encoding3();
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 7039d8b..849b644 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -216,7 +216,8 @@
  public:
   enum OffsetKind {
     Immediate,
-    ShiftedRegister,
+    IndexRegister,
+    ScaledIndexRegister,
   };
 
   // Memory operand addressing mode
@@ -255,7 +256,11 @@
           Shift shift = LSL, uint32_t shift_imm = 0, Mode am = Offset) {
     ShifterOperand so(rm, shift, shift_imm);
 
-    kind_ = ShiftedRegister;
+    if ((shift == LSL) && (shift_imm == 0)) {
+      kind_ = IndexRegister;
+    } else {
+      kind_ = ScaledIndexRegister;
+    }
     encoding_ = so.encoding() | am | (static_cast<uint32_t>(rn) << kRnShift);
   }
 
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index a7e8f2b..7a18568 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -789,9 +789,7 @@
 
 
 ASSEMBLER_TEST_GENERATE(Ldrh, assembler) {
-  Label Test1;
-  Label Test2;
-  Label Done;
+  Label Test1, Test2, Test3, Done;
 
   __ mov(R1, ShifterOperand(0x11));
   __ mov(R2, ShifterOperand(SP));
@@ -803,16 +801,26 @@
   __ b(&Done);
   __ Bind(&Test1);
 
-  __ mov(R0, ShifterOperand(0));
+  __ mov(R0, ShifterOperand(0x22));
   __ strh(R0, Address(R2, (-kWordSize * 30)));
   __ ldrh(R1, Address(R2, (-kWordSize * 30)));
-  __ cmp(R1, ShifterOperand(0));
+  __ cmp(R1, ShifterOperand(0x22));
   __ b(&Test2, EQ);
   __ mov(R0, ShifterOperand(1));
   __ b(&Done);
   __ Bind(&Test2);
 
   __ mov(R0, ShifterOperand(0));
+  __ AddImmediate(R2, (-kWordSize * 30));
+  __ strh(R0, Address(R2));
+  __ ldrh(R1, Address(R2));
+  __ cmp(R1, ShifterOperand(0));
+  __ b(&Test3, EQ);
+  __ mov(R0, ShifterOperand(1));
+  __ b(&Done);
+  __ Bind(&Test3);
+
+  __ mov(R0, ShifterOperand(0));
   __ Bind(&Done);
   __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
   __ mov(PC, ShifterOperand(LR));
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index d4029ce..3f496db 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -81,7 +81,7 @@
 
 
 void Assembler::AdduDetectOverflow(Register rd, Register rs, Register rt,
-                                   Register ro) {
+                                   Register ro, Register scratch) {
   ASSERT(rd != ro);
   ASSERT(rd != TMP1);
   ASSERT(ro != TMP1);
@@ -89,12 +89,14 @@
   ASSERT(ro != rt);
 
   if ((rs == rt) && (rd == rs)) {
-    ASSERT(rd != TMP2);
-    ASSERT(ro != TMP2);
-    ASSERT(rs != TMP2);
-    ASSERT(rt != TMP2);
-    mov(TMP2, rt);
-    rt = TMP2;
+    ASSERT(scratch != kNoRegister);
+    ASSERT(scratch != TMP1);
+    ASSERT(rd != scratch);
+    ASSERT(ro != scratch);
+    ASSERT(rs != scratch);
+    ASSERT(rt != scratch);
+    mov(scratch, rt);
+    rt = scratch;
   }
 
   if (rd == rs) {
@@ -236,8 +238,8 @@
   sll(TMP1, value, kObjectAlignmentLog2 - 1);
   and_(TMP1, value, TMP1);
   // And the result with the negated space bit of the object.
-  nor(TMP2, ZR, object);
-  and_(TMP1, TMP1, TMP2);
+  nor(CMPRES, ZR, object);
+  and_(TMP1, TMP1, CMPRES);
   andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
   beq(TMP1, ZR, no_update);
 }
@@ -371,6 +373,24 @@
 }
 
 
+void Assembler::LeaveStubFrameAndReturn(Register ra, bool uses_pp) {
+  if (uses_pp) {
+    addiu(SP, FP, Immediate(-1 * kWordSize));
+    lw(RA, Address(SP, 2 * kWordSize));
+    lw(FP, Address(SP, 1 * kWordSize));
+    lw(PP, Address(SP, 0 * kWordSize));
+    jr(ra);
+    delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
+  } else {
+    mov(SP, FP);
+    lw(RA, Address(SP, 1 * kWordSize));
+    lw(FP, Address(SP, 0 * kWordSize));
+    jr(ra);
+    delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize));
+  }
+}
+
+
 void Assembler::CallRuntime(const RuntimeEntry& entry) {
   entry.Call(this);
 }
@@ -420,15 +440,16 @@
 }
 
 
-void Assembler::LeaveDartFrame() {
+void Assembler::LeaveDartFrameAndReturn() {
   addiu(SP, FP, Immediate(-kWordSize));
 
   lw(RA, Address(SP, 2 * kWordSize));
   lw(FP, Address(SP, 1 * kWordSize));
   lw(PP, Address(SP, 0 * kWordSize));
 
-  // Adjust SP for PC pushed in EnterDartFrame.
-  addiu(SP, SP, Immediate(4 * kWordSize));
+  // Adjust SP for PC pushed in EnterDartFrame, and return.
+  Ret();
+  delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
 }
 
 
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 8269737..07d19bc 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -171,6 +171,9 @@
   // a stub frame.
   void EnterStubFrame(bool uses_pp = false);
   void LeaveStubFrame(bool uses_pp = false);
+  // A separate macro for when a Ret immediately follows, so that we can use
+  // the branch delay slot.
+  void LeaveStubFrameAndReturn(Register ra = RA, bool uses_pp = false);
 
   // Instruction pattern from entrypoint is used in dart frame prologs
   // to set up the frame and save a PC which can be used to figure out the
@@ -571,16 +574,21 @@
 
   // Addition of rs and rt with the result placed in rd.
   // After, ro < 0 if there was signed overflow, ro >= 0 otherwise.
-  // rd and ro must not be TMP1 or TMP2.
+  // rd and ro must not be TMP1.
   // ro must be different from all the other registers.
-  void AdduDetectOverflow(Register rd, Register rs, Register rt, Register ro);
+  // If rd, rs, and rt are the same register, then a scratch register different
+  // from the other registers is needed.
+  void AdduDetectOverflow(Register rd, Register rs, Register rt, Register ro,
+                          Register scratch = kNoRegister);
 
   // ro must be different from rd and rs.
-  // rd and ro must not be TMP1 or TMP2
+  // rd and ro must not be TMP1.
+  // If rd and rs are the same, a scratch register different from the other
+  // registers is needed.
   void AddImmediateDetectOverflow(Register rd, Register rs, int32_t imm,
-                                  Register ro) {
+                                  Register ro, Register scratch = kNoRegister) {
     LoadImmediate(rd, imm);
-    AdduDetectOverflow(rd, rs, rd, ro);
+    AdduDetectOverflow(rd, rs, rd, ro, scratch);
   }
 
   // Subtraction of rt from rs (rs - rt) with the result placed in rd.
@@ -845,7 +853,7 @@
   // enable easy access to the RawInstruction object of code corresponding
   // to this frame.
   void EnterDartFrame(intptr_t frame_size);
-  void LeaveDartFrame();
+  void LeaveDartFrameAndReturn();
 
  private:
   AssemblerBuffer buffer_;
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index be5c939..f4cdcdc 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -1060,6 +1060,7 @@
   Register right = T1;
   Register result = T2;
   Register overflow = T3;
+  Register scratch = T4;
   Label error, done;
 
   __ LoadImmediate(V0, 1);  // Success value.
@@ -1094,7 +1095,7 @@
   __ bgez(overflow, &error);  // INT_MIN - 1 overflows.
 
   // result has 0x7fffffff.
-  __ AdduDetectOverflow(result, result, result, overflow);
+  __ AdduDetectOverflow(result, result, result, overflow, scratch);
   __ bgez(overflow, &error);  // INT_MAX + INT_MAX overflows.
 
   __ LoadImmediate(left, 0x80000000);
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index d88e130..c0d1172 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -287,7 +287,7 @@
   String& source = String::Handle(String::New(kScriptChars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   EXPECT(ClassFinalizer::FinalizePendingClasses());
@@ -334,7 +334,7 @@
   String& source = String::Handle(String::New(kScriptChars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   EXPECT(ClassFinalizer::FinalizePendingClasses());
@@ -521,7 +521,7 @@
   String& source = String::Handle(String::New(kScriptChars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = MakeTestLibrary("TestLib");
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   EXPECT(ClassFinalizer::FinalizePendingClasses());
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index dc2e042..60af119 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -170,7 +170,7 @@
     // Collect all instance fields that are loaded in the graph and
     // have non-generic type feedback attached to them that can
     // potentially affect optimizations.
-    GrowableArray<Field*> guarded_fields(10);
+    GrowableArray<const Field*> guarded_fields(10);
     if (optimized) {
       TimerScope timer(FLAG_compiler_stats,
                        &CompilerStats::graphoptimizer_timer,
@@ -291,7 +291,14 @@
         propagator.Propagate();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
       }
-      optimizer.Canonicalize();
+      if (optimizer.Canonicalize()) {
+        // To fully remove redundant boxing (e.g. BoxDouble used only in
+        // environments and UnboxDouble instructions) instruction we
+        // first need to replace all their uses and then fold them away.
+        // For now we just repeat Canonicalize twice to do that.
+        // TODO(vegorov): implement a separate representation folding pass.
+        optimizer.Canonicalize();
+      }
       DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
       // Perform register allocation on the SSA graph.
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 0058593..2287be2 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -25,7 +25,7 @@
   String& source = String::Handle(String::New(kScriptChars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT(CompilerTest::TestCompileScript(lib, script));
 }
@@ -43,7 +43,7 @@
   String& source = String::Handle(String::New(kScriptChars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = Library::Handle(Library::CoreLibrary());
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   EXPECT(ClassFinalizer::FinalizePendingClasses());
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 0668062..5859800 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -139,7 +139,6 @@
 
 // Register aliases.
 const Register TMP1 = AT;  // Used as scratch register by assembler.
-const Register TMP2 = T9;  // Used as scratch register by assembler.
 const Register TMP = TMP1;  // Arch independent flow graph compiler needs a
                             // Register called TMP.
 const Register CTX = S6;  // Caches current context in generated code.
@@ -147,10 +146,17 @@
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
 
+// NULLREG holds reinterpret_cast<intptr_t>(Object::null()).
+// TODO(zra): Is it worthwhile to devote a register to this? Investigate
+// performance effects when we are running on real hardware. Same with
+// CMPRES. Try moving CTX and PP to T8 and T9 and shifting kLastCpuRegister
+// down to S7.
+const Register NULLREG = T8;
+
 // The code that generates a comparison can be far away from the code that
 // generates the branch that uses the result of that comparison. In this case,
 // CMPRES is used for the result of the comparison.
-const Register CMPRES = T8;
+const Register CMPRES = T9;
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index f79c008..6008c9c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -5653,7 +5653,7 @@
   const char* kLibrary1Chars =
       "library library1_name;";
   const char* kSourceChars =
-      "// Something innocuous";
+      "part of library1_name;\n// Something innocuous";
   const char* kBadSourceChars =
       ")";
   Dart_Handle error = Dart_Error("incoming error");
@@ -5739,6 +5739,7 @@
       "  foo() => 'foo';\n"
       "}\n";
   const char* kSourceChars =
+      "part of library1_name;\n"
       "class NewClass extends OldClass{\n"
       "  bar() => 'bar';\n"
       "}\n";
@@ -5781,6 +5782,7 @@
   const char* kLibrary1Chars =
       "library library1_name;";
   const char* kSourceChars =
+      "part of library1_name;\n"
       "external int foo();";
   const char* kPatchChars =
       "patch int foo() => 42;";
@@ -7515,6 +7517,7 @@
 
 TEST_CASE(LazyLoadDeoptimizes) {
   const char* kLoadFirst =
+      "library L;\n"
       "start(a) {\n"
       "  var obj = (a == 1) ? createB() : new A();\n"
       "  for (int i = 0; i < 4000; i++) {\n"
@@ -7531,6 +7534,7 @@
       "  goo() => 2;\n"
       "}\n";
   const char* kLoadSecond =
+      "part of L;"
       "class B extends A {\n"
       "  goo() => 1;\n"
       "}\n";
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 0692ef5..c125731 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -900,38 +900,34 @@
   Code& code = Code::Handle(isolate);
   StackFrameIterator iterator(false);
   StackFrame* frame = iterator.NextFrame();
+  ActivationFrame* callee_activation = NULL;
   bool optimized_frame_found = false;
   while (frame != NULL) {
     ASSERT(frame->IsValid());
     if (frame->IsDartFrame()) {
       code = frame->LookupDartCode();
-      ActivationFrame* activation = new ActivationFrame(frame->pc(),
-                                                        frame->fp(),
-                                                        frame->sp(),
-                                                        code);
+      ActivationFrame* activation =
+          new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code);
       // If this activation frame called a closure, the function has
       // saved its context before the call.
-      if (stack_trace->Length() > 0) {
-        ActivationFrame* callee_frame =
-            stack_trace->ActivationFrameAt(stack_trace->Length() - 1);
-        if (callee_frame->function().IsClosureFunction()) {
-          ctx = activation->GetSavedCurrentContext();
-          if (FLAG_verbose_debug && ctx.IsNull()) {
-            const Function& caller = activation->function();
-            const Function& callee = callee_frame->function();
-            const Script& script =
-                Script::Handle(Class::Handle(caller.Owner()).script());
-            intptr_t line, col;
-            script.GetTokenLocation(activation->TokenPos(), &line, &col);
-            printf("CollectStackTrace error: no saved context in function "
-                "'%s' which calls closure '%s' "
-                " in line %"Pd" column %"Pd"\n",
-                caller.ToFullyQualifiedCString(),
-                callee.ToFullyQualifiedCString(),
-                line, col);
-          }
-          ASSERT(!ctx.IsNull());
+      if ((callee_activation != NULL) &&
+          (callee_activation->function().IsClosureFunction())) {
+        ctx = activation->GetSavedCurrentContext();
+        if (FLAG_verbose_debug && ctx.IsNull()) {
+          const Function& caller = activation->function();
+          const Function& callee = callee_activation->function();
+          const Script& script =
+              Script::Handle(Class::Handle(caller.Owner()).script());
+          intptr_t line, col;
+          script.GetTokenLocation(activation->TokenPos(), &line, &col);
+          OS::Print("CollectStackTrace error: no saved context in function "
+              "'%s' which calls closure '%s' "
+              " in line %"Pd" column %"Pd"\n",
+              caller.ToFullyQualifiedCString(),
+              callee.ToFullyQualifiedCString(),
+              line, col);
         }
+        ASSERT(!ctx.IsNull());
       }
       if (optimized_frame_found || code.is_optimized()) {
         // Set context to null, to avoid returning bad context variable values.
@@ -941,10 +937,12 @@
         activation->SetContext(ctx);
       }
       stack_trace->AddActivation(activation);
+      callee_activation = activation;
       // Get caller's context if this function saved it on entry.
       ctx = activation->GetSavedEntryContext(ctx);
     } else if (frame->IsEntryFrame()) {
       ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext();
+      callee_activation = NULL;
     }
     frame = iterator.NextFrame();
   }
@@ -961,7 +959,7 @@
 
 
 Dart_ExceptionPauseInfo Debugger::GetExceptionPauseInfo() {
-  return (Dart_ExceptionPauseInfo)exc_pause_info_;
+  return exc_pause_info_;
 }
 
 
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index cef4502..9291b91 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -378,7 +378,7 @@
   // be run as a side effect of getting values of fields.
   bool ignore_breakpoints_;
 
-  intptr_t exc_pause_info_;
+  Dart_ExceptionPauseInfo exc_pause_info_;
 
   static BreakpointHandler* bp_handler_;
   static EventHandler* event_handler_;
diff --git a/runtime/vm/debugger_mips.cc b/runtime/vm/debugger_mips.cc
index a234dcd..dcf7df6 100644
--- a/runtime/vm/debugger_mips.cc
+++ b/runtime/vm/debugger_mips.cc
@@ -31,21 +31,19 @@
 
 
 void CodeBreakpoint::PatchFunctionReturn() {
-  Instr* instr1 = Instr::At(pc_ - 6 * Instr::kInstrSize);
-  Instr* instr2 = Instr::At(pc_ - 5 * Instr::kInstrSize);
-  Instr* instr3 = Instr::At(pc_ - 4 * Instr::kInstrSize);
-  Instr* instr4 = Instr::At(pc_ - 3 * Instr::kInstrSize);
-  Instr* instr5 = Instr::At(pc_ - 2 * Instr::kInstrSize);
-  Instr* instr6 = Instr::At(pc_ - 1 * Instr::kInstrSize);
+  Instr* instr1 = Instr::At(pc_ - 5 * Instr::kInstrSize);
+  Instr* instr2 = Instr::At(pc_ - 4 * Instr::kInstrSize);
+  Instr* instr3 = Instr::At(pc_ - 3 * Instr::kInstrSize);
+  Instr* instr4 = Instr::At(pc_ - 2 * Instr::kInstrSize);
+  Instr* instr5 = Instr::At(pc_ - 1 * Instr::kInstrSize);
 
 #if defined(DEBUG)
 
   instr1->AssertIsImmInstr(LW, SP, RA, 2 * kWordSize);
   instr2->AssertIsImmInstr(LW, SP, FP, 1 * kWordSize);
   instr3->AssertIsImmInstr(LW, SP, PP, 0 * kWordSize);
-  instr4->AssertIsImmInstr(ADDIU, SP, SP, 4 * kWordSize);
-  instr5->AssertIsSpecialInstr(JR, RA, ZR, ZR);
-  ASSERT(instr6->InstructionBits() == Instr::kNopInstruction);
+  instr4->AssertIsSpecialInstr(JR, RA, ZR, ZR);
+  instr5->AssertIsImmInstr(ADDIU, SP, SP, 4 * kWordSize);
 #endif  // defined(DEBUG)
 
   // Smash code with call instruction and target address.
@@ -57,34 +55,31 @@
   // than the sequence we are replacing. We pad at the top with nops so that
   // the end of the new sequence is lined up with the code descriptor.
   instr1->SetInstructionBits(Instr::kNopInstruction);
-  instr2->SetInstructionBits(Instr::kNopInstruction);
-  instr3->SetImmInstrBits(LUI, ZR, TMP1, target_hi);
-  instr4->SetImmInstrBits(ORI, TMP1, TMP1, target_lo);
-  instr5->SetSpecialInstrBits(JALR, TMP1, ZR, RA);
-  instr6->SetInstructionBits(Instr::kNopInstruction);
+  instr2->SetImmInstrBits(LUI, ZR, TMP1, target_hi);
+  instr3->SetImmInstrBits(ORI, TMP1, TMP1, target_lo);
+  instr4->SetSpecialInstrBits(JALR, TMP1, ZR, RA);
+  instr5->SetInstructionBits(Instr::kNopInstruction);
 
-  CPU::FlushICache(pc_ - 6 * Instr::kInstrSize, 6 * Instr::kInstrSize);
+  CPU::FlushICache(pc_ - 5 * Instr::kInstrSize, 5 * Instr::kInstrSize);
 }
 
 
 void CodeBreakpoint::RestoreFunctionReturn() {
-  Instr* instr1 = Instr::At(pc_ - 6 * Instr::kInstrSize);
-  Instr* instr2 = Instr::At(pc_ - 5 * Instr::kInstrSize);
-  Instr* instr3 = Instr::At(pc_ - 4 * Instr::kInstrSize);
-  Instr* instr4 = Instr::At(pc_ - 3 * Instr::kInstrSize);
-  Instr* instr5 = Instr::At(pc_ - 2 * Instr::kInstrSize);
-  Instr* instr6 = Instr::At(pc_ - 1 * Instr::kInstrSize);
+  Instr* instr1 = Instr::At(pc_ - 5 * Instr::kInstrSize);
+  Instr* instr2 = Instr::At(pc_ - 4 * Instr::kInstrSize);
+  Instr* instr3 = Instr::At(pc_ - 3 * Instr::kInstrSize);
+  Instr* instr4 = Instr::At(pc_ - 2 * Instr::kInstrSize);
+  Instr* instr5 = Instr::At(pc_ - 1 * Instr::kInstrSize);
 
-  ASSERT(instr3->OpcodeField() == LUI && instr3->RtField() == TMP1);
+  ASSERT(instr2->OpcodeField() == LUI && instr2->RtField() == TMP1);
 
   instr1->SetImmInstrBits(LW, SP, RA, 2 * kWordSize);
   instr2->SetImmInstrBits(LW, SP, FP, 1 * kWordSize);
   instr3->SetImmInstrBits(LW, SP, PP, 0 * kWordSize);
-  instr4->SetImmInstrBits(ADDIU, SP, SP, 4 * kWordSize);
-  instr5->SetSpecialInstrBits(JR, RA, ZR, ZR);
-  instr6->SetInstructionBits(Instr::kNopInstruction);
+  instr4->SetSpecialInstrBits(JR, RA, ZR, ZR);
+  instr5->SetImmInstrBits(ADDIU, SP, SP, 4 * kWordSize);
 
-  CPU::FlushICache(pc_ - 6 * Instr::kInstrSize, 6 * Instr::kInstrSize);
+  CPU::FlushICache(pc_ - 5 * Instr::kInstrSize, 5 * Instr::kInstrSize);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/find_code_object_test.cc b/runtime/vm/find_code_object_test.cc
index 94fee57..3200439 100644
--- a/runtime/vm/find_code_object_test.cc
+++ b/runtime/vm/find_code_object_test.cc
@@ -56,7 +56,7 @@
   }
   OS::SNPrint((scriptChars + written), (kScriptSize - written), "}");
   source = String::New(scriptChars);
-  script = Script::New(url, source, RawScript::kSourceTag);
+  script = Script::New(url, source, RawScript::kScriptTag);
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   clsA = lib.LookupClass(String::Handle(Symbols::New("A")));
   EXPECT(!clsA.IsNull());
@@ -104,7 +104,7 @@
   OS::SNPrint((scriptChars + written), (kScriptSize - written), "}");
   url = String::New("dart-test:FindCodeObject");
   source = String::New(scriptChars);
-  script = Script::New(url, source, RawScript::kSourceTag);
+  script = Script::New(url, source, RawScript::kScriptTag);
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   clsB = lib.LookupClass(String::Handle(Symbols::New("B")));
   EXPECT(!clsB.IsNull());
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index b4b833a..a1d6e6b 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2634,6 +2634,7 @@
       for_instance.value(),
       node->field().Offset(),
       AbstractType::ZoneHandle(node->field().type()));
+  load->set_field(&node->field());
   ReturnDefinition(load);
 }
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 2c286f1..6451979 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -91,14 +91,19 @@
   const SubtypeTestCache& type_test_cache =
       SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
   __ LoadObject(A2, type_test_cache);
+  intptr_t null = reinterpret_cast<intptr_t>(Object::null());
+  uint16_t null_lo = Utils::Low16Bits(null);
+  uint16_t null_hi = Utils::High16Bits(null);
   if (test_kind == kTestTypeOneArg) {
     ASSERT(type_arguments_reg == kNoRegister);
-    __ LoadImmediate(A1, reinterpret_cast<intptr_t>(Object::null()));
+    __ lui(A1, Immediate(null_hi));
     __ BranchLink(&StubCode::Subtype1TestCacheLabel());
+    __ delay_slot()->ori(A1, A1, Immediate(null_lo));
   } else if (test_kind == kTestTypeTwoArgs) {
     ASSERT(type_arguments_reg == kNoRegister);
-    __ LoadImmediate(A1, reinterpret_cast<intptr_t>(Object::null()));
+    __ lui(A1, Immediate(null_hi));
     __ BranchLink(&StubCode::Subtype2TestCacheLabel());
+    __ delay_slot()->ori(A1, A1, Immediate(null_lo));
   } else if (test_kind == kTestTypeThreeArgs) {
     ASSERT(type_arguments_reg == A1);
     __ BranchLink(&StubCode::Subtype3TestCacheLabel());
@@ -469,10 +474,11 @@
   // Preserve instantiator and its type arguments.
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
   __ sw(A2, Address(SP, 1 * kWordSize));
-  __ sw(A1, Address(SP, 0 * kWordSize));
+
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
   __ BranchEqual(A0, reinterpret_cast<int32_t>(Object::null()), &is_assignable);
+  __ delay_slot()->sw(A1, Address(SP, 0 * kWordSize));
 
   if (!FLAG_eliminate_type_checks) {
     // If type checks are not eliminated during the graph building then
@@ -626,20 +632,17 @@
   __ AddImmediate(T0, FP, (kFirstLocalSlotIndex + 1) * kWordSize);
   __ sll(T2, T2, 1);  // T2 is a Smi.
 
-  Label loop, loop_condition;
-  __ b(&loop_condition);
+  Label loop, loop_exit;
+  __ blez(T2, &loop_exit);
   __ delay_slot()->subu(T0, T0, T2);
-  // We do not use the final allocation index of the variable here, i.e.
-  // scope->VariableAt(i)->index(), because captured variables still need
-  // to be copied to the context that is not yet allocated.
   __ Bind(&loop);
   __ addu(T4, T1, T2);
-  __ addu(T5, T0, T2);
-  __ lw(T3, Address(T4));
-  __ sw(T3, Address(T5));
-  __ Bind(&loop_condition);
+  __ lw(T3, Address(T4, -kWordSize));
   __ addiu(T2, T2, Immediate(-kWordSize));
-  __ bgez(T2, &loop);
+  __ addu(T5, T0, T2);
+  __ bgtz(T2, &loop);
+  __ delay_slot()->sw(T3, Address(T5));
+  __ Bind(&loop_exit);
 
   // Copy or initialize optional named arguments.
   Label all_arguments_processed;
@@ -782,8 +785,7 @@
                                       0);  // No registers.
   }
   // The noSuchMethod call may return.
-  __ LeaveDartFrame();
-  __ Ret();
+  __ LeaveDartFrameAndReturn();
 
   __ Bind(&all_arguments_processed);
   // Nullify originally passed arguments only after they have been copied and
@@ -792,23 +794,21 @@
   // implicitly final, since garbage collecting the unmodified value is not
   // an issue anymore.
 
+  __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
+
   // S4 : arguments descriptor array.
   __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
   __ sll(T2, T2, 1);  // T2 is a Smi.
 
-  __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
-  Label null_args_loop, null_args_loop_condition;
-
-  __ b(&null_args_loop_condition);
+  Label null_args_loop, null_args_loop_exit;
+  __ blez(T2, &null_args_loop_exit);
   __ delay_slot()->addiu(T1, FP, Immediate(kLastParamSlotIndex * kWordSize));
-
   __ Bind(&null_args_loop);
-  __ addu(T3, T1, T2);
-  __ sw(T0, Address(T3));
-
-  __ Bind(&null_args_loop_condition);
   __ addiu(T2, T2, Immediate(-kWordSize));
-  __ bgez(T2, &null_args_loop);
+  __ addu(T3, T1, T2);
+  __ bgtz(T2, &null_args_loop);
+  __ delay_slot()->sw(T0, Address(T3));
+  __ Bind(&null_args_loop_exit);
 }
 
 
@@ -830,8 +830,12 @@
   __ lw(T0, Address(SP, 1 * kWordSize));  // Receiver.
   __ lw(T1, Address(SP, 0 * kWordSize));  // Value.
   __ StoreIntoObject(T0, FieldAddress(T0, offset), T1);
-  __ LoadImmediate(V0, reinterpret_cast<intptr_t>(Object::null()));
+  intptr_t null = reinterpret_cast<intptr_t>(Object::null());
+  uint16_t null_lo = Utils::Low16Bits(null);
+  uint16_t null_hi = Utils::High16Bits(null);
+  __ lui(V0, Immediate(null_hi));
   __ Ret();
+  __ delay_slot()->ori(V0, V0, Immediate(null_lo));
 }
 
 
@@ -994,8 +998,7 @@
                                             0);  // No registers.
         }
         // The noSuchMethod call may return.
-        __ LeaveDartFrame();
-        __ Ret();
+        __ LeaveDartFrameAndReturn();
       } else {
         __ Stop("Wrong number of arguments");
       }
@@ -1205,8 +1208,8 @@
     __ addiu(SP, SP, Immediate(-2 * kWordSize));
     __ sw(reg, Address(SP, 1 * kWordSize));
     __ LoadObject(TMP1, obj);
-    __ sw(TMP1, Address(SP, 0 * kWordSize));
     __ BranchLink(&StubCode::IdenticalWithNumberCheckLabel());
+    __ delay_slot()->sw(TMP1, Address(SP, 0 * kWordSize));
     __ lw(reg, Address(SP, 1 * kWordSize));  // Restore 'reg'.
     __ addiu(SP, SP, Immediate(2 * kWordSize));  // Discard constant.
     return;
@@ -1222,8 +1225,8 @@
   if (needs_number_check) {
     __ addiu(SP, SP, Immediate(-2 * kWordSize));
     __ sw(left, Address(SP, 1 * kWordSize));
-    __ sw(right, Address(SP, 0 * kWordSize));
     __ BranchLink(&StubCode::IdenticalWithNumberCheckLabel());
+    __ delay_slot()->sw(right, Address(SP, 0 * kWordSize));
     __ TraceSimMsg("EqualityRegRegCompare return");
     // Stub returns result in CMPRES. If it is 0, then left and right are equal.
     __ lw(right, Address(SP, 0 * kWordSize));
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index fab2e96..af3f6e2 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -24,7 +24,7 @@
 // Flags for inlining heuristics.
 DEFINE_FLAG(int, inlining_depth_threshold, 3,
     "Inline function calls up to threshold nesting depth");
-DEFINE_FLAG(int, inlining_size_threshold, 20,
+DEFINE_FLAG(int, inlining_size_threshold, 22,
     "Always inline functions that have threshold or fewer instructions");
 DEFINE_FLAG(int, inlining_callee_call_sites_threshold, 1,
     "Always inline functions containing threshold or fewer calls.");
@@ -292,7 +292,8 @@
 
 class CallSiteInliner : public ValueObject {
  public:
-  CallSiteInliner(FlowGraph* flow_graph, GrowableArray<Field*>* guarded_fields)
+  CallSiteInliner(FlowGraph* flow_graph,
+                  GrowableArray<const Field*>* guarded_fields)
       : caller_graph_(flow_graph),
         inlined_(false),
         initial_size_(flow_graph->InstructionCount()),
@@ -869,7 +870,7 @@
   CallSites* collected_call_sites_;
   CallSites* inlining_call_sites_;
   GrowableArray<ParsedFunction*> function_cache_;
-  GrowableArray<Field*>* guarded_fields_;
+  GrowableArray<const Field*>* guarded_fields_;
 
   DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
 };
diff --git a/runtime/vm/flow_graph_inliner.h b/runtime/vm/flow_graph_inliner.h
index fd8c518..57318e3 100644
--- a/runtime/vm/flow_graph_inliner.h
+++ b/runtime/vm/flow_graph_inliner.h
@@ -15,7 +15,8 @@
 
 class FlowGraphInliner : ValueObject {
  public:
-  FlowGraphInliner(FlowGraph* flow_graph, GrowableArray<Field*>* guarded_fields)
+  FlowGraphInliner(FlowGraph* flow_graph,
+                   GrowableArray<const Field*>* guarded_fields)
       : flow_graph_(flow_graph), guarded_fields_(guarded_fields) {}
 
   // The flow graph is destructively updated upon inlining.
@@ -25,7 +26,7 @@
 
  private:
   FlowGraph* flow_graph_;
-  GrowableArray<Field*>* guarded_fields_;
+  GrowableArray<const Field*>* guarded_fields_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphInliner);
 };
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 555b859..3182806 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -302,7 +302,8 @@
 }
 
 
-void FlowGraphOptimizer::Canonicalize() {
+bool FlowGraphOptimizer::Canonicalize() {
+  bool changed = false;
   for (intptr_t i = 0; i < block_order_.length(); ++i) {
     BlockEntryInstr* entry = block_order_[i];
     entry->Accept(this);
@@ -314,9 +315,11 @@
         // this.
         ASSERT((replacement == NULL) || current->IsDefinition());
         ReplaceCurrentInstruction(&it, current, replacement, flow_graph_);
+        changed = true;
       }
     }
   }
+  return changed;
 }
 
 
@@ -1240,17 +1243,17 @@
 }
 
 
-void FlowGraphOptimizer::AddToGuardedFields(Field* field) {
-  if ((field->guarded_cid() == kDynamicCid) ||
-      (field->guarded_cid() == kIllegalCid)) {
+void FlowGraphOptimizer::AddToGuardedFields(const Field& field) {
+  if ((field.guarded_cid() == kDynamicCid) ||
+      (field.guarded_cid() == kIllegalCid)) {
     return;
   }
   for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
-    if ((*guarded_fields_)[j]->raw() == field->raw()) {
+    if ((*guarded_fields_)[j]->raw() == field.raw()) {
       return;
     }
   }
-  guarded_fields_->Add(field);
+  guarded_fields_->Add(&field);
 }
 
 
@@ -1264,7 +1267,7 @@
   // Inline implicit instance getter.
   const String& field_name =
       String::Handle(Field::NameFromGetter(call->function_name()));
-  const Field& field = Field::Handle(GetField(class_ids[0], field_name));
+  const Field& field = Field::ZoneHandle(GetField(class_ids[0], field_name));
   ASSERT(!field.IsNull());
 
   if (InstanceCallNeedsClassCheck(call)) {
@@ -1275,13 +1278,12 @@
       field.Offset(),
       AbstractType::ZoneHandle(field.type()),
       field.is_final());
+  load->set_field(&field);
   if (field.guarded_cid() != kIllegalCid) {
     if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
       load->set_result_cid(field.guarded_cid());
     }
-    Field* the_field = &Field::ZoneHandle(field.raw());
-    load->set_field(the_field);
-    AddToGuardedFields(the_field);
+    AddToGuardedFields(field);
   }
   load->set_field_name(String::Handle(field.name()).ToCString());
 
@@ -1738,88 +1740,163 @@
   }
 
   if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
-    switch (recognized_kind) {
-      case MethodRecognizer::kFloat32x4Equal:
-      case MethodRecognizer::kFloat32x4GreaterThan:
-      case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
-      case MethodRecognizer::kFloat32x4LessThan:
-      case MethodRecognizer::kFloat32x4LessThanOrEqual:
-      case MethodRecognizer::kFloat32x4NotEqual: {
-        Definition* left = call->ArgumentAt(0);
-        Definition* right = call->ArgumentAt(1);
-        // Type check left.
-        AddCheckClass(left,
-                      ICData::ZoneHandle(
-                          call->ic_data()->AsUnaryClassChecksForArgNr(0)),
-                      call->deopt_id(),
-                      call->env(),
-                      call);
-        // Replace call.
-        Float32x4ComparisonInstr* cmp =
-            new Float32x4ComparisonInstr(recognized_kind, new Value(left),
-                                         new Value(right), call);
-        ReplaceCall(call, cmp);
-        return true;
-      }
-      case MethodRecognizer::kFloat32x4Min:
-      case MethodRecognizer::kFloat32x4Max: {
-        Definition* left = call->ArgumentAt(0);
-        Definition* right = call->ArgumentAt(1);
-        // Type check left.
-        AddCheckClass(left,
-                      ICData::ZoneHandle(
-                          call->ic_data()->AsUnaryClassChecksForArgNr(0)),
-                      call->deopt_id(),
-                      call->env(),
-                      call);
-        Float32x4MinMaxInstr* minmax =
-            new Float32x4MinMaxInstr(recognized_kind, new Value(left),
-                                     new Value(right), call);
-        ReplaceCall(call, minmax);
-        return true;
-      }
-      case MethodRecognizer::kFloat32x4Scale: {
-        Definition* left = call->ArgumentAt(0);
-        Definition* right = call->ArgumentAt(1);
-        // Type check left.
-        AddCheckClass(left,
-                      ICData::ZoneHandle(
-                          call->ic_data()->AsUnaryClassChecksForArgNr(0)),
-                      call->deopt_id(),
-                      call->env(),
-                      call);
-        // Left and right values are swapped when handed to the instruction,
-        // this is done so that the double value is loaded into the output
-        // register and can be destroyed.
-        Float32x4ScaleInstr* scale =
-            new Float32x4ScaleInstr(recognized_kind, new Value(right),
-                                    new Value(left), call);
-        ReplaceCall(call, scale);
-        return true;
-      }
-      case MethodRecognizer::kFloat32x4Sqrt:
-      case MethodRecognizer::kFloat32x4ReciprocalSqrt:
-      case MethodRecognizer::kFloat32x4Reciprocal: {
-        Definition* left = call->ArgumentAt(0);
-        AddCheckClass(left,
-              ICData::ZoneHandle(
-                  call->ic_data()->AsUnaryClassChecksForArgNr(0)),
-              call->deopt_id(),
-              call->env(),
-              call);
-        Float32x4SqrtInstr* sqrt =
-            new Float32x4SqrtInstr(recognized_kind, new Value(left), call);
-        ReplaceCall(call, sqrt);
-        return true;
-      }
-      default:
-        return false;
-    }
+    return TryInlineFloat32x4Method(call, recognized_kind);
   }
   return false;
 }
 
 
+bool FlowGraphOptimizer::TryInlineFloat32x4Method(
+    InstanceCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  ASSERT(call->HasICData());
+  switch (recognized_kind) {
+    case MethodRecognizer::kFloat32x4Equal:
+    case MethodRecognizer::kFloat32x4GreaterThan:
+    case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
+    case MethodRecognizer::kFloat32x4LessThan:
+    case MethodRecognizer::kFloat32x4LessThanOrEqual:
+    case MethodRecognizer::kFloat32x4NotEqual: {
+      Definition* left = call->ArgumentAt(0);
+      Definition* right = call->ArgumentAt(1);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      // Replace call.
+      Float32x4ComparisonInstr* cmp =
+          new Float32x4ComparisonInstr(recognized_kind, new Value(left),
+                                       new Value(right), call);
+      ReplaceCall(call, cmp);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4Min:
+    case MethodRecognizer::kFloat32x4Max: {
+      Definition* left = call->ArgumentAt(0);
+      Definition* right = call->ArgumentAt(1);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      Float32x4MinMaxInstr* minmax =
+          new Float32x4MinMaxInstr(recognized_kind, new Value(left),
+                                   new Value(right), call);
+      ReplaceCall(call, minmax);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4Scale: {
+      Definition* left = call->ArgumentAt(0);
+      Definition* right = call->ArgumentAt(1);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      // Left and right values are swapped when handed to the instruction,
+      // this is done so that the double value is loaded into the output
+      // register and can be destroyed.
+      Float32x4ScaleInstr* scale =
+          new Float32x4ScaleInstr(recognized_kind, new Value(right),
+                                  new Value(left), call);
+      ReplaceCall(call, scale);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4Sqrt:
+    case MethodRecognizer::kFloat32x4ReciprocalSqrt:
+    case MethodRecognizer::kFloat32x4Reciprocal: {
+      Definition* left = call->ArgumentAt(0);
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      Float32x4SqrtInstr* sqrt =
+          new Float32x4SqrtInstr(recognized_kind, new Value(left), call);
+      ReplaceCall(call, sqrt);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4WithX:
+    case MethodRecognizer::kFloat32x4WithY:
+    case MethodRecognizer::kFloat32x4WithZ:
+    case MethodRecognizer::kFloat32x4WithW: {
+      Definition* left = call->ArgumentAt(0);
+      Definition* right = call->ArgumentAt(1);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      Float32x4WithInstr* with = new Float32x4WithInstr(recognized_kind,
+                                                        new Value(left),
+                                                        new Value(right),
+                                                        call);
+      ReplaceCall(call, with);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4Absolute:
+    case MethodRecognizer::kFloat32x4Negate: {
+      Definition* left = call->ArgumentAt(0);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      Float32x4ZeroArgInstr* zeroArg =
+          new Float32x4ZeroArgInstr(recognized_kind, new Value(left), call);
+      ReplaceCall(call, zeroArg);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4Clamp: {
+      Definition* left = call->ArgumentAt(0);
+      Definition* lower = call->ArgumentAt(1);
+      Definition* upper = call->ArgumentAt(2);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left),
+                                                           new Value(lower),
+                                                           new Value(upper),
+                                                           call);
+      ReplaceCall(call, clamp);
+      return true;
+    }
+    case MethodRecognizer::kFloat32x4ToUint32x4: {
+      Definition* left = call->ArgumentAt(0);
+      // Type check left.
+      AddCheckClass(left,
+                    ICData::ZoneHandle(
+                        call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      Float32x4ToUint32x4Instr* cast =
+          new Float32x4ToUint32x4Instr(new Value(left), call);
+      ReplaceCall(call, cast);
+      return true;
+    }
+    default:
+      return false;
+  }
+}
+
+
 bool FlowGraphOptimizer::BuildByteArrayViewLoad(
     InstanceCallInstr* call,
     intptr_t receiver_cid,
@@ -3215,22 +3292,23 @@
     return Alias(kIndexesAlias);
   }
 
-  // Field load/stores alias each other when field offset matches.
-  // TODO(vegorov): use field information to disambiguate load/stores into
-  // different fields that by accident share offset.
-  static Alias Field(intptr_t offset_in_bytes) {
+  // Field load/stores alias each other only when they access the same field.
+  // AliasedSet assigns ids to a combination of instance and field during
+  // the optimization phase.
+  static Alias Field(intptr_t id) {
+    ASSERT(id >= kFirstFieldAlias);
+    return Alias(id * 2 + 1);
+  }
+
+  // VMField load/stores alias each other when field offset matches.
+  // TODO(vegorov) storing a context variable does not alias loading array
+  // length.
+  static Alias VMField(intptr_t offset_in_bytes) {
     const intptr_t idx = offset_in_bytes / kWordSize;
     ASSERT(idx >= kFirstFieldAlias);
     return Alias(idx * 2);
   }
 
-  // Static field load/stores alias each other.
-  // AliasedSet assigns ids to static fields during optimization phase.
-  static Alias StaticField(intptr_t id) {
-    ASSERT(id >= kFirstFieldAlias);
-    return Alias(id * 2 + 1);
-  }
-
   // Current context load/stores alias each other.
   static Alias CurrentContext() {
     return Alias(kCurrentContextAlias);
@@ -3283,7 +3361,12 @@
 
     LoadFieldInstr* load_field = defn->AsLoadField();
     if (load_field != NULL) {
-      return Alias::Field(load_field->offset_in_bytes());
+      if (load_field->field() != NULL) {
+        Definition* instance = load_field->instance()->definition();
+        return Alias::Field(GetInstanceFieldId(instance, *load_field->field()));
+      } else {
+        return Alias::VMField(load_field->offset_in_bytes());
+      }
     }
 
     if (defn->IsCurrentContext()) {
@@ -3292,7 +3375,7 @@
 
     LoadStaticFieldInstr* load_static_field = defn->AsLoadStaticField();
     if (load_static_field != NULL) {
-      return Alias::StaticField(GetFieldId(load_static_field->field()));
+      return Alias::Field(GetFieldId(kAnyInstance, load_static_field->field()));
     }
 
     UNREACHABLE();
@@ -3307,12 +3390,14 @@
     StoreInstanceFieldInstr* store_instance_field =
         instr->AsStoreInstanceField();
     if (store_instance_field != NULL) {
-      return Alias::Field(store_instance_field->field().Offset());
+      Definition* instance = store_instance_field->instance()->definition();
+      return Alias::Field(GetInstanceFieldId(instance,
+                                             store_instance_field->field()));
     }
 
     StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
     if (store_vm_field != NULL) {
-      return Alias::Field(store_vm_field->offset_in_bytes());
+      return Alias::VMField(store_vm_field->offset_in_bytes());
     }
 
     if (instr->IsStoreContext() || instr->IsChainContext()) {
@@ -3321,7 +3406,7 @@
 
     StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
     if (store_static_field != NULL) {
-      return Alias::StaticField(GetFieldId(store_static_field->field()));
+      return Alias::Field(GetStaticFieldId(store_static_field->field()));
     }
 
     return Alias::None();
@@ -3363,18 +3448,86 @@
 
   // Get id assigned to the given field. Assign a new id if the field is seen
   // for the first time.
-  intptr_t GetFieldId(const Field& field) {
-    intptr_t id = field_ids_.Lookup(&field);
+  intptr_t GetFieldId(intptr_t instance_id, const Field& field) {
+    intptr_t id = field_ids_.Lookup(FieldIdPair::Key(instance_id, &field));
     if (id == 0) {
       id = ++max_field_id_;
-      field_ids_.Insert(FieldIdPair(&field, id));
+      field_ids_.Insert(FieldIdPair(FieldIdPair::Key(instance_id, &field), id));
     }
     return id;
   }
 
+  enum {
+    kAnyInstance = -1
+  };
+
+  // Get or create an identifier for an instance field belonging to the
+  // given instance.
+  // The space of identifiers assigned to instance fields is split into
+  // parts based on the instance that contains the field.
+  // If compiler can prove that instance has a single SSA name in the compiled
+  // function then we use that SSA name to distinguish fields of this object
+  // from the same fields in other objects.
+  // If multiple SSA names can point to the same object then we use
+  // kAnyInstance instead of a concrete SSA name.
+  intptr_t GetInstanceFieldId(Definition* defn, const Field& field) {
+    ASSERT(!field.is_static());
+
+    intptr_t instance_id = kAnyInstance;
+
+    AllocateObjectInstr* alloc = defn->AsAllocateObject();
+    if ((alloc != NULL) && !CanBeAliased(alloc)) {
+      instance_id = alloc->ssa_temp_index();
+      ASSERT(instance_id != kAnyInstance);
+    }
+
+    return GetFieldId(instance_id, field);
+  }
+
+  // Get or create an identifier for a static field.
+  intptr_t GetStaticFieldId(const Field& field) {
+    ASSERT(field.is_static());
+    return GetFieldId(kAnyInstance, field);
+  }
+
+  // Returns true if the result of AllocateObject can be aliased by some
+  // other SSA variable and false otherwise. Currently simply checks if
+  // this value is stored in a field, escapes to another function or
+  // participates in a phi.
+  bool CanBeAliased(AllocateObjectInstr* alloc) {
+    if (alloc->identity() == AllocateObjectInstr::kUnknown) {
+      bool escapes = false;
+      for (Value* use = alloc->input_use_list();
+           use != NULL;
+           use = use->next_use()) {
+        Instruction* instr = use->instruction();
+        if (instr->IsPushArgument() ||
+            (instr->IsStoreVMField() && (use->use_index() != 0)) ||
+            (instr->IsStoreInstanceField() && (use->use_index() != 0)) ||
+            (instr->IsStoreStaticField()) ||
+            (instr->IsPhi())) {
+          escapes = true;
+          break;
+        }
+
+        alloc->set_identity(escapes ? AllocateObjectInstr::kAliased
+                                    : AllocateObjectInstr::kNotAliased);
+      }
+    }
+
+    return alloc->identity() != AllocateObjectInstr::kNotAliased;
+  }
+
   class FieldIdPair {
    public:
-    typedef const Field* Key;
+    struct Key {
+      Key(intptr_t instance_id, const Field* field)
+          : instance_id_(instance_id), field_(field) { }
+
+      intptr_t instance_id_;
+      const Field* field_;
+    };
+
     typedef intptr_t Value;
     typedef FieldIdPair Pair;
 
@@ -3389,11 +3542,12 @@
     }
 
     static intptr_t Hashcode(Key key) {
-      return String::Handle(key->name()).Hash();
+      return String::Handle(key.field_->name()).Hash();
     }
 
     static inline bool IsKeyEqual(Pair kv, Key key) {
-      return KeyOf(kv)->raw() == key->raw();
+      return (KeyOf(kv).field_->raw() == key.field_->raw()) &&
+          (KeyOf(kv).instance_id_ == key.instance_id_);
     }
 
    private:
@@ -3466,7 +3620,7 @@
       location = store_indexed->index()->definition()->ssa_temp_index();
     } else if (key->IsLoadField()) {
       LoadFieldInstr* load_field = key->AsLoadField();
-      object = load_field->value()->definition()->ssa_temp_index();
+      object = load_field->instance()->definition()->ssa_temp_index();
       location = load_field->offset_in_bytes();
     } else if (key->IsStoreInstanceField()) {
       StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
@@ -3522,11 +3676,11 @@
     LoadFieldInstr* load_field = kv->AsLoadField();
     if (key->IsStoreVMField()) {
       StoreVMFieldInstr* store_field = key->AsStoreVMField();
-      return load_field->value()->Equals(store_field->dest()) &&
+      return load_field->instance()->Equals(store_field->dest()) &&
              (load_field->offset_in_bytes() == store_field->offset_in_bytes());
     } else if (key->IsStoreInstanceField()) {
       StoreInstanceFieldInstr* store_field = key->AsStoreInstanceField();
-      return load_field->value()->Equals(store_field->instance()) &&
+      return load_field->instance()->Equals(store_field->instance()) &&
              (load_field->offset_in_bytes() == store_field->field().Offset());
     }
 
@@ -4652,16 +4806,16 @@
 
 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
   if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) &&
-      (instr->value()->definition()->IsCreateArray())) {
+      (instr->instance()->definition()->IsCreateArray())) {
     const intptr_t length =
-        instr->value()->definition()->AsCreateArray()->num_elements();
+        instr->instance()->definition()->AsCreateArray()->num_elements();
     const Object& result = Smi::ZoneHandle(Smi::New(length));
     SetValue(instr, result);
     return;
   }
 
   if (instr->IsImmutableLengthLoad()) {
-    ConstantInstr* constant = instr->value()->definition()->AsConstant();
+    ConstantInstr* constant = instr->instance()->definition()->AsConstant();
     if (constant != NULL) {
       if (constant->value().IsString()) {
         SetValue(instr, Smi::ZoneHandle(
@@ -4937,6 +5091,27 @@
 }
 
 
+void ConstantPropagator::VisitFloat32x4ZeroArg(Float32x4ZeroArgInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloat32x4ToUint32x4(
+    Float32x4ToUint32x4Instr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) {
   const Object& value = instr->value()->definition()->constant_value();
   if (IsNonConstant(value)) {
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 980890b..5b2bfa6 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -17,7 +17,7 @@
 class FlowGraphOptimizer : public FlowGraphVisitor {
  public:
   FlowGraphOptimizer(FlowGraph* flow_graph,
-                     GrowableArray<Field*>* guarded_fields)
+                     GrowableArray<const Field*>* guarded_fields)
       : FlowGraphVisitor(flow_graph->reverse_postorder()),
         flow_graph_(flow_graph),
         guarded_fields_(guarded_fields) { }
@@ -35,7 +35,8 @@
   // shift can be a truncating Smi shift-left and result is always Smi.
   void TryOptimizeLeftShiftWithBitAndPattern();
 
-  void Canonicalize();
+  // Returns true if any instructions were canonicalized away.
+  bool Canonicalize();
 
   void EliminateDeadPhis();
 
@@ -81,6 +82,8 @@
                                const ICData& unary_ic_data);
 
   bool TryInlineInstanceMethod(InstanceCallInstr* call);
+  bool TryInlineFloat32x4Method(InstanceCallInstr* call,
+                                MethodRecognizer::Kind recognized_kind);
   void ReplaceWithInstanceOf(InstanceCallInstr* instr);
   void ReplaceWithTypeCast(InstanceCallInstr* instr);
 
@@ -168,10 +171,10 @@
                                     Definition* left_instr,
                                     Definition* right_instr);
 
-  void AddToGuardedFields(Field* field);
+  void AddToGuardedFields(const Field& field);
 
   FlowGraph* flow_graph_;
-  GrowableArray<Field*>* guarded_fields_;
+  GrowableArray<const Field*>* guarded_fields_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer);
 };
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 253697a..2b5f1a4 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -891,7 +891,7 @@
     return CompileType::FromAbstractType(type());
   }
 
-  if (field_ != NULL) {
+  if (field_ != NULL && (field_->guarded_cid() != kIllegalCid)) {
     return CompileType::CreateNullable(field_->is_nullable(),
                                        field_->guarded_cid());
   }
@@ -1011,6 +1011,26 @@
 }
 
 
+CompileType Float32x4ZeroArgInstr::ComputeType() const {
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Float32x4ClampInstr::ComputeType() const {
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Float32x4WithInstr::ComputeType() const {
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Float32x4ToUint32x4Instr::ComputeType() const {
+  return CompileType::FromCid(kUint32x4Cid);
+}
+
+
 CompileType MathSqrtInstr::ComputeType() const {
   return CompileType::FromCid(kDoubleCid);
 }
diff --git a/runtime/vm/heap_profiler.cc b/runtime/vm/heap_profiler.cc
index 6503b6e..781ef5b 100644
--- a/runtime/vm/heap_profiler.cc
+++ b/runtime/vm/heap_profiler.cc
@@ -336,9 +336,11 @@
   uint32_t size = htonl(kObjectIdSize);
   Write(&size, sizeof(size));
   uint64_t milliseconds = OS::GetCurrentTimeMillis();
-  uint32_t hi = htonl((uint32_t)((milliseconds >> 32) & 0x00000000FFFFFFFF));
+  uint32_t hi = htonl(
+      static_cast<uint32_t>((milliseconds >> 32) & 0x00000000FFFFFFFF));
   Write(&hi, sizeof(hi));
-  uint32_t lo = htonl((uint32_t)(milliseconds & 0x00000000FFFFFFFF));
+  uint32_t lo = htonl(
+      static_cast<uint32_t>(milliseconds & 0x00000000FFFFFFFF));
   Write(&lo, sizeof(lo));
 }
 
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index bf50596..406c445 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -514,7 +514,7 @@
 
 
 void LoadFieldInstr::PrintOperandsTo(BufferFormatter* f) const {
-  value()->PrintTo(f);
+  instance()->PrintTo(f);
   f->Print(", %"Pd, offset_in_bytes());
 
   if (field_name_ != NULL) {
@@ -664,6 +664,32 @@
 }
 
 
+void Float32x4ZeroArgInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
+  left()->PrintTo(f);
+}
+
+
+void Float32x4ClampInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("Float32x4.clamp, ");
+  left()->PrintTo(f);
+}
+
+
+void Float32x4WithInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
+  left()->PrintTo(f);
+  f->Print(", ");
+  replacement()->PrintTo(f);
+}
+
+
+void Float32x4ToUint32x4Instr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("Float32x4.toUint32x4 ");
+  left()->PrintTo(f);
+}
+
+
 void BinaryMintOpInstr::PrintOperandsTo(BufferFormatter* f) const {
   f->Print("%s, ", Token::Str(op_kind()));
   left()->PrintTo(f);
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index db49612..bb57209 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1196,7 +1196,7 @@
   // For fixed length arrays if the array is the result of a known constructor
   // call we can replace the length load with the length argument passed to
   // the constructor.
-  StaticCallInstr* call = value()->definition()->AsStaticCall();
+  StaticCallInstr* call = instance()->definition()->AsStaticCall();
   if ((call != NULL) &&
       call->is_known_list_constructor() &&
       IsFixedLengthArrayCid(call->Type()->ToCid())) {
@@ -1245,6 +1245,29 @@
 }
 
 
+Definition* BoxDoubleInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
+  if (input_use_list() == NULL) {
+    // Environments can accomodate any representation. No need to box.
+    return value()->definition();
+  }
+
+  // Fold away BoxDouble(UnboxDouble(v)) if value is known to be double.
+  UnboxDoubleInstr* defn = value()->definition()->AsUnboxDouble();
+  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kDoubleCid)) {
+    return defn->value()->definition();
+  }
+
+  return this;
+}
+
+
+Definition* UnboxDoubleInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
+  // Fold away UnboxDouble(BoxDouble(v)).
+  BoxDoubleInstr* defn = value()->definition()->AsBoxDouble();
+  return (defn != NULL) ? defn->value()->definition() : this;
+}
+
+
 Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) {
   // Only handle strict-compares.
   if (comparison()->IsStrictCompare()) {
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 6b560f6..dc33a3f 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -94,6 +94,15 @@
   V(_Float32x4, _sqrt, Float32x4Sqrt, 42621627)                                \
   V(_Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 42621627)            \
   V(_Float32x4, _reciprocal, Float32x4Reciprocal, 42621627)                    \
+  V(_Float32x4, _negate, Float32x4Negate, 42621627)                            \
+  V(_Float32x4, _abs, Float32x4Absolute, 42621627)                             \
+  V(_Float32x4, _clamp, Float32x4Clamp, 615895313)                             \
+  V(_Float32x4, withX, Float32x4WithX, 219466242)                              \
+  V(_Float32x4, withY, Float32x4WithY, 219466242)                              \
+  V(_Float32x4, withZ, Float32x4WithZ, 219466242)                              \
+  V(_Float32x4, withW, Float32x4WithW, 219466242)                              \
+  V(_Float32x4, _toUint32x4, Float32x4ToUint32x4, 1044409108)                  \
+
 
 // Class that recognizes the name and owner of a function and returns the
 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -571,6 +580,10 @@
   M(Float32x4MinMax)                                                           \
   M(Float32x4Scale)                                                            \
   M(Float32x4Sqrt)                                                             \
+  M(Float32x4ZeroArg)                                                          \
+  M(Float32x4Clamp)                                                            \
+  M(Float32x4With)                                                             \
+  M(Float32x4ToUint32x4)                                                       \
 
 
 #define FORWARD_DECLARATION(type) class type##Instr;
@@ -835,6 +848,10 @@
   friend class Float32x4MinMaxInstr;
   friend class Float32x4ScaleInstr;
   friend class Float32x4SqrtInstr;
+  friend class Float32x4ZeroArgInstr;
+  friend class Float32x4ClampInstr;
+  friend class Float32x4WithInstr;
+  friend class Float32x4ToUint32x4Instr;
   friend class BinaryMintOpInstr;
   friend class BinarySmiOpInstr;
   friend class UnarySmiOpInstr;
@@ -3408,7 +3425,8 @@
                       ZoneGrowableArray<PushArgumentInstr*>* arguments)
       : ast_node_(*node),
         arguments_(arguments),
-        cid_(Class::Handle(node->constructor().Owner()).id()) {
+        cid_(Class::Handle(node->constructor().Owner()).id()),
+        identity_(kUnknown) {
     // Either no arguments or one type-argument and one instantiator.
     ASSERT(arguments->is_empty() || (arguments->length() == 2));
   }
@@ -3430,10 +3448,23 @@
 
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
+  // If the result of the allocation is not stored into any field, passed
+  // as an argument or used in a phi then it can't alias with any other
+  // SSA value.
+  enum Identity {
+    kUnknown,
+    kAliased,
+    kNotAliased
+  };
+
+  Identity identity() const { return identity_; }
+  void set_identity(Identity identity) { identity_ = identity; }
+
  private:
   const ConstructorCallNode& ast_node_;
   ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
   const intptr_t cid_;
+  Identity identity_;
 
   DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr);
 };
@@ -3575,7 +3606,7 @@
 
 class LoadFieldInstr : public TemplateDefinition<1> {
  public:
-  LoadFieldInstr(Value* value,
+  LoadFieldInstr(Value* instance,
                  intptr_t offset_in_bytes,
                  const AbstractType& type,
                  bool immutable = false)
@@ -3587,10 +3618,10 @@
         field_name_(NULL),
         field_(NULL) {
     ASSERT(type.IsZoneHandle());  // May be null if field is not an instance.
-    SetInputAt(0, value);
+    SetInputAt(0, instance);
   }
 
-  Value* value() const { return inputs_[0]; }
+  Value* instance() const { return inputs_[0]; }
   intptr_t offset_in_bytes() const { return offset_in_bytes_; }
   const AbstractType& type() const { return type_; }
   void set_result_cid(intptr_t value) { result_cid_ = value; }
@@ -3599,8 +3630,8 @@
   void set_field_name(const char* name) { field_name_ = name; }
   const char* field_name() const { return field_name_; }
 
-  Field* field() const { return field_; }
-  void set_field(Field* field) { field_ = field; }
+  const Field* field() const { return field_; }
+  void set_field(const Field* field) { field_ = field; }
 
   void set_recognized_kind(MethodRecognizer::Kind kind) {
     recognized_kind_ = kind;
@@ -3641,7 +3672,7 @@
   MethodRecognizer::Kind recognized_kind_;
 
   const char* field_name_;
-  Field* field_;
+  const Field* field_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr);
 };
@@ -3939,6 +3970,8 @@
   virtual EffectSet Dependencies() const { return EffectSet::None(); }
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
+  Definition* Canonicalize(FlowGraphOptimizer* optimizer);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr);
 };
@@ -4054,6 +4087,8 @@
   virtual EffectSet Dependencies() const { return EffectSet::None(); }
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
+  Definition* Canonicalize(FlowGraphOptimizer* optimizer);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr);
 };
@@ -4688,6 +4723,195 @@
 };
 
 
+class Float32x4ZeroArgInstr : public TemplateDefinition<1> {
+ public:
+  Float32x4ZeroArgInstr(MethodRecognizer::Kind op_kind, Value* left,
+                        InstanceCallInstr* instance_call) : op_kind_(op_kind) {
+    SetInputAt(0, left);
+    deopt_id_ = instance_call->deopt_id();
+  }
+
+  Value* left() const { return inputs_[0]; }
+
+  MethodRecognizer::Kind op_kind() const { return op_kind_; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedFloat32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4ZeroArg)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const {
+    return op_kind() == other->AsFloat32x4ZeroArg()->op_kind();
+  }
+
+ private:
+  const MethodRecognizer::Kind op_kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(Float32x4ZeroArgInstr);
+};
+
+
+class Float32x4ClampInstr : public TemplateDefinition<3> {
+ public:
+  Float32x4ClampInstr(Value* left, Value* lower, Value* upper,
+                      InstanceCallInstr* instance_call) {
+    SetInputAt(0, left);
+    SetInputAt(1, lower);
+    SetInputAt(2, upper);
+    deopt_id_ = instance_call->deopt_id();
+  }
+
+  Value* left() const { return inputs_[0]; }
+  Value* lower() const { return inputs_[1]; }
+  Value* upper() const { return inputs_[2]; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT((idx == 0) || (idx == 1) || (idx == 2));
+    return kUnboxedFloat32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4Clamp)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Float32x4ClampInstr);
+};
+
+
+class Float32x4WithInstr : public TemplateDefinition<2> {
+ public:
+  Float32x4WithInstr(MethodRecognizer::Kind op_kind, Value* left,
+                     Value* replacement, InstanceCallInstr* instance_call)
+      : op_kind_(op_kind) {
+    SetInputAt(0, replacement);
+    SetInputAt(1, left);
+    deopt_id_ = instance_call->deopt_id();
+  }
+
+  Value* left() const { return inputs_[1]; }
+  Value* replacement() const { return inputs_[0]; }
+
+  MethodRecognizer::Kind op_kind() const { return op_kind_; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT((idx == 0) || (idx == 1));
+    if (idx == 0) {
+      return kUnboxedDouble;
+    }
+    return kUnboxedFloat32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4With)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const {
+    return op_kind() == other->AsFloat32x4With()->op_kind();
+  }
+
+ private:
+  const MethodRecognizer::Kind op_kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(Float32x4WithInstr);
+};
+
+
+class Float32x4ToUint32x4Instr : public TemplateDefinition<1> {
+ public:
+  Float32x4ToUint32x4Instr(Value* left, InstanceCallInstr* instance_call) {
+    SetInputAt(0, left);
+    deopt_id_ = instance_call->deopt_id();
+  }
+
+  Value* left() const { return inputs_[0]; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    return kUnboxedUint32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedFloat32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4ToUint32x4)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AllowsCSE() const { return true; }
+  virtual EffectSet Effects() const { return EffectSet::None(); }
+  virtual EffectSet Dependencies() const { return EffectSet::None(); }
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Float32x4ToUint32x4Instr);
+};
+
+
 class BinaryMintOpInstr : public TemplateDefinition<2> {
  public:
   BinaryMintOpInstr(Token::Kind op_kind,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 60f959f..9361168 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2085,6 +2085,50 @@
 }
 
 
+LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index b085eed..20095ed 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -3166,6 +3166,139 @@
 }
 
 
+LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister left = locs()->in(0).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == left);
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4Negate:
+      __ negateps(left);
+      break;
+    case MethodRecognizer::kFloat32x4Absolute:
+      __ absps(left);
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
+LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 3;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_in(2, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister left = locs()->in(0).fpu_reg();
+  XmmRegister lower = locs()->in(1).fpu_reg();
+  XmmRegister upper = locs()->in(2).fpu_reg();
+  ASSERT(locs()->out().fpu_reg() == left);
+  __ minps(left, upper);
+  __ maxps(left, lower);
+}
+
+
+LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister replacement = locs()->in(0).fpu_reg();
+  XmmRegister value = locs()->in(1).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == replacement);
+
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4WithX:
+      __ cvtsd2ss(replacement, replacement);
+      __ subl(ESP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(ESP, -16), value);
+      // Write over X value.
+      __ movss(Address(ESP, -16), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(ESP, -16));
+      __ addl(ESP, Immediate(16));
+      break;
+    case MethodRecognizer::kFloat32x4WithY:
+      __ cvtsd2ss(replacement, replacement);
+      __ subl(ESP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(ESP, -16), value);
+      // Write over Y value.
+      __ movss(Address(ESP, -12), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(ESP, -16));
+      __ addl(ESP, Immediate(16));
+      break;
+    case MethodRecognizer::kFloat32x4WithZ:
+      __ cvtsd2ss(replacement, replacement);
+      __ subl(ESP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(ESP, -16), value);
+      // Write over Z value.
+      __ movss(Address(ESP, -8), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(ESP, -16));
+      __ addl(ESP, Immediate(16));
+      break;
+    case MethodRecognizer::kFloat32x4WithW:
+      __ cvtsd2ss(replacement, replacement);
+      __ subl(ESP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(ESP, -16), value);
+      // Write over W value.
+      __ movss(Address(ESP, -4), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(ESP, -16));
+      __ addl(ESP, Immediate(16));
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
+LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // NOP.
+}
+
+
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 21ba210..c3ffa5b 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -102,8 +102,7 @@
   // This sequence is patched by a debugger breakpoint. There is no need for
   // extra NOP instructions here because the sequence patched in for a
   // breakpoint is shorter than the sequence here.
-  __ LeaveDartFrame();
-  __ Ret();
+  __ LeaveDartFrameAndReturn();
   compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
                                  Isolate::kNoDeoptId,
                                  token_pos());
@@ -1247,13 +1246,13 @@
     } else if (value_cid == kNullCid) {
       // TODO(regis): TMP1 may conflict. Revisit.
       __ lw(TMP1, field_nullability_operand);
-      __ LoadImmediate(TMP2, value_cid);
-      __ subu(CMPRES, TMP1, TMP2);
+      __ LoadImmediate(CMPRES, value_cid);
+      __ subu(CMPRES, TMP1, CMPRES);
     } else {
       // TODO(regis): TMP1 may conflict. Revisit.
       __ lw(TMP1, field_cid_operand);
-      __ LoadImmediate(TMP2, value_cid);
-      __ subu(CMPRES, TMP1, TMP2);
+      __ LoadImmediate(CMPRES, value_cid);
+      __ subu(CMPRES, TMP1, CMPRES);
     }
     __ beq(CMPRES, ZR, &ok);
 
@@ -1502,9 +1501,9 @@
     // A runtime call to instantiate the type arguments is required.
     __ addiu(SP, SP, Immediate(-3 * kWordSize));
     __ LoadObject(TMP1, Object::ZoneHandle());
-    __ LoadObject(TMP2, type_arguments());
     __ sw(TMP1, Address(SP, 2 * kWordSize));  // Make room for the result.
-    __ sw(TMP2, Address(SP, 1 * kWordSize));
+    __ LoadObject(TMP1, type_arguments());
+    __ sw(TMP1, Address(SP, 1 * kWordSize));
     // Push instantiator type arguments.
     __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
 
@@ -1678,10 +1677,10 @@
         Address(FP, stacktrace_var().index() * kWordSize));
 
   Label next;
-  __ mov(TMP1, RA);  // Save return adress.
+  __ mov(T0, RA);  // Save return adress.
   // Restore the pool pointer.
   __ bal(&next);  // Branch and link to next instruction to get PC in RA.
-  __ delay_slot()->mov(TMP2, RA);  // Save PC of the following mov.
+  __ delay_slot()->mov(T1, RA);  // Save PC of the following mov.
 
   // Calculate offset of pool pointer from the PC.
   const intptr_t object_pool_pc_dist =
@@ -1689,8 +1688,8 @@
      compiler->assembler()->CodeSize();
 
   __ Bind(&next);
-  __ mov(RA, TMP1);  // Restore return address.
-  __ lw(PP, Address(TMP2, -object_pool_pc_dist));
+  __ mov(RA, T0);  // Restore return address.
+  __ lw(PP, Address(T1, -object_pool_pc_dist));
 }
 
 
@@ -1758,6 +1757,10 @@
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RequiresRegister());
     summary->set_in(1, Location::RegisterOrSmiConstant(right()));
+    if (op_kind() == Token::kADD) {
+      // Need an extra temp for the overflow detection code.
+      summary->set_temp(0, Location::RequiresRegister());
+    }
     // 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());
@@ -1799,7 +1802,8 @@
         if (deopt == NULL) {
           __ AddImmediate(result, left, imm);
         } else {
-          __ AddImmediateDetectOverflow(result, left, imm, CMPRES);
+          Register temp = locs()->temp(0).reg();
+          __ AddImmediateDetectOverflow(result, left, imm, CMPRES, temp);
           __ bltz(CMPRES, deopt);
         }
         break;
@@ -1825,8 +1829,8 @@
             __ mflo(result);
             __ mfhi(TMP1);
           }
-          __ sra(TMP2, result, 31);
-          __ bne(TMP1, TMP2, deopt);
+          __ sra(CMPRES, result, 31);
+          __ bne(TMP1, CMPRES, deopt);
         }
         break;
       }
@@ -1882,7 +1886,8 @@
       if (deopt == NULL) {
         __ addu(result, left, right);
       } else {
-        __ AdduDetectOverflow(result, left, right, CMPRES);
+        Register temp = locs()->temp(0).reg();
+        __ AdduDetectOverflow(result, left, right, CMPRES, temp);
         __ bltz(CMPRES, deopt);
       }
       break;
@@ -2140,6 +2145,50 @@
 }
 
 
+LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index ac9d6f8..989c41b 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -3173,6 +3173,139 @@
 }
 
 
+LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister left = locs()->in(0).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == left);
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4Negate:
+      __ negateps(left);
+      break;
+    case MethodRecognizer::kFloat32x4Absolute:
+      __ absps(left);
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
+LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 3;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_in(2, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister left = locs()->in(0).fpu_reg();
+  XmmRegister lower = locs()->in(1).fpu_reg();
+  XmmRegister upper = locs()->in(2).fpu_reg();
+  ASSERT(locs()->out().fpu_reg() == left);
+  __ minps(left, upper);
+  __ maxps(left, lower);
+}
+
+
+LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+void Float32x4WithInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister replacement = locs()->in(0).fpu_reg();
+  XmmRegister value = locs()->in(1).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == replacement);
+
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4WithX:
+      __ cvtsd2ss(replacement, replacement);
+      __ subq(RSP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(RSP, -16), value);
+      // Write over X value.
+      __ movss(Address(RSP, -16), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(RSP, -16));
+      __ addq(RSP, Immediate(16));
+      break;
+    case MethodRecognizer::kFloat32x4WithY:
+      __ cvtsd2ss(replacement, replacement);
+      __ subq(RSP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(RSP, -16), value);
+      // Write over Y value.
+      __ movss(Address(RSP, -12), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(RSP, -16));
+      __ addq(RSP, Immediate(16));
+      break;
+    case MethodRecognizer::kFloat32x4WithZ:
+      __ cvtsd2ss(replacement, replacement);
+      __ subq(RSP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(RSP, -16), value);
+      // Write over Z value.
+      __ movss(Address(RSP, -8), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(RSP, -16));
+      __ addq(RSP, Immediate(16));
+      break;
+    case MethodRecognizer::kFloat32x4WithW:
+      __ cvtsd2ss(replacement, replacement);
+      __ subq(RSP, Immediate(16));
+      // Move value to stack.
+      __ movups(Address(RSP, -16), value);
+      // Write over W value.
+      __ movss(Address(RSP, -4), replacement);
+      // Move updated value into output register.
+      __ movups(replacement, Address(RSP, -16));
+      __ addq(RSP, Immediate(16));
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
+LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // NOP.
+}
+
+
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
diff --git a/runtime/vm/object_mips_test.cc b/runtime/vm/object_mips_test.cc
index 750f65c..76b9871 100644
--- a/runtime/vm/object_mips_test.cc
+++ b/runtime/vm/object_mips_test.cc
@@ -37,8 +37,7 @@
   const String& string_object =
       String::ZoneHandle(String::New(str, Heap::kOld));
   __ LoadObject(V0, string_object);
-  __ LeaveDartFrame();
-  __ Ret();
+  __ LeaveDartFrameAndReturn();
 }
 
 
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 56e8aeb..4b027c9 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -1963,7 +1963,7 @@
   const String& source = String::Handle(String::New(source_chars));
   const Script& script = Script::Handle(Script::New(url,
                                                     source,
-                                                    RawScript::kSourceTag));
+                                                    RawScript::kScriptTag));
   EXPECT(!script.IsNull());
   EXPECT(script.IsScript());
   String& str = String::Handle(script.url());
@@ -2018,7 +2018,7 @@
   const String& url = String::Handle(String::New(url_chars));
   const String& source = String::Handle(String::New(src_chars));
   const Script& script = Script::Handle(
-      Script::New(url, source, RawScript::kSourceTag));
+      Script::New(url, source, RawScript::kScriptTag));
   script.SetLocationOffset(line_offset, col_offset);
 
   String& str = String::Handle();
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index b7814db..10adced 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -4439,28 +4439,23 @@
 
 
 void Parser::ParsePartHeader() {
-  intptr_t metadata_pos = TokenPos();
   SkipMetadata();
-  // TODO(hausner): Once support for old #source directive is removed
-  // from the compiler, add an error message here if we don't find
-  // a 'part of' directive.
-  if (CurrentToken() == Token::kPART) {
-    ConsumeToken();
-    if (!IsLiteral("of")) {
-      ErrorMsg("'part of' expected");
-    }
-    ConsumeToken();
-    // The VM is not required to check that the library name matches the
-    // name of the current library, so we ignore it.
-    ExpectIdentifier("library name expected");
-    while (CurrentToken() == Token::kPERIOD) {
-      ConsumeToken();
-      ExpectIdentifier("malformed library name");
-    }
-    ExpectSemicolon();
-  } else {
-    SetPosition(metadata_pos);
+  if (CurrentToken() != Token::kPART) {
+    ErrorMsg("'part of' expected");
   }
+  ConsumeToken();
+  if (!IsLiteral("of")) {
+    ErrorMsg("'part of' expected");
+  }
+  ConsumeToken();
+  // The VM is not required to check that the library name matches the
+  // name of the current library, so we ignore it.
+  ExpectIdentifier("library name expected");
+  while (CurrentToken() == Token::kPERIOD) {
+    ConsumeToken();
+    ExpectIdentifier("malformed library name");
+  }
+  ExpectSemicolon();
 }
 
 
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index f04eef1..2e4c4b7 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -117,7 +117,7 @@
   String& source = String::Handle(String::New(script_chars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = Library::ZoneHandle(Library::CoreLibrary());
 
   script.Tokenize(String::Handle(String::New("")));
@@ -152,7 +152,7 @@
   String& source = String::Handle(String::New(script_chars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   Library& lib = Library::ZoneHandle(Library::CoreLibrary());
 
   script.Tokenize(String::Handle(String::New("")));
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 2bdca58..66e90c9 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -815,7 +815,7 @@
   String& source = String::Handle(String::New(kScriptChars));
   Script& script = Script::Handle(Script::New(url,
                                               source,
-                                              RawScript::kSourceTag));
+                                              RawScript::kScriptTag));
   const String& lib_url = String::Handle(Symbols::New("TestLib"));
   Library& lib = Library::Handle(Library::New(lib_url));
   lib.Register();
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 1174f54..852768a 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -517,7 +517,7 @@
     __ cmp(R1, ShifterOperand(R7));
     __ str(IP, Address(R1, 0), CC);  // Store if unsigned lower.
     __ AddImmediate(R1, kWordSize, CC);
-    __ b(&loop, CS);
+    __ b(&loop, CC);  // Loop until R1 == R7.
 
     // Done allocating and initializing the array.
     // R0: new object.
@@ -1595,7 +1595,6 @@
     __ LoadClass(R3, R0, R4);
     // Compute instance type arguments into R4.
     Label has_no_type_arguments;
-    __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null()));
     __ ldr(R5, FieldAddress(R3,
         Class::type_arguments_field_offset_in_words_offset()));
     __ CompareImmediate(R5, Class::kNoTypeArguments);
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index a50383d..b475ae7 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -81,10 +81,11 @@
   __ addiu(A2, A2, Immediate(kWordSize));  // Set argv in NativeArguments.
 
   ASSERT(retval_offset == 3 * kWordSize);
-  __ addiu(A3, A2, Immediate(kWordSize));  // Retval is next to 1st argument.
 
   // Call runtime or redirection via simulator.
   __ jalr(S5);
+  // Retval is next to 1st argument.
+  __ delay_slot()->addiu(A3, A2, Immediate(kWordSize));
   __ TraceSimMsg("CallToRuntimeStub return");
 
   // Reset exit frame information in Isolate structure.
@@ -93,9 +94,11 @@
   // Load Context pointer from Isolate structure into A2.
   __ lw(A2, Address(CTX, Isolate::top_context_offset()));
 
+  // Reload NULLREG.
+  __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null()));
+
   // Reset Context pointer in Isolate structure.
-  __ LoadImmediate(A3, reinterpret_cast<intptr_t>(Object::null()));
-  __ sw(A3, Address(CTX, Isolate::top_context_offset()));
+  __ sw(NULLREG, Address(CTX, Isolate::top_context_offset()));
 
   // Cache Context pointer into CTX while executing Dart code.
   __ mov(CTX, A2);
@@ -175,10 +178,9 @@
   __ sw(A1, Address(SP, 1 * kWordSize));
   __ sw(A0, Address(SP, 0 * kWordSize));
 
-  __ mov(A0, SP);  // Pass the pointer to the NativeArguments.
-
   // Call native function or redirection via simulator.
   __ jalr(T5);
+  __ delay_slot()->mov(A0, SP);  // Pass the pointer to the NativeArguments.
   __ TraceSimMsg("CallNativeCFunctionStub return");
 
   // Reset exit frame information in Isolate structure.
@@ -187,9 +189,11 @@
   // Load Context pointer from Isolate structure into A2.
   __ lw(A2, Address(CTX, Isolate::top_context_offset()));
 
+  // Reload NULLREG.
+  __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null()));
+
   // Reset Context pointer in Isolate structure.
-  __ LoadImmediate(A3, reinterpret_cast<intptr_t>(Object::null()));
-  __ sw(A3, Address(CTX, Isolate::top_context_offset()));
+  __ sw(NULLREG, Address(CTX, Isolate::top_context_offset()));
 
   // Cache Context pointer into CTX while executing Dart code.
   __ mov(CTX, A2);
@@ -208,11 +212,10 @@
   __ TraceSimMsg("CallStaticFunctionStub");
   __ EnterStubFrame();
   // Setup space on stack for return value and preserve arguments descriptor.
-  __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
 
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
   __ sw(S4, Address(SP, 1 * kWordSize));
-  __ sw(T0, Address(SP, 0 * kWordSize));
+  __ sw(NULLREG, Address(SP, 0 * kWordSize));
 
   __ CallRuntime(kPatchStaticCallRuntimeEntry);
   __ TraceSimMsg("CallStaticFunctionStub return");
@@ -222,12 +225,11 @@
   __ lw(S4, Address(SP, 1 * kWordSize));
   __ addiu(SP, SP, Immediate(2 * kWordSize));
 
-  // Remove the stub frame as we are about to jump to the dart function.
-  __ LeaveStubFrame();
-
   __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
   __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
-  __ jr(T0);
+
+  // Remove the stub frame as we are about to jump to the dart function.
+  __ LeaveStubFrameAndReturn(T0);
 }
 
 
@@ -239,21 +241,21 @@
   // calling into the runtime.
   __ EnterStubFrame();
   // Setup space on stack for return value and preserve arguments descriptor.
-  __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
   __ sw(S4, Address(SP, 1 * kWordSize));
-  __ sw(T0, Address(SP, 0 * kWordSize));
+  __ sw(NULLREG, Address(SP, 0 * kWordSize));
   __ CallRuntime(kFixCallersTargetRuntimeEntry);
   // Get Code object result and restore arguments descriptor array.
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ lw(S4, Address(SP, 1 * kWordSize));
   __ addiu(SP, SP, Immediate(2 * kWordSize));
-  // Remove the stub frame.
-  __ LeaveStubFrame();
+
   // Jump to the dart function.
   __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
   __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag);
-  __ jr(T0);
+
+  // Remove the stub frame.
+  __ LeaveStubFrameAndReturn(T0);
 }
 
 
@@ -263,7 +265,7 @@
 static void PushArgumentsArray(Assembler* assembler) {
   __ TraceSimMsg("PushArgumentsArray");
   // Allocate array to store arguments of caller.
-  __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null()));
+  __ mov(A0, NULLREG);
   // A0: Null element type for raw Array.
   // A1: Smi-tagged argument count, may be zero.
   __ BranchLink(&StubCode::AllocateArrayLabel());
@@ -274,19 +276,21 @@
   __ sll(T1, A1, 1);
   __ addu(T1, FP, T1);
   __ AddImmediate(T1, (kLastParamSlotIndex - 1) * kWordSize);
-  __ AddImmediate(T2, V0, Array::data_offset() - kHeapObjectTag);
   // T1: address of first argument on stack.
   // T2: address of first argument in array.
-  Label loop, loop_condition;
-  __ b(&loop_condition);
+
+  Label loop, loop_exit;
+  __ blez(A1, &loop_exit);
+  __ delay_slot()->addiu(T2, V0,
+                         Immediate(Array::data_offset() - kHeapObjectTag));
   __ Bind(&loop);
   __ lw(TMP, Address(T1));
-  __ sw(TMP, Address(T2));
-  __ AddImmediate(T1, -kWordSize);
-  __ AddImmediate(T2, kWordSize);
-  __ Bind(&loop_condition);
-  __ AddImmediate(A1, -Smi::RawValue(1));  // A1 is Smi.
-  __ BranchSignedGreaterEqual(A1, ZR, &loop);
+  __ addiu(A1, A1, Immediate(-Smi::RawValue(1)));
+  __ addiu(T1, T1, Immediate(-kWordSize));
+  __ addiu(T2, T2, Immediate(kWordSize));
+  __ bgez(A1, &loop);
+  __ delay_slot()->sw(TMP, Address(T2, -kWordSize));
+  __ Bind(&loop_exit);
 }
 
 
@@ -310,9 +314,8 @@
   // Push the receiver.
   // Push TMP1 data object.
   // Push arguments descriptor array.
-  __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
   __ addiu(SP, SP, Immediate(-4 * kWordSize));
-  __ sw(TMP1, Address(SP, 3 * kWordSize));
+  __ sw(NULLREG, Address(SP, 3 * kWordSize));
   __ sw(T1, Address(SP, 2 * kWordSize));
   __ sw(S5, Address(SP, 1 * kWordSize));
   __ sw(S4, Address(SP, 0 * kWordSize));
@@ -333,11 +336,11 @@
   // TOS + 8: last argument of caller.
   // ....
   __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
-  // Remove arguments.
-  __ lw(V0, Address(SP, 4 * kWordSize));
-  __ addiu(SP, SP, Immediate(5 * kWordSize));  // Get result into V0.
-  __ LeaveStubFrame();
-  __ Ret();
+
+  __ lw(V0, Address(SP, 4 * kWordSize));  // Get result into V0.
+  __ addiu(SP, SP, Immediate(5 * kWordSize));    // Remove arguments.
+
+  __ LeaveStubFrameAndReturn();
 }
 
 
@@ -452,8 +455,8 @@
   if (preserve_result) {
     __ Pop(V0);  // Restore result.
   }
-  __ LeaveStubFrame();
-  __ Ret();
+
+  __ LeaveStubFrameAndReturn();
 }
 
 
@@ -554,11 +557,11 @@
     // T3: array size.
     const intptr_t shift = RawObject::kSizeTagBit - kObjectAlignmentLog2;
     // If no size tag overflow, shift T3 left, else set T3 to zero.
-    __ LoadImmediate(TMP2, RawObject::SizeTag::kMaxSizeTag);
-    __ sltu(CMPRES, TMP2, T3);  // CMPRES = TMP2 < T3 ? 1 : 0
+    __ LoadImmediate(T4, RawObject::SizeTag::kMaxSizeTag);
+    __ sltu(CMPRES, T4, T3);  // CMPRES = T4 < T3 ? 1 : 0
     __ sll(TMP1, T3, shift);  // TMP1 = T3 << shift;
-    __ movz(T3, TMP1, CMPRES);  // T3 = TMP2 >= T3 ? 0 : T3
-    __ movn(T3, ZR, CMPRES);  // T3 = TMP2 < T3 ? TMP1 : T3
+    __ movz(T3, TMP1, CMPRES);  // T3 = T4 >= T3 ? 0 : T3
+    __ movn(T3, ZR, CMPRES);  // T3 = T4 < T3 ? TMP1 : T3
 
     // Get the class index and insert it into the tags.
     __ LoadImmediate(TMP1, RawObject::ClassIdTag::encode(kArrayCid));
@@ -570,17 +573,16 @@
     // T2: new object end address.
     // A1: Array length as Smi.
     __ AddImmediate(T3, V0, Array::data_offset() - kHeapObjectTag);
-    // R1: iterator which initially points to the start of the variable
+    // T3: iterator which initially points to the start of the variable
     // data area to be initialized.
-    __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
-    Label loop, test;
-    __ b(&test);
+
+    Label loop, loop_exit;
+    __ BranchUnsignedGreaterEqual(T3, T2, &loop_exit);
     __ Bind(&loop);
-    // TODO(cshapiro): StoreIntoObjectNoBarrier
-    __ sw(TMP1, Address(T3, 0));
-    __ AddImmediate(T3, kWordSize);
-    __ Bind(&test);
+    __ addiu(T3, T3, Immediate(kWordSize));
     __ bne(T3, T2, &loop);
+    __ delay_slot()->sw(NULLREG, Address(T3, -kWordSize));
+    __ Bind(&loop_exit);
 
     // Done allocating and initializing the array.
     // V0: new object.
@@ -594,11 +596,10 @@
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
-  __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
   // Setup space on stack for return value.
   // Push array length as Smi and element type.
   __ addiu(SP, SP, Immediate(-3 * kWordSize));
-  __ sw(TMP1, Address(SP, 2 * kWordSize));
+  __ sw(NULLREG, Address(SP, 2 * kWordSize));
   __ sw(A1, Address(SP, 1 * kWordSize));
   __ sw(T3, Address(SP, 0 * kWordSize));
   __ CallRuntime(kAllocateArrayRuntimeEntry);
@@ -609,8 +610,8 @@
   __ lw(T3, Address(SP, 0 * kWordSize));
   __ addiu(SP, SP, Immediate(3 * kWordSize));
   __ mov(V0, TMP1);
-  __ LeaveStubFrame();
-  __ Ret();
+
+  __ LeaveStubFrameAndReturn();
 }
 
 
@@ -637,9 +638,8 @@
   // Verify that T1 is a closure by checking its class.
   Label not_closure;
 
-  __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null()));
   // See if it is not a closure, but null object.
-  __ beq(T1, T7, &not_closure);
+  __ beq(T1, NULLREG, &not_closure);
 
   __ andi(CMPRES, T1, Immediate(kSmiTagMask));
   __ beq(CMPRES, ZR, &not_closure);  // Not a closure, but a smi.
@@ -650,7 +650,7 @@
   __ lw(T0, FieldAddress(T0, Class::signature_function_offset()));
 
   // See if actual class is not a closure class.
-  __ beq(T0, T7, &not_closure);
+  __ beq(T0, NULLREG, &not_closure);
 
   // T0 is just the signature function. Load the actual closure function.
   __ lw(T2, FieldAddress(T1, Closure::function_offset()));
@@ -661,7 +661,7 @@
   Label function_compiled;
   // Load closure function code in T0.
   __ lw(T0, FieldAddress(T2, Function::code_offset()));
-  __ bne(T0, T7, &function_compiled);
+  __ bne(T0, NULLREG, &function_compiled);
 
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
@@ -704,7 +704,8 @@
 
   // Setup space on stack for result from error reporting.
   __ addiu(SP, SP, Immediate(2 * kWordSize));
-  __ sw(T7, Address(SP, 1 * kWordSize));  // Arguments descriptor and raw null.
+  // Arguments descriptor and raw null.
+  __ sw(NULLREG, Address(SP, 1 * kWordSize));
   __ sw(S4, Address(SP, 0 * kWordSize));
 
   // Load smi-tagged arguments array length, including the non-closure.
@@ -725,8 +726,7 @@
   __ addiu(SP, SP, Immediate(3 * kWordSize));  // Remove arguments.
 
   // Remove the stub frame as we are about to return.
-  __ LeaveStubFrame();
-  __ Ret();
+  __ LeaveStubFrameAndReturn();
 }
 
 
@@ -795,12 +795,16 @@
 
   // Compute address of 'arguments array' data area into A2.
   __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle));
-  __ AddImmediate(A2, Array::data_offset() - kHeapObjectTag);
+
+  // Load the null Object into NULLREG for easy comparisons.
+  __ LoadImmediate(NULLREG, reinterpret_cast<intptr_t>(Object::null()));
 
   // Set up arguments for the Dart call.
   Label push_arguments;
   Label done_push_arguments;
   __ beq(T1, ZR, &done_push_arguments);  // check if there are arguments.
+  __ delay_slot()->addiu(A2, A2,
+                         Immediate(Array::data_offset() - kHeapObjectTag));
   __ mov(A1, ZR);
   __ Bind(&push_arguments);
   __ lw(A3, Address(A2));
@@ -843,8 +847,7 @@
   __ addiu(SP, SP, Immediate((3 + kAbiPreservedCpuRegCount) * kWordSize));
 
   // Restore the frame pointer and return.
-  __ LeaveStubFrame();
-  __ Ret();
+  __ LeaveStubFrameAndReturn();
 }
 
 
@@ -905,7 +908,7 @@
     __ LoadImmediate(TMP1, RawObject::SizeTag::kMaxSizeTag);
     __ sltu(CMPRES, TMP1, T2);  // CMPRES = T2 > TMP1 ? 1 : 0.
     __ movn(T2, ZR, CMPRES);  // T2 = CMPRES != 0 ? 0 : T2.
-    __ sll(TMP1, T2, shift);  // TMP2 = T2 << shift.
+    __ sll(TMP1, T2, shift);  // TMP1 = T2 << shift.
     __ movz(T2, TMP1, CMPRES);  // T2 = CMPRES == 0 ? TMP1 : T2.
 
     // Get the class index and insert it into the tags.
@@ -927,26 +930,21 @@
     // T2: isolate, not an object.
     __ sw(T2, FieldAddress(V0, Context::isolate_offset()));
 
-    // Setup the parent field.
-    // V0: new object.
-    // T1: number of context variables.
-    __ LoadImmediate(T2, reinterpret_cast<intptr_t>(Object::null()));
-    __ sw(T2, FieldAddress(V0, Context::parent_offset()));
-
     // Initialize the context variables.
     // V0: new object.
     // T1: number of context variables.
-    // T2: raw null.
-    Label loop, loop_test;
+    Label loop, loop_exit;
+    __ blez(T1, &loop_exit);
+    // Setup the parent field.
+    __ delay_slot()->sw(NULLREG, FieldAddress(V0, Context::parent_offset()));
     __ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag);
-    __ b(&loop_test);
-    __ delay_slot()->sll(T1, T1, 2);
+    __ sll(T1, T1, 2);
     __ Bind(&loop);
-    __ addu(TMP1, T3, T1);
-    __ sw(T2, Address(TMP1));
-    __ Bind(&loop_test);
     __ addiu(T1, T1, Immediate(-kWordSize));
-    __ bne(T1, ZR, &loop);  // Loop if R1 not zero.
+    __ addu(TMP1, T3, T1);
+    __ bgtz(T1, &loop);
+    __ delay_slot()->sw(NULLREG, Address(TMP1));
+    __ Bind(&loop_exit);
 
     // Done allocating and initializing the context.
     // V0: new object.
@@ -958,10 +956,9 @@
   // calling into the runtime.
   __ EnterStubFrame();
   // Setup space on stack for return value.
-  __ LoadImmediate(T2, reinterpret_cast<intptr_t>(Object::null()));
   __ SmiTag(T1);
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
-  __ sw(T2, Address(SP, 1 * kWordSize));
+  __ sw(NULLREG, Address(SP, 1 * kWordSize));
   __ sw(T1, Address(SP, 0 * kWordSize));
   __ CallRuntime(kAllocateContextRuntimeEntry);  // Allocate context.
   __ lw(V0, Address(SP, 1 * kWordSize));  // Get the new context.
@@ -969,8 +966,7 @@
 
   // V0: new object
   // Restore the frame pointer.
-  __ LeaveStubFrame();
-  __ Ret();
+  __ LeaveStubFrameAndReturn();
 }
 
 
@@ -1129,9 +1125,6 @@
     __ sw(T0, Address(T2, Instance::tags_offset()));
 
     // Initialize the remaining words of the object.
-    __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
-
-    // T0: raw null.
     // T2: new object start.
     // T3: next object start.
     // T1: new object type arguments (if is_cls_parameterized).
@@ -1142,24 +1135,22 @@
       for (intptr_t current_offset = sizeof(RawObject);
            current_offset < instance_size;
            current_offset += kWordSize) {
-        __ sw(T0, Address(T2, current_offset));
+        __ sw(NULLREG, Address(T2, current_offset));
       }
     } else {
       __ addiu(T4, T2, Immediate(sizeof(RawObject)));
       // Loop until the whole object is initialized.
-      // T0: raw null.
       // T2: new object.
       // T3: next object start.
       // T4: next word to be initialized.
       // T1: new object type arguments (if is_cls_parameterized).
-      Label init_loop;
-      Label done;
-      __ Bind(&init_loop);
-      __ BranchUnsignedGreaterEqual(T4, T3, &done);  // Done if T4 >= T3.
-      __ sw(T0, Address(T4));
-      __ AddImmediate(T4, kWordSize);
-      __ b(&init_loop);
-      __ Bind(&done);
+      Label loop, loop_exit;
+      __ BranchUnsignedGreaterEqual(T4, T3, &loop_exit);
+      __ Bind(&loop);
+      __ addiu(T4, T4, Immediate(kWordSize));
+      __ bne(T4, T3, &loop);
+      __ delay_slot()->sw(NULLREG, Address(T4, -kWordSize));
+      __ Bind(&loop_exit);
     }
     if (is_cls_parameterized) {
       // R1: new object type arguments.
@@ -1180,11 +1171,11 @@
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame(true);  // Uses pool pointer to pass cls to runtime.
-  __ LoadImmediate(T2, reinterpret_cast<intptr_t>(Object::null()));
   __ LoadObject(TMP1, cls);
 
   __ addiu(SP, SP, Immediate(-4 * kWordSize));
-  __ sw(T2, Address(SP, 3 * kWordSize));  // Space on stack for return value.
+  // Space on stack for return value.
+  __ sw(NULLREG, Address(SP, 3 * kWordSize));
   __ sw(TMP1, Address(SP, 2 * kWordSize));  // Class of object to be allocated.
 
   if (is_cls_parameterized) {
@@ -1194,7 +1185,7 @@
   } else {
     // Push null type arguments and kNoInstantiator.
     __ LoadImmediate(T1, Smi::RawValue(StubCode::kNoInstantiator));
-    __ sw(T2, Address(SP, 1 * kWordSize));
+    __ sw(NULLREG, Address(SP, 1 * kWordSize));
     __ sw(T1, Address(SP, 0 * kWordSize));
   }
   __ CallRuntime(kAllocateObjectRuntimeEntry);  // Allocate object.
@@ -1203,9 +1194,8 @@
   __ lw(V0, Address(SP, 3 * kWordSize));
   __ addiu(SP, SP, Immediate(4 * kWordSize));  // Pop arguments.
   // V0: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame(true);
-  __ Ret();
+  // Restore the frame pointer and return.
+  __ LeaveStubFrameAndReturn(RA, true);
 }
 
 
@@ -1299,8 +1289,7 @@
       __ sw(T0, Address(T4, Context::isolate_offset()));
 
       // Set the parent to null.
-      __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
-      __ sw(T0, Address(T4, Context::parent_offset()));
+      __ sw(NULLREG, Address(T4, Context::parent_offset()));
 
       // Initialize the context variable to the receiver.
       __ lw(T0, Address(FP, kReceiverFPOffset));
@@ -1320,8 +1309,8 @@
     // Done allocating and initializing the instance.
     // V0: new object.
     __ addiu(V0, T2, Immediate(kHeapObjectTag));
-    __ LeaveStubFrame(true);
-    __ Ret();
+
+    __ LeaveStubFrameAndReturn(RA, true);
 
     __ Bind(&slow_case);
   }
@@ -1333,10 +1322,9 @@
     num_slots = is_implicit_instance_closure ? 4 : 3;
   }
   __ addiu(SP, SP, Immediate(-num_slots * kWordSize));
-  __ LoadImmediate(V0, reinterpret_cast<intptr_t>(Object::null()));
   __ LoadObject(TMP1, func);
   // Setup space on stack for return value.
-  __ sw(V0, Address(SP, (num_slots - 1) * kWordSize));
+  __ sw(NULLREG, Address(SP, (num_slots - 1) * kWordSize));
   __ sw(TMP1, Address(SP, (num_slots - 2) * kWordSize));
   if (is_implicit_static_closure) {
     __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
@@ -1345,7 +1333,7 @@
     if (is_implicit_instance_closure) {
       __ lw(T1, Address(FP, kReceiverFPOffset));
       __ sw(T1, Address(SP, (num_slots - 3) * kWordSize));  // Receiver.
-      __ sw(V0, Address(SP, (num_slots - 4) * kWordSize));  // Push null.
+      __ sw(NULLREG, Address(SP, (num_slots - 4) * kWordSize));  // Push null.
     }
     if (has_type_arguments) {
       __ lw(V0, Address(FP, kTypeArgumentsFPOffset));
@@ -1367,8 +1355,7 @@
 
   // V0: new object
   // Restore the frame pointer.
-  __ LeaveStubFrame(true);
-  __ Ret();
+  __ LeaveStubFrameAndReturn(RA, true);
 }
 
 
@@ -1544,14 +1531,13 @@
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
-  __ LoadImmediate(T3, reinterpret_cast<intptr_t>(Object::null()));
   // Preserve IC data object and arguments descriptor array and
   // setup space on stack for result (target code object).
   int num_slots = num_args + 5;
   __ addiu(SP, SP, Immediate(-num_slots * kWordSize));
   __ sw(S5, Address(SP, (num_slots - 1) * kWordSize));
   __ sw(S4, Address(SP, (num_slots - 2) * kWordSize));
-  __ sw(T3, Address(SP, (num_slots - 3) * kWordSize));
+  __ sw(NULLREG, Address(SP, (num_slots - 3) * kWordSize));
   // Push call arguments.
   for (intptr_t i = 0; i < num_args; i++) {
     __ lw(TMP1, Address(T1, -i * kWordSize));
@@ -1581,14 +1567,14 @@
   __ addiu(SP, SP, Immediate(num_slots * kWordSize));
   __ LeaveStubFrame();
   Label call_target_function;
-  __ BranchNotEqual(T3, reinterpret_cast<intptr_t>(Object::null()),
-                    &call_target_function);
+  __ bne(T3, NULLREG, &call_target_function);
+
   // NoSuchMethod or closure.
   // Mark IC call that it may be a closure call that does not collect
   // type feedback.
-  __ LoadImmediate(TMP2, 1);
+  __ LoadImmediate(TMP1, 1);
   __ Branch(&StubCode::InstanceFunctionLookupLabel());
-  __ delay_slot()->sb(TMP2, FieldAddress(S5, ICData::is_closure_call_offset()));
+  __ delay_slot()->sb(TMP1, FieldAddress(S5, ICData::is_closure_call_offset()));
 
   __ Bind(&found);
   // T0: Pointer to an IC data check group.
@@ -1597,7 +1583,7 @@
   __ lw(T3, Address(T0, target_offset));
   __ lw(T4, Address(T0, count_offset));
 
-  __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5);
+  __ AddImmediateDetectOverflow(T4, T4, Smi::RawValue(1), T5, T6);
 
   __ bgez(T5, &call_target_function);  // No overflow.
   __ delay_slot()->sw(T4, Address(T0, count_offset));
@@ -1611,6 +1597,8 @@
   __ lw(T3, FieldAddress(T3, Code::instructions_offset()));
   __ AddImmediate(T3, Instructions::HeaderSize() - kHeapObjectTag);
   __ jr(T3);
+  __ delay_slot()->addiu(T3, T3,
+      Immediate(Instructions::HeaderSize() - kHeapObjectTag));
 
   // Instance in T3, return its class-id in T3 as Smi.
   __ Bind(&get_class_id_as_smi);
@@ -1618,13 +1606,13 @@
   // Test if Smi -> load Smi class for comparison.
   __ andi(TMP1, T3, Immediate(kSmiTagMask));
   __ bne(TMP1, ZR, &not_smi);
-  __ LoadImmediate(T3, Smi::RawValue(kSmiCid));
   __ jr(RA);
+  __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
 
   __ Bind(&not_smi);
   __ LoadClassId(T3, T3);
-  __ SmiTag(T3);
   __ jr(RA);
+  __ delay_slot()->SmiTag(T3);
 }
 
 
@@ -1695,11 +1683,10 @@
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
-  __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
   // Preserve arguments descriptor and make room for result.
   __ addiu(SP, SP, Immediate(-2 * kWordSize));
   __ sw(S4, Address(SP, 1 * kWordSize));
-  __ sw(T0, Address(SP, 0 * kWordSize));
+  __ sw(NULLREG, Address(SP, 0 * kWordSize));
   __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry);
   // Pop code object result and restore arguments descriptor.
   __ lw(T0, Address(SP, 0 * kWordSize));
@@ -1728,8 +1715,7 @@
 
   // Instead of returning to the patched Dart function, emulate the
   // smashed return code pattern and return to the function's caller.
-  __ LeaveDartFrame();
-  __ Ret();
+  __ LeaveDartFrameAndReturn();
 }
 
 
@@ -1782,7 +1768,6 @@
     __ LoadClass(T0, A0);
     // Compute instance type arguments into R4.
     Label has_no_type_arguments;
-    __ LoadImmediate(T1, reinterpret_cast<intptr_t>(Object::null()));
     __ lw(T2, FieldAddress(T0,
         Class::type_arguments_field_offset_in_words_offset()));
     __ BranchEqual(T2, Class::kNoTypeArguments, &has_no_type_arguments);
@@ -1807,7 +1792,7 @@
   __ SmiTag(T0);
   __ Bind(&loop);
   __ lw(T3, Address(T2, kWordSize * SubtypeTestCache::kInstanceClassId));
-  __ BranchEqual(T3, reinterpret_cast<intptr_t>(Object::null()), &not_found);
+  __ beq(T3, NULLREG, &not_found);
 
   if (n == 1) {
     __ beq(T3, T0, &found);
@@ -1825,12 +1810,13 @@
     }
   }
   __ Bind(&next_iteration);
-  __ AddImmediate(T2, kWordSize * SubtypeTestCache::kTestEntryLength);
   __ b(&loop);
+  __ delay_slot()->addiu(T2, T2,
+      Immediate(kWordSize * SubtypeTestCache::kTestEntryLength));
   // Fall through to not found.
   __ Bind(&not_found);
-  __ LoadImmediate(V0, reinterpret_cast<intptr_t>(Object::null()));
   __ Ret();
+  __ delay_slot()->mov(V0, NULLREG);
 
   __ Bind(&found);
   __ Ret();
@@ -1893,8 +1879,8 @@
   __ mov(V0, A3);  // Exception object.
   __ lw(V1, Address(SP, 0));  // StackTrace object.
   __ mov(FP, A2);  // Frame_pointer.
-  __ mov(SP, A1);  // Stack pointer.
   __ jr(A0);  // Jump to the exception handler code.
+  __ delay_slot()->mov(SP, A1);  // Stack pointer.
 }
 
 
@@ -1939,8 +1925,14 @@
   __ beq(T2, T3, &found);  // Class id match?
   __ Bind(&no_match);
   // Next check group.
-  __ AddImmediate(T6, kWordSize * ICData::TestEntryLengthFor(kNumArgsTested));
-  __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop);  // Done?
+  intptr_t entry_bytes = kWordSize * ICData::TestEntryLengthFor(kNumArgsTested);
+  if (Utils::IsInt(kImmBits, entry_bytes)) {
+    __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop);  // Done?
+    __ delay_slot()->addiu(T6, T6, Immediate(entry_bytes));
+  } else {
+    __ AddImmediate(T6, entry_bytes);
+    __ BranchNotEqual(T3, Smi::RawValue(kIllegalCid), &loop);  // Done?
+  }
 
   Label update_ic_data;
   __ b(&update_ic_data);
@@ -1950,7 +1942,7 @@
       ICData::CountIndexFor(kNumArgsTested) * kWordSize;
   Label no_overflow;
   __ lw(T1, Address(T6, count_offset));
-  __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES);
+  __ AddImmediateDetectOverflow(T1, T1, Smi::RawValue(1), CMPRES, T6);
   __ bgez(CMPRES, &no_overflow);
   __ LoadImmediate(TMP1, Smi::RawValue(Smi::kMaxValue));
   __ sw(TMP1, Address(T6, count_offset));  // If overflow.
@@ -1958,13 +1950,12 @@
 
   Label compute_result;
   __ Bind(&compute_result);
-  __ LoadObject(TMP1, Bool::True());
-  __ LoadObject(TMP2, Bool::False());
+  __ LoadObject(T4, Bool::True());
+  __ LoadObject(T5, Bool::False());
   __ subu(CMPRES, A0, A1);
-  __ movz(V0, TMP1, CMPRES);
-  __ movn(V0, TMP2, CMPRES);
-  __ LeaveStubFrame();
-  __ Ret();
+  __ movz(V0, T4, CMPRES);
+  __ movn(V0, T5, CMPRES);
+  __ LeaveStubFrameAndReturn();
 
   __ Bind(&get_class_id_as_smi);
   // Test if Smi -> load Smi class for comparison.
@@ -2003,8 +1994,7 @@
   __ addiu(SP, SP, Immediate(-3 * kWordSize));
   __ sw(S4, Address(SP, 2 * kWordSize));
   // Setup space on stack for return value.
-  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
-  __ sw(TMP1, Address(SP, 1 * kWordSize));
+  __ sw(NULLREG, Address(SP, 1 * kWordSize));
   __ sw(T0, Address(SP, 0 * kWordSize));
   __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry);
   __ TraceSimMsg("OptimizeFunctionStub return");
@@ -2014,8 +2004,7 @@
 
   __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
   __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
-  __ LeaveStubFrame();
-  __ jr(T0);
+  __ LeaveStubFrameAndReturn(T0);
   __ break_(0);
 }
 
@@ -2037,8 +2026,8 @@
 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) {
   __ TraceSimMsg("IdenticalWithNumberCheckStub");
   const Register ret = CMPRES;
-  const Register temp1 = TMP1;
-  const Register temp2 = TMP2;
+  const Register temp1 = T2;
+  const Register temp2 = T3;
   const Register left = T1;
   const Register right = T0;
   // Preserve left, right.
diff --git a/runtime/vm/stub_code_mips_test.cc b/runtime/vm/stub_code_mips_test.cc
index bbe5744..6fdbdfd 100644
--- a/runtime/vm/stub_code_mips_test.cc
+++ b/runtime/vm/stub_code_mips_test.cc
@@ -54,8 +54,7 @@
   __ CallRuntime(kTestSmiSubRuntimeEntry);  // Call SmiSub runtime func.
   __ addiu(SP, SP, Immediate(argc * kWordSize));
   __ Pop(V0);  // Pop return value from return slot.
-  __ LeaveDartFrame();
-  __ Ret();
+  __ LeaveDartFrameAndReturn();
 }
 
 
@@ -87,8 +86,7 @@
   __ LoadObject(A0, smi1);  // Set up argument 1 smi1.
   __ LoadObject(A1, smi2);  // Set up argument 2 smi2.
   __ CallRuntime(kTestLeafSmiAddRuntimeEntry);  // Call SmiAdd runtime func.
-  __ LeaveDartFrame();
-  __ Ret();  // Return value is in R0.
+  __ LeaveDartFrameAndReturn();  // Return value is in V0.
 }
 
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index fd859af..78febab 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -43,7 +43,7 @@
                                       isBinaryOperator,
                                       isTernaryOperator,
                                       isMinusOperator;
-export 'universe/universe.dart' show Selector;
+export 'universe/universe.dart' show Selector, TypedSelector;
 
 part 'code_buffer.dart';
 part 'compile_time_constants.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/js/builder.dart b/sdk/lib/_internal/compiler/implementation/js/builder.dart
index 1a22692..a1d4f41 100644
--- a/sdk/lib/_internal/compiler/implementation/js/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/builder.dart
@@ -10,19 +10,39 @@
 class JsBuilder {
   const JsBuilder();
 
-  // Parse a bit of JS, and return an expression.  See the MiniJsParser class.
+  // Parse a bit of JavaScript, and return an expression.
+  // See the MiniJsParser class.
   // You can provide an expression or a list of expressions, which will be
   // interpolated into the source at the '#' signs.
   Expression call(String source, [var expression]) {
+    var result = new MiniJsParser(source).expression();
+    if (expression == null) return result;
+
     List<Expression> expressions;
-    if (expression != null) {
-      if (expression is List) {
-        expressions = expression;
-      } else {
-        expressions = <Expression>[expression];
-      }
+    if (expression is List) {
+      expressions = expression;
+    } else {
+      expressions = <Expression>[expression];
     }
-    return new MiniJsParser(source, expressions).expression();
+    if (expressions.length != result.interpolatedExpressions.length) {
+      throw "Unmatched number of interpolated expressions";
+    }
+    for (int i = 0; i < expressions.length; i++) {
+      result.interpolatedExpressions[i].value = expressions[i];
+    }
+
+    return result.value;
+  }
+
+  // Parse JavaScript written in the JS foreign instruction.
+  Expression parseForeignJS(String source, [var expression]) {
+    // 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 (source.contains("{") || source.startsWith("throw ")) {
+      assert(expression == null);
+      return new LiteralExpression(source);
+    }
+    return call(source, expression);
   }
 
   LiteralString string(String value) => new LiteralString('"$value"');
@@ -181,12 +201,11 @@
 /// allowed in string and regexp literals because the machinery for checking
 /// their correctness is rather involved.
 class MiniJsParser {
-  MiniJsParser(this.src, this.interpolatedValues)
+  MiniJsParser(this.src)
       : lastCategory = NONE,
         lastToken = null,
         lastPosition = 0,
-        position = 0,
-        valuesUsed = 0 {
+        position = 0 {
     getToken();
   }
 
@@ -194,9 +213,9 @@
   String lastToken;
   int lastPosition;
   int position;
-  int valuesUsed;
   String src;
-  List<Expression> interpolatedValues;
+  final List<InterpolatedExpression> interpolatedValues =
+      <InterpolatedExpression>[];
 
   static const NONE = -1;
   static const ALPHA = 0;
@@ -459,11 +478,9 @@
       Expression expression = new RegExpLiteral(regexp + flags);
       return expression;
     } else if (acceptCategory(HASH)) {
-      if (interpolatedValues == null ||
-          valuesUsed >= interpolatedValues.length) {
-        error("Too few values for '#'s");
-      }
-      return interpolatedValues[valuesUsed++];
+      InterpolatedExpression expression = new InterpolatedExpression(null);
+      interpolatedValues.add(expression);
+      return expression;
     } else {
       error("Expected primary expression");
     }
@@ -638,9 +655,141 @@
     if (lastCategory != NONE || position != src.length) {
       error("Unparsed junk: ${categoryToString(lastCategory)}");
     }
-    if (interpolatedValues != null && valuesUsed != interpolatedValues.length) {
-      error("Too many values for #es");
+    if (!interpolatedValues.isEmpty) {
+      return new JSExpression(expression, interpolatedValues);
     }
     return expression;
   }
 }
+
+/**
+ * Clone a JSExpression node into an expression where all children
+ * have been cloned, and [InterpolatedExpression]s have been replaced
+ * with real [Expression].
+ */
+class UninterpolateJSExpression extends BaseVisitor<Node> {
+  final List<Expression> arguments;
+  int argumentIndex = 0;
+
+  UninterpolateJSExpression(this.arguments);
+
+  void error(message) {
+    throw message;
+  }
+
+  Node visitNode(Node node) {
+    error('Cannot handle $node');
+  }
+
+  Node copyPosition(Node oldNode, Node newNode) {
+    newNode.sourcePosition = oldNode.sourcePosition;
+    newNode.endSourcePosition = oldNode.endSourcePosition;
+    return newNode;
+  }
+
+  Node visit(Node node) {
+    return node == null ? null : node.accept(this);
+  }
+
+  List<Node> visitList(List<Node> list) {
+    return list.map((e) => visit(e)).toList();
+  }
+
+  Node visitLiteralString(LiteralString node) {
+    return node;
+  }
+
+  Node visitVariableUse(VariableUse node) {
+    return node;
+  }
+
+  Node visitAccess(PropertyAccess node) {
+    return copyPosition(node,
+        new PropertyAccess(visit(node.receiver), visit(node.selector)));
+  }
+
+  Node visitCall(Call node) {
+    return copyPosition(node,
+        new Call(visit(node.target), visitList(node.arguments)));
+  }
+
+  Node visitInterpolatedExpression(InterpolatedExpression expression) {
+    return arguments[argumentIndex++];
+  }
+
+  Node visitJSExpression(JSExpression expression) {
+    assert(argumentIndex == 0);
+    Node result = visit(expression.value);
+    if (argumentIndex != arguments.length) {
+      error("Invalid number of arguments");
+    }
+    assert(result is! JSExpression);
+    return result;
+  }
+
+  Node visitLiteralExpression(LiteralExpression node) {
+    assert(argumentIndex == 0);
+    return copyPosition(node,
+        new LiteralExpression.withData(node.template, arguments));
+  }
+
+  Node visitAssignment(Assignment node) {
+    return copyPosition(node,
+        new Assignment._internal(visit(node.leftHandSide),
+                                 visit(node.compoundTarget),
+                                 visit(node.value)));
+  }
+
+  Node visitRegExpLiteral(RegExpLiteral node) {
+    return node;
+  }
+
+  Node visitLiteralNumber(LiteralNumber node) {
+    return node;
+  }
+
+  Node visitBinary(Binary node) {
+    return copyPosition(node,
+        new Binary(node.op, visit(node.left), visit(node.right)));
+  }
+
+  Node visitPrefix(Prefix node) {
+    return copyPosition(node,
+        new Prefix(node.op, visit(node.argument)));
+  }
+
+  Node visitPostfix(Postfix node) {
+    return copyPosition(node,
+        new Postfix(node.op, visit(node.argument)));
+  }
+
+  Node visitNew(New node) {
+    return copyPosition(node,
+        new New(visit(node.target), visitList(node.arguments)));
+  }
+
+  Node visitArrayInitializer(ArrayInitializer node) {
+    return copyPosition(node,
+        new ArrayInitializer(node.length, visitList(node.elements)));
+  }
+
+  Node visitArrayElement(ArrayElement node) {
+    return copyPosition(node,
+        new ArrayElement(node.index, visit(node.value)));
+  }
+
+  Node visitConditional(Conditional node) {
+    return copyPosition(node,
+        new Conditional(visit(node.condition),
+                        visit(node.then),
+                        visit(node.otherwise)));
+  }
+
+  Node visitLiteralNull(LiteralNull node) {
+    return node;
+  }
+
+  Node visitLiteralBool(LiteralBool node) {
+    return node;
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js/nodes.dart b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
index 5fe00a4..9f57b32 100644
--- a/sdk/lib/_internal/compiler/implementation/js/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/nodes.dart
@@ -61,6 +61,9 @@
   T visitRegExpLiteral(RegExpLiteral node);
 
   T visitComment(Comment node);
+
+  T visitInterpolatedExpression(InterpolatedExpression node);
+  T visitJSExpression(JSExpression node);
 }
 
 class BaseVisitor<T> implements NodeVisitor<T> {
@@ -144,6 +147,10 @@
   T visitProperty(Property node) => visitNode(node);
   T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node);
 
+  T visitInterpolatedExpression(InterpolatedExpression node)
+      => visitExpression(node);
+  T visitJSExpression(JSExpression node) => visitExpression(node);
+
   // Ignore comments by default.
   T visitComment(Comment node) {}
 }
@@ -569,9 +576,11 @@
   final VariableReference compoundTarget;
   final Expression value;  // May be null, for [VariableInitialization]s.
 
-  Assignment(this.leftHandSide, this.value) : compoundTarget = null;
-  Assignment.compound(this.leftHandSide, String op, this.value)
-      : compoundTarget = new VariableUse(op);
+  Assignment(leftHandSide, value)
+      : this._internal(leftHandSide, null, value);
+  Assignment.compound(leftHandSide, String op, value)
+      : this._internal(leftHandSide, new VariableUse(op), value);
+  Assignment._internal(this.leftHandSide, this.compoundTarget, this.value);
 
   int get precedenceLevel => ASSIGNMENT;
 
@@ -917,6 +926,38 @@
   }
 }
 
+class InterpolatedExpression extends Expression {
+  Expression value;
+
+  InterpolatedExpression(this.value);
+
+  accept(NodeVisitor visitor) => visitor.visitInterpolatedExpression(this);
+
+  void visitChildren(NodeVisitor visitor) {
+    value.accept(visitor);
+  }
+
+  int get precedenceLevel => value.precedenceLevel;
+}
+
+class JSExpression extends Expression {
+  Expression value;
+  List<InterpolatedExpression> interpolatedExpressions;
+
+  JSExpression(this.value, this.interpolatedExpressions);
+
+  accept(NodeVisitor visitor) => visitor.visitJSExpression(this);
+
+  void visitChildren(NodeVisitor visitor) {
+    value.accept(visitor);
+    for (InterpolatedExpression expression in interpolatedExpressions) {
+      expression.accept(visitor);
+    }
+  }
+
+  int get precedenceLevel => value.precedenceLevel;
+}
+
 /**
  * [RegExpLiteral]s, despite being called "Literal", do not inherit from
  * [Literal]. Indeed, regular expressions in JavaScript have a side-effect and
diff --git a/sdk/lib/_internal/compiler/implementation/js/printer.dart b/sdk/lib/_internal/compiler/implementation/js/printer.dart
index 91d46b5..2645362 100644
--- a/sdk/lib/_internal/compiler/implementation/js/printer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/printer.dart
@@ -853,6 +853,14 @@
     outLn(node.code);
   }
 
+  visitJSExpression(JSExpression node) {
+    compiler.internalError('JSPrinter should never see a JSExpression');
+  }
+
+  visitInterpolatedExpression(InterpolatedExpression node) {
+    visit(node.value);
+  }
+
   void visitComment(Comment node) {
     if (shouldCompressOutput) return;
     String comment = node.comment.trim();
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 1289c7f..1966691 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -351,7 +351,7 @@
 
     return [
       js('var $supportsProtoName = false'),
-      js('var tmp = defineClass("c", "c", ["f?"], {}).prototype'),
+      js('var tmp = defineClass("c", "c", ["f<"], {}).prototype'),
 
       js.if_(js('tmp.__proto__'), [
         js('tmp.__proto__ = {}'),
@@ -1251,11 +1251,14 @@
     // Add checks to the constructors of instantiated classes.
     for (ClassElement cls in typeChecks) {
       String holder = namer.isolateAccess(backend.getImplementationClass(cls));
-      for (ClassElement check in typeChecks[cls]) {
-        buffer.write('$holder.${namer.operatorIs(check)}$_=${_}true$N');
-        String body = rti.getSupertypeSubstitution(cls, check);
-        if (body != null) {
-          buffer.write('$holder.${namer.substitutionName(check)}$_=${_}$body$N');
+      for (TypeCheck check in typeChecks[cls]) {
+        ClassElement cls = check.cls;
+        buffer.write('$holder.${namer.operatorIs(check.cls)}$_=${_}true$N');
+        buffer.write('$holder.${namer.operatorIs(cls)}$_=${_}true$N');
+        Substitution substitution = check.substitution;
+        if (substitution != null) {
+          String body = substitution.getCode(rti, false);
+          buffer.write('$holder.${namer.substitutionName(cls)}$_=${_}$body$N');
         }
       };
     }
@@ -2233,32 +2236,16 @@
       DartType objectType = objectClass.computeType(compiler);
 
       for (Selector selector in selectors) {
-        // Introduce a helper function that determines if the given
-        // class has a member that matches the current name and
-        // selector (grabbed from the scope).
-        bool hasMatchingMember(ClassElement holder) {
-          Element element = holder.lookupSelector(selector);
-          return (element != null)
-              ? selector.applies(element, compiler)
-              : false;
-        }
-
         // If the selector is typed, we check to see if that type may
         // have a user-defined noSuchMethod implementation. If not, we
         // skip the selector altogether.
 
-        // TODO(kasperl): This shouldn't depend on the internals of
-        // the type mask. Move more of this code to the type mask.
-        ClassElement receiverClass = objectClass;
         TypeMask mask = selector.mask;
-        if (mask != null) {
-          // If the mask is empty it doesn't contain a noSuchMethod
-          // handler -- not even if it is nullable.
-          if (mask.isEmpty) continue;
-          receiverClass = mask.base.element;
+        if (mask == null) {
+          mask = new TypeMask.subclass(compiler.objectClass.rawType);
         }
 
-        // If the receiver class is guaranteed to have a member that
+        // If the receiver is guaranteed to have a member that
         // matches what we're looking for, there's no need to
         // introduce a noSuchMethod handler. It will never be called.
         //
@@ -2273,7 +2260,6 @@
         // because objects of type B implement foo. On the other hand,
         // if we end up calling foo on something of type C we have to
         // add a handler for it.
-        if (hasMatchingMember(receiverClass)) continue;
 
         // If the holders of all user-defined noSuchMethod
         // implementations that might be applicable to the receiver
@@ -2300,9 +2286,7 @@
         // If we're calling bar on an object of type A we do need the
         // handler because we may have to call B.noSuchMethod since B
         // does not implement bar.
-        Iterable<ClassElement> holders =
-            compiler.world.locateNoSuchMethodHolders(selector);
-        if (holders.every(hasMatchingMember)) continue;
+        if (mask.willHit(selector, compiler)) continue;
         String jsName = namer.invocationMirrorInternalName(selector);
         addedJsNames[jsName] = selector;
       }
@@ -2597,37 +2581,53 @@
         compiler.codegenWorld.instantiatedClasses.where(computeClassFilter())
             .toSet();
 
-    RuntimeTypes rti = backend.rti;
-
-    // We need to generate classes that are instantiated or used as a type
-    // arguments.
-    neededClasses.addAll(instantiatedClasses);
-    rti.allArguments.forEach((ClassElement c) {
-      // Types that we represent with JS native types (like int and String) do
-      // not need a class definition as we use the interceptor classes instead.
-      if (!rti.isJsNative(c)) {
-        neededClasses.add(c);
-      }
-    });
-
-    // Then add all superclasses of these classes.
-    for (ClassElement element in neededClasses.toList() /* copy */) {
-      for (ClassElement superclass = element.superclass;
+    void addClassWithSuperclasses(ClassElement cls) {
+      neededClasses.add(cls);
+      for (ClassElement superclass = cls.superclass;
           superclass != null;
           superclass = superclass.superclass) {
-        if (neededClasses.contains(superclass)) break;
         neededClasses.add(superclass);
       }
     }
 
-    // Then add all classes used as mixins.
+    void addClassesWithSuperclasses(Iterable<ClassElement> classes) {
+      for (ClassElement cls in classes) {
+        addClassWithSuperclasses(cls);
+      }
+    }
+
+    // 1. We need to generate all classes that are instantiated.
+    addClassesWithSuperclasses(instantiatedClasses);
+
+    // 2. Add all classes used as mixins.
     Set<ClassElement> mixinClasses = neededClasses
         .where((ClassElement element) => element.isMixinApplication)
         .map(computeMixinClass)
         .toSet();
     neededClasses.addAll(mixinClasses);
 
-    // Finally, sort the classes.
+    // 3a. Add classes that are referenced by type arguments or substitutions in
+    //     argument checks.
+    // TODO(karlklose): merge this case with 3b when unifying argument and
+    // object checks.
+    RuntimeTypes rti = backend.rti;
+    backend.rti.getRequiredArgumentClasses(backend).forEach((ClassElement c) {
+      // Types that we represent with JS native types (like int and String) do
+      // not need a class definition as we use the interceptor classes instead.
+      if (!rti.isJsNative(c)) {
+        addClassWithSuperclasses(c);
+      }
+    });
+
+    // 3b. Add classes that are referenced by substitutions in object checks and
+    //     their superclasses.
+    TypeChecks requiredChecks =
+        backend.rti.computeChecks(neededClasses, checkedClasses);
+    Set<ClassElement> classesUsedInSubstitutions =
+        rti.getClassesUsedInSubstitutions(backend, requiredChecks);
+    addClassesWithSuperclasses(classesUsedInSubstitutions);
+
+    // 4. Finally, sort the classes.
     List<ClassElement> sortedClasses = Elements.sortedByPosition(neededClasses);
 
     // If we need noSuchMethod support, we run through all needed
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
index 77ed6f4..81e68be 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/js_backend.dart
@@ -12,7 +12,7 @@
 import '../elements/modelx.dart' show FunctionElementX;
 
 // TODO(ahe): There seems to be a bug in the VM, so we have to hide "js".
-import '../dart2jslib.dart' hide Selector, js;
+import '../dart2jslib.dart' hide Selector, TypedSelector, js;
 import '../dart_types.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js; // TODO(ahe): VM bug, see above.
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index b3355b5..0c02e6e 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -7,11 +7,13 @@
 /// For each class, stores the possible class subtype tests that could succeed.
 abstract class TypeChecks {
   /// Get the set of checks required for class [element].
-  Iterable<ClassElement> operator[](ClassElement element);
+  Iterable<TypeCheck> operator[](ClassElement element);
   /// Get the iterator for all classes that need type checks.
   Iterator<ClassElement> get iterator;
 }
 
+typedef String VariableSubstitution(TypeVariableType variable);
+
 class RuntimeTypes {
   final Compiler compiler;
   final TypeRepresentationGenerator representationGenerator;
@@ -31,9 +33,9 @@
         rtiDependencies = new Map<ClassElement, Set<ClassElement>>(),
         classesUsingTypeVariableExpression = new Set<ClassElement>();
 
-  /// Contains the classes of all arguments that have been used in
-  /// instantiations and checks.
-  Set<ClassElement> cachedAllArguments;
+  Set<ClassElement> directlyInstantiatedArguments;
+  Set<ClassElement> allInstantiatedArguments;
+  Set<ClassElement> checkedArguments;
 
   bool isJsNative(Element element) {
     return (element == compiler.intClass ||
@@ -44,14 +46,6 @@
             element == compiler.listClass);
   }
 
-  Set<ClassElement> get allArguments {
-    if (cachedRequiredChecks == null) {
-      computeRequiredChecks();
-    }
-    assert(cachedAllArguments != null);
-    return cachedAllArguments;
-  }
-
   void registerRtiDependency(Element element, Element dependency) {
     // We're not dealing with typedef for now.
     if (!element.isClass() || !dependency.isClass()) return;
@@ -174,42 +168,45 @@
   TypeChecks cachedRequiredChecks;
 
   TypeChecks get requiredChecks {
+    if (cachedRequiredChecks == null) {
+      computeRequiredChecks();
+    }
     assert(cachedRequiredChecks != null);
     return cachedRequiredChecks;
   }
 
-  void computeRequiredChecks() {
-    // Get all types used in type arguments of instantiated types.
-    Set<ClassElement> instantiatedArguments =
-        getInstantiatedArguments(compiler.codegenWorld);
-
-    // Collect all type arguments used in is-checks.
-    Set<ClassElement> checkedArguments =
-        getCheckedArguments(compiler.codegenWorld);
-
-    // Precompute the set of all seen type arguments for use in the emitter.
-    cachedAllArguments = new Set<ClassElement>.from(instantiatedArguments)
-        ..addAll(checkedArguments);
-
-    // Finally, run through the combination of instantiated and checked
+  /// Compute the required type checkes and substitutions for the given
+  /// instantitated and checked classes.
+  TypeChecks computeChecks(Set<ClassElement> instantiated,
+                           Set<ClassElement> checked) {
+    // Run through the combination of instantiated and checked
     // arguments and record all combination where the element of a checked
     // argument is a superclass of the element of an instantiated type.
-    TypeCheckMapping requiredChecks = new TypeCheckMapping();
-    for (ClassElement element in instantiatedArguments) {
+    TypeCheckMapping result = new TypeCheckMapping();
+    for (ClassElement element in instantiated) {
       if (element == compiler.dynamicClass) continue;
-      if (checkedArguments.contains(element)) {
-        requiredChecks.add(element, element);
+      if (checked.contains(element)) {
+        result.add(element, element, null);
       }
-      // Find all supertypes of [element] in [checkedArguments] and add checks.
+      // Find all supertypes of [element] in [checkedArguments] and add checks
+      // and precompute the substitutions for them.
       for (DartType supertype in element.allSupertypes) {
         ClassElement superelement = supertype.element;
-        if (checkedArguments.contains(superelement)) {
-          requiredChecks.add(element, superelement);
+        if (checked.contains(superelement)) {
+          Substitution substitution =
+              computeSubstitution(element, superelement);
+          result.add(element, superelement, substitution);
         }
       }
     }
+    return result;
+  }
 
-    cachedRequiredChecks = requiredChecks;
+  void computeRequiredChecks() {
+    computeInstantiatedArguments(compiler.codegenWorld);
+    computeCheckedArguments(compiler.codegenWorld);
+    cachedRequiredChecks =
+        computeChecks(allInstantiatedArguments, checkedArguments);
   }
 
   /**
@@ -219,30 +216,58 @@
    * have a type check against this supertype that includes a check against
    * the type arguments.
    */
-  Set<ClassElement> getInstantiatedArguments(Universe universe) {
-    ArgumentCollector collector = new ArgumentCollector(backend);
+  void computeInstantiatedArguments(Universe universe) {
+    ArgumentCollector superCollector = new ArgumentCollector(backend);
+    ArgumentCollector directCollector = new ArgumentCollector(backend);
     for (DartType type in universe.instantiatedTypes) {
-      collector.collect(type);
+      directCollector.collect(type);
       ClassElement cls = type.element;
       for (DartType supertype in cls.allSupertypes) {
-        collector.collect(supertype);
+        superCollector.collect(supertype);
       }
     }
-    for (ClassElement cls in collector.classes.toList()) {
+    for (ClassElement cls in superCollector.classes.toList()) {
       for (DartType supertype in cls.allSupertypes) {
-        collector.collect(supertype);
+        superCollector.collect(supertype);
       }
     }
-    return collector.classes;
+    directlyInstantiatedArguments = directCollector.classes;
+    allInstantiatedArguments =
+        superCollector.classes..addAll(directlyInstantiatedArguments);
   }
 
   /// Collects all type arguments used in is-checks.
-  Set<ClassElement> getCheckedArguments(Universe universe) {
+  void computeCheckedArguments(Universe universe) {
     ArgumentCollector collector = new ArgumentCollector(backend);
     for (DartType type in universe.isChecks) {
       collector.collect(type);
     }
-    return collector.classes;
+    checkedArguments = collector.classes;
+  }
+
+  Set<ClassElement> getClassesUsedInSubstitutions(JavaScriptBackend backend,
+                                                  TypeChecks checks) {
+    Set<ClassElement> instantiated = new Set<ClassElement>();
+    ArgumentCollector collector = new ArgumentCollector(backend);
+    for (ClassElement target in checks) {
+      instantiated.add(target);
+      for (TypeCheck check in checks[target]) {
+        Substitution substitution = check.substitution;
+        if (substitution != null) {
+          collector.collectAll(substitution.arguments);
+        }
+      }
+    }
+    return instantiated..addAll(collector.classes);
+  }
+
+  Set<ClassElement> getRequiredArgumentClasses(JavaScriptBackend backend) {
+    Set<ClassElement> requiredArgumentClasses =
+        new Set<ClassElement>.from(
+            getClassesUsedInSubstitutions(backend, requiredChecks));
+    return requiredArgumentClasses
+        ..addAll(directlyInstantiatedArguments)
+        ..addAll(checkedArguments);
   }
 
   /// Return the unique name for the element as an unquoted string.
@@ -314,9 +339,30 @@
    */
   String getSupertypeSubstitution(ClassElement cls, ClassElement check,
                                   {bool alwaysGenerateFunction: false}) {
+    Substitution substitution = getSubstitution(cls, check);
+    if (substitution != null) {
+      return substitution.getCode(this, alwaysGenerateFunction);
+    } else {
+      return null;
+    }
+  }
+
+  Substitution getSubstitution(ClassElement cls, ClassElement other) {
+    // Look for a precomputed check.
+    for (TypeCheck check in cachedRequiredChecks[cls]) {
+      if (check.cls == other) {
+        return check.substitution;
+      }
+    }
+    // There is no precomputed check for this pair (because the check is not
+    // done on type arguments only.  Compute a new substitution.
+    return computeSubstitution(cls, other);
+  }
+
+  Substitution computeSubstitution(ClassElement cls, ClassElement check,
+                                   { bool alwaysGenerateFunction: false }) {
     if (isTrivialSubstitution(cls, check)) return null;
 
-    // TODO(karlklose): maybe precompute this value and store it in typeChecks?
     bool usesTypeVariables = false;
     String onVariable(TypeVariableType v) {
       usesTypeVariables = true;
@@ -324,18 +370,21 @@
     };
     InterfaceType type = cls.computeType(compiler);
     InterfaceType target = type.asInstanceOf(check);
-    String substitution = target.typeArguments.toList()
-        .map((type) => _getTypeRepresentation(type, onVariable))
-        .join(', ');
-    substitution = '[$substitution]';
-    if (!usesTypeVariables && !alwaysGenerateFunction) {
-      return substitution;
+    if (cls.typeVariables.isEmpty && !alwaysGenerateFunction) {
+      return new Substitution.list(target.typeArguments);
     } else {
-      String parameters = cls.typeVariables.toList().join(', ');
-      return 'function ($parameters) { return $substitution; }';
+      return new Substitution.function(target.typeArguments, cls.typeVariables);
     }
   }
 
+  String getSubstitutionRepresentation(Link<DartType> types,
+                                       VariableSubstitution variableName) {
+    String code = types.toList(growable: false)
+        .map((type) => _getTypeRepresentation(type, variableName))
+        .join(', ');
+    return '[$code]';
+  }
+
   String getTypeRepresentation(DartType type, void onVariable(variable)) {
     // Create a type representation.  For type variables call the original
     // callback for side effects and return a template placeholder.
@@ -346,7 +395,8 @@
   }
 
   // TODO(karlklose): rewrite to use js.Expressions.
-  String _getTypeRepresentation(DartType type, String onVariable(variable)) {
+  String _getTypeRepresentation(DartType type,
+                                VariableSubstitution onVariable) {
     return representationGenerator.getTypeRepresentation(type, onVariable);
   }
 
@@ -477,18 +527,19 @@
   }
 }
 
-class TypeCheckMapping implements TypeChecks {
-  final Map<ClassElement, Set<ClassElement>> map =
-      new Map<ClassElement, Set<ClassElement>>();
 
-  Iterable<ClassElement> operator[](ClassElement element) {
-    Set<ClassElement> result = map[element];
-    return result != null ? result : const <ClassElement>[];
+class TypeCheckMapping implements TypeChecks {
+  final Map<ClassElement, Set<TypeCheck>> map =
+      new Map<ClassElement, Set<TypeCheck>>();
+
+  Iterable<TypeCheck> operator[](ClassElement element) {
+    Set<TypeCheck> result = map[element];
+    return result != null ? result : const <TypeCheck>[];
   }
 
-  void add(ClassElement cls, ClassElement check) {
-    map.putIfAbsent(cls, () => new Set<ClassElement>());
-    map[cls].add(check);
+  void add(ClassElement cls, ClassElement check, Substitution substitution) {
+    map.putIfAbsent(cls, () => new Set<TypeCheck>());
+    map[cls].add(new TypeCheck(check, substitution));
   }
 
   Iterator<ClassElement> get iterator => map.keys.iterator;
@@ -515,6 +566,14 @@
     type.accept(this, false);
   }
 
+  /// Collect all types in the list as if they were arguments of an
+  /// InterfaceType.
+  collectAll(Link<DartType> types) {
+    for (Link<DartType> link = types; !link.isEmpty; link = link.tail) {
+      link.head.accept(this, true);
+    }
+  }
+
   visitType(DartType type, _) {
     // Do nothing.
   }
@@ -534,3 +593,52 @@
     type.visitChildren(this, true);
   }
 }
+
+/**
+ * Representation of the substitution of type arguments
+ * when going from the type of a class to one of its supertypes.
+ *
+ * For [:class B<T> extends A<List<T>, int>:], the substitution is
+ * the representation of [: (T) => [<List, T>, int] :].  For more details
+ * of the representation consult the documentation of
+ * [getSupertypeSubstitution].
+ */
+class Substitution {
+  final bool isFunction;
+  final Link<DartType> arguments;
+  final Link<TypeVariableType> parameters;
+
+  Substitution.list(this.arguments)
+      : isFunction = false,
+        parameters = const Link<TypeVariableType>();
+
+  Substitution.function(this.arguments, this.parameters)
+      : isFunction = true;
+
+  String getCode(RuntimeTypes rti, bool ensureIsFunction) {
+    String variableName(TypeVariableType variable) {
+      return variable.name.slowToString();
+    }
+
+    String code = rti.getSubstitutionRepresentation(arguments, variableName);
+    if (isFunction) {
+      String formals = parameters.toList().map(variableName).join(', ');
+      return 'function ($formals) { return $code; }';
+    } else if (ensureIsFunction) {
+      return 'function() { return $code; }';
+    } else {
+      return code;
+    }
+  }
+}
+
+/**
+ * A pair of a class that we need a check against and the type argument
+ * substition for this check.
+ */
+class TypeCheck {
+  final ClassElement cls;
+  final Substitution substitution;
+
+  TypeCheck(this.cls, this.substitution);
+}
diff --git a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
index a34694a..fab0cf5 100644
--- a/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
+++ b/sdk/lib/_internal/compiler/implementation/lib/io_patch.dart
@@ -207,23 +207,25 @@
     throw new UnsupportedError("InternetAddress.ANY_IP_V6");
   }
   patch static Future<List<InternetAddress>> lookup(
-      String host, {InternetAddressType type: InternetAddressType.IP_V4}) {
+      String host, {InternetAddressType type: InternetAddressType.ANY}) {
     throw new UnsupportedError("InternetAddress.lookup");
   }
 }
 
 patch class RawServerSocket {
-  patch static Future<RawServerSocket> bind([String address = "127.0.0.1",
-                                             int port = 0,
-                                             int backlog = 0]) {
+  patch static Future<RawServerSocket> bind(address,
+                                            int port,
+                                            {int backlog: 0,
+                                             bool v6Only: false}) {
     throw new UnsupportedError("RawServerSocket.bind");
   }
 }
 
 patch class ServerSocket {
-  patch static Future<ServerSocket> bind([String address = "127.0.0.1",
-                                          int port = 0,
-                                          int backlog = 0]) {
+  patch static Future<ServerSocket> bind(address,
+                                         int port,
+                                         {int backlog: 0,
+                                          bool v6Only: false}) {
     throw new UnsupportedError("ServerSocket.bind");
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index fbde5f9..8dcfdab 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -209,6 +209,7 @@
   options.add('--analyze-only');
   options.add('--analyze-signatures-only');
   options.add('--analyze-all');
+  options.add('--categories=Client,Server');
 
   bool compilationFailed = false;
   void internalDiagnosticHandler(Uri uri, int begin, int end,
@@ -549,6 +550,8 @@
       _members = <String, MemberMirror>{};
       _library.forEachLocalMember((Element e) {
         if (!e.isClass() && !e.isTypedef()) {
+          // TODO(ahe): I think it is incorrect to filter out classes
+          // and typedefs.  See http://dartbug.com/10371.
           for (var member in _convertElementMemberToMemberMirrors(this, e)) {
             assert(!_members.containsKey(member.simpleName));
             _members[member.simpleName] = member;
@@ -1682,3 +1685,54 @@
     throw new UnsupportedError('InstanceMirror does not have a reflectee');
   }
 }
+
+_convertElementToMembers(Dart2JsLibraryMirror library, Element e) {
+  // TODO(ahe): This method creates new mirror objects which is not correct.
+  if (e.isClass()) {
+    ClassElement classElement = e;
+    classElement.ensureResolved(library.mirrors.compiler);
+    return [new Dart2JsClassMirror.fromLibrary(library, classElement)];
+  } else if (e.isTypedef()) {
+    return [new Dart2JsTypedefMirror.fromLibrary(
+          library, e.computeType(library.mirrors.compiler))];
+  } else {
+    return _convertElementMemberToMemberMirrors(library, e);
+  }
+}
+
+/**
+ * Experimental API for accessing compilation units defined in a
+ * library.
+ */
+// TODO(ahe): Superclasses? Is this really a mirror?
+class Dart2JsCompilationUnitMirror extends Dart2JsMirror {
+  final Dart2JsLibraryMirror _library;
+  final CompilationUnitElement _element;
+
+  Dart2JsCompilationUnitMirror(this._element, this._library);
+
+  Dart2JsMirrorSystem get mirrors => _library.mirrors;
+
+  List<DeclarationMirror> get members {
+    // TODO(ahe): Should return an immutable List.
+    return _element.localMembers.toList().map(
+        (m) => _convertElementToMembers(_library, m))
+      .fold([], (a, b) => a..addAll(b)).toList();
+  }
+
+  Uri get uri => _element.script.uri;
+}
+
+/**
+ * Transitional class that allows access to features that have not yet
+ * made it to the mirror API.
+ *
+ * All API in this class is experimental.
+ */
+class BackDoor {
+  /// Return the compilation units comprising [library].
+  static List<Mirror> compilationUnitsOf(Dart2JsLibraryMirror library) {
+    return library._element.compilationUnits.toList().map(
+        (cu) => new Dart2JsCompilationUnitMirror(cu, library)).toList();
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 9c521a2..27d990d 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -15,6 +15,7 @@
 import 'ssa/ssa.dart';
 import 'tree/tree.dart';
 import 'util/util.dart';
+import 'js/js.dart' as js;
 
 
 /// This class is a temporary work-around until we get a more powerful DartType.
@@ -535,9 +536,9 @@
   /// [DartType]s or [SpecialType]s instantiated by the native element.
   final List typesInstantiated = [];
 
-  static final NativeBehavior NONE = new NativeBehavior();
-
-  //NativeBehavior();
+  // If this behavior is for a JS expression, [codeAst] contains the
+  // parsed tree.
+  js.Expression codeAst;
 
   static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) {
     // The first argument of a JS-call is a string encoding various attributes
@@ -552,33 +553,38 @@
       compiler.cancel("JS expression has no type", node: jsCall);
     }
 
-    var firstArg = argNodes.head;
-    LiteralString specLiteral = firstArg.asLiteralString();
-    if (specLiteral != null) {
-      String specString = specLiteral.dartString.slowToString();
-      // Various things that are not in fact types.
-      if (specString == 'void') return NativeBehavior.NONE;
-      if (specString == '' || specString == 'var') {
-        var behavior = new NativeBehavior();
-        behavior.typesReturned.add(compiler.objectClass.computeType(compiler));
-        behavior.typesReturned.add(compiler.nullClass.computeType(compiler));
-        return behavior;
-      }
-      var behavior = new NativeBehavior();
-      for (final typeString in specString.split('|')) {
-        var type = _parseType(typeString, compiler,
-            (name) => resolver.resolveTypeFromString(name),
-            jsCall);
-        behavior.typesInstantiated.add(type);
-        behavior.typesReturned.add(type);
-      }
-      return behavior;
+    var code = argNodes.tail.head;
+    if (code is !StringNode || code.isInterpolation) {
+      compiler.cancel('JS code must be a string literal', node: code);
     }
 
-    // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2').  It
-    // is not very satisfactory because it does not work for void, dynamic.
+    LiteralString specLiteral = argNodes.head.asLiteralString();
+    if (specLiteral == null) {
+      // TODO(sra): We could accept a type identifier? e.g. JS(bool, '1<2').  It
+      // is not very satisfactory because it does not work for void, dynamic.
+      compiler.cancel("Unexpected JS first argument", node: argNodes.head);
+    }
 
-    compiler.cancel("Unexpected JS first argument", node: firstArg);
+    var behavior = new NativeBehavior();
+    behavior.codeAst = js.js.parseForeignJS(code.dartString.slowToString());
+
+    String specString = specLiteral.dartString.slowToString();
+    // Various things that are not in fact types.
+    if (specString == 'void') return behavior;
+    if (specString == '' || specString == 'var') {
+      behavior.typesReturned.add(compiler.objectClass.computeType(compiler));
+      behavior.typesReturned.add(compiler.nullClass.computeType(compiler));
+      return behavior;
+    }
+    for (final typeString in specString.split('|')) {
+      var type = _parseType(typeString, compiler,
+          (name) => resolver.resolveTypeFromString(name),
+          jsCall);
+      behavior.typesInstantiated.add(type);
+      behavior.typesReturned.add(type);
+    }
+
+    return behavior;
   }
 
   static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) {
@@ -911,8 +917,7 @@
                                      element: element);
     }
 
-    DartString jsCode = new DartString.literal(nativeMethodCall);
-    builder.push(new HForeign(jsCode, HType.UNKNOWN, inputs));
+    builder.push(new HForeign(js.js(nativeMethodCall), HType.UNKNOWN, inputs));
     builder.close(new HReturn(builder.pop())).addSuccessor(builder.graph.exit);
   } else {
     if (parameters.parameterCount != 0) {
@@ -921,6 +926,8 @@
           node: nativeBody);
     }
     LiteralString jsCode = nativeBody.asLiteralString();
-    builder.push(new HForeign.statement(jsCode.dartString, <HInstruction>[]));
+    builder.push(new HForeign.statement(
+        new js.LiteralStatement(jsCode.dartString.slowToString()),
+        <HInstruction>[]));
   }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/byte_array_scanner.dart b/sdk/lib/_internal/compiler/implementation/scanner/byte_array_scanner.dart
index a5d801d..4cf9eeb 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/byte_array_scanner.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/byte_array_scanner.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of parser;
+
 /**
  * Scanner that reads from a byte array and creates tokens that points
  * to the same array.
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
index 4ae62ed..543cd6c 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/byte_strings.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of parser;
+
 /**
  * An abstract string representation.
  */
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 70659e0..874300b 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -47,6 +47,8 @@
         relativize(cwd, resourceUri, isWindows), source);
     return new Future.value(source);
   }
+
+  Future<String> call(Uri resourceUri) => readStringFromUri(resourceUri);
 }
 
 class FormattingDiagnosticHandler {
@@ -61,7 +63,9 @@
   final int INFO =
       api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal;
 
-  FormattingDiagnosticHandler(SourceFileProvider this.provider);
+  FormattingDiagnosticHandler([SourceFileProvider provider])
+      : this.provider =
+          (provider == null) ? new SourceFileProvider() : provider;
 
   void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
     if (!verbose && identical(kind, api.Diagnostic.VERBOSE_INFO)) return;
@@ -116,6 +120,8 @@
       throw new AbortLeg(message);
     }
   }
+
+  void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) {
+    return diagnosticHandler(uri, begin, end, message, kind);
+  }
 }
-
-
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 19525ee..b769c27 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -162,7 +162,7 @@
   HInstruction createBox() {
     // TODO(floitsch): Clean up this hack. Should we create a box-object by
     // just creating an empty object literal?
-    HInstruction box = new HForeign(const LiteralDartString("{}"),
+    HInstruction box = new HForeign(new js.ObjectInitializer([]),
                                     HType.UNKNOWN,
                                     <HInstruction>[]);
     builder.add(box);
@@ -2518,9 +2518,8 @@
         HInstruction instruction = new HStatic(element.declaration);
         if (element.isGetter()) {
           add(instruction);
-          push(new HInvokeStatic(
-              <HInstruction>[instruction],
-              new HType.inferredReturnTypeForElement(element, compiler)));
+          instruction = buildInvokeStatic(<HInstruction>[instruction]);
+          push(instruction);
         } else {
           instruction.instructionType =
               new HType.inferredTypeForElement(element, compiler);
@@ -2581,9 +2580,9 @@
       if (element.isSetter()) {
         HStatic target = new HStatic(element);
         add(target);
-        addWithPosition(
-            new HInvokeStatic(<HInstruction>[target, value], HType.UNKNOWN),
-            location);
+        var instruction = buildInvokeStatic(
+            <HInstruction>[target, value], HType.UNKNOWN);
+        addWithPosition(instruction, location);
       } else {
         value = potentiallyCheckType(value, element.computeType(compiler));
         addWithPosition(new HStaticStore(element, value), location);
@@ -2612,8 +2611,7 @@
   }
 
   HInstruction invokeInterceptor(Set<ClassElement> intercepted,
-                                 HInstruction receiver,
-                                 Node node) {
+                                 HInstruction receiver) {
     HInterceptor interceptor = new HInterceptor(intercepted, receiver);
     add(interceptor);
     return interceptor;
@@ -2623,16 +2621,14 @@
     HInstruction reference = new HStatic(helper);
     add(reference);
     List<HInstruction> inputs = <HInstruction>[reference];
-    HInstruction result = new HInvokeStatic(inputs, type);
-    push(result);
+    push(buildInvokeStatic(inputs, type));
   }
 
   void pushInvokeHelper1(Element helper, HInstruction a0, HType type) {
     HInstruction reference = new HStatic(helper);
     add(reference);
     List<HInstruction> inputs = <HInstruction>[reference, a0];
-    HInstruction result = new HInvokeStatic(inputs, type);
-    push(result);
+    push(buildInvokeStatic(inputs, type));
   }
 
   void pushInvokeHelper2(Element helper,
@@ -2642,8 +2638,7 @@
     HInstruction reference = new HStatic(helper);
     add(reference);
     List<HInstruction> inputs = <HInstruction>[reference, a0, a1];
-    HInstruction result = new HInvokeStatic(inputs, type);
-    push(result);
+    push(buildInvokeStatic(inputs, type));
   }
 
   void pushInvokeHelper3(Element helper,
@@ -2654,8 +2649,7 @@
     HInstruction reference = new HStatic(helper);
     add(reference);
     List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2];
-    HInstruction result = new HInvokeStatic(inputs, type);
-    push(result);
+    push(buildInvokeStatic(inputs, type));
   }
 
   void pushInvokeHelper4(Element helper,
@@ -2667,8 +2661,7 @@
     HInstruction reference = new HStatic(helper);
     add(reference);
     List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3];
-    HInstruction result = new HInvokeStatic(inputs, type);
-    push(result);
+    push(buildInvokeStatic(inputs, type));
   }
 
   void pushInvokeHelper5(Element helper,
@@ -2681,15 +2674,14 @@
     HInstruction reference = new HStatic(helper);
     add(reference);
     List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3, a4];
-    HInstruction result = new HInvokeStatic(inputs, type);
-    push(result);
+    push(buildInvokeStatic(inputs, type));
   }
 
   HForeign createForeign(String code,
                          HType type,
                          List<HInstruction> inputs,
                          {bool isSideEffectFree: false}) {
-    return new HForeign(new LiteralDartString(code),
+    return new HForeign(js.js.parseForeignJS(code),
                         type,
                         inputs,
                         isSideEffectFree: isSideEffectFree);
@@ -2789,7 +2781,7 @@
       add(helperCall);
       List<HInstruction> inputs = <HInstruction>[helperCall, expression,
                                                  runtimeType];
-      HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN);
+      HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN);
       add(call);
       instruction = new HIs(type, <HInstruction>[expression, call],
                             HIs.VARIABLE_CHECK);
@@ -2813,7 +2805,7 @@
                                                  isFieldName,
                                                  representations,
                                                  asFieldName];
-      HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN);
+      HInstruction call = buildInvokeStatic(inputs, HType.BOOLEAN);
       add(call);
       instruction = new HIs(type, <HInstruction>[expression, call],
                             HIs.COMPOUND_CHECK);
@@ -2992,23 +2984,15 @@
       compiler.cancel('At least two arguments expected',
                       node: node.argumentsNode);
     }
-    List<HInstruction> inputs = <HInstruction>[];
-    Node type = link.head;
-    Node code = link.tail.head;
-    addGenericSendArgumentsToList(link.tail.tail, inputs);
-
     native.NativeBehavior nativeBehavior =
         compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
+
+    List<HInstruction> inputs = <HInstruction>[];
+    addGenericSendArgumentsToList(link.tail.tail, inputs);
+
     HType ssaType = new HType.fromNativeBehavior(nativeBehavior, compiler);
-    if (code is StringNode) {
-      StringNode codeString = code;
-      if (!codeString.isInterpolation) {
-        // codeString may not be an interpolation, but may be a juxtaposition.
-        push(new HForeign(codeString.dartString, ssaType, inputs));
-        return;
-      }
-    }
-    compiler.cancel('JS code must be a string literal', node: code);
+    push(new HForeign(nativeBehavior.codeAst, ssaType, inputs));
+    return;
   }
 
   void handleForeignJsCurrentIsolate(Send node) {
@@ -3019,9 +3003,9 @@
 
     if (!compiler.hasIsolateSupport()) {
       // If the isolate library is not used, we just generate code
-      // to fetch the Leg's current isolate.
+      // to fetch the current isolate.
       String name = backend.namer.CURRENT_ISOLATE;
-      push(new HForeign(new DartString.literal(name),
+      push(new HForeign(new js.LiteralString(name),
                         HType.UNKNOWN,
                         <HInstruction>[]));
     } else {
@@ -3058,7 +3042,7 @@
       add(target);
       List<HInstruction> inputs = <HInstruction>[target];
       addGenericSendArgumentsToList(link, inputs);
-      push(new HInvokeStatic(inputs, HType.UNKNOWN));
+      push(buildInvokeStatic(inputs, HType.UNKNOWN));
     }
   }
 
@@ -3094,7 +3078,7 @@
     List<HInstruction> inputs = <HInstruction>[pop()];
     String invocationName = backend.namer.invocationName(
         new Selector.callClosure(params.requiredParameterCount));
-    push(new HForeign(new DartString.literal('#.$invocationName'),
+    push(new HForeign(js.js('#.$invocationName'),
                       HType.UNKNOWN,
                       inputs));
   }
@@ -3106,7 +3090,7 @@
     }
     visit(node.arguments.head);
     String isolateName = backend.namer.CURRENT_ISOLATE;
-    push(new HForeign(new DartString.literal("$isolateName = #"),
+    push(new HForeign(js.js("$isolateName = #"),
                       HType.UNKNOWN,
                       <HInstruction>[pop()]));
   }
@@ -3117,7 +3101,7 @@
                       node: node.argumentsNode);
     }
     String constructorName = backend.namer.isolateName;
-    push(new HForeign(new DartString.literal("new $constructorName()"),
+    push(new HForeign(js.js("new $constructorName()"),
                       HType.UNKNOWN,
                       <HInstruction>[]));
   }
@@ -3127,7 +3111,7 @@
       compiler.cancel('Too many arguments', node: node.argumentsNode);
     }
     String jsClassReference = backend.namer.isolateAccess(compiler.objectClass);
-    push(new HForeign(new DartString.literal(jsClassReference),
+    push(new HForeign(new js.LiteralString(jsClassReference),
                       HType.UNKNOWN,
                       <HInstruction>[]));
   }
@@ -3174,9 +3158,6 @@
       // [JSInvocationMirror._invokeOn].
       compiler.enqueuer.codegen.registerSelectorUse(selector);
     }
-    HStatic target = new HStatic(element);
-    add(target);
-    HInstruction self = localsHandler.readThis();
     Constant nameConstant = constantSystem.createString(
         new DartString.literal(name.slowToString()), node);
 
@@ -3209,12 +3190,8 @@
                       argumentNamesInstruction,
                       HType.UNKNOWN);
 
-    var inputs = <HInstruction>[target, self];
-    if (backend.isInterceptedMethod(element)) {
-      inputs.add(self);
-    }
-    inputs.add(pop());
-    push(new HInvokeSuper(currentNonClosureClass, inputs));
+    var inputs = <HInstruction>[pop()];
+    push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs));
   }
 
   visitSend(Send node) {
@@ -3235,13 +3212,9 @@
       }
       return generateSuperNoSuchMethodSend(node, selector, arguments);
     }
-    List<HInstruction> inputs = buildSuperAccessorInputs(element);
+    List<HInstruction> inputs = <HInstruction>[];
     if (node.isPropertyAccess) {
-      HInstruction invokeSuper =
-          new HInvokeSuper(currentNonClosureClass, inputs);
-      invokeSuper.instructionType =
-          new HType.inferredTypeForElement(element, compiler);
-      push(invokeSuper);
+      push(buildInvokeSuper(selector, element, inputs));
     } else if (element.isFunction() || element.isGenerativeConstructor()) {
       // TODO(5347): Try to avoid the need for calling [implementation] before
       // calling [addStaticSendArgumentsToList].
@@ -3251,16 +3224,10 @@
       if (!succeeded) {
         generateWrongArgumentCountError(node, element, node.arguments);
       } else {
-        HInstruction invokeSuper =
-            new HInvokeSuper(currentNonClosureClass, inputs);
-        invokeSuper.instructionType =
-            new HType.inferredReturnTypeForElement(element, compiler);
-        push(invokeSuper);
+        push(buildInvokeSuper(selector, element, inputs));
       }
     } else {
-      HInstruction target = new HInvokeSuper(currentNonClosureClass, inputs);
-      target.instructionType =
-          new HType.inferredTypeForElement(element, compiler);
+      HInstruction target = buildInvokeSuper(selector, element, inputs);
       add(target);
       inputs = <HInstruction>[target];
       addDynamicSendArgumentsToList(node, inputs);
@@ -3374,7 +3341,7 @@
     Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo();
     HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement);
     add(typeInfoSetter);
-    add(new HInvokeStatic(
+    add(buildInvokeStatic(
         <HInstruction>[typeInfoSetter, newObject, typeInfo], HType.UNKNOWN));
   }
 
@@ -3464,7 +3431,7 @@
       compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
     }
     HType elementType = computeType(constructor);
-    HInstruction newInstance = new HInvokeStatic(inputs, elementType);
+    HInstruction newInstance = buildInvokeStatic(inputs, elementType);
     pushWithPosition(newInstance, node);
 
     // The List constructor forwards to a Dart static method that does
@@ -3521,7 +3488,7 @@
         return;
       }
 
-      HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN);
+      HInvokeStatic instruction = buildInvokeStatic(inputs, HType.UNKNOWN);
       HType returnType =
           new HType.inferredReturnTypeForElement(element, compiler);
       if (returnType.isUnknown()) {
@@ -3532,6 +3499,7 @@
                 currentElement, element);
       }
       if (returnType != null) instruction.instructionType = returnType;
+
       pushWithPosition(instruction, node);
     } else {
       generateGetter(node, element);
@@ -3723,7 +3691,7 @@
     bool isIntercepted = interceptedClasses != null;
     if (isIntercepted) {
       assert(!interceptedClasses.isEmpty);
-      inputs.add(invokeInterceptor(interceptedClasses, receiver, node));
+      inputs.add(invokeInterceptor(interceptedClasses, receiver));
     }
     inputs.addAll(arguments);
     if (selector.isGetter()) {
@@ -3737,6 +3705,44 @@
     }
   }
 
+  HInstruction buildInvokeStatic(List<HInstruction> inputs,
+                                 [HType type = null]) {
+    HStatic staticInstruction = inputs[0];
+    Element element = staticInstruction.element;
+    if (type == null) {
+      type = new HType.inferredReturnTypeForElement(element, compiler);
+    }
+    HInstruction instruction = new HInvokeStatic(inputs, type);
+    instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
+    return instruction;
+  }
+
+  HInstruction buildInvokeSuper(Selector selector,
+                                Element element,
+                                List<HInstruction> arguments) {
+    HInstruction receiver = localsHandler.readThis();
+    // TODO(5346): Try to avoid the need for calling [declaration] before
+    // creating an [HStatic].
+    HInstruction target = new HStatic(element.declaration);
+    add(target);
+    List<HInstruction> inputs = <HInstruction>[target];
+    Set<ClassElement> interceptedClasses =
+        backend.getInterceptedClassesOn(selector.name);
+    if (interceptedClasses != null) {
+      inputs.add(invokeInterceptor(interceptedClasses, receiver));
+    }
+    inputs.add(receiver);
+    inputs.addAll(arguments);
+    HInstruction instruction = new HInvokeSuper(
+        currentNonClosureClass,
+        inputs,
+        isSetter: selector.isSetter() || selector.isIndexSet());
+    instruction.instructionType =
+        new HType.inferredReturnTypeForElement(element, compiler);
+    instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
+    return instruction;
+  }
+
   void handleComplexOperatorSend(SendSet node,
                                  HInstruction receiver,
                                  Link<Node> arguments) {
@@ -3752,23 +3758,6 @@
                 elements.getOperatorSelectorInComplexSendSet(node), node);
   }
 
-  List<HInstruction> buildSuperAccessorInputs(Element element) {
-    List<HInstruction> inputs = <HInstruction>[];
-    if (Elements.isUnresolved(element)) return inputs;
-    // TODO(5346): Try to avoid the need for calling [declaration] before
-    // creating an [HStatic].
-    HInstruction target = new HStatic(element.declaration);
-    add(target);
-    inputs.add(target);
-    HInstruction context = localsHandler.readThis();
-    inputs.add(context);
-    if (backend.isInterceptedMethod(element)) {
-      inputs.add(context);
-    }
-    return inputs;
-  }
-
-
   visitSendSet(SendSet node) {
     Element element = elements[node];
     if (!Elements.isUnresolved(element) && element.impliesType()) {
@@ -3780,13 +3769,13 @@
     Operator op = node.assignmentOperator;
     if (node.isSuperCall) {
       HInstruction result;
-      List<HInstruction> setterInputs = buildSuperAccessorInputs(element);
+      List<HInstruction> setterInputs = <HInstruction>[];
       if (identical(node.assignmentOperator.source.stringValue, '=')) {
         addDynamicSendArgumentsToList(node, setterInputs);
         result = setterInputs.last;
       } else {
         Element getter = elements[node.selector];
-        List<HInstruction> getterInputs = buildSuperAccessorInputs(getter);
+        List<HInstruction> getterInputs = <HInstruction>[];
         Link<Node> arguments = node.arguments;
         if (node.isIndex) {
           // If node is of the from [:super.foo[0] += 2:], the send has
@@ -3800,15 +3789,17 @@
           setterInputs.add(index);
         }
         HInstruction getterInstruction;
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
         if (Elements.isUnresolved(getter)) {
           generateSuperNoSuchMethodSend(
               node,
-              elements.getGetterSelectorInComplexSendSet(node),
+              getterSelector,
               getterInputs);
           getterInstruction = pop();
         } else {
-          getterInstruction = new HInvokeSuper(
-              currentNonClosureClass, getterInputs);
+          getterInstruction = buildInvokeSuper(
+              getterSelector, getter, getterInputs);
           add(getterInstruction);
         }
         handleComplexOperatorSend(node, getterInstruction, arguments);
@@ -3820,13 +3811,13 @@
           result = setterInputs.last;
         }
       }
+      Selector setterSelector = elements.getSelector(node);
       if (Elements.isUnresolved(element)) {
         generateSuperNoSuchMethodSend(
-            node, elements.getSelector(node), setterInputs);
+            node, setterSelector, setterInputs);
         pop();
       } else {
-        add(new HInvokeSuper(
-            currentNonClosureClass, setterInputs, isSetter: true));
+        add(buildInvokeSuper(setterSelector, element, setterInputs));
       }
       stack.add(result);
     } else if (node.isIndex) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 0f48064..924ed88 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1693,43 +1693,35 @@
   }
 
   void registerForeignType(HType type) {
-    // TODO(kasperl): This looks shaky. It makes sense if the type is
-    // exact, but otherwise we should be registering more types as
-    // instantiated. We should find a way of using something along the
-    // lines of the NativeEnqueuerBase.processNativeBehavior method.
     if (type.isUnknown()) return;
     TypeMask mask = type.computeMask(compiler);
-    world.registerInstantiatedClass(mask.base.element, work.resolutionTree);
+    for (ClassElement cls in mask.containedClasses(compiler)) {
+      world.registerInstantiatedClass(cls, work.resolutionTree);
+    }
   }
 
   visitForeign(HForeign node) {
-    String code = node.code.slowToString();
     List<HInstruction> inputs = node.inputs;
     if (node.isJsStatement()) {
       if (!inputs.isEmpty) {
-        compiler.internalError("foreign statement with inputs: $code",
+        compiler.internalError("foreign statement with inputs",
                                instruction: node);
       }
-      pushStatement(new js.LiteralStatement(code), node);
+      pushStatement(node.codeAst, node);
     } else {
-      List<js.Expression> interpolatedExpressions;
       if (!inputs.isEmpty) {
-        interpolatedExpressions = <js.Expression>[];
+        List<js.Expression> interpolatedExpressions = <js.Expression>[];
         for (int i = 0; i < inputs.length; i++) {
           use(inputs[i]);
           interpolatedExpressions.add(pop());
         }
-      }
-      // 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);
+        var visitor = new js.UninterpolateJSExpression(interpolatedExpressions);
+        push(visitor.visit(node.codeAst), node);
       } else {
-        push(new js.LiteralExpression.withData(code, interpolatedExpressions),
-             node);
+        push(node.codeAst, node);
       }
     }
+
     registerForeignType(node.instructionType);
     // TODO(sra): Tell world.nativeEnqueuer about the types created here.
   }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
index 209a5c0..ce3c0e3 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
@@ -58,6 +58,15 @@
             // between do not prevent making it generate at use site.
             input.moveBefore(user);
             pureInputs.add(input);
+            // Previous computations done on [input] are now invalid
+            // because we moved [input] to another place. So all
+            // non code motion invariant instructions need
+            // to be removed from the [generateAtUseSite] set.
+            input.inputs.forEach((instruction) {
+              if (!instruction.isCodeMotionInvariant()) {
+                generateAtUseSite.remove(instruction);
+              }
+            });
             // Visit the pure input now so that the expected inputs
             // are after the expected inputs of [user].
             input.accept(this);
@@ -160,7 +169,6 @@
     }
 
     block.last.accept(this);
-    bool dontVisitPure = false;
     for (HInstruction instruction = block.last.previous;
          instruction != null;
          instruction = instruction.previous) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
index 9d78bfd..985a7a3 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
@@ -267,8 +267,8 @@
       // Even if there is no builtin equivalent instruction, we know
       // the instruction does not have any side effect, and that it
       // can be GVN'ed.
-      instruction.clearAllSideEffects();
-      instruction.clearAllDependencies();
+      instruction.sideEffects.clearAllSideEffects();
+      instruction.sideEffects.clearAllDependencies();
       instruction.setUseGvn();
     }
     return null;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 3491b3f..aa28dfd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -754,26 +754,9 @@
   HBasicBlock block;
   HInstruction previous = null;
   HInstruction next = null;
-  int flags = 0;
 
-  // Changes flags.
-  static const int FLAG_CHANGES_INDEX = 0;
-  static const int FLAG_CHANGES_INSTANCE_PROPERTY = FLAG_CHANGES_INDEX + 1;
-  static const int FLAG_CHANGES_STATIC_PROPERTY
-      = FLAG_CHANGES_INSTANCE_PROPERTY + 1;
-  static const int FLAG_CHANGES_COUNT = FLAG_CHANGES_STATIC_PROPERTY + 1;
-
-  // Depends flags (one for each changes flag).
-  static const int FLAG_DEPENDS_ON_INDEX_STORE = FLAG_CHANGES_COUNT;
-  static const int FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE =
-      FLAG_DEPENDS_ON_INDEX_STORE + 1;
-  static const int FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE =
-      FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE + 1;
-  static const int FLAG_DEPENDS_ON_COUNT =
-      FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE + 1;
-
-  // Other flags.
-  static const int FLAG_USE_GVN = FLAG_DEPENDS_ON_COUNT;
+  SideEffects sideEffects = new SideEffects.empty();
+  bool _useGvn = false;
 
   // Type codes.
   static const int UNDEFINED_TYPECODE = -1;
@@ -812,54 +795,8 @@
 
   int get hashCode => id;
 
-  bool getFlag(int position) => (flags & (1 << position)) != 0;
-  void setFlag(int position) { flags |= (1 << position); }
-  void clearFlag(int position) { flags &= ~(1 << position); }
-
-  static int computeDependsOnFlags(int flags) => flags << FLAG_CHANGES_COUNT;
-
-  int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1);
-  int getDependsOnFlags() {
-    return (flags & ((1 << FLAG_DEPENDS_ON_COUNT) - 1)) >> FLAG_CHANGES_COUNT;
-  }
-
-  bool hasSideEffects() => getChangesFlags() != 0;
-  bool dependsOnSomething() => getDependsOnFlags() != 0;
-
-  void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); }
-  void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); }
-
-  void setDependsOnSomething() {
-    int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
-    flags |= (((1 << count) - 1) << FLAG_CHANGES_COUNT);
-  }
-  void clearAllDependencies() {
-    int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
-    flags &= ~(((1 << count) - 1) << FLAG_CHANGES_COUNT);
-  }
-
-  bool dependsOnStaticPropertyStore() {
-    return getFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
-  }
-  void setDependsOnStaticPropertyStore() {
-    setFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
-  }
-  void setChangesStaticProperty() { setFlag(FLAG_CHANGES_STATIC_PROPERTY); }
-
-  bool dependsOnIndexStore() => getFlag(FLAG_DEPENDS_ON_INDEX_STORE);
-  void setDependsOnIndexStore() { setFlag(FLAG_DEPENDS_ON_INDEX_STORE); }
-  void setChangesIndex() { setFlag(FLAG_CHANGES_INDEX); }
-
-  bool dependsOnInstancePropertyStore() {
-    return getFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
-  }
-  void setDependsOnInstancePropertyStore() {
-    setFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
-  }
-  void setChangesInstanceProperty() { setFlag(FLAG_CHANGES_INSTANCE_PROPERTY); }
-
-  bool useGvn() => getFlag(FLAG_USE_GVN);
-  void setUseGvn() { setFlag(FLAG_USE_GVN); }
+  bool useGvn() => _useGvn;
+  void setUseGvn() { _useGvn = true; }
 
   void updateInput(int i, HInstruction insn) {
     inputs[i] = insn;
@@ -870,7 +807,11 @@
    * effect, nor any dependency. They can be moved anywhere in the
    * graph.
    */
-  bool isPure() => !hasSideEffects() && !dependsOnSomething() && !canThrow();
+  bool isPure() {
+    return !sideEffects.hasSideEffects()
+        && !sideEffects.dependsOnSomething()
+        && !canThrow();
+  }
 
   // Can this node throw an exception?
   bool canThrow() => false;
@@ -932,11 +873,11 @@
 
   bool gvnEquals(HInstruction other) {
     assert(useGvn() && other.useGvn());
-    // Check that the type and the flags match.
+    // Check that the type and the sideEffects match.
     bool hasSameType = typeEquals(other);
     assert(hasSameType == (typeCode() == other.typeCode()));
     if (!hasSameType) return false;
-    if (flags != other.flags) return false;
+    if (sideEffects != other.sideEffects) return false;
     // Check that the inputs match.
     final int inputsLength = inputs.length;
     final List<HInstruction> otherInputs = other.inputs;
@@ -1162,7 +1103,6 @@
 
 class HBoolify extends HInstruction {
   HBoolify(HInstruction value) : super(<HInstruction>[value]) {
-    assert(!hasSideEffects());
     setUseGvn();
     instructionType = HType.BOOLEAN;
   }
@@ -1182,7 +1122,6 @@
  */
 abstract class HCheck extends HInstruction {
   HCheck(inputs) : super(inputs) {
-    assert(!hasSideEffects());
     setUseGvn();
   }
   HInstruction get checkedInput => inputs[0];
@@ -1198,7 +1137,6 @@
   // bailout function.
   List<int> padding;
   HBailoutTarget(this.state) : super(<HInstruction>[]) {
-    assert(!hasSideEffects());
     setUseGvn();
   }
 
@@ -1299,8 +1237,8 @@
     * to the invocation.
     */
   HInvoke(List<HInstruction> inputs) : super(inputs) {
-    setAllSideEffects();
-    setDependsOnSomething();
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
   }
   static const int ARGUMENTS_OFFSET = 1;
   bool canThrow() => true;
@@ -1387,13 +1325,13 @@
 class HInvokeDynamicGetter extends HInvokeDynamicField {
   HInvokeDynamicGetter(selector, element, inputs, isSideEffectFree)
     : super(selector, element, inputs, isSideEffectFree) {
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     if (isSideEffectFree) {
       setUseGvn();
-      setDependsOnInstancePropertyStore();
+      sideEffects.setDependsOnInstancePropertyStore();
     } else {
-      setDependsOnSomething();
-      setAllSideEffects();
+      sideEffects.setDependsOnSomething();
+      sideEffects.setAllSideEffects();
     }
   }
   toString() => 'invoke dynamic getter: $selector';
@@ -1403,12 +1341,12 @@
 class HInvokeDynamicSetter extends HInvokeDynamicField {
   HInvokeDynamicSetter(selector, element, inputs, isSideEffectFree)
     : super(selector, element, inputs, isSideEffectFree) {
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     if (isSideEffectFree) {
-      setChangesInstanceProperty();
+      sideEffects.setChangesInstanceProperty();
     } else {
-      setAllSideEffects();
-      setDependsOnSomething();
+      sideEffects.setAllSideEffects();
+      sideEffects.setDependsOnSomething();
     }
   }
   toString() => 'invoke dynamic setter: $selector';
@@ -1433,7 +1371,7 @@
   final ClassElement caller;
   final bool isSetter;
 
-  HInvokeSuper(this.caller, inputs, {this.isSetter: false})
+  HInvokeSuper(this.caller, inputs, {this.isSetter})
       : super(inputs, HType.UNKNOWN);
   toString() => 'invoke super: ${element.name}';
   accept(HVisitor visitor) => visitor.visitInvokeSuper(this);
@@ -1462,10 +1400,10 @@
             ? isAssignable
             : element.isAssignable(),
         super(element, <HInstruction>[receiver]) {
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     setUseGvn();
     if (this.isAssignable) {
-      setDependsOnInstancePropertyStore();
+      sideEffects.setDependsOnInstancePropertyStore();
     }
   }
 
@@ -1495,8 +1433,8 @@
             HInstruction receiver,
             HInstruction value)
       : super(element, <HInstruction>[receiver, value]) {
-    clearAllSideEffects();
-    setChangesInstanceProperty();
+    sideEffects.clearAllSideEffects();
+    sideEffects.setChangesInstanceProperty();
   }
 
   bool canThrow() => receiver.canBeNull();
@@ -1531,25 +1469,25 @@
 }
 
 class HForeign extends HInstruction {
-  final DartString code;
+  final js.Node codeAst;
   final bool isStatement;
   final bool isSideEffectFree;
 
-  HForeign(this.code,
+  HForeign(this.codeAst,
            HType type,
            List<HInstruction> inputs,
            {this.isStatement: false,
             this.isSideEffectFree: false})
       : super(inputs) {
     if (!isSideEffectFree) {
-      setAllSideEffects();
-      setDependsOnSomething();
+      sideEffects.setAllSideEffects();
+      sideEffects.setDependsOnSomething();
     }
     instructionType = type;
   }
 
-  HForeign.statement(code, List<HInstruction> inputs)
-      : this(code, HType.UNKNOWN, inputs, isStatement: true);
+  HForeign.statement(codeAst, List<HInstruction> inputs)
+      : this(codeAst, HType.UNKNOWN, inputs, isStatement: true);
 
   accept(HVisitor visitor) => visitor.visitForeign(this);
 
@@ -1560,7 +1498,7 @@
 class HForeignNew extends HForeign {
   ClassElement element;
   HForeignNew(this.element, HType type, List<HInstruction> inputs)
-      : super(const LiteralDartString("new"), type, inputs);
+      : super(null, type, inputs);
   accept(HVisitor visitor) => visitor.visitForeignNew(this);
 }
 
@@ -1568,7 +1506,7 @@
   final Selector selector;
   HInvokeBinary(HInstruction left, HInstruction right, this.selector)
       : super(<HInstruction>[left, right]) {
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     setUseGvn();
   }
 
@@ -1706,7 +1644,7 @@
   final Selector selector;
   HInvokeUnary(HInstruction input, this.selector)
       : super(<HInstruction>[input]) {
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     setUseGvn();
   }
 
@@ -2046,9 +1984,9 @@
   HStatic(this.element) : super(<HInstruction>[]) {
     assert(element != null);
     assert(invariant(this, element.isDeclaration));
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     if (element.isAssignable()) {
-      setDependsOnStaticPropertyStore();
+      sideEffects.setDependsOnStaticPropertyStore();
     }
     setUseGvn();
   }
@@ -2066,7 +2004,7 @@
   Set<ClassElement> interceptedClasses;
   HInterceptor(this.interceptedClasses, HInstruction receiver)
       : super(<HInstruction>[receiver]) {
-    clearAllSideEffects();
+    sideEffects.clearAllSideEffects();
     setUseGvn();
   }
   String toString() => 'interceptor on $interceptedClasses';
@@ -2113,8 +2051,8 @@
   HLazyStatic(this.element) : super(<HInstruction>[]) {
     // TODO(4931): The first access has side-effects, but we afterwards we
     // should be able to GVN.
-    setAllSideEffects();
-    setDependsOnSomething();
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
   }
 
   toString() => 'lazy static ${element.name}';
@@ -2130,8 +2068,8 @@
   Element element;
   HStaticStore(this.element, HInstruction value)
       : super(<HInstruction>[value]) {
-    clearAllSideEffects();
-    setChangesStaticProperty();
+    sideEffects.clearAllSideEffects();
+    sideEffects.setChangesStaticProperty();
   }
   toString() => 'static store ${element.name}';
   accept(HVisitor visitor) => visitor.visitStaticStore(this);
@@ -2158,8 +2096,8 @@
   final Selector selector;
   HIndex(HInstruction receiver, HInstruction index, this.selector)
       : super(<HInstruction>[receiver, index]) {
-    clearAllSideEffects();
-    setDependsOnIndexStore();
+    sideEffects.clearAllSideEffects();
+    sideEffects.setDependsOnIndexStore();
     setUseGvn();
   }
 
@@ -2185,8 +2123,8 @@
                HInstruction value,
                this.selector)
       : super(<HInstruction>[receiver, index, value]) {
-    clearAllSideEffects();
-    setChangesIndex();
+    sideEffects.clearAllSideEffects();
+    sideEffects.setChangesIndex();
   }
   String toString() => 'index assign operator';
   accept(HVisitor visitor) => visitor.visitIndexAssign(this);
@@ -2305,7 +2243,7 @@
     // TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the
     // concats bunched with stringified inputs for much better looking code with
     // fewer temps.
-    setDependsOnSomething();
+    sideEffects.setDependsOnSomething();
     instructionType = HType.STRING;
   }
 
@@ -2323,8 +2261,8 @@
 class HStringify extends HInstruction {
   final Node node;
   HStringify(HInstruction input, this.node) : super(<HInstruction>[input]) {
-    setAllSideEffects();
-    setDependsOnSomething();
+    sideEffects.setAllSideEffects();
+    sideEffects.setDependsOnSomething();
     instructionType = HType.STRING;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index e5d7981..98b2725 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -1003,7 +1003,7 @@
   SsaDeadCodeEliminator();
 
   bool isDeadCode(HInstruction instruction) {
-    return !instruction.hasSideEffects()
+    return !instruction.sideEffects.hasSideEffects()
            && !instruction.canThrow()
            && instruction.usedBy.isEmpty
            && instruction is !HTypeGuard
@@ -1168,13 +1168,13 @@
                                       int changesFlags) {
     assert(block.parentLoopHeader == loopHeader);
     HBasicBlock preheader = loopHeader.predecessors[0];
-    int dependsFlags = HInstruction.computeDependsOnFlags(changesFlags);
+    int dependsFlags = SideEffects.computeDependsOnFlags(changesFlags);
     HInstruction instruction = block.first;
     while (instruction != null) {
       HInstruction next = instruction.next;
       if (instruction.useGvn()
           && (instruction is !HCheck)
-          && (instruction.flags & dependsFlags) == 0) {
+          && !instruction.sideEffects.dependsOn(dependsFlags)) {
         bool loopInvariantInputs = true;
         List<HInstruction> inputs = instruction.inputs;
         for (int i = 0, length = inputs.length; i < length; i++) {
@@ -1192,9 +1192,9 @@
         }
       }
       int oldChangesFlags = changesFlags;
-      changesFlags |= instruction.getChangesFlags();
+      changesFlags |= instruction.sideEffects.getChangesFlags();
       if (oldChangesFlags != changesFlags) {
-        dependsFlags = HInstruction.computeDependsOnFlags(changesFlags);
+        dependsFlags = SideEffects.computeDependsOnFlags(changesFlags);
       }
       instruction = next;
     }
@@ -1213,7 +1213,7 @@
     }
     while (instruction != null) {
       HInstruction next = instruction.next;
-      int flags = instruction.getChangesFlags();
+      int flags = instruction.sideEffects.getChangesFlags();
       assert(flags == 0 || !instruction.useGvn());
       values.kill(flags);
       if (instruction.useGvn()) {
@@ -1268,7 +1268,7 @@
       int changesFlags = 0;
       HInstruction instruction = block.first;
       while (instruction != null) {
-        changesFlags |= instruction.getChangesFlags();
+        changesFlags |= instruction.sideEffects.getChangesFlags();
         instruction = instruction.next;
       }
       assert(blockChangesFlags[id] == null);
@@ -1379,8 +1379,8 @@
     HInstruction instruction = block.first;
     int flags = 0;
     while (instruction != null) {
-      int dependsFlags = HInstruction.computeDependsOnFlags(flags);
-      flags |= instruction.getChangesFlags();
+      int dependsFlags = SideEffects.computeDependsOnFlags(flags);
+      flags |= instruction.sideEffects.getChangesFlags();
 
       HInstruction current = instruction;
       instruction = instruction.next;
@@ -1389,7 +1389,7 @@
       // not have flags to express 'Gvn'able', but not movable.
       if (current is HCheck) continue;
       if (!current.useGvn()) continue;
-      if ((current.flags & dependsFlags) != 0) continue;
+      if (current.sideEffects.dependsOn(dependsFlags)) continue;
 
       bool canBeMoved = true;
       for (final HInstruction input in current.inputs) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index 13de8b6..fe79732 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -8,7 +8,7 @@
 
 import '../closure.dart';
 import '../js/js.dart' as js;
-import '../dart2jslib.dart' hide Selector;
+import '../dart2jslib.dart' hide Selector, TypedSelector;
 import '../dart_types.dart';
 import '../source_file.dart';
 import '../source_map_builder.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index 76415a6..740d0f9 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -81,8 +81,8 @@
          instruction = instruction.next) {
       int bci = 0;
       int uses = instruction.usedBy.length;
-      String changes = instruction.hasSideEffects() ? '!' : ' ';
-      String depends = instruction.dependsOnSomething() ? '?' : '';
+      String changes = instruction.sideEffects.hasSideEffects() ? '!' : ' ';
+      String depends = instruction.sideEffects.dependsOnSomething() ? '?' : '';
       addIndent();
       String temporaryId = stringifier.temporaryId(instruction);
       String instructionString = stringifier.visit(instruction);
@@ -368,7 +368,7 @@
   }
 
   String visitForeign(HForeign foreign) {
-    return visitGenericInvoke("Foreign", "${foreign.code}", foreign.inputs);
+    return visitGenericInvoke("Foreign", "${foreign.codeAst}", foreign.inputs);
   }
 
   String visitForeignNew(HForeignNew node) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index da6ad83..20a0b64 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -18,43 +18,37 @@
       return isNullable ? HType.NULL : HType.CONFLICTING;
     }
 
-    Element element = mask.base.element;
-    JavaScriptBackend backend = compiler.backend;
-    if (element == compiler.intClass || element == backend.jsIntClass) {
+    if (mask.containsOnlyInt(compiler)) {
       return isNullable ? HType.INTEGER_OR_NULL : HType.INTEGER;
-    } else if (element == compiler.numClass
-               || element == backend.jsNumberClass) {
-      return isNullable ? HType.NUMBER_OR_NULL : HType.NUMBER;
-    } else if (element == compiler.doubleClass
-               || element == backend.jsDoubleClass) {
+    } else if (mask.containsOnlyDouble(compiler)) {
       return isNullable ? HType.DOUBLE_OR_NULL : HType.DOUBLE;
-    } else if (element == compiler.stringClass
-               || element == backend.jsStringClass) {
+    } else if (mask.containsOnlyNum(compiler)) {
+      return isNullable ? HType.NUMBER_OR_NULL : HType.NUMBER;
+    } else if (mask.containsOnlyString(compiler)) {
       return isNullable ? HType.STRING_OR_NULL : HType.STRING;
-    } else if (element == compiler.boolClass
-               || element == backend.jsBoolClass) {
+    } else if (mask.containsOnlyBool(compiler)) {
       return isNullable ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
-    } else if (element == compiler.nullClass
-               || element == backend.jsNullClass) {
+    } else if (mask.containsOnlyNull(compiler)) {
       return HType.NULL;
     }
 
     // TODO(kasperl): A lot of the code in the system currently
     // expects the top type to be 'unknown'. I'll rework this.
-    if (element == compiler.objectClass || element == compiler.dynamicClass) {
+    if (mask.containsAll(compiler)) {
       return isNullable ? HType.UNKNOWN : HType.NON_NULL;
     }
 
+    JavaScriptBackend backend = compiler.backend;
     if (!isNullable) {
-      if (element == backend.jsIndexableClass) {
+      if (mask.containsOnly(backend.jsIndexableClass)) {
         return HType.INDEXABLE_PRIMITIVE;
-      } else if (element == backend.jsArrayClass) {
+      } else if (mask.containsOnly(backend.jsArrayClass)) {
         return HType.READABLE_ARRAY;
-      } else if (element == backend.jsMutableArrayClass) {
+      } else if (mask.containsOnly(backend.jsMutableArrayClass)) {
         return HType.MUTABLE_ARRAY;
-      } else if (element == backend.jsFixedArrayClass) {
+      } else if (mask.containsOnly(backend.jsFixedArrayClass)) {
         return HType.FIXED_ARRAY;
-      } else if (element == backend.jsExtendableArrayClass) {
+      } else if (mask.containsOnly(backend.jsExtendableArrayClass)) {
         return HType.EXTENDABLE_ARRAY;
       }
     }
@@ -144,6 +138,8 @@
       return HType.NULL;
     } else if (type.element == compiler.nullClass) {
       return HType.NULL;
+    } else if (type.isDynamic) {
+      return HType.UNKNOWN;
     } else if (compiler.world.hasAnySubtype(type.element)) {
       return new HType.nonNullSubtype(type, compiler);
     } else if (compiler.world.hasAnySubclass(type.element)) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index eced1c4..5e1eb2a 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -129,6 +129,14 @@
     HType receiverType = instruction.getDartReceiver(compiler).instructionType;
     Selector refined = receiverType.refine(instruction.selector, compiler);
     HType type = new HType.inferredTypeForSelector(refined, compiler);
+    // TODO(ngeoffray): Because we don't know yet the side effects of
+    // a JS call, we sometimes know more in the compiler about the
+    // side effects of an element (for example operator% on the int
+    // class). We should remove this check once we analyze JS calls.
+    if (!instruction.useGvn()) {
+      instruction.sideEffects =
+          compiler.world.getSideEffectsOfSelector(refined);
+    }
     if (type.isUseful()) return type;
     return instruction.specializer.computeTypeFromInputTypes(
         instruction, compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
index eae106e..092a99c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
@@ -692,7 +692,6 @@
     // narrows it. Use that new range for this instruction as well.
     Range newIndexRange = indexRange.intersection(
         info.newNormalizedRange(info.intZero, maxIndex));
-    return newIndexRange;
     if (indexRange == newIndexRange) return indexRange;
     // Explicitly attach the range information to the index instruction,
     // which may be used by other instructions.  Returning the new range will
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/value_set.dart b/sdk/lib/_internal/compiler/implementation/ssa/value_set.dart
index b68e688..07681b6 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_set.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_set.dart
@@ -50,11 +50,11 @@
 
   void kill(int flags) {
     if (flags == 0) return;
-    int depends = HInstruction.computeDependsOnFlags(flags);
+    int depends = SideEffects.computeDependsOnFlags(flags);
     // Kill in the hash table.
     for (int index = 0, length = table.length; index < length; index++) {
       HInstruction instruction = table[index];
-      if (instruction != null && (instruction.flags & depends) != 0) {
+      if (instruction != null && instruction.sideEffects.dependsOn(depends)) {
         table[index] = null;
         size--;
       }
@@ -65,7 +65,7 @@
     while (current != null) {
       ValueSetNode next = current.next;
       HInstruction cached = current.value;
-      if ((cached.flags & depends) != 0) {
+      if (cached.sideEffects.dependsOn(depends)) {
         if (previous == null) {
           collisions = next;
         } else {
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 b346692..68e22f1 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -833,6 +833,8 @@
       if (element != null) {
         if (element == compiler.numClass) {
           return new TypeMask.nonNullSubclass(compiler.numClass.rawType);
+        } else if (element == compiler.dynamicClass) {
+          return new TypeMask.nonNullSubclass(compiler.objectClass.rawType);
         } else {
           return new TypeMask.nonNullExact(element.rawType);
         }
@@ -939,7 +941,7 @@
     }
 
     if (selector != null && receiverType != null) {
-      TypeMask receiverMask = new TypeMask.exact(receiverType.rawType);
+      TypeMask receiverMask = new TypeMask.nonNullExact(receiverType.rawType);
       TypeMask resultMask = concreteTypeToTypeMask(result);
       augmentInferredSelectorType(selector, receiverMask, resultMask);
     }
@@ -2035,6 +2037,8 @@
       return returnType.isEmpty()
           ? returnType
           : inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
+    } else if (name.stringValue == '&&' || name.stringValue == '||'){
+      return inferrer.singletonConcreteType(inferrer.baseTypes.boolBaseType);
     } else {
       return analyzeDynamicSend(elements.getSelector(node),
                                 receiverType, name, argumentsTypes);
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index d4fdd13..39fecf2 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -12,13 +12,13 @@
 import '../native_handler.dart' as native;
 import '../tree/tree.dart';
 import '../util/util.dart' show Link;
-import 'types.dart' show TypesInferrer, TypeMask;
+import 'types.dart' show TypesInferrer, FlatTypeMask, TypeMask;
 
 // BUG(8802): There's a bug in the analyzer that makes the re-export
 // of Selector from dart2jslib.dart fail. For now, we work around that
 // by importing universe.dart explicitly and disabling the re-export.
-import '../dart2jslib.dart' hide Selector;
-import '../universe/universe.dart' show Selector, TypedSelector;
+import '../dart2jslib.dart' hide Selector, TypedSelector;
+import '../universe/universe.dart' show Selector, SideEffects, TypedSelector;
 
 /**
  * A work queue that ensures there are no duplicates, and adds and
@@ -100,7 +100,7 @@
  * A sentinel type mask class used by the inferrer for the give up
  * type, and the dynamic type.
  */
-class SentinelTypeMask extends TypeMask {
+class SentinelTypeMask extends FlatTypeMask {
   final String name;
 
   SentinelTypeMask(this.name) : super(null, 0, false);
@@ -261,7 +261,7 @@
    * Sentinel used by the inferrer to notify that it does not know
    * the type of a specific element.
    */
-  final TypeMask dynamicType = new SentinelTypeMask('dynamic');
+  TypeMask dynamicType = new SentinelTypeMask('dynamic');
   bool isDynamicType(TypeMask type) => identical(type, dynamicType);
 
   TypeMask nullType;
@@ -712,6 +712,8 @@
         mappedType = nullType;
       } else if (type.isVoid) {
         mappedType = nullType;
+      } else if (type.isDynamic) {
+        return dynamicType;
       } else if (compiler.world.hasAnySubclass(type.element)) {
         mappedType = new TypeMask.nonNullSubclass(rawTypeOf(type.element));
       } else if (compiler.world.hasAnySubtype(type.element)) {
@@ -817,6 +819,31 @@
     return existing != arguments;
   }
 
+  void updateSideEffects(SideEffects sideEffects,
+                         Selector selector,
+                         Element callee) {
+    if (callee.isField()) {
+      if (callee.isInstanceMember()) {
+        if (selector.isSetter()) {
+          sideEffects.setChangesInstanceProperty();
+        } else if (selector.isGetter()) {
+          sideEffects.setDependsOnInstancePropertyStore();
+        }
+      } else {
+        if (selector.isSetter()) {
+          sideEffects.setChangesStaticProperty();
+        } else if (selector.isGetter()) {
+          sideEffects.setDependsOnStaticPropertyStore();
+        }
+      }
+    } else if (callee.isGetter() && !selector.isGetter()) {
+      sideEffects.setAllSideEffects();
+      sideEffects.setDependsOnSomething();
+    } else {
+      sideEffects.add(compiler.world.getSideEffectsOfElement(callee));
+    }
+  }
+
   /**
    * Registers that [caller] calls [callee] with the given
    * [arguments]. [constraint] is a setter constraint (see
@@ -828,6 +855,7 @@
                              Element callee,
                              ArgumentsTypes arguments,
                              Selector constraint,
+                             SideEffects sideEffects,
                              bool inLoop) {
     // Bailout for closure calls. We're not tracking types of
     // arguments for closures.
@@ -847,6 +875,7 @@
       }
     }
 
+    updateSideEffects(sideEffects, selector, callee);
     assert(isNotClosure(caller));
     callee = callee.implementation;
     if (!analyzeCount.containsKey(caller)) {
@@ -1011,6 +1040,7 @@
                                   Element caller,
                                   ArgumentsTypes arguments,
                                   Selector constraint,
+                                  SideEffects sideEffects,
                                   bool inLoop) {
     TypeMask result;
     iterateOverElements(selector.asUntyped, (Element element) {
@@ -1018,7 +1048,7 @@
       if (isTargetFor(receiverType, selector, element)) {
         registerCalledElement(
             node, selector, caller, element, arguments,
-            constraint, inLoop);
+            constraint, sideEffects, inLoop);
 
         if (!selector.isSetter()) {
           TypeMask type = handleIntrisifiedSelector(selector, arguments);
@@ -1378,6 +1408,7 @@
   bool visitingInitializers = false;
   bool isConstructorRedirect = false;
   int loopLevel = 0;
+  SideEffects sideEffects = new SideEffects.empty();
 
   bool get inLoop => loopLevel > 0;
   bool get isThisExposed => locals.isThisExposed;
@@ -1528,6 +1559,7 @@
       });
       // TODO(ngeoffray): Re-analyze method if [changed]?
     }
+    compiler.world.registerSideEffects(analyzedElement, sideEffects);    
     return returnType;
   }
 
@@ -1936,6 +1968,8 @@
   }
 
   TypeMask handleForeignSend(Send node) {
+    // TODO(ngeoffray): Analyze JS expressions.
+    sideEffects.setAllSideEffects();    
     node.visitChildren(this);
     Selector selector = elements.getSelector(node);
     SourceString name = selector.name;
@@ -2053,7 +2087,8 @@
                         ArgumentsTypes arguments) {
     if (Elements.isUnresolved(element)) return;
     inferrer.registerCalledElement(
-        node, selector, outermostElement, element, arguments, null, inLoop);
+        node, selector, outermostElement, element, arguments, null,
+        sideEffects, inLoop);
   }
 
   void updateSelectorInTree(Node node, Selector selector) {
@@ -2085,7 +2120,7 @@
     }
     return inferrer.registerCalledSelector(
         node, selector, receiver, outermostElement, arguments,
-        constraint, inLoop);
+        constraint, sideEffects, inLoop);
   }
 
   TypeMask visitDynamicSend(Send node) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 8e7843d..df459be 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -4,12 +4,104 @@
 
 part of types;
 
+abstract class TypeMask {
+  factory TypeMask(DartType base, int kind, bool isNullable)
+      => new FlatTypeMask(base, kind, isNullable);
+
+  factory TypeMask.empty() => new FlatTypeMask.empty();
+
+  factory TypeMask.exact(DartType base) => new FlatTypeMask.exact(base);
+  factory TypeMask.subclass(DartType base) => new FlatTypeMask.subclass(base);
+  factory TypeMask.subtype(DartType base) => new FlatTypeMask.subtype(base);
+
+  factory TypeMask.nonNullEmpty()
+      => new FlatTypeMask.nonNullEmpty();
+  factory TypeMask.nonNullExact(DartType base)
+      => new FlatTypeMask.nonNullExact(base);
+  factory TypeMask.nonNullSubclass(DartType base)
+      => new FlatTypeMask.nonNullSubclass(base);
+  factory TypeMask.nonNullSubtype(DartType base)
+      => new FlatTypeMask.nonNullSubtype(base);
+
+  /**
+   * Returns a nullable variant of [this] type mask.
+   */
+  TypeMask nullable();
+
+  /**
+   * Returns a non-nullable variant of [this] type mask.
+   */
+  TypeMask nonNullable();
+
+  bool get isEmpty;
+  bool get isNullable;
+  bool get isExact;
+
+  bool containsOnlyInt(Compiler compiler);
+  bool containsOnlyDouble(Compiler compiler);
+  bool containsOnlyNum(Compiler compiler);
+  bool containsOnlyNull(Compiler compiler);
+  bool containsOnlyBool(Compiler compiler);
+  bool containsOnlyString(Compiler compiler);
+  bool containsOnly(ClassElement element);
+
+  /**
+   * Returns whether or not this type mask contains the given type.
+   */
+  bool contains(DartType type, Compiler compiler);
+
+  /**
+   * Returns whether or not this type mask contains all types.
+   */
+  bool containsAll(Compiler compiler);
+
+  /**
+   * Returns the [ClassElement] if this type represents a single class,
+   * otherwise returns `null`.  This method is conservative.
+   */
+  ClassElement singleClass(Compiler compiler);
+
+  /**
+   * Returns the set of classes this type mask can be.
+   */
+  Set<ClassElement> containedClasses(Compiler compiler);
+
+  /**
+   * Returns a type mask representing the union of [this] and [other].
+   */
+  TypeMask union(TypeMask other, Compiler compiler);
+
+  /**
+   * Returns a type mask representing the intersection of [this] and [other].
+   */
+  TypeMask intersection(TypeMask other, Compiler compiler);
+
+  /**
+   * Returns whether a [selector] call will hit a method at runtime,
+   * and not go through [noSuchMethod].
+   */
+  bool willHit(Selector selector, Compiler compiler);
+
+  /**
+   * Returns whether [element] is a potential target when being
+   * invoked on this type mask. [selector] is used to ensure library
+   * privacy is taken into account.
+   */
+  bool canHit(Element element, Selector selector, Compiler compiler);
+
+  /**
+   * Returns the [element] that is known to always be hit at runtime
+   * on this mask. Returns null if there is none.
+   */
+  Element locateSingleElement(Selector selector, Compiler compiler);
+}
+
 /**
  * A type mask represents a set of contained classes, but the
  * operations on it are not guaranteed to be precise and they may
  * yield conservative answers that contain too many classes.
  */
-class TypeMask {
+class FlatTypeMask implements TypeMask {
 
   static const int EMPTY    = 0;
   static const int EXACT    = 1;
@@ -19,29 +111,31 @@
   final DartType base;
   final int flags;
 
-  TypeMask(DartType base, int kind, bool isNullable)
+  FlatTypeMask(DartType base, int kind, bool isNullable)
       : this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
 
-  TypeMask.empty()
+  FlatTypeMask.empty()
       : this.internal(null, (EMPTY << 1) | 1);
-  TypeMask.exact(DartType base)
+  FlatTypeMask.exact(DartType base)
       : this.internal(base, (EXACT << 1) | 1);
-  TypeMask.subclass(DartType base)
+  FlatTypeMask.subclass(DartType base)
       : this.internal(base, (SUBCLASS << 1) | 1);
-  TypeMask.subtype(DartType base)
+  FlatTypeMask.subtype(DartType base)
       : this.internal(base, (SUBTYPE << 1) | 1);
 
-  TypeMask.nonNullEmpty()
+  FlatTypeMask.nonNullEmpty()
       : this.internal(null, EMPTY << 1);
-  TypeMask.nonNullExact(DartType base)
+  FlatTypeMask.nonNullExact(DartType base)
       : this.internal(base, EXACT << 1);
-  TypeMask.nonNullSubclass(DartType base)
+  FlatTypeMask.nonNullSubclass(DartType base)
       : this.internal(base, SUBCLASS << 1);
-  TypeMask.nonNullSubtype(DartType base)
+  FlatTypeMask.nonNullSubtype(DartType base)
       : this.internal(base, SUBTYPE << 1);
 
-  TypeMask.internal(DartType base, this.flags)
-      : this.base = transformBase(base);
+  FlatTypeMask.internal(DartType base, this.flags)
+      : this.base = transformBase(base) {
+    assert(base == null || !(isExact && base.isDynamic));
+  }
 
   // TODO(kasperl): We temporarily transform the base to be the raw
   // variant of the type. Long term, we're going to keep the class
@@ -68,25 +162,14 @@
   bool get isSubclass => (flags >> 1) == SUBCLASS;
   bool get isSubtype => (flags >> 1) == SUBTYPE;
 
-  DartType get exactType => isExact ? base : null;
-
-  /**
-   * Returns a nullable variant of [this] type mask.
-   */
   TypeMask nullable() {
-    return isNullable ? this : new TypeMask.internal(base, flags | 1);
+    return isNullable ? this : new FlatTypeMask.internal(base, flags | 1);
   }
 
-  /**
-   * Returns a non-nullable variant of [this] type mask.
-   */
   TypeMask nonNullable() {
-    return isNullable ? new TypeMask.internal(base, flags & ~1) : this;
+    return isNullable ? new FlatTypeMask.internal(base, flags & ~1) : this;
   }
 
-  /**
-   * Returns whether or not this type mask contains the given type.
-   */
   bool contains(DartType type, Compiler compiler) {
     if (isEmpty) {
       return false;
@@ -102,6 +185,40 @@
     }
   }
 
+  bool containsOnlyInt(Compiler compiler) {
+    return base.element == compiler.intClass
+        || base.element == compiler.backend.intImplementation;
+  }
+
+  bool containsOnlyDouble(Compiler compiler) {
+    return base.element == compiler.doubleClass
+        || base.element == compiler.backend.doubleImplementation;
+  }
+
+  bool containsOnlyNum(Compiler compiler) {
+    return base.element == compiler.numClass
+        || base.element == compiler.backend.numImplementation;
+  }
+
+  bool containsOnlyNull(Compiler compiler) {
+    return base.element == compiler.nullClass
+        || base.element == compiler.backend.nullImplementation;
+  }
+
+  bool containsOnlyBool(Compiler compiler) {
+    return base.element == compiler.boolClass
+        || base.element == compiler.backend.boolImplementation;
+  }
+
+  bool containsOnlyString(Compiler compiler) {
+    return base.element == compiler.stringClass
+        || base.element == compiler.backend.stringImplementation;
+  }
+
+  bool containsOnly(ClassElement cls) {
+    return base.element == cls;
+  }
+
   /**
    * Returns the [ClassElement] if this type represents a single class,
    * otherwise returns `null`.  This method is conservative.
@@ -129,7 +246,7 @@
         || identical(base.element, compiler.dynamicClass);
   }
 
-  TypeMask union(TypeMask other, Compiler compiler) {
+  TypeMask union(FlatTypeMask other, Compiler compiler) {
     if (isEmpty) {
       return isNullable ? other.nullable() : other;
     } else if (other.isEmpty) {
@@ -149,7 +266,7 @@
     }
   }
 
-  TypeMask unionSame(TypeMask other, Compiler compiler) {
+  TypeMask unionSame(FlatTypeMask other, Compiler compiler) {
     assert(base == other.base);
     // The two masks share the base type, so we must chose the least
     // constraining kind (the highest) of the two. If either one of
@@ -162,11 +279,11 @@
     } else if (other.flags == combined) {
       return other;
     } else {
-      return new TypeMask.internal(base, combined);
+      return new FlatTypeMask.internal(base, combined);
     }
   }
 
-  TypeMask unionSubclass(TypeMask other, Compiler compiler) {
+  TypeMask unionSubclass(FlatTypeMask other, Compiler compiler) {
     assert(isSubclassOf(other.base, base, compiler));
     int combined;
     if (isExact && other.isExact) {
@@ -183,22 +300,22 @@
           : other.flags | (flags & 1);
     }
     return (flags != combined)
-        ? new TypeMask.internal(base, combined)
+        ? new FlatTypeMask.internal(base, combined)
         : this;
   }
 
-  TypeMask unionSubtype(TypeMask other, Compiler compiler) {
+  TypeMask unionSubtype(FlatTypeMask other, Compiler compiler) {
     assert(isSubtypeOf(other.base, base, compiler));
     // Since the other mask is a subtype of this mask, we need the
     // resulting union to be a subtype too. If either one of the masks
     // are nullable the result should be nullable too.
     int combined = (SUBTYPE << 1) | ((flags | other.flags) & 1);
     return (flags != combined)
-        ? new TypeMask.internal(base, combined)
+        ? new FlatTypeMask.internal(base, combined)
         : this;
   }
 
-  TypeMask unionDisjoint(TypeMask other, Compiler compiler) {
+  TypeMask unionDisjoint(FlatTypeMask other, Compiler compiler) {
     assert(base != other.base);
     assert(!isSubtypeOf(base, other.base, compiler));
     assert(!isSubtypeOf(other.base, base, compiler));
@@ -253,7 +370,7 @@
                         isNullable || other.isNullable);
   }
 
-  TypeMask intersection(TypeMask other, Compiler compiler) {
+  TypeMask intersection(FlatTypeMask other, Compiler compiler) {
     if (isEmpty) {
       return other.isNullable ? this : nonNullable();
     } else if (other.isEmpty) {
@@ -273,7 +390,7 @@
     }
   }
 
-  TypeMask intersectionSame(TypeMask other, Compiler compiler) {
+  TypeMask intersectionSame(FlatTypeMask other, Compiler compiler) {
     assert(base == other.base);
     // The two masks share the base type, so we must chose the most
     // constraining kind (the lowest) of the two. Only if both masks
@@ -286,11 +403,11 @@
     } else if (other.flags == combined) {
       return other;
     } else {
-      return new TypeMask.internal(base, combined);
+      return new FlatTypeMask.internal(base, combined);
     }
   }
 
-  TypeMask intersectionSubclass(TypeMask other, Compiler compiler) {
+  TypeMask intersectionSubclass(FlatTypeMask other, Compiler compiler) {
     assert(isSubclassOf(other.base, base, compiler));
     // If this mask isn't at least a subclass mask, then the
     // intersection with the other mask is empty.
@@ -302,11 +419,11 @@
     if (other.flags == combined) {
       return other;
     } else {
-      return new TypeMask.internal(other.base, combined);
+      return new FlatTypeMask.internal(other.base, combined);
     }
   }
 
-  TypeMask intersectionSubtype(TypeMask other, Compiler compiler) {
+  TypeMask intersectionSubtype(FlatTypeMask other, Compiler compiler) {
     assert(isSubtypeOf(other.base, base, compiler));
     // If this mask isn't a subtype mask, then the intersection with
     // the other mask is empty.
@@ -318,11 +435,11 @@
     if (other.flags == combined) {
       return other;
     } else {
-      return new TypeMask.internal(other.base, combined);
+      return new FlatTypeMask.internal(other.base, combined);
     }
   }
 
-  TypeMask intersectionDisjoint(TypeMask other, Compiler compiler) {
+  TypeMask intersectionDisjoint(FlatTypeMask other, Compiler compiler) {
     assert(base != other.base);
     assert(!isSubtypeOf(base, other.base, compiler));
     assert(!isSubtypeOf(other.base, base, compiler));
@@ -358,13 +475,13 @@
     int combined = (kind << 1) | (flags & other.flags & 1);
     TypeMask result;
     for (ClassElement each in candidates) {
-      TypeMask mask = new TypeMask.internal(each.rawType, combined);
+      TypeMask mask = new FlatTypeMask.internal(each.rawType, combined);
       result = (result == null) ? mask : result.union(mask, compiler);
     }
     return result;
   }
 
-  TypeMask intersectionEmpty(TypeMask other) {
+  TypeMask intersectionEmpty(FlatTypeMask other) {
     return new TypeMask(null, EMPTY, isNullable && other.isNullable);
   }
 
@@ -451,9 +568,13 @@
                                Selector selector,
                                Compiler compiler) {
     Element element = findMatchIn(cls, selector);
-    return element != null
-        && !element.isAbstract(compiler)
-        && selector.appliesUntyped(element, compiler);
+    if (element == null) return false;
+
+    if (element.isAbstract(compiler)) {
+      ClassElement enclosingClass = element.getEnclosingClass();
+      return hasConcreteMatch(enclosingClass.superclass, selector, compiler);
+    }
+    return selector.appliesUntyped(element, compiler);
   }
 
   /**
@@ -491,9 +612,23 @@
            });
   }
 
+  Element locateSingleElement(Selector selector, Compiler compiler) {
+    if (isEmpty) return null;
+    Iterable<Element> targets = compiler.world.allFunctions.filter(selector);
+    if (targets.length != 1) return null;
+    Element result = targets.first;
+    ClassElement enclosing = result.getEnclosingClass();
+    // We only return the found element if it is guaranteed to be
+    // implemented on the exact receiver type. It could be found in a
+    // subclass or in an inheritance-wise unrelated class in case of
+    // subtype selectors.
+    ClassElement cls = base.element;
+    return (cls.isSubclassOf(enclosing)) ? result : null;
+  }
+
   bool operator ==(var other) {
-    if (other is !TypeMask) return false;
-    TypeMask otherMask = other;
+    if (other is !FlatTypeMask) return false;
+    FlatTypeMask otherMask = other;
     return (flags == otherMask.flags) && (base == otherMask.base);
   }
 
@@ -526,7 +661,8 @@
     return (subtypes != null) ? subtypes.contains(xElement) : false;
   }
 
-  static Set<ClassElement> commonContainedClasses(TypeMask x, TypeMask y,
+  static Set<ClassElement> commonContainedClasses(FlatTypeMask x,
+                                                  FlatTypeMask y,
                                                   Compiler compiler) {
     Set<ClassElement> xSubset = x.containedClasses(compiler);
     if (xSubset == null) return null;
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index cd778f6..dee04af 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -6,7 +6,7 @@
 
 import 'dart:collection' show Queue, IterableBase;
 
-import '../dart2jslib.dart' hide Selector;
+import '../dart2jslib.dart' hide Selector, TypedSelector;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../tree/tree.dart';
 import '../elements/elements.dart';
@@ -89,11 +89,14 @@
    * exactness, subclassing, subtyping and nullability. The [element] parameter
    * is for debugging purposes only and can be omitted.
    */
-  TypeMask best(TypeMask type1, TypeMask type2, [element]) {
+  TypeMask best(var type1, var type2, [element]) {
     final result = _best(type1, type2);
-    similar() {
-      if (type1 == null) return type2 == null;
-      if (type2 == null) return false;
+    // Tests type1 and type2 for equality modulo normalization of native types.
+    // Only called when DUMP_SURPRISING_RESULTS is true.
+    bool similar() {
+      if (type1 == null || type2 == null || type1.isEmpty || type2.isEmpty) {
+        return type1 == type2;
+      }
       return same(type1.base, type2.base);
     }
     if (DUMP_SURPRISING_RESULTS && result == type1 && !similar()) {
@@ -103,7 +106,7 @@
   }
 
   /// Helper method for [best].
-  TypeMask _best(TypeMask type1, TypeMask type2) {
+  TypeMask _best(var type1, var type2) {
     if (type1 == null) return type2;
     if (type2 == null) return type1;
     if (type1.isExact) {
diff --git a/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart b/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart
new file mode 100644
index 0000000..1e27efa
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart
@@ -0,0 +1,108 @@
+// 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 universe;
+
+class SideEffects {
+  // Changes flags.
+  static const int FLAG_CHANGES_INDEX = 0;
+  static const int FLAG_CHANGES_INSTANCE_PROPERTY = FLAG_CHANGES_INDEX + 1;
+  static const int FLAG_CHANGES_STATIC_PROPERTY
+      = FLAG_CHANGES_INSTANCE_PROPERTY + 1;
+  static const int FLAG_CHANGES_COUNT = FLAG_CHANGES_STATIC_PROPERTY + 1;
+
+  // Depends flags (one for each changes flag).
+  static const int FLAG_DEPENDS_ON_INDEX_STORE = FLAG_CHANGES_COUNT;
+  static const int FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE =
+      FLAG_DEPENDS_ON_INDEX_STORE + 1;
+  static const int FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE =
+      FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE + 1;
+  static const int FLAG_DEPENDS_ON_COUNT =
+      FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE + 1;
+
+  int flags = 0;
+
+  SideEffects() {
+    setAllSideEffects();
+    setDependsOnSomething();
+  }
+
+  SideEffects.empty();
+
+  bool operator==(other) => flags == other.flags;
+
+  bool getFlag(int position) => (flags & (1 << position)) != 0;
+  void setFlag(int position) { flags |= (1 << position); }
+  void clearFlag(int position) { flags &= ~(1 << position); }
+
+  int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1);
+  int getDependsOnFlags() {
+    return (flags & ((1 << FLAG_DEPENDS_ON_COUNT) - 1)) >> FLAG_CHANGES_COUNT;
+  }
+
+  bool hasSideEffects() => getChangesFlags() != 0;
+  bool dependsOnSomething() => getDependsOnFlags() != 0;
+
+  void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); }
+  bool hasAllSideEffects() {
+    return getChangesFlags() == (1 << FLAG_CHANGES_COUNT) - 1;
+  }
+  void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); }
+
+  void setDependsOnSomething() {
+    int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
+    flags |= (((1 << count) - 1) << FLAG_CHANGES_COUNT);
+  }
+  void clearAllDependencies() {
+    int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
+    flags &= ~(((1 << count) - 1) << FLAG_CHANGES_COUNT);
+  }
+
+  bool dependsOnStaticPropertyStore() {
+    return getFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
+  }
+  void setDependsOnStaticPropertyStore() {
+    setFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
+  }
+  void setChangesStaticProperty() { setFlag(FLAG_CHANGES_STATIC_PROPERTY); }
+  bool changesStaticProperty() => getFlag(FLAG_CHANGES_STATIC_PROPERTY);
+
+  bool dependsOnIndexStore() => getFlag(FLAG_DEPENDS_ON_INDEX_STORE);
+  void setDependsOnIndexStore() { setFlag(FLAG_DEPENDS_ON_INDEX_STORE); }
+  void setChangesIndex() { setFlag(FLAG_CHANGES_INDEX); }
+  bool changesIndex() => getFlag(FLAG_CHANGES_INDEX);
+
+  bool dependsOnInstancePropertyStore() {
+    return getFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
+  }
+  void setDependsOnInstancePropertyStore() {
+    setFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
+  }
+  void setChangesInstanceProperty() { setFlag(FLAG_CHANGES_INSTANCE_PROPERTY); }
+  bool changesInstanceProperty() => getFlag(FLAG_CHANGES_INSTANCE_PROPERTY);
+
+  static int computeDependsOnFlags(int flags) => flags << FLAG_CHANGES_COUNT;
+
+  bool dependsOn(int dependsFlags) => (flags & dependsFlags) != 0;
+
+  void add(SideEffects other) {
+    flags |= other.flags;
+  }
+
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write('Depends on');
+    if (dependsOnIndexStore()) buffer.write(' []');
+    if (dependsOnInstancePropertyStore()) buffer.write(' field store');
+    if (dependsOnStaticPropertyStore()) buffer.write(' static store');
+    if (!dependsOnSomething()) buffer.write(' nothing');
+    buffer.write(', Changes');
+    if (changesIndex()) buffer.write(' []');
+    if (changesInstanceProperty()) buffer.write(' field');
+    if (changesStaticProperty()) buffer.write(' static');
+    if (!hasSideEffects()) buffer.write(' nothing');
+    buffer.write('.');
+    return buffer.toString();
+  }
+}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index b1b3cb9..ecead0f 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -16,6 +16,7 @@
 part 'function_set.dart';
 part 'full_function_set.dart';
 part 'selector_map.dart';
+part 'side_effects.dart';
 
 class Universe {
   /**
@@ -422,8 +423,6 @@
               selector.library,
               selector.argumentCount,
               selector.namedArguments) {
-    // Invariant: Typed selector can not be based on a malformed type.
-    assert(mask.isEmpty || !identical(mask.base.kind, TypeKind.MALFORMED_TYPE));
     assert(asUntyped.mask == null);
   }
 
@@ -436,7 +435,6 @@
   TypedSelector.subtype(DartType base, Selector selector)
       : this(new TypeMask.subtype(base), selector);
 
-  bool get hasExactMask => mask.isExact;
 
   bool appliesUnnamed(Element element, Compiler compiler) {
     assert(sameNameHack(element, compiler));
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 2ecc117..f0bd537 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -10,6 +10,7 @@
   final Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses;
   final FullFunctionSet allFunctions;
   final Set<Element> functionsCalledInLoop = new Set<Element>();
+  final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
 
   // We keep track of subtype and subclass relationships in four
   // distinct sets to make class hierarchy analysis faster.
@@ -148,20 +149,10 @@
   }
 
   Element locateSingleElement(Selector selector) {
-    Iterable<Element> targets = allFunctions.filter(selector);
-    if (targets.length != 1) return null;
-    Element result = targets.first;
-    ClassElement enclosing = result.getEnclosingClass();
-    // TODO(kasperl): Move this code to the type mask.
-    ti.TypeMask mask = selector.mask;
-    ClassElement receiverTypeElement = (mask == null || mask.base == null)
-        ? compiler.objectClass
-        : mask.base.element;
-    // We only return the found element if it is guaranteed to be
-    // implemented on the exact receiver type. It could be found in a
-    // subclass or in an inheritance-wise unrelated class in case of
-    // subtype selectors.
-    return (receiverTypeElement.isSubclassOf(enclosing)) ? result : null;
+    ti.TypeMask mask = selector.mask == null
+        ? new ti.TypeMask.subclass(compiler.objectClass.rawType)
+        : selector.mask;
+    return mask.locateSingleElement(selector, compiler);
   }
 
   bool hasSingleMatch(Selector selector) {
@@ -183,10 +174,39 @@
   }
 
   void addFunctionCalledInLoop(Element element) {
-    functionsCalledInLoop.add(element);
+    functionsCalledInLoop.add(element.declaration);
   }
 
   bool isCalledInLoop(Element element) {
-    return functionsCalledInLoop.contains(element);
+    return functionsCalledInLoop.contains(element.declaration);
+  }
+
+  SideEffects getSideEffectsOfElement(Element element) {
+    return sideEffects.putIfAbsent(element.declaration, () {
+      return new SideEffects();
+    });
+  }
+
+  void registerSideEffects(Element element, SideEffects effects) {
+    sideEffects[element.declaration] = effects;
+  }
+
+  SideEffects getSideEffectsOfSelector(Selector selector) {
+    // We're not tracking side effects of closures.
+    if (selector.isClosureCall()) {
+      return new SideEffects();
+    }
+    SideEffects sideEffects = new SideEffects.empty();
+    for (Element e in allFunctions.filter(selector)) {
+      if (e.isField()) {
+        if (selector.isGetter()) {
+          sideEffects.setDependsOnInstancePropertyStore();
+        } else if (selector.isSetter()) {
+          sideEffects.setChangesInstanceProperty();
+        }
+      }
+      sideEffects.add(getSideEffectsOfElement(e));
+    }
+    return sideEffects;
   }
 }
diff --git a/sdk/lib/_internal/compiler/samples/darttags/darttags.dart b/sdk/lib/_internal/compiler/samples/darttags/darttags.dart
new file mode 100644
index 0000000..f600188
--- /dev/null
+++ b/sdk/lib/_internal/compiler/samples/darttags/darttags.dart
@@ -0,0 +1,137 @@
+// 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.
+
+// Usage: Add the following to your .gclient file (found in the parent
+// of the "dart" in a gclient checkout of the Dart repositor).
+//
+// hooks = [
+//   {
+//     "pattern": ".",
+//     "action": [
+//       "dart/sdk/bin/dart",
+//       "dart/sdk/lib/_internal/compiler/samples/darttags/darttags.dart",
+//       "dart/TAGS"
+//     ],
+//   },
+// ]
+//
+// Modify .emacs to contain:
+//
+//      (setq tags-table-list
+//           '("DART_LOCATION/dart"))
+//
+// Where DART_LOCATION is the gclient directory where you found .gclient.
+
+import 'dart:io';
+import 'dart:uri';
+
+// TODO(ahe): Should be dart:mirrors.
+import '../../implementation/mirrors/mirrors.dart';
+
+import '../../../libraries.dart'
+    show LIBRARIES, LibraryInfo;
+
+import '../../implementation/mirrors/dart2js_mirror.dart'
+    show analyze, BackDoor;
+
+import '../../implementation/filenames.dart';
+import '../../implementation/source_file.dart';
+import '../../implementation/source_file_provider.dart';
+import '../../implementation/util/uri_extras.dart';
+
+const DART2JS = '../../implementation/dart2js.dart';
+const DART2JS_MIRROR = '../../implementation/mirrors/dart2js_mirror.dart';
+const SDK_ROOT = '../../../../../';
+
+bool isPublicDart2jsLibrary(String name) {
+  return !name.startsWith('_') && LIBRARIES[name].isDart2jsLibrary;
+}
+
+var handler;
+RandomAccessFile output;
+Uri outputUri;
+
+main() {
+  mainWithOptions(new Options());
+}
+
+mainWithOptions(Options options) {
+  handler = new FormattingDiagnosticHandler()
+      ..throwOnError = true;
+
+  outputUri =
+      handler.provider.cwd.resolve(nativeToUriPath(options.arguments.first));
+  output = new File(options.arguments.first).openSync(mode: FileMode.WRITE);
+
+  Uri myLocation =
+      handler.provider.cwd.resolve(nativeToUriPath(options.script));
+
+  // Get the names of public dart2js libraries.
+  Iterable<String> names = LIBRARIES.keys.where(isPublicDart2jsLibrary);
+
+  // Prepend "dart:" to the names.
+  List<Uri> uris = names.map((String name) => Uri.parse('dart:$name')).toList();
+
+  // Append dart2js itself.
+  uris.add(myLocation.resolve(DART2JS));
+  uris.add(myLocation.resolve(DART2JS_MIRROR));
+
+  analyze(uris, myLocation.resolve(SDK_ROOT), null, handler.provider, handler)
+      .then(processMirrors);
+}
+
+processMirrors(MirrorSystem mirrors) {
+  mirrors.libraries.forEach((_, LibraryMirror library) {
+    BackDoor.compilationUnitsOf(library).forEach(emitTagsForCompilationUnit);
+  });
+
+  output.closeSync();
+}
+
+/**
+ * From http://en.wikipedia.org/wiki/Ctags#Etags_2
+ *
+ * A section starts with a two line header, one line containing a
+ * single <\x0c> character, followed by a line which consists of:
+ *
+ * {src_file},{size_of_tag_definition_data_in_bytes}
+ *
+ * The header is followed by tag definitions, one definition per line,
+ * with the format:
+ *
+ * {tag_definition_text}<\x7f>{tagname}<\x01>{line_number},{byte_offset}
+ */
+emitTagsForCompilationUnit(compilationUnit) {
+  // Certain variables in this method do not follow Dart naming
+  // conventions.  This is because the format as written on Wikipedia
+  // looks very similar to Dart string interpolation that the author
+  // felt it would make sense to keep the names.
+  Uri uri = compilationUnit.uri;
+  var buffer = new StringBuffer();
+  SourceFile file = handler.provider.sourceFiles['$uri'];
+
+  compilationUnit.members.forEach((DeclarationMirror mirror) {
+    var tagname = mirror.simpleName;
+    var byte_offset = mirror.getBeginToken().charOffset;
+    var line_number = file.getLine(byte_offset) + 1;
+
+    var lineStart = file.lineStarts[line_number - 1];
+    // TODO(ahe): Most often an empty string.  Try to see if we can
+    // get the position of the name token instead.
+    var tag_definition_text = file.text.substring(lineStart, byte_offset);
+
+    // One definition.
+    buffer.write('${tag_definition_text}\x7f${tagname}'
+                 '\x01${line_number},${byte_offset}\n');
+  });
+
+  var tag_definition_data = '$buffer';
+  var src_file = relativize(outputUri, uri, false);
+  var size_of_tag_definition_data_in_bytes = tag_definition_data.length;
+
+  // The header.
+  output.writeStringSync(
+      '\x0c\n${src_file},${size_of_tag_definition_data_in_bytes}\n');
+  output.writeStringSync(tag_definition_data);
+}
diff --git a/sdk/lib/_internal/pub/lib/src/oauth2.dart b/sdk/lib/_internal/pub/lib/src/oauth2.dart
index e4b8ee0..56b1494 100644
--- a/sdk/lib/_internal/pub/lib/src/oauth2.dart
+++ b/sdk/lib/_internal/pub/lib/src/oauth2.dart
@@ -169,7 +169,7 @@
   // Spin up a one-shot HTTP server to receive the authorization code from the
   // Google OAuth2 server via redirect. This server will close itself as soon as
   // the code is received.
-  return SafeHttpServer.bind('127.0.0.1', 0).then((server) {
+  return SafeHttpServer.bind('localhost', 0).then((server) {
     var authUrl = grant.getAuthorizationUrl(
         Uri.parse('http://localhost:${server.port}'), scopes: _scopes);
 
diff --git a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
index b6e1c83..25d57ee 100644
--- a/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
+++ b/sdk/lib/_internal/pub/lib/src/safe_http_server.dart
@@ -21,9 +21,9 @@
 class SafeHttpServer extends StreamView<HttpRequest> implements HttpServer {
   final HttpServer _inner;
 
-  static Future<SafeHttpServer> bind([String host = "127.0.0.1",
+  static Future<SafeHttpServer> bind([String host = "localhost",
       int port = 0, int backlog = 0]) {
-    return HttpServer.bind(host, port, backlog)
+    return HttpServer.bind(host, port, backlog: backlog)
         .then((server) => new SafeHttpServer(server));
   }
 
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 4e60ccb..b170e83 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -14,6 +14,4 @@
 *: Skip
 
 [ $system == windows ]
-test/install/git/dependency_name_match_pubspec_test: Fail # Issue 10348
 test/io_test: Fail # Issue 7505
-test/install/hosted/fail_gracefully_on_url_resolve_test: Pass, Fail # Issue 9503
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index dbc326c..a175c7b 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -96,7 +96,7 @@
 
   schedule(() {
     return _closeServer().then((_) {
-      return SafeHttpServer.bind("127.0.0.1", 0).then((server) {
+      return SafeHttpServer.bind("localhost", 0).then((server) {
         _server = server;
         server.listen((request) {
           var response = request.response;
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index d25e580..40efe9a 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -30288,6 +30288,7 @@
  * on how we can make this class work with as many international keyboards as
  * possible. Bugs welcome!
  */
+
 class KeyEvent extends _WrappedEvent implements KeyboardEvent {
   /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
   KeyboardEvent _parent;
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index ef467ac..57cfda6 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -71,22 +71,14 @@
     // Don't start a new read if one is already in progress.
     if (_readInProgress) return;
     _readInProgress = true;
-    _openedFile.length()
-      .then((length) {
-        if (_position >= length) {
-          _readInProgress = false;
+    _openedFile.read(_BLOCK_SIZE)
+      .then((block) {
+        _readInProgress = false;
+        if (block.length == 0) {
           if (!_unsubscribed) {
             _closeFile().then((_) { _controller.close(); });
             _unsubscribed = true;
           }
-          return null;
-        } else {
-          return _openedFile.read(_BLOCK_SIZE);
-        }
-      })
-      .then((block) {
-        _readInProgress = false;
-        if (block == null || _unsubscribed) {
           return;
         }
         _position += block.length;
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 853b858..5f6a75a 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -64,32 +64,63 @@
    * Starts listening for HTTP requests on the specified [address] and
    * [port].
    *
-   * The default value for [address] is 127.0.0.1, which will allow
-   * only incoming connections from the local host. To allow for
-   * incoming connection from the network use either the value 0.0.0.0
-   * to bind to all interfaces or the IP address of a specific
-   * interface.
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.LOOPBACK_IP_V4] or
+   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
+   * bind to all interfaces or the IP address of a specific interface.
    *
-   * If [port] has the value [:0:] (the default) an ephemeral port
-   * will be chosen by the system. The actual port used can be
-   * retrieved using the [:port:] getter.
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [HttpServer.listenOn]
+   * with a [ServerSocket] configured for IP version 6 connections
+   * only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
    *
    * The optional argument [backlog] can be used to specify the listen
    * backlog for the underlying OS listen setup. If [backlog] has the
    * value of [:0:] (the default) a reasonable value will be chosen by
    * the system.
    */
-  static Future<HttpServer> bind([String address = "127.0.0.1",
-                                  int port = 0,
-                                  int backlog = 0])
+  static Future<HttpServer> bind(address,
+                                 int port,
+                                 {int backlog: 0})
       => _HttpServer.bind(address, port, backlog);
 
   /**
-   * Starts listening for HTTPS requests on the specified [address] and
-   * [port]. If a [port] of 0 is specified the server will choose an
-   * ephemeral port. The optional argument [backlog] can be used to
-   * specify the listen backlog for the underlying OS listen
-   * setup.
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.LOOPBACK_IP_V4] or
+   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
+   * bind to all interfaces or the IP address of a specific interface.
+   *
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [HttpServer.listenOn]
+   * with a [ServerSocket] configured for IP version 6 connections
+   * only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
    *
    * The certificate with Distinguished Name [certificateName] is looked
    * up in the certificate database, and is used as the server certificate.
@@ -97,7 +128,7 @@
    * to authenticate with a client certificate.
    */
 
-  static Future<HttpServer> bindSecure(String address,
+  static Future<HttpServer> bindSecure(address,
                                        int port,
                                        {int backlog: 0,
                                         String certificateName,
@@ -697,7 +728,8 @@
 
 
 /**
- * HTTP response to be send back to the client.
+ * An [HttpResponse] represents the headers and data to be returned to
+ * a client in response to an HTTP request.
  *
  * This object has a number of properties for setting up the HTTP
  * header of the response. When the header has been set up the methods
@@ -806,7 +838,7 @@
  * provided which provides access to the headers and body of the response.
  *
  *     HttpClient client = new HttpClient();
- *     client.getUrl(new Uri.fromString("http://www.example.com/"))
+ *     client.getUrl(Uri.parse("http://www.example.com/"))
  *         .then((HttpClientRequest request) {
  *           // Prepare the request then call close on it to send it.
  *           return request.close();
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 44337ca..ee855ec 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -128,6 +128,12 @@
 
   HttpSession get session {
     if (_session != null) {
+      if (_session._destroyed) {
+        // It's destroyed, clear it.
+        _session = null;
+        // Create new session object by calling recursive.
+        return session;
+      }
       // It's already mapped, use it.
       return _session;
     }
@@ -1634,22 +1640,22 @@
 // HTTP server waiting for socket connections.
 class _HttpServer extends Stream<HttpRequest> implements HttpServer {
 
-  static Future<HttpServer> bind(String host, int port, int backlog) {
-    return ServerSocket.bind(host, port, backlog).then((socket) {
+  static Future<HttpServer> bind(address, int port, int backlog) {
+    return ServerSocket.bind(address, port, backlog: backlog).then((socket) {
       return new _HttpServer._(socket, true);
     });
   }
 
-  static Future<HttpServer> bindSecure(String host,
+  static Future<HttpServer> bindSecure(address,
                                        int port,
                                        int backlog,
                                        String certificate_name,
                                        bool requestClientCertificate) {
     return SecureServerSocket.bind(
-        host,
+        address,
         port,
-        backlog,
         certificate_name,
+        backlog: backlog,
         requestClientCertificate: requestClientCertificate)
         .then((socket) {
           return new _HttpServer._(socket, true);
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index 851b58d..7d7dfd1 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -20,12 +20,25 @@
    * completes the server socket is bound to the given [address] and
    * [port] and has started listening on it.
    *
-   * If [port] has the value [:0:] (the default) an ephemeral port will
-   * be chosen by the system. The actual port used can be retrieved
-   * using the [port] getter.
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.LOOPBACK_IP_V4] or
+   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
+   * bind to all interfaces or the IP address of a specific interface.
    *
-   * If [backlog] has the value of [:0:] a reasonable value will be
-   * chosen by the system.
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
    *
    * Incoming client connections are promoted to secure connections, using
    * the server certificate given by [certificateName].
@@ -47,17 +60,19 @@
    * was received, the result will be null.
    */
   static Future<SecureServerSocket> bind(
-      String address,
+      address,
       int port,
-      int backlog,
       String certificateName,
-      {bool requestClientCertificate: false,
+      {int backlog: 0,
+       bool v6Only: false,
+       bool requestClientCertificate: false,
        bool requireClientCertificate: false}) {
     return RawSecureServerSocket.bind(
         address,
         port,
-        backlog,
         certificateName,
+        backlog: backlog,
+        v6Only: v6Only,
         requestClientCertificate: requestClientCertificate,
         requireClientCertificate: requireClientCertificate).then(
             (serverSocket) => new SecureServerSocket._(serverSocket));
@@ -118,12 +133,25 @@
    * completes the server socket is bound to the given [address] and
    * [port] and has started listening on it.
    *
-   * If [port] has the value [:0:] (the default) an ephemeral port will
-   * be chosen by the system. The actual port used can be retrieved
-   * using the [port] getter.
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.LOOPBACK_IP_V4] or
+   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
+   * bind to all interfaces or the IP address of a specific interface.
    *
-   * If [backlog] has the value of [:0:] a reasonable value will be
-   * chosen by the system.
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
+   *
+   * The optional argument [backlog] can be used to specify the listen
+   * backlog for the underlying OS listen setup. If [backlog] has the
+   * value of [:0:] (the default) a reasonable value will be chosen by
+   * the system.
    *
    * Incoming client connections are promoted to secure connections,
    * using the server certificate given by [certificateName].
@@ -146,11 +174,12 @@
   static Future<RawSecureServerSocket> bind(
       String address,
       int port,
-      int backlog,
       String certificateName,
-      {bool requestClientCertificate: false,
+      {int backlog: 0,
+       bool v6Only: false,
+       bool requestClientCertificate: false,
        bool requireClientCertificate: false}) {
-    return RawServerSocket.bind(address, port, backlog)
+    return RawServerSocket.bind(address, port, backlog: backlog, v6Only: v6Only)
         .then((serverSocket) => new RawSecureServerSocket._(
             serverSocket,
             certificateName,
@@ -183,7 +212,7 @@
 
   void _onData(RawSocket connection) {
     _RawSecureSocket.connect(
-        connection.remoteHost,
+        connection.address,
         connection.remotePort,
         certificateName,
         is_server: true,
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 9b4d4c6..4ed4da4 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -295,7 +295,7 @@
     socket.readEventsEnabled = false;
     socket.writeEventsEnabled = false;
     return _RawSecureSocket.connect(
-        socket.remoteHost,
+        socket.address,
         socket.remotePort,
         certificateName,
         is_server: true,
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 6ad9592..040cf39 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -96,12 +96,13 @@
    * change over time.
    */
   external static Future<List<InternetAddress>> lookup(
-      String host, {InternetAddressType type: InternetAddressType.IP_V4});
+      String host, {InternetAddressType type: InternetAddressType.ANY});
 }
 
 /**
- * The RawServerSocket is a server socket, providing a stream of low-level
- * [RawSocket]s.
+ * A [RawServerSocket] represents a listening socket, and provides a
+ * stream of low-level [RawSocket] objects, one for each connection
+ * made to the listening socket.
  *
  * See [RawSocket] for more info.
  */
@@ -111,13 +112,23 @@
    * completes the server socket is bound to the given [address] and
    * [port] and has started listening on it.
    *
-   * The default value for [address] is 127.0.0.1, which will allow
-   * only incoming connections from the local host. To allow for
-   * incoming connection from the network use either the value 0.0.0.0
-   * to bind to all interfaces or the IP address of a specific
-   * interface.
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.LOOPBACK_IP_V4] or
+   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
+   * bind to all interfaces or the IP address of a specific interface.
    *
-   * If [port] has the value [:0:] (the default) an ephemeral port will
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [v6Only] to set
+   * version 6 only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will
    * be chosen by the system. The actual port used can be retrieved
    * using the [:port:] getter.
    *
@@ -126,9 +137,10 @@
    * value of [:0:] (the default) a reasonable value will be chosen by
    * the system.
    */
-  external static Future<RawServerSocket> bind([address = "127.0.0.1",
-                                                int port = 0,
-                                                int backlog = 0]);
+  external static Future<RawServerSocket> bind(address,
+                                               int port,
+                                               {int backlog: 0,
+                                                bool v6Only: false});
 
   /**
    * Returns the port used by this socket.
@@ -143,8 +155,9 @@
 
 
 /**
- * The [ServerSocket] is server socket, providing a stream of high-level
- * [Socket]s.
+ * A [ServerSocket] represents a listening socket, and provides a
+ * stream of [Socket] objects, one for each connection made to the
+ * listening socket.
  *
  * See [Socket] for more info.
  */
@@ -154,24 +167,35 @@
    * completes the server socket is bound to the given [address] and
    * [port] and has started listening on it.
    *
-   * The default value for [address] is 127.0.0.1, which will allow
-   * only incoming connections from the local host. To allow for
-   * incoming connection from the network use either the value 0.0.0.0
-   * to bind to all interfaces or the IP address of a specific
-   * interface.
+   * The [address] can either be a [String] or an
+   * [InternetAddress]. If [address] is a [String], [bind] will
+   * perform a [InternetAddress.lookup] and use the first value in the
+   * list. To listen on the loopback adapter, which will allow only
+   * incoming connections from the local host, use the value
+   * [InternetAddress.LOOPBACK_IP_V4] or
+   * [InternetAddress.LOOPBACK_IP_V6]. To allow for incoming
+   * connection from the network use either one of the values
+   * [InternetAddress.ANY_IP_V4] or [InternetAddress.ANY_IP_V6] to
+   * bind to all interfaces or the IP address of a specific interface.
    *
-   * If [port] has the value [:0:] (the default) an ephemeral port will
-   * be chosen by the system. The actual port used can be retrieved
-   * using the [port] getter.
+   * If an IP version 6 (IPv6) address is used, both IP version 6
+   * (IPv6) and version 4 (IPv4) connections will be accepted. To
+   * restrict this to version 6 (IPv6) only, use [v6Only] to set
+   * version 6 only.
+   *
+   * If [port] has the value [:0:] an ephemeral port will be chosen by
+   * the system. The actual port used can be retrieved using the
+   * [port] getter.
    *
    * The optional argument [backlog] can be used to specify the listen
    * backlog for the underlying OS listen setup. If [backlog] has the
    * value of [:0:] (the default) a reasonable value will be chosen by
    * the system.
    */
-  external static Future<ServerSocket> bind([address = "127.0.0.1",
-                                             int port = 0,
-                                             int backlog = 0]);
+  external static Future<ServerSocket> bind(address,
+                                            int port,
+                                            {int backlog: 0,
+                                             bool v6Only: false});
 
   /**
    * Returns the port used by this socket.
@@ -210,6 +234,7 @@
    * TCP_NODELAY is disabled by default.
    */
   static const SocketOption TCP_NODELAY = const SocketOption._(0);
+
   const SocketOption._(this._value);
   final _value;
 }
diff --git a/sdk/lib/uri/uri.dart b/sdk/lib/uri/uri.dart
index 640ce3d..967e9a3 100644
--- a/sdk/lib/uri/uri.dart
+++ b/sdk/lib/uri/uri.dart
@@ -12,8 +12,13 @@
 
 /**
  * A parsed URI, inspired by Closure's [URI][] class. Implements [RFC-3986][].
- * [uri]: http://closure-library.googlecode.com/svn/docs/class_goog_Uri.html
+ * The domain component can either be a hostname, a IPv4 address or an IPv6
+ * address, contained in '[' and ']', following [RFC-2732][]. If the domain
+ * component contains a ':', the String returned from [toString] will have
+ * '[' and ']' around the domain part.
+ * [URI]: http://closure-library.googlecode.com/svn/docs/class_goog_Uri.html
  * [RFC-3986]: http://tools.ietf.org/html/rfc3986#section-4.3)
+ * [RFC-2732]: http://www.ietf.org/rfc/rfc2732.txt
  */
 class Uri {
   final String scheme;
@@ -24,17 +29,13 @@
   final String query;
   final String fragment;
 
-  /**
-   * Deprecated. Please use [parse] instead.
-   */
-  Uri.fromString(String uri) : this._fromMatch(_splitRe.firstMatch(uri));
-
   static Uri parse(String uri) => new Uri._fromMatch(_splitRe.firstMatch(uri));
 
   Uri._fromMatch(Match m) :
     this.fromComponents(scheme: _emptyIfNull(m[_COMPONENT_SCHEME]),
                         userInfo: _emptyIfNull(m[_COMPONENT_USER_INFO]),
-                        domain: _emptyIfNull(m[_COMPONENT_DOMAIN]),
+                        domain: _eitherOf(
+                            m[_COMPONENT_DOMAIN], m[_COMPONENT_DOMAIN_IPV6]),
                         port: _parseIntOrZero(m[_COMPONENT_PORT]),
                         path: _emptyIfNull(m[_COMPONENT_PATH]),
                         query: _emptyIfNull(m[_COMPONENT_QUERY_DATA]),
@@ -48,7 +49,7 @@
                             this.query: "",
                             this.fragment: ""});
 
-  Uri(String uri) : this.fromString(uri);
+  Uri(String uri) : this._fromMatch(_splitRe.firstMatch(uri));
 
   static String _emptyIfNull(String val) => val != null ? val : '';
 
@@ -60,6 +61,12 @@
     }
   }
 
+  static String _eitherOf(String val1, String val2) {
+    if (val1 != null) return val1;
+    if (val2 != null) return val2;
+    return '';
+  }
+
   // NOTE: This code was ported from: closure-library/closure/goog/uri/utils.js
   static final RegExp _splitRe = new RegExp(
       '^'
@@ -70,24 +77,31 @@
       ':)?'
       '(?://'
         '(?:([^/?#]*)@)?'               // userInfo
-        '([\\w\\d\\-\\u0100-\\uffff.%]*)'
+        '(?:'
+          r'([\w\d\-\u0100-\uffff.%]*)'
                                         // domain - restrict to letters,
                                         // digits, dashes, dots, percent
                                         // escapes, and unicode characters.
+          '|'
+          // TODO(ajohnsen): Only allow a max number of parts?
+          r'\[([A-Fa-f0-9:.]*)\])'
+                                        // IPv6 domain - restrict to hex,
+                                        // dot and colon.
         '(?::([0-9]+))?'                // port
       ')?'
-      '([^?#]+)?'                       // path
-      '(?:\\?([^#]*))?'                 // query
+      r'([^?#[]+)?'                     // path
+      r'(?:\?([^#]*))?'                 // query
       '(?:#(.*))?'                      // fragment
-      '\$');
+      r'$');
 
   static const _COMPONENT_SCHEME = 1;
   static const _COMPONENT_USER_INFO = 2;
   static const _COMPONENT_DOMAIN = 3;
-  static const _COMPONENT_PORT = 4;
-  static const _COMPONENT_PATH = 5;
-  static const _COMPONENT_QUERY_DATA = 6;
-  static const _COMPONENT_FRAGMENT = 7;
+  static const _COMPONENT_DOMAIN_IPV6 = 4;
+  static const _COMPONENT_PORT = 5;
+  static const _COMPONENT_PATH = 6;
+  static const _COMPONENT_QUERY_DATA = 7;
+  static const _COMPONENT_FRAGMENT = 8;
 
   /**
    * Returns `true` if the URI is absolute.
@@ -222,7 +236,8 @@
     if (hasAuthority || (scheme == "file")) {
       sb.write("//");
       _addIfNonEmpty(sb, userInfo, userInfo, "@");
-      sb.write(domain == null ? "null" : domain);
+      sb.write(domain == null ? "null" :
+          domain.contains(':') ? '[$domain]' : domain);
       if (port != 0) {
         sb.write(":");
         sb.write(port.toString());
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 237a6a9..e602004 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -23,6 +23,7 @@
             Message,
             MessageKind,
             Selector,
+            TypedSelector,
             SourceSpan;
 
 import '../../../sdk/lib/_internal/compiler/implementation/ssa/ssa.dart' as ssa;
diff --git a/tests/compiler/dart2js/cpa_inference_test.dart b/tests/compiler/dart2js/cpa_inference_test.dart
index d67dd56..619f3bf 100644
--- a/tests/compiler/dart2js/cpa_inference_test.dart
+++ b/tests/compiler/dart2js/cpa_inference_test.dart
@@ -780,6 +780,26 @@
   }
 }
 
+testBooleanOperators() {
+  String source(op) {
+    return """
+        main() {
+          var a = true $op null;
+          var b = null $op true;
+          var c = 1 $op true;
+          var d = true $op "a";
+          a; b; c; d;
+        }""";
+  }
+  for (String op in ['&&', '||']) {
+    AnalysisResult result = analyze(source(op));
+    result.checkNodeHasType('a', [result.bool]);
+    result.checkNodeHasType('b', [result.bool]);
+    result.checkNodeHasType('c', [result.bool]);
+    result.checkNodeHasType('d', [result.bool]);
+  }
+}
+
 testOperators() {
   final String source = r"""
       class A {
@@ -1221,7 +1241,7 @@
 
   for (ClassElement cls in [a, b, c, d]) {
     Expect.equals(convert(singleton(cls)),
-                  new TypeMask.exact(cls.rawType).nonNullable());
+                  new TypeMask.nonNullExact(cls.rawType));
   }
 
   for (ClassElement cls in [a, b, c, d]) {
@@ -1230,13 +1250,76 @@
   }
 
   Expect.equals(convert(singleton(a).union(singleton(b))),
-                new TypeMask.subclass(a.rawType).nonNullable());
+                new TypeMask.nonNullSubclass(a.rawType));
 
   Expect.equals(convert(singleton(a).union(singleton(b)).union(nullSingleton)),
                 new TypeMask.subclass(a.rawType));
 
   Expect.equals(convert(singleton(b).union(singleton(d))),
-                new TypeMask.subtype(a.rawType).nonNullable());
+                new TypeMask.nonNullSubtype(a.rawType));
+}
+
+testSelectors() {
+  final String source = r"""
+      // ABC <--- A
+      //       `- BC <--- B
+      //               `- C
+
+      class ABC {}
+      class A extends ABC {}
+      class BC extends ABC {}
+      class B extends BC {}
+      class C extends BC {}
+
+      class XY {}
+      class X extends XY { foo() => new B(); }
+      class Y extends XY { foo() => new C(); }
+      class Z { foo() => new A(); }
+
+      main() {
+        new X().foo();
+        new Y().foo();
+        new Z().foo();
+      }
+      """;
+  AnalysisResult result = analyze(source);
+
+  inferredType(Selector selector) {
+    return result.compiler.typesTask.concreteTypesInferrer
+        .getTypeOfSelector(selector);
+  }
+
+  ClassElement abc = findElement(result.compiler, 'ABC');
+  ClassElement bc = findElement(result.compiler, 'BC');
+  ClassElement a = findElement(result.compiler, 'A');
+  ClassElement b = findElement(result.compiler, 'B');
+  ClassElement c = findElement(result.compiler, 'C');
+  ClassElement xy = findElement(result.compiler, 'XY');
+  ClassElement x = findElement(result.compiler, 'X');
+  ClassElement y = findElement(result.compiler, 'Y');
+  ClassElement z = findElement(result.compiler, 'Z');
+
+  Selector foo = new Selector.call(buildSourceString("foo"), null, 0);
+
+  Expect.equals(
+      inferredType(foo),
+      new TypeMask.nonNullSubclass(abc.rawType));
+  Expect.equals(
+      inferredType(new TypedSelector.subclass(x.rawType, foo)),
+      new TypeMask.nonNullExact(b.rawType));
+  Expect.equals(
+      inferredType(new TypedSelector.subclass(y.rawType, foo)),
+      new TypeMask.nonNullExact(c.rawType));
+  Expect.equals(
+      inferredType(new TypedSelector.subclass(z.rawType, foo)),
+      new TypeMask.nonNullExact(a.rawType));
+  Expect.equals(
+      inferredType(new TypedSelector.subclass(xy.rawType, foo)),
+      new TypeMask.nonNullSubclass(bc.rawType));
+
+  Selector bar = new Selector.call(buildSourceString("bar"), null, 0);
+
+  Expect.isNull(inferredType(bar));
 }
 
 void main() {
@@ -1266,6 +1349,7 @@
   testReturn();
   // testNoReturn(); // right now we infer the empty type instead of null
   testArithmeticOperators();
+  testBooleanOperators();
   testOperators();
   testCompoundOperators1();
   testCompoundOperators2();
@@ -1287,4 +1371,5 @@
   testGoodGuys();
   testIntDoubleNum();
   testConcreteTypeToTypeMask();
+  testSelectors();
 }
diff --git a/tests/compiler/dart2js/dead_bailout_target_test.dart b/tests/compiler/dart2js/dead_bailout_target_test.dart
index b6fe836..760da9c 100644
--- a/tests/compiler/dart2js/dead_bailout_target_test.dart
+++ b/tests/compiler/dart2js/dead_bailout_target_test.dart
@@ -60,7 +60,7 @@
 
   // Check that the bailout method has a case 2 for the state, which
   // is the second bailout in foo.
-  RegExp state = new RegExp('case 2:[ \n]+state0 = 0;');
+  RegExp state = new RegExp('case 2:');
   checkNumberOfMatches(state.allMatches(generated).iterator, 1);
 
   // Finally, make sure that the reason foo does not contain
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 42bfc60..f2fa92a 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -6,9 +6,6 @@
 import "../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/tree/tree.dart";
-import
-    "../../../sdk/lib/_internal/compiler/implementation/universe/universe.dart"
-        show TypedSelector;
 import "../../../sdk/lib/_internal/compiler/implementation/util/util.dart";
 import "mock_compiler.dart";
 import "parser_helper.dart";
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 7257bf3..1315cac 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -9,7 +9,6 @@
 native_null_closure_frog_test: Fail
 native_no_such_method_exception4_frog_test: Fail  # Issue 9631
 native_no_such_method_exception5_frog_test: Fail  # Issue 9631
-super_call_test: Fail  # Issue 10166
 
 [ $compiler == dart2js && $checked ]
 native_no_such_method_exception3_frog_test: Fail # TODO(ahe): investigate.
diff --git a/tests/language/abstract_object_method_test.dart b/tests/language/abstract_object_method_test.dart
new file mode 100644
index 0000000..f88094b
--- /dev/null
+++ b/tests/language/abstract_object_method_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class A {
+  noSuchMethod(_) {
+    Expect.fail('Should not reach here');
+  }
+}
+
+class B extends A {
+  operator ==(other);
+}
+
+class C extends B {
+}
+
+var a = [new C()];
+
+main() {
+  C c = a[0];
+  a.add(c);
+  Expect.isTrue(c == a[1]);
+}
diff --git a/tests/language/empty_main.dart b/tests/language/empty_main.dart
index 7def6ef..0946204 100644
--- a/tests/language/empty_main.dart
+++ b/tests/language/empty_main.dart
@@ -2,4 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of ApplicationTest.dart;
+
 main() {}
diff --git a/tests/language/generic_instanceof.dart b/tests/language/generic_instanceof.dart
index 3f64976..8b9388d 100644
--- a/tests/language/generic_instanceof.dart
+++ b/tests/language/generic_instanceof.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Test that instanceof works correctly with type variables.
 
+part of GenericInstanceofTest.dart;
+
 class Foo<T> {
   Foo() {}
 
diff --git a/tests/language/hello_script_lib_source.dart b/tests/language/hello_script_lib_source.dart
index 8f44b7b..8c74bc4 100644
--- a/tests/language/hello_script_lib_source.dart
+++ b/tests/language/hello_script_lib_source.dart
@@ -7,4 +7,6 @@
 
 // A top-level variable being accessed both from the library and the importer.
 
+part of HelloScriptLib;
+
 var x;
diff --git a/tests/language/issue10321_test.dart b/tests/language/issue10321_test.dart
new file mode 100644
index 0000000..fb35dcd
--- /dev/null
+++ b/tests/language/issue10321_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Regression test for dart2js that used to miscompile [A.foo].
+
+var global = 54;
+
+class A {
+  int a = 0;
+  int b = 42;
+  final int c = global;
+  foo() {
+    int start = a - 1;
+    a = 54;
+    if (b == 42) {
+      b = 32;
+    } else {
+      b = 42;
+    }
+    Expect.equals(-1, start);
+  }
+
+  bar() {
+    int start = a - c - 1;
+    a = 42;
+    if (b == 42) {
+      b = 32;
+    } else {
+      b = 42;
+    }
+    Expect.equals(-55, start);
+  }
+}
+
+main() {
+  new A().foo();
+  new A().bar();
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 2a940a4..740c10f 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -120,7 +120,6 @@
 metadata_test: Fail
 const_locals_test: Fail
 const_nested_test: Fail
-application_negative_test: Fail # Runtime only test, rewrite as multitest
 assign_instance_method_negative_test: Fail # Runtime only test, rewrite as multitest
 body_less_constructor_wrong_arg_negative_test: Fail # Runtime only test, rewrite as multitest
 call_nonexistent_static_test/03: Fail # Unresolved static calls are no longer errors.
@@ -178,11 +177,9 @@
 library4_negative_test: Fail # still a valid test? Issue 3530
 library6_negative_test: Fail # still a valid test? Issue 3650
 named_parameters_with_object_property_names_test: Fail # Issue 2137
-many_overridden_no_such_method_test: Fail
 no_such_method_negative_test: Fail # Runtime only test, rewrite as multitest
 override_field_test/03: Fail # still a valid test? Issue 3894
 override_field_method6_negative_test: Fail, OK # test issue 5249
-overridden_no_such_method_test: Fail
 parameter_initializer6_negative_test: Fail # language change 4288
 prefix1_negative_test : Fail # language change 1031
 prefix4_negative_test : Fail # language change 1031
@@ -223,23 +220,6 @@
 # test issue 5529
 interface_test/none: Fail, OK
 
-# test issue 6338
-application_negative_test: Pass
-application_test: Fail, OK
-generic_instanceof_test: Fail, OK
-hello_script_test: Fail, OK
-lazy_static6_test: Fail, OK
-library1_test: Fail, OK
-library_prefixes_test: Fail, OK
-many_generic_instanceof_test: Fail, OK
-multi_pass2_test: Fail, OK
-multi_pass_test: Fail, OK
-private2_test: Fail, OK
-private3_test: Fail, OK
-private_test: Fail, OK
-top_level_entry_test: Fail, OK
-top_level_multiple_files_test: Fail, OK
-top_level_non_prefixed_library_test: Fail, OK
 
 prefix6_negative_test: Fail
 
diff --git a/tests/language/lazy_static6_src.dart b/tests/language/lazy_static6_src.dart
index 779d3d8..c17f7da 100644
--- a/tests/language/lazy_static6_src.dart
+++ b/tests/language/lazy_static6_src.dart
@@ -18,6 +18,7 @@
  ******************************************************************************
  ******************************************************************************
  */
+part of lazy_static6_test;
 
 final x = (t) => (u) => t + u;
 
diff --git a/tests/language/library1_lib.dart b/tests/language/library1_lib.dart
index c605f426..66af369 100644
--- a/tests/language/library1_lib.dart
+++ b/tests/language/library1_lib.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of Library1Lib;
+
 class A {
   A() {}
   String foo() { return "foo-rty two"; }
diff --git a/tests/language/library_prefixes.dart b/tests/language/library_prefixes.dart
index d44e374..bac0079 100644
--- a/tests/language/library_prefixes.dart
+++ b/tests/language/library_prefixes.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of LibraryPrefixes.lib;
+
 class LibraryPrefixes {
 
   static void main(var expectEquals) {
diff --git a/tests/language/library_prefixes_test1.dart b/tests/language/library_prefixes_test1.dart
index 53ab581..0ed6c8d 100644
--- a/tests/language/library_prefixes_test1.dart
+++ b/tests/language/library_prefixes_test1.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of LibraryPrefixesTest1.lib;
+
 class Constants {
   static const PI = 3.14;
   static const foo = 1;
diff --git a/tests/language/library_prefixes_test2.dart b/tests/language/library_prefixes_test2.dart
index 7e5e600..4415040 100644
--- a/tests/language/library_prefixes_test2.dart
+++ b/tests/language/library_prefixes_test2.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of LibraryPrefixesTest2.lib;
+
 class Constants {
   static const PI = 3.14;
   static const foo = 2;
diff --git a/tests/language/many_generic_instanceof_test.dart b/tests/language/many_generic_instanceof_test.dart
index 5f92367..6f1d9c2 100644
--- a/tests/language/many_generic_instanceof_test.dart
+++ b/tests/language/many_generic_instanceof_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.
 
-library ManyGenericInstanceofTest.dart;
+library GenericInstanceofTest.dart;
 import "package:expect/expect.dart";
 part "generic_instanceof.dart";
 
diff --git a/tests/language/many_overridden_no_such_method_test.dart b/tests/language/many_overridden_no_such_method_test.dart
index f772998..7c90383 100644
--- a/tests/language/many_overridden_no_such_method_test.dart
+++ b/tests/language/many_overridden_no_such_method_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.
 
-library ManyOverriddenNoSuchMethodTest.dart;
+library OverriddenNoSuchMethodTest.dart;
 
 import "dart:mirrors" show reflect;
 import "package:expect/expect.dart";
diff --git a/tests/language/multi_pass2_test.dart b/tests/language/multi_pass2_test.dart
index 4e67d98..f7042a0 100644
--- a/tests/language/multi_pass2_test.dart
+++ b/tests/language/multi_pass2_test.dart
@@ -4,7 +4,7 @@
 // Dart test for loading several dart files and resolving superclasses lazily.
 // Same as MultiPassTest, except that the file order is reversed.
 
-library MultiPass2Test.dart;
+library MultiPassTest.dart;
 import "package:expect/expect.dart";
 part "multi_pass_a.dart";
 part "multi_pass_b.dart";
diff --git a/tests/language/multi_pass_a.dart b/tests/language/multi_pass_a.dart
index 05f4189..5b2863f 100644
--- a/tests/language/multi_pass_a.dart
+++ b/tests/language/multi_pass_a.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for loading several dart files and resolving superclasses lazily.
 
+part of MultiPassTest.dart;
 
 class A extends Base {
   A(v) : super(v) {}
diff --git a/tests/language/multi_pass_b.dart b/tests/language/multi_pass_b.dart
index 802f1c6..ed99b83 100644
--- a/tests/language/multi_pass_b.dart
+++ b/tests/language/multi_pass_b.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for loading several dart files and resolving superclasses lazily.
 
+part of MultiPassTest.dart;
+
 class B extends A {
   B(v) : super(v) {}
 }
diff --git a/tests/language/overridden_no_such_method.dart b/tests/language/overridden_no_such_method.dart
index d3a87b2..54b44a4 100644
--- a/tests/language/overridden_no_such_method.dart
+++ b/tests/language/overridden_no_such_method.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program testing overridden messageNotUnderstood.
 
+part of OverriddenNoSuchMethodTest.dart;
+
 class GetName {
   foo(a, b) => "foo";
 }
diff --git a/tests/language/private1.dart b/tests/language/private1.dart
index b4e9371..5329acf 100644
--- a/tests/language/private1.dart
+++ b/tests/language/private1.dart
@@ -4,6 +4,8 @@
 
 // Dart test for testing access to private fields.
 
+part of PrivateTest.dart; 
+
 main() {
   testPrivateTopLevel();
   testPrivateClasses();
diff --git a/tests/language/private2.dart b/tests/language/private2.dart
index 8a624b7..eb50027 100644
--- a/tests/language/private2.dart
+++ b/tests/language/private2.dart
@@ -4,6 +4,8 @@
 
 // Dart test for testing access to private fields.
 
+part of PrivateTest.dart;
+
 String _private2() { return "private2"; }
 const String _private2Field = "private2Field";
 
diff --git a/tests/language/private2_lib.dart b/tests/language/private2_lib.dart
index 0443f26..938b5b4 100644
--- a/tests/language/private2_lib.dart
+++ b/tests/language/private2_lib.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for testing access to private fields across class hierarchies.
 
+part of Private2Lib;
+
 class B extends A {
   B() : super();
 }
diff --git a/tests/language/private2_main.dart b/tests/language/private2_main.dart
index a39ff70..1d4d15f 100644
--- a/tests/language/private2_main.dart
+++ b/tests/language/private2_main.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for testing access to private fields across class hierarchies.
 
+part of Private2Test;
+
 class A {
   var _f;
   var g;
diff --git a/tests/language/private3.dart b/tests/language/private3.dart
index 93a3d41..d058fc8 100644
--- a/tests/language/private3.dart
+++ b/tests/language/private3.dart
@@ -4,6 +4,8 @@
 
 // Dart test for testing access to private fields.
 
+part of PrivateOther;
+
 class LibOther3 {
   static accessFieldA3(var a) => a.fieldA;
   static accessFieldB3(var b) => b._fieldB;
diff --git a/tests/language/private_lib.dart b/tests/language/private_lib.dart
index cb9331e..d5dea43 100644
--- a/tests/language/private_lib.dart
+++ b/tests/language/private_lib.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for testing access to private fields.
 
+part of PrivateLib;
+
 class PrivateLib {
 
   final _myPrecious;
diff --git a/tests/language/private_main.dart b/tests/language/private_main.dart
index 531cbb0..5e1f8d4 100644
--- a/tests/language/private_main.dart
+++ b/tests/language/private_main.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for testing access to private fields.
 
+part of Private3Test.dart;
+
 main() {
   PrivateMain.main();
 }
diff --git a/tests/language/private_other.dart b/tests/language/private_other.dart
index c4e19ec..107d8fc 100644
--- a/tests/language/private_other.dart
+++ b/tests/language/private_other.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test for testing access to private fields.
 
+part of Private3Test.dart;
+
 class PrivateOther {
 
   final _myPrecious;
diff --git a/tests/language/top_level_entry.dart b/tests/language/top_level_entry.dart
index 1b483b6..bbe7035 100644
--- a/tests/language/top_level_entry.dart
+++ b/tests/language/top_level_entry.dart
@@ -2,5 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of top_level_entry_test.dart;
+
 main() {
 }
diff --git a/tests/language/top_level_file1.dart b/tests/language/top_level_file1.dart
index 160d300..e0f5d98 100644
--- a/tests/language/top_level_file1.dart
+++ b/tests/language/top_level_file1.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of TopLevelMultipleFilesTest.dart;
+
 main() {
   Expect.equals(topLevelVar, 42);
   Expect.equals(topLevelMethod(), 87);
diff --git a/tests/language/top_level_file2.dart b/tests/language/top_level_file2.dart
index 1b8f549..19ca8ca 100644
--- a/tests/language/top_level_file2.dart
+++ b/tests/language/top_level_file2.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+part of TopLevelMultipleFilesTest.dart;
+
 const topLevelVar = 42;
 
 topLevelMethod() => 87;
diff --git a/tests/language/top_level_non_prefixed_library_test.dart b/tests/language/top_level_non_prefixed_library_test.dart
index 5a3995c..d0f8dab 100644
--- a/tests/language/top_level_non_prefixed_library_test.dart
+++ b/tests/language/top_level_non_prefixed_library_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.
 
-library TopLevelNonPrefixLibraryTest.dart;
+library TopLevelMultipleFilesTest.dart;
 
 import "package:expect/expect.dart";
 import 'top_level_prefixed_library_test.lib';
diff --git a/tests/lib/crypto/hmac_sha1_test_vectors.dart b/tests/lib/crypto/hmac_sha1_test_vectors.dart
index 9298817..26f37f9 100644
--- a/tests/lib/crypto/hmac_sha1_test_vectors.dart
+++ b/tests/lib/crypto/hmac_sha1_test_vectors.dart
@@ -5,6 +5,8 @@
 // Standard test vectors from:
 //   http://csrc.nist.gov/groups/STM/cavp/documents/mac/hmactestvectors.zip
 
+part of hmac_sha1_test;
+
 const hmac_sha1_inputs = const [
 const [ 0xfc, 0xd6, 0xd9, 0x8b, 0xef, 0x45, 0xed, 0x68, 0x50, 0x80, 0x6e, 0x96, 0xf2, 0x55, 0xfa, 0x0c, 0x81, 0x14, 0xb7, 0x28, 0x73, 0xab, 0xe8, 0xf4, 0x3c, 0x10, 0xbe, 0xa7, 0xc1, 0xdf, 0x70, 0x6f, 0x10, 0x45, 0x8e, 0x6d, 0x4e, 0x1c, 0x92, 0x01, 0xf0, 0x57, 0xb8, 0x49, 0x2f, 0xa1, 0x0f, 0xe4, 0xb5, 0x41, 0xd0, 0xfc, 0x9d, 0x41, 0xef, 0x83, 0x9a, 0xcf, 0xf1, 0xbc, 0x76, 0xe3, 0xfd, 0xfe, 0xbf, 0x22, 0x35, 0xb5, 0xbd, 0x03, 0x47, 0xa9, 0xa6, 0x30, 0x3e, 0x83, 0x15, 0x2f, 0x9f, 0x8d, 0xb9, 0x41, 0xb1, 0xb9, 0x4a, 0x8a, 0x1c, 0xe5, 0xc2, 0x73, 0xb5, 0x5d, 0xc9, 0x4d, 0x99, 0xa1, 0x71, 0x37, 0x79, 0x69, 0x23, 0x41, 0x34, 0xe7, 0xda, 0xd1, 0xab, 0x4c, 0x8e, 0x46, 0xd1, 0x8d, 0xf4, 0xdc, 0x01, 0x67, 0x64, 0xcf, 0x95, 0xa1, 0x1a, 0xc4, 0xb4, 0x91, 0xa2, 0x64, 0x6b, 0xe1 ],
 const [ 0xd6, 0x8b, 0x82, 0x8a, 0x15, 0x3f, 0x51, 0x98, 0xc0, 0x05, 0xee, 0x36, 0xc0, 0xaf, 0x2f, 0xf9, 0x2e, 0x84, 0x90, 0x75, 0x17, 0xf0, 0x1d, 0x9b, 0x7c, 0x79, 0x93, 0x46, 0x9d, 0xf5, 0xc2, 0x10, 0x78, 0xfa, 0x35, 0x6a, 0x8c, 0x97, 0x15, 0xec, 0xe2, 0x41, 0x4b, 0xe9, 0x4e, 0x10, 0xe5, 0x47, 0xf3, 0x2c, 0xbb, 0x8d, 0x05, 0x82, 0x52, 0x3e, 0xd3, 0xbb, 0x00, 0x66, 0x04, 0x6e, 0x51, 0x72, 0x20, 0x94, 0xaa, 0x44, 0x53, 0x3d, 0x2c, 0x87, 0x6e, 0x82, 0xdb, 0x40, 0x2f, 0xbb, 0x00, 0xa6, 0xc2, 0xf2, 0xcc, 0x34, 0x87, 0x97, 0x3d, 0xfc, 0x16, 0x74, 0x46, 0x3e, 0x81, 0xe4, 0x2a, 0x39, 0xd9, 0x40, 0x29, 0x41, 0xf3, 0x9b, 0x5e, 0x12, 0x6b, 0xaf, 0xe8, 0x64, 0xea, 0x16, 0x48, 0xc0, 0xa5, 0xbe, 0x0a, 0x91, 0x26, 0x97, 0xa8, 0x7e, 0x4f, 0x8e, 0xab, 0xf7, 0x9c, 0xbf, 0x13, 0x0e ],
diff --git a/tests/lib/crypto/hmac_sha256_test_vectors.dart b/tests/lib/crypto/hmac_sha256_test_vectors.dart
index 32962f8..6cb65b1 100644
--- a/tests/lib/crypto/hmac_sha256_test_vectors.dart
+++ b/tests/lib/crypto/hmac_sha256_test_vectors.dart
@@ -5,6 +5,8 @@
 // Standard test vectors from:
 //   http://csrc.nist.gov/groups/STM/cavp/documents/mac/hmactestvectors.zip
 
+part of hmac_sha256_test;
+
 const hmac_sha256_inputs = const [
 const [ 0x75, 0x2c, 0xff, 0x52, 0xe4, 0xb9, 0x07, 0x68, 0x55, 0x8e, 0x53, 0x69, 0xe7, 0x5d, 0x97, 0xc6, 0x96, 0x43, 0x50, 0x9a, 0x5e, 0x59, 0x04, 0xe0, 0xa3, 0x86, 0xcb, 0xe4, 0xd0, 0x97, 0x0e, 0xf7, 0x3f, 0x91, 0x8f, 0x67, 0x59, 0x45, 0xa9, 0xae, 0xfe, 0x26, 0xda, 0xea, 0x27, 0x58, 0x7e, 0x8d, 0xc9, 0x09, 0xdd, 0x56, 0xfd, 0x04, 0x68, 0x80, 0x5f, 0x83, 0x40, 0x39, 0xb3, 0x45, 0xf8, 0x55, 0xcf, 0xe1, 0x9c, 0x44, 0xb5, 0x5a, 0xf2, 0x41, 0xff, 0xf3, 0xff, 0xcd, 0x80, 0x45, 0xcd, 0x5c, 0x28, 0x8e, 0x6c, 0x4e, 0x28, 0x4c, 0x37, 0x20, 0x57, 0x0b, 0x58, 0xe4, 0xd4, 0x7b, 0x8f, 0xee, 0xed, 0xc5, 0x2f, 0xd1, 0x40, 0x1f, 0x69, 0x8a, 0x20, 0x9f, 0xcc, 0xfa, 0x3b, 0x4c, 0x0d, 0x9a, 0x79, 0x7b, 0x04, 0x6a, 0x27, 0x59, 0xf8, 0x2a, 0x54, 0xc4, 0x1c, 0xcd, 0x7b, 0x5f, 0x59, 0x2b ],
 const [ 0xe0, 0xef, 0xf0, 0x0f, 0x3c, 0x46, 0xe9, 0x6c, 0x8d, 0x5b, 0xd1, 0x81, 0x28, 0x3e, 0x46, 0x05, 0x34, 0x8e, 0x3f, 0xa1, 0x0b, 0x47, 0x94, 0x5d, 0xe3, 0xdc, 0xc1, 0x59, 0xae, 0x86, 0xe7, 0xbd, 0x3f, 0xdb, 0x13, 0xf2, 0xad, 0xa2, 0xc3, 0x13, 0xfc, 0xe6, 0xa6, 0x9e, 0xfa, 0x49, 0xa4, 0x70, 0x68, 0x9b, 0x1e, 0xf0, 0x5a, 0xab, 0x77, 0x8a, 0xe1, 0x5d, 0xd3, 0x5f, 0xe6, 0xfd, 0x1e, 0x3a, 0x59, 0xd3, 0x51, 0xc6, 0x8c, 0xf8, 0xf0, 0xff, 0xd9, 0x68, 0xd7, 0xe7, 0x8b, 0x57, 0x37, 0x7a, 0xfc, 0xc9, 0xdc, 0xe3, 0xfa, 0x5d, 0xb1, 0xf0, 0x6f, 0x69, 0x85, 0xc4, 0x41, 0x4c, 0x0f, 0xcc, 0x78, 0x00, 0x30, 0xf4, 0x9f, 0xef, 0x79, 0x1a, 0x6c, 0x08, 0xed, 0xc2, 0xa3, 0x11, 0x08, 0x0c, 0x37, 0x3f, 0x00, 0xe4, 0xb2, 0x04, 0x4a, 0x79, 0xd8, 0x28, 0x60, 0xf0, 0x87, 0x1b, 0xc2, 0x59 ],
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 053f62a..26e406b 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -57,11 +57,6 @@
 # Skip until we stabilize language tests.
 *: Skip
 
-[ $compiler == dartc ]
-# lib issue 6322
-crypto/hmac_sha1_test: Fail
-crypto/hmac_sha256_test: Fail
-
 [ $runtime == safari]
  # Bug in JSC: the test only passes when being debugged.
 crypto/hmac_md5_test: Fail, Pass
diff --git a/tests/lib/uri/uri_ipv6_test.dart b/tests/lib/uri/uri_ipv6_test.dart
new file mode 100644
index 0000000..1b69cf9
--- /dev/null
+++ b/tests/lib/uri/uri_ipv6_test.dart
@@ -0,0 +1,80 @@
+// 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';
+import 'dart:uri';
+
+
+void testValidIpv6Uri() {
+  var path = 'http://[::1]:1234/path?query=5#now';
+  var uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('::1', uri.domain);
+  Expect.equals(1234, uri.port);
+  Expect.equals('/path', uri.path);
+  Expect.equals('query=5', uri.query);
+  Expect.equals('now', uri.fragment);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', uri.domain);
+  Expect.equals(80, uri.port);
+  Expect.equals('/index.html', uri.path);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[1080:0:0:0:8:800:200C:417A]/index.html';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('1080:0:0:0:8:800:200C:417A', uri.domain);
+  Expect.equals(0, uri.port);
+  Expect.equals('/index.html', uri.path);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[3ffe:2a00:100:7031::1]';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('3ffe:2a00:100:7031::1', uri.domain);
+  Expect.equals(0, uri.port);
+  Expect.equals('', uri.path);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[1080::8:800:200C:417A]/foo';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('1080::8:800:200C:417A', uri.domain);
+  Expect.equals(0, uri.port);
+  Expect.equals('/foo', uri.path);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[::192.9.5.5]/ipng';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('::192.9.5.5', uri.domain);
+  Expect.equals(0, uri.port);
+  Expect.equals('/ipng', uri.path);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[::FFFF:129.144.52.38]:80/index.html';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('::FFFF:129.144.52.38', uri.domain);
+  Expect.equals(80, uri.port);
+  Expect.equals('/index.html', uri.path);
+  Expect.equals(path, uri.toString());
+
+  path = 'http://[2010:836B:4179::836B:4179]';
+  uri = Uri.parse(path);
+  Expect.equals('http', uri.scheme);
+  Expect.equals('2010:836B:4179::836B:4179', uri.domain);
+  Expect.equals(0, uri.port);
+  Expect.equals('', uri.path);
+  Expect.equals(path, uri.toString());
+}
+
+void main() {
+  testValidIpv6Uri();
+}
+
diff --git a/tests/standalone/io/http_10_test.dart b/tests/standalone/io/http_10_test.dart
index 9250a36..d3ade02 100644
--- a/tests/standalone/io/http_10_test.dart
+++ b/tests/standalone/io/http_10_test.dart
@@ -16,7 +16,7 @@
 // server sets a content length but still needs to close the
 // connection as there is no keep alive.
 void testHttp10NoKeepAlive() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
         (HttpRequest request) {
           Expect.isNull(request.headers.value('content-length'));
@@ -71,7 +71,7 @@
 // content length so it has to close the connection to mark the end of
 // the response.
 void testHttp10ServerClose() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
         (HttpRequest request) {
           Expect.isNull(request.headers.value('content-length'));
@@ -124,7 +124,7 @@
 // server sets a content length so the persistent connection can be
 // used.
 void testHttp10KeepAlive() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
         (HttpRequest request) {
           Expect.isNull(request.headers.value('content-length'));
@@ -180,7 +180,7 @@
 // server does not set a content length so it cannot honor connection
 // keep alive.
 void testHttp10KeepAliveServerCloses() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
         (HttpRequest request) {
           Expect.isNull(request.headers.value('content-length'));
diff --git a/tests/standalone/io/http_advanced_test.dart b/tests/standalone/io/http_advanced_test.dart
index 1d4ca89..deab970 100644
--- a/tests/standalone/io/http_advanced_test.dart
+++ b/tests/standalone/io/http_advanced_test.dart
@@ -206,7 +206,7 @@
   void dispatch(message, replyTo) {
     if (message.isStart) {
       try {
-        HttpServer.bind().then((server) {
+        HttpServer.bind("127.0.0.1", 0).then((server) {
           _server = server;
           _server.listen(_requestReceivedHandler);
           replyTo.send(new IsolatedHttpServerStatus.started(_server.port),
diff --git a/tests/standalone/io/http_auth_test.dart b/tests/standalone/io/http_auth_test.dart
index 8871d40..f0a9733 100644
--- a/tests/standalone/io/http_auth_test.dart
+++ b/tests/standalone/io/http_auth_test.dart
@@ -16,7 +16,7 @@
 
   Future<Server> start() {
     var completer = new Completer();
-    HttpServer.bind().then((s) {
+    HttpServer.bind("127.0.0.1", 0).then((s) {
       server = s;
       server.listen((HttpRequest request) {
         var response = request.response;
diff --git a/tests/standalone/io/http_basic_test.dart b/tests/standalone/io/http_basic_test.dart
index 9ebb389..6d9caaf 100644
--- a/tests/standalone/io/http_basic_test.dart
+++ b/tests/standalone/io/http_basic_test.dart
@@ -156,7 +156,7 @@
   void dispatch(var message, SendPort replyTo) {
     if (message.isStart) {
       try {
-        HttpServer.bind().then((server) {
+        HttpServer.bind("127.0.0.1", 0).then((server) {
           _server = server;
           _server.listen(_requestReceivedHandler);
           replyTo.send(new TestServerStatus.started(_server.port), null);
diff --git a/tests/standalone/io/http_body_test.dart b/tests/standalone/io/http_body_test.dart
index b0f5f73..b036da2 100644
--- a/tests/standalone/io/http_body_test.dart
+++ b/tests/standalone/io/http_body_test.dart
@@ -13,7 +13,7 @@
             dynamic expectedBody,
             String type,
             [bool shouldFail = false]) {
-    HttpServer.bind().then((server) {
+    HttpServer.bind("127.0.0.1", 0).then((server) {
       server.listen((request) {
         request.listen(
             (_) {},
@@ -91,7 +91,7 @@
             dynamic expectedBody,
             String type,
             [bool shouldFail = false]) {
-    HttpServer.bind().then((server) {
+    HttpServer.bind("127.0.0.1", 0).then((server) {
       server.transform(new HttpBodyHandler())
           .listen((body) {
             if (shouldFail) Expect.fail("Error expected");
diff --git a/tests/standalone/io/http_client_connect_test.dart b/tests/standalone/io/http_client_connect_test.dart
index 9c18e75..67ee2a5 100644
--- a/tests/standalone/io/http_client_connect_test.dart
+++ b/tests/standalone/io/http_client_connect_test.dart
@@ -13,7 +13,7 @@
 import 'dart:isolate';
 
 void testGetEmptyRequest() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       request.pipe(request.response);
     });
@@ -30,7 +30,7 @@
 }
 
 void testGetDataRequest() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     var data = "lalala".codeUnits;
     server.listen((request) {
       request.response.add(data);
@@ -63,7 +63,7 @@
 }
 
 void testGetServerClose() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       server.close();
     });
@@ -82,7 +82,7 @@
 
 void testGetDataServerClose() {
   var completer = new Completer();
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       request.response.contentLength = 100;
       request.response.write("data");
@@ -110,7 +110,7 @@
 }
 
 void testPostEmptyRequest() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       request.pipe(request.response);
     });
diff --git a/tests/standalone/io/http_client_request_test.dart b/tests/standalone/io/http_client_request_test.dart
index b72551f..35d565b 100644
--- a/tests/standalone/io/http_client_request_test.dart
+++ b/tests/standalone/io/http_client_request_test.dart
@@ -8,7 +8,7 @@
 import "dart:typed_data";
 
 void testClientRequest(void handler(request)) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       request.listen((_) {}, onDone: () {
         request.response.close();
diff --git a/tests/standalone/io/http_close_test.dart b/tests/standalone/io/http_close_test.dart
index d88f5f5..a4f8175 100644
--- a/tests/standalone/io/http_close_test.dart
+++ b/tests/standalone/io/http_close_test.dart
@@ -14,7 +14,7 @@
 
 
 void testClientAndServerCloseNoListen(int connections) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     int closed = 0;
     server.listen((request) {
       request.response.close();
@@ -40,7 +40,7 @@
 
 
 void testClientCloseServerListen(int connections) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     int closed = 0;
     void check() {
       closed++;
@@ -70,7 +70,7 @@
 
 
 void testClientCloseSendingResponse(int connections) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     int closed = 0;
     void check() {
       closed++;
diff --git a/tests/standalone/io/http_compression_test.dart b/tests/standalone/io/http_compression_test.dart
index 47c2906..b5addc7 100644
--- a/tests/standalone/io/http_compression_test.dart
+++ b/tests/standalone/io/http_compression_test.dart
@@ -13,7 +13,7 @@
 
 void testServerCompress() {
   void test(List<int> data) {
-    HttpServer.bind().then((server) {
+    HttpServer.bind("127.0.0.1", 0).then((server) {
       server.listen((request) {
         request.response.add(data);
         request.response.close();
@@ -49,7 +49,7 @@
 
 void testAcceptEncodingHeader() {
   void test(String encoding, bool valid) {
-    HttpServer.bind().then((server) {
+    HttpServer.bind("127.0.0.1", 0).then((server) {
       server.listen((request) {
         request.response.write("data");
         request.response.close();
diff --git a/tests/standalone/io/http_connection_close_test.dart b/tests/standalone/io/http_connection_close_test.dart
index 5a22540..c56ef39 100644
--- a/tests/standalone/io/http_connection_close_test.dart
+++ b/tests/standalone/io/http_connection_close_test.dart
@@ -9,7 +9,7 @@
 import "dart:uri";
 
 void testHttp10Close(bool closeRequest) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       request.response.close();
     });
@@ -29,7 +29,7 @@
 }
 
 void testHttp11Close(bool closeRequest) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
      request.response.close();
     });
@@ -50,7 +50,7 @@
 }
 
 void testStreamResponse() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       var timer = new Timer.periodic(const Duration(milliseconds: 0), (_) {
         request.response.write(
diff --git a/tests/standalone/io/http_connection_header_test.dart b/tests/standalone/io/http_connection_header_test.dart
index 9d43624..cd37ead 100644
--- a/tests/standalone/io/http_connection_header_test.dart
+++ b/tests/standalone/io/http_connection_header_test.dart
@@ -32,7 +32,7 @@
 }
 
 void test(int totalConnections, bool clientPersistentConnection) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((HttpRequest request) {
       // Check expected request.
       Expect.equals(clientPersistentConnection, request.persistentConnection);
diff --git a/tests/standalone/io/http_content_length_test.dart b/tests/standalone/io/http_content_length_test.dart
index 4efd9af..335121d 100644
--- a/tests/standalone/io/http_content_length_test.dart
+++ b/tests/standalone/io/http_content_length_test.dart
@@ -9,7 +9,7 @@
 
 void testNoBody(int totalConnections, bool explicitContentLength) {
   var errors = 0;
-  HttpServer.bind("127.0.0.1", 0, totalConnections).then((server) {
+  HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
     server.listen(
         (HttpRequest request) {
           Expect.equals("0", request.headers.value('content-length'));
@@ -75,7 +75,7 @@
 }
 
 void testBody(int totalConnections, bool useHeader) {
-  HttpServer.bind("127.0.0.1", 0, totalConnections).then((server) {
+  HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
     int serverCount = 0;
     server.listen(
         (HttpRequest request) {
@@ -153,7 +153,7 @@
 }
 
 void testBodyChunked(int totalConnections, bool useHeader) {
-  HttpServer.bind("127.0.0.1", 0, totalConnections).then((server) {
+  HttpServer.bind("127.0.0.1", 0, backlog: totalConnections).then((server) {
     server.listen(
         (HttpRequest request) {
           Expect.isNull(request.headers.value('content-length'));
@@ -229,7 +229,7 @@
 }
 
 void testSetContentLength() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
         (HttpRequest request) {
           var response = request.response;
diff --git a/tests/standalone/io/http_detach_socket_test.dart b/tests/standalone/io/http_detach_socket_test.dart
index 7d14b37..2345079 100644
--- a/tests/standalone/io/http_detach_socket_test.dart
+++ b/tests/standalone/io/http_detach_socket_test.dart
@@ -12,7 +12,7 @@
 import "dart:isolate";
 
 void testServerDetachSocket() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       var response = request.response;
       response.contentLength = 0;
@@ -48,7 +48,7 @@
 }
 
 void testBadServerDetachSocket() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       var response = request.response;
       response.contentLength = 0;
@@ -68,7 +68,7 @@
 }
 
 void testClientDetachSocket() {
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind("127.0.0.1", 0).then((server) {
     server.listen((socket) {
       socket.write("HTTP/1.1 200 OK\r\n"
                        "\r\n"
diff --git a/tests/standalone/io/http_head_test.dart b/tests/standalone/io/http_head_test.dart
index ea5974b..4874e47 100644
--- a/tests/standalone/io/http_head_test.dart
+++ b/tests/standalone/io/http_head_test.dart
@@ -6,7 +6,7 @@
 import "dart:io";
 
 void testHEAD(int totalConnections) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
         var response = request.response;
         if (request.uri.path == "/test100") {
diff --git a/tests/standalone/io/http_headers_state_test.dart b/tests/standalone/io/http_headers_state_test.dart
index db4cdc1..42e5384 100644
--- a/tests/standalone/io/http_headers_state_test.dart
+++ b/tests/standalone/io/http_headers_state_test.dart
@@ -8,7 +8,7 @@
 import "dart:io";
 
 void test(int totalConnections, [String body]) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
 
     server.listen((HttpRequest request) {
       HttpResponse response = request.response;
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index 365ce29..197b11a 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -23,7 +23,7 @@
     Future f = secure
         ? HttpServer.bindSecure(
             "localhost", 0, certificateName: 'localhost_cert')
-        : HttpServer.bind("localhost");
+        : HttpServer.bind("localhost", 0);
     return f.then((s) {
       server = s;
       x.complete(this);
@@ -97,7 +97,7 @@
 
   Future<ProxyServer> start() {
     var x = new Completer();
-    HttpServer.bind("localhost").then((s) {
+    HttpServer.bind("localhost", 0).then((s) {
       server = s;
       x.complete(this);
       server.listen((HttpRequest request) {
diff --git a/tests/standalone/io/http_read_test.dart b/tests/standalone/io/http_read_test.dart
index e9f9cfc..e5f543e 100644
--- a/tests/standalone/io/http_read_test.dart
+++ b/tests/standalone/io/http_read_test.dart
@@ -126,7 +126,7 @@
   void dispatch(message, SendPort replyTo) {
     if (message.isStart) {
       try {
-        HttpServer.bind().then((server) {
+        HttpServer.bind("127.0.0.1", 0).then((server) {
           _server = server;
           _server.listen(_requestReceivedHandler);
           replyTo.send(
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index adcd6c3..363f8d0 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -10,7 +10,7 @@
 
 Future<HttpServer> setupServer() {
   Completer completer = new Completer();
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
 
     var handlers = new Map<String, Function>();
     addRequestHandler(String path, void handler(HttpRequest request,
diff --git a/tests/standalone/io/http_request_pipeling_test.dart b/tests/standalone/io/http_request_pipeling_test.dart
index 152fd15..682c592 100644
--- a/tests/standalone/io/http_request_pipeling_test.dart
+++ b/tests/standalone/io/http_request_pipeling_test.dart
@@ -14,7 +14,7 @@
 void main() {
   final int REQUEST_COUNT = 100;
   int count = 0;
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((HttpRequest request) {
       count++;
       request.response.write(request.uri.path);
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 d9c0113..c4ec244 100644
--- a/tests/standalone/io/http_server_early_client_close_test.dart
+++ b/tests/standalone/io/http_server_early_client_close_test.dart
@@ -135,7 +135,7 @@
 }
 
 void testEarlyClose3() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       var subscription;
       subscription = request.listen(
diff --git a/tests/standalone/io/http_server_response_test.dart b/tests/standalone/io/http_server_response_test.dart
index 2df33cd..d27dcc7 100644
--- a/tests/standalone/io/http_server_response_test.dart
+++ b/tests/standalone/io/http_server_response_test.dart
@@ -13,7 +13,7 @@
 import "dart:typed_data";
 
 void testServerRequest(void handler(server, request), {int bytes}) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       handler(server, request);
     });
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index bd8362e..afdd819 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -39,7 +39,7 @@
   }
 
   // Test two connection after each other.
-  ServerSocket.bind().then((s) {
+  ServerSocket.bind("127.0.0.1", 0).then((s) {
     socket = s;
     server = new HttpServer.listenOn(socket);
     ReceivePort serverPort = new ReceivePort();
diff --git a/tests/standalone/io/http_session_test.dart b/tests/standalone/io/http_session_test.dart
index 6c9d565..4fe3d9d 100644
--- a/tests/standalone/io/http_session_test.dart
+++ b/tests/standalone/io/http_session_test.dart
@@ -37,7 +37,7 @@
 
 void testSessions(int sessionCount) {
   var client = new HttpClient();
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     var sessions = new Set();
     server.listen((request) {
       sessions.add(request.session.id);
@@ -67,7 +67,7 @@
 
 void testTimeout(int sessionCount) {
   var client = new HttpClient();
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.sessionTimeout = 0;
     var timeouts = [];
     server.listen((request) {
@@ -103,7 +103,7 @@
 }
 
 void testSessionsData() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     bool firstHit = false;
     bool secondHit = false;
     server.listen((request) {
@@ -150,8 +150,51 @@
   });
 }
 
+void testSessionsDestroy() {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
+    bool firstHit = false;
+    server.listen((request) {
+      var session = request.session;
+      if (session.isNew) {
+        Expect.isFalse(firstHit);
+        firstHit = true;
+      } else {
+        Expect.isTrue(firstHit);
+        session.destroy();
+        var session2 = request.session;
+        Expect.notEquals(session.id, session2.id);
+      };
+      request.response.close();
+    });
+
+    var client = new HttpClient();
+    client.get("127.0.0.1", server.port, "/")
+      .then((request) => request.close())
+      .then((response) {
+        response.listen((_) {}, onDone: () {
+          var id = getSessionId(response.cookies);
+          Expect.isNotNull(id);
+          client.get("127.0.0.1", server.port, "/")
+            .then((request) {
+              request.cookies.add(new Cookie(SESSION_ID, id));
+              return request.close();
+            })
+            .then((response) {
+              response.listen((_) {}, onDone: () {
+                Expect.isTrue(firstHit);
+                Expect.notEquals(id, getSessionId(response.cookies));
+                server.close();
+                client.close();
+              });
+            });
+        });
+      });
+  });
+}
+
 void main() {
   testSessions(1);
   testTimeout(5);
   testSessionsData();
+  testSessionsDestroy();
 }
diff --git a/tests/standalone/io/http_shutdown_test.dart b/tests/standalone/io/http_shutdown_test.dart
index 1cf4803..f6b1424 100644
--- a/tests/standalone/io/http_shutdown_test.dart
+++ b/tests/standalone/io/http_shutdown_test.dart
@@ -13,7 +13,7 @@
 
 void test1(int totalConnections) {
   // Server which just closes immediately.
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((HttpRequest request) {
       request.response.close();
     });
@@ -39,7 +39,7 @@
 
 void test2(int totalConnections, int outputStreamWrites) {
   // Server which responds without waiting for request body.
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((HttpRequest request) {
       request.response.write("!dlrow ,olleH");
       request.response.close();
@@ -83,7 +83,7 @@
 
 void test3(int totalConnections) {
   // Server which responds when request body has been received.
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
 
   server.listen((HttpRequest request) {
     request.listen((_) {}, onDone: () {
@@ -117,7 +117,7 @@
 
 
 void test4() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
 
   server.listen((var request) {
     request.listen((_) {}, onDone: () {
@@ -145,7 +145,7 @@
 
 
 void test5(int totalConnections) {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen(
         (request) {
           request.listen(
diff --git a/tests/standalone/io/raw_secure_server_closing_test.dart b/tests/standalone/io/raw_secure_server_closing_test.dart
index 11e641b..c1b7ddc 100644
--- a/tests/standalone/io/raw_secure_server_closing_test.dart
+++ b/tests/standalone/io/raw_secure_server_closing_test.dart
@@ -24,7 +24,7 @@
       .then((_) {
         port.close();
       });
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     server.listen((serverConnection) {
       serverConnection.listen((event) {
         if (toClose == "server" || event == RawSocketEvent.READ_CLOSED) {
@@ -54,7 +54,7 @@
 
 void testCloseBothEnds() {
   ReceivePort port = new ReceivePort();
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     var clientEndFuture = RawSecureSocket.connect(HOST_NAME, server.port);
     server.listen((serverEnd) {
       clientEndFuture.then((clientEnd) {
@@ -76,8 +76,8 @@
 
   RawSecureServerSocket.bind(HOST_NAME,
                              0,
-                             2 * socketCount,
-                             CERTIFICATE).then((server) {
+                             CERTIFICATE,
+                             backlog: 2 * socketCount).then((server) {
     Expect.isTrue(server.port > 0);
     var subscription;
     subscription = server.listen((connection) {
@@ -116,7 +116,7 @@
   ReceivePort port = new ReceivePort();
   List ends = [];
 
-  RawSecureServerSocket.bind(HOST_NAME, 0, 15, CERTIFICATE).then((server) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     Expect.isTrue(server.port > 0);
     void checkDone() {
       if (ends.length < 2 * socketCount) return;
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index 2ca5688..a07083b 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -17,7 +17,7 @@
 
 void testSimpleBind() {
   ReceivePort port = new ReceivePort();
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((s) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((s) {
     Expect.isTrue(s.port > 0);
     s.close();
     port.close();
@@ -30,7 +30,7 @@
   port.receive((_, __) { count++; if (count == 3) port.close(); });
 
   // Bind to a unknown DNS name.
-  RawSecureServerSocket.bind("ko.faar.__hest__", 0, 5, CERTIFICATE).then((_) {
+  RawSecureServerSocket.bind("ko.faar.__hest__", 0, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
   }).catchError((error) {
     Expect.isTrue(error is SocketIOException);
@@ -38,7 +38,7 @@
   });
 
   // Bind to an unavaliable IP-address.
-  RawSecureServerSocket.bind("8.8.8.8", 0, 5, CERTIFICATE).then((_) {
+  RawSecureServerSocket.bind("8.8.8.8", 0, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
   }).catchError((error) {
     Expect.isTrue(error is SocketIOException);
@@ -49,10 +49,9 @@
   // Either an error or a successful bind is allowed.
   // Windows platforms allow multiple binding to the same socket, with
   // unpredictable results.
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((s) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((s) {
     RawSecureServerSocket.bind(HOST_NAME,
                                s.port,
-                               5,
                                CERTIFICATE).then((t) {
       Expect.equals('windows', Platform.operatingSystem);
       Expect.equals(s.port, t.port);
@@ -71,7 +70,7 @@
 
 void testSimpleConnect(String certificate) {
   ReceivePort port = new ReceivePort();
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, certificate).then((server) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, certificate).then((server) {
     var clientEndFuture = RawSecureSocket.connect(HOST_NAME, server.port);
     server.listen((serverEnd) {
       clientEndFuture.then((clientEnd) {
@@ -86,7 +85,7 @@
 
 void testSimpleConnectFail(String certificate) {
   ReceivePort port = new ReceivePort();
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, certificate).then((server) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, certificate).then((server) {
     var clientEndFuture = RawSecureSocket.connect(HOST_NAME, server.port)
       .then((clientEnd) {
         Expect.fail("No client connection expected.");
@@ -106,7 +105,7 @@
 
 void testServerListenAfterConnect() {
   ReceivePort port = new ReceivePort();
-  RawSecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  RawSecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     Expect.isTrue(server.port > 0);
     var clientEndFuture = RawSecureSocket.connect(HOST_NAME, server.port);
     new Timer(const Duration(milliseconds: 500), () {
@@ -430,9 +429,9 @@
 
   if (listenSecure) {
     RawSecureServerSocket.bind(
-        HOST_NAME, 0, 5, CERTIFICATE).then(serverReady);
+        HOST_NAME, 0, CERTIFICATE).then(serverReady);
   } else {
-    RawServerSocket.bind(HOST_NAME, 0, 5).then(serverReady);
+    RawServerSocket.bind(HOST_NAME, 0).then(serverReady);
   }
 }
 
diff --git a/tests/standalone/io/raw_server_socket_cancel_test.dart b/tests/standalone/io/raw_server_socket_cancel_test.dart
index 1b9fe0d..b03b5c7 100644
--- a/tests/standalone/io/raw_server_socket_cancel_test.dart
+++ b/tests/standalone/io/raw_server_socket_cancel_test.dart
@@ -21,7 +21,7 @@
 
   ReceivePort port = new ReceivePort();
 
-  RawServerSocket.bind("127.0.0.1", 0, backlog).then((server) {
+  RawServerSocket.bind("127.0.0.1", 0, backlog: backlog).then((server) {
     Expect.isTrue(server.port > 0);
 
     void checkDone() {
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index 23fc6a5..ed5c494 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -15,12 +15,12 @@
 void testArguments() {
   Expect.throws(() => RawServerSocket.bind("127.0.0.1", 65536));
   Expect.throws(() => RawServerSocket.bind("127.0.0.1", -1));
-  Expect.throws(() => RawServerSocket.bind("127.0.0.1", 0, -1));
+  Expect.throws(() => RawServerSocket.bind("127.0.0.1", 0, backlog: -1));
 }
 
 void testSimpleBind() {
   ReceivePort port = new ReceivePort();
-  RawServerSocket.bind().then((s) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((s) {
     Expect.isTrue(s.port > 0);
     port.close();
   });
@@ -32,7 +32,7 @@
   port.receive((_, __) { count++; if (count == 3) port.close(); });
 
   // Bind to a unknown DNS name.
-  RawServerSocket.bind("ko.faar.__hest__")
+  RawServerSocket.bind("ko.faar.__hest__", 0)
       .then((_) { Expect.fail("Failure expected"); } )
       .catchError((error) {
         Expect.isTrue(error is SocketIOException);
@@ -40,7 +40,7 @@
       });
 
   // Bind to an unavaliable IP-address.
-  RawServerSocket.bind("8.8.8.8")
+  RawServerSocket.bind("8.8.8.8", 0)
       .then((_) { Expect.fail("Failure expected"); } )
       .catchError((error) {
         Expect.isTrue(error is SocketIOException);
@@ -51,9 +51,9 @@
   // Either an error or a successful bind is allowed.
   // Windows platforms allow multiple binding to the same socket, with
   // unpredictable results.
-  RawServerSocket.bind("127.0.0.1")
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0)
       .then((s) {
-        RawServerSocket.bind("127.0.0.1", s.port)
+          RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, s.port)
             .then((t) {
               Expect.equals('windows', Platform.operatingSystem);
               Expect.equals(s.port, t.port);
@@ -69,7 +69,7 @@
 
 void testSimpleConnect() {
   ReceivePort port = new ReceivePort();
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((_) { });
     RawSocket.connect("127.0.0.1", server.port).then((_) {
       server.close();
@@ -87,7 +87,7 @@
       .then((_) {
         port.close();
       });
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((serverConnection) {
       serverConnection.listen((event) {
         if (toClose == "server" || event == RawSocketEvent.READ_CLOSED) {
@@ -117,7 +117,7 @@
 
 void testServerListenAfterConnect() {
   ReceivePort port = new ReceivePort();
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     Expect.isTrue(server.port > 0);
     RawSocket.connect("127.0.0.1", server.port).then((_) {
       server.listen((_) {
@@ -153,7 +153,7 @@
     }
   }
 
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((client) {
       int bytesRead = 0;
       int bytesWritten = 0;
@@ -235,7 +235,7 @@
 
   ReceivePort port = new ReceivePort();
 
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     Expect.isTrue(server.port > 0);
     var subscription = server.listen((_) {
       Expect.isTrue(resumed);
@@ -276,7 +276,7 @@
 
   ReceivePort port = new ReceivePort();
 
-  RawServerSocket.bind().then((server) {
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     Expect.isTrue(server.port > 0);
     server.listen((client) {
       List<int> data = new List<int>.filled(messageSize, 0);
diff --git a/tests/standalone/io/raw_socket_write_destroy_test.dart b/tests/standalone/io/raw_socket_write_destroy_test.dart
index 13ecaf3..b5eed7c 100644
--- a/tests/standalone/io/raw_socket_write_destroy_test.dart
+++ b/tests/standalone/io/raw_socket_write_destroy_test.dart
@@ -15,7 +15,7 @@
 
 void testWriteDestroyServer() {
   int WROTE = 100000;
-  RawServerSocket.bind(SERVER_ADDRESS).then((server) {
+  RawServerSocket.bind(SERVER_ADDRESS, 0).then((server) {
     server.listen((socket) {
       socket.writeEventsEnabled = false;
 
@@ -54,7 +54,7 @@
 
 void testWriteDestroyClient() {
   int WROTE = 100000;
-  RawServerSocket.bind(SERVER_ADDRESS).then((server) {
+  RawServerSocket.bind(SERVER_ADDRESS, 0).then((server) {
     server.listen((socket) {
       var bytes = 0;
       socket.listen((e) {
diff --git a/tests/standalone/io/regress_8828_test.dart b/tests/standalone/io/regress_8828_test.dart
index 7842be5..c33a56d 100644
--- a/tests/standalone/io/regress_8828_test.dart
+++ b/tests/standalone/io/regress_8828_test.dart
@@ -11,7 +11,7 @@
 import 'dart:io';
 
 void main() {
-  HttpServer.bind().then((server) {
+  HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
       request.response
         ..writeln("first line")
diff --git a/tests/standalone/io/secure_client_raw_server_test.dart b/tests/standalone/io/secure_client_raw_server_test.dart
index e72036a..1fce350 100644
--- a/tests/standalone/io/secure_client_raw_server_test.dart
+++ b/tests/standalone/io/secure_client_raw_server_test.dart
@@ -17,7 +17,6 @@
 Future<RawSecureServerSocket> startEchoServer() {
   return RawSecureServerSocket.bind(HOST_NAME,
                                     0,
-                                    5,
                                     CERTIFICATE).then((server) {
     server.listen((RawSecureSocket client) {
       List<List<int>> readChunks = <List<int>>[];
diff --git a/tests/standalone/io/secure_client_server_test.dart b/tests/standalone/io/secure_client_server_test.dart
index 494d54c..11cf433 100644
--- a/tests/standalone/io/secure_client_server_test.dart
+++ b/tests/standalone/io/secure_client_server_test.dart
@@ -17,7 +17,6 @@
 Future<SecureServerSocket> startEchoServer() {
   return SecureServerSocket.bind(HOST_NAME,
                                  0,
-                                 5,
                                  CERTIFICATE).then((server) {
     server.listen((SecureSocket client) {
       client.fold(<int>[], (message, data) => message..addAll(data))
diff --git a/tests/standalone/io/secure_multiple_client_server_test.dart b/tests/standalone/io/secure_multiple_client_server_test.dart
index 69dfb92..e0e91e4 100644
--- a/tests/standalone/io/secure_multiple_client_server_test.dart
+++ b/tests/standalone/io/secure_multiple_client_server_test.dart
@@ -17,7 +17,6 @@
 Future<SecureServerSocket> startServer() {
   return SecureServerSocket.bind(HOST_NAME,
                                  0,
-                                 5,
                                  CERTIFICATE).then((server) {
     server.listen((SecureSocket client) {
       client.fold(<int>[], (message, data) => message..addAll(data))
diff --git a/tests/standalone/io/secure_server_client_certificate_test.dart b/tests/standalone/io/secure_server_client_certificate_test.dart
index 4edabef..35475e2 100644
--- a/tests/standalone/io/secure_server_client_certificate_test.dart
+++ b/tests/standalone/io/secure_server_client_certificate_test.dart
@@ -14,7 +14,6 @@
   ReceivePort port = new ReceivePort();
   SecureServerSocket.bind(HOST_NAME,
                           0,
-                          5,
                           CERTIFICATE,
                           requestClientCertificate: true).then((server) {
     var clientEndFuture = SecureSocket.connect(HOST_NAME,
@@ -43,7 +42,6 @@
   ReceivePort port = new ReceivePort();
   SecureServerSocket.bind(HOST_NAME,
                           0,
-                          5,
                           CERTIFICATE,
                           requireClientCertificate: true).then((server) {
     var clientEndFuture = SecureSocket.connect(HOST_NAME,
@@ -72,7 +70,6 @@
   ReceivePort port = new ReceivePort();
   SecureServerSocket.bind(HOST_NAME,
                           0,
-                          5,
                           CERTIFICATE,
                           requestClientCertificate: true).then((server) {
     var clientEndFuture = SecureSocket.connect(HOST_NAME,
@@ -95,7 +92,6 @@
   bool clientError = false;
   SecureServerSocket.bind(HOST_NAME,
                           0,
-                          5,
                           CERTIFICATE,
                           requireClientCertificate: true).then((server) {
     Future clientDone = SecureSocket.connect(HOST_NAME, server.port)
diff --git a/tests/standalone/io/secure_server_closing_test.dart b/tests/standalone/io/secure_server_closing_test.dart
index 2e0bd4b..0d27cb2 100644
--- a/tests/standalone/io/secure_server_closing_test.dart
+++ b/tests/standalone/io/secure_server_closing_test.dart
@@ -24,7 +24,7 @@
       .then((_) {
         port.close();
       });
-  SecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     server.listen((serverConnection) {
       serverConnection.listen(
         (data) {
@@ -60,7 +60,7 @@
 
 void testCloseBothEnds() {
   ReceivePort port = new ReceivePort();
-  SecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     var clientEndFuture = SecureSocket.connect(HOST_NAME, server.port);
     server.listen((serverEnd) {
       clientEndFuture.then((clientEnd) {
@@ -82,8 +82,8 @@
 
   SecureServerSocket.bind(HOST_NAME,
                           0,
-                          2 * socketCount,
-                          CERTIFICATE).then((server) {
+                          CERTIFICATE,
+                          backlog: 2 * socketCount).then((server) {
     Expect.isTrue(server.port > 0);
     var subscription;
     subscription = server.listen((connection) {
@@ -124,7 +124,7 @@
   ReceivePort port = new ReceivePort();
   List ends = [];
 
-  SecureServerSocket.bind(HOST_NAME, 0, 15, CERTIFICATE).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     Expect.isTrue(server.port > 0);
     void checkDone() {
       if (ends.length < 2 * socketCount) return;
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index bf1bc05..478a53a 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -17,7 +17,7 @@
 
 void testSimpleBind() {
   ReceivePort port = new ReceivePort();
-  SecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((s) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((s) {
     Expect.isTrue(s.port > 0);
     s.close();
     port.close();
@@ -30,7 +30,7 @@
   port.receive((_, __) { count++; if (count == 3) port.close(); });
 
   // Bind to a unknown DNS name.
-  SecureServerSocket.bind("ko.faar.__hest__", 0, 5, CERTIFICATE).then((_) {
+  SecureServerSocket.bind("ko.faar.__hest__", 0, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
   }).catchError((error) {
     Expect.isTrue(error is SocketIOException);
@@ -38,7 +38,7 @@
   });
 
   // Bind to an unavaliable IP-address.
-  SecureServerSocket.bind("8.8.8.8", 0, 5, CERTIFICATE).then((_) {
+  SecureServerSocket.bind("8.8.8.8", 0, CERTIFICATE).then((_) {
     Expect.fail("Failure expected");
   }).catchError((error) {
     Expect.isTrue(error is SocketIOException);
@@ -49,10 +49,9 @@
   // Either an error or a successful bind is allowed.
   // Windows platforms allow multiple binding to the same socket, with
   // unpredictable results.
-  SecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((s) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((s) {
     SecureServerSocket.bind(HOST_NAME,
                             s.port,
-                            5,
                             CERTIFICATE).then((t) {
       Expect.equals('windows', Platform.operatingSystem);
       Expect.equals(s.port, t.port);
@@ -70,7 +69,7 @@
 
 void testSimpleConnect(String certificate) {
   ReceivePort port = new ReceivePort();
-  SecureServerSocket.bind(HOST_NAME, 0, 5, certificate).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, certificate).then((server) {
     var clientEndFuture = SecureSocket.connect(HOST_NAME, server.port);
     server.listen((serverEnd) {
       clientEndFuture.then((clientEnd) {
@@ -85,7 +84,7 @@
 
 void testSimpleConnectFail(String certificate) {
   ReceivePort port = new ReceivePort();
-  SecureServerSocket.bind(HOST_NAME, 0, 5, certificate).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, certificate).then((server) {
     var clientEndFuture = SecureSocket.connect(HOST_NAME, server.port)
       .then((clientEnd) {
         Expect.fail("No client connection expected.");
@@ -105,7 +104,7 @@
 
 void testServerListenAfterConnect() {
   ReceivePort port = new ReceivePort();
-  SecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     Expect.isTrue(server.port > 0);
     var clientEndFuture = SecureSocket.connect(HOST_NAME, server.port);
     new Timer(const Duration(milliseconds: 500), () {
@@ -146,7 +145,7 @@
     }
   }
 
-  SecureServerSocket.bind(HOST_NAME, 0, 5, CERTIFICATE).then((server) {
+  SecureServerSocket.bind(HOST_NAME, 0, CERTIFICATE).then((server) {
     server.listen((client) {
       int bytesRead = 0;
       int bytesWritten = 0;
diff --git a/tests/standalone/io/secure_session_resume_test.dart b/tests/standalone/io/secure_session_resume_test.dart
index 532dcec..17873e8 100644
--- a/tests/standalone/io/secure_session_resume_test.dart
+++ b/tests/standalone/io/secure_session_resume_test.dart
@@ -26,7 +26,6 @@
 Future<SecureServerSocket> startServer() {
   return SecureServerSocket.bind(HOST_NAME,
                                  0,
-                                 5,
                                  CERTIFICATE).then((server) {
     server.listen((SecureSocket client) {
       client.fold(<int>[], (message, data) => message..addAll(data))
diff --git a/tests/standalone/io/socket_close_test.dart b/tests/standalone/io/socket_close_test.dart
index 791c679..d89c798 100644
--- a/tests/standalone/io/socket_close_test.dart
+++ b/tests/standalone/io/socket_close_test.dart
@@ -339,7 +339,7 @@
       _closeEvents = 0;
       _iterations = 0;
       _mode = message;
-      ServerSocket.bind().then((server) {
+      ServerSocket.bind("127.0.0.1", 0).then((server) {
         _server = server;
         _server.listen(
           (socket) {
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index 4713c74c..79f5b72 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -15,7 +15,7 @@
     bool exceptionCaught = false;
     bool wrongExceptionCaught = false;
 
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       Expect.isNotNull(server);
       server.close();
       try {
@@ -29,7 +29,7 @@
       Expect.equals(true, !wrongExceptionCaught);
 
       // Test invalid host.
-      ServerSocket.bind("__INVALID_HOST__")
+      ServerSocket.bind("__INVALID_HOST__", 0)
         .then((server) { })
         .catchError((e) => e is SocketIOException);
     });
@@ -37,7 +37,7 @@
 
   static void serverSocketCloseListenTest() {
     var port = new ReceivePort();
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       Socket.connect("127.0.0.1", server.port).then((socket) {
         server.close();
         server.listen(
@@ -49,7 +49,7 @@
 
   static void serverSocketListenCloseTest() {
     var port = new ReceivePort();
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       Socket.connect("127.0.0.1", server.port).then((socket) {
         server.listen(
           (incoming) => server.close(),
@@ -62,7 +62,7 @@
     bool exceptionCaught = false;
     bool wrongExceptionCaught = false;
 
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       Expect.isNotNull(server);
      int port = server.port;
       Socket.connect("127.0.0.1", port).then((client) {
@@ -104,7 +104,7 @@
   }
 
   static void clientSocketDestroyNoErrorTest() {
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       server.listen((socket) {
         socket.pipe(socket);
       });
@@ -116,7 +116,7 @@
   }
 
   static void clientSocketAddDestroyNoErrorTest() {
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       server.listen((socket) {
         // Passive block data by not sobscribing to socket.
       });
@@ -129,7 +129,7 @@
   }
 
   static void clientSocketAddCloseNoErrorTest() {
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       var completer = new Completer();
       server.listen((socket) {
         // The socket is 'paused' until the future completes.
@@ -153,7 +153,7 @@
   }
 
   static void clientSocketAddCloseErrorTest() {
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       var completer = new Completer();
       server.listen((socket) {
         completer.future.then((_) => socket.destroy());
@@ -192,7 +192,7 @@
   }
 
   static void clientSocketAddCloseResultErrorTest() {
-    ServerSocket.bind().then((server) {
+    ServerSocket.bind("127.0.0.1", 0).then((server) {
       var completer = new Completer();
       server.listen((socket) {
         completer.future.then((_) => socket.destroy());
diff --git a/tests/standalone/io/socket_info_test.dart b/tests/standalone/io/socket_info_test.dart
index f626d66..395b6e4 100644
--- a/tests/standalone/io/socket_info_test.dart
+++ b/tests/standalone/io/socket_info_test.dart
@@ -6,7 +6,7 @@
 import "dart:io";
 
 void testHostAndPort() {
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind("127.0.0.1", 0).then((server) {
 
     Socket.connect("127.0.0.1", server.port).then((clientSocket) {
       server.listen((socket) {
diff --git a/tests/standalone/io/socket_invalid_arguments_test.dart b/tests/standalone/io/socket_invalid_arguments_test.dart
index 61d526d..e3b8714 100644
--- a/tests/standalone/io/socket_invalid_arguments_test.dart
+++ b/tests/standalone/io/socket_invalid_arguments_test.dart
@@ -25,7 +25,7 @@
 }
 
 testAdd(buffer) {
-  ServerSocket.bind("127.0.0.1", 0, 5).then((server) {
+  ServerSocket.bind("127.0.0.1", 0).then((server) {
     server.listen((socket) => socket.destroy());
     Socket.connect("127.0.0.1", server.port).then((socket) {
       int errors = 0;
@@ -49,7 +49,7 @@
   var server;
   var port = new ReceivePort();
   try {
-    ServerSocket.bind(address, port, backlog)
+    ServerSocket.bind(address, port, backlog: backlog)
         .then((_) { Expect.fail("ServerSocket bound"); });
   } catch (e) {
     port.close();
diff --git a/tests/standalone/io/socket_ipv6_test.dart b/tests/standalone/io/socket_ipv6_test.dart
index 032bd9c..d483b8e 100644
--- a/tests/standalone/io/socket_ipv6_test.dart
+++ b/tests/standalone/io/socket_ipv6_test.dart
@@ -10,7 +10,7 @@
 void testIPv6toIPv6() {
   InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
     InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
-      ServerSocket.bind(serverAddr.first).then((server) {
+        ServerSocket.bind(serverAddr.first, 0).then((server) {
         server.listen((socket) {
           socket.destroy();
           server.close();
@@ -25,7 +25,7 @@
 
 void testIPv4toIPv6() {
   InternetAddress.lookup("::0", type: ANY).then((serverAddr) {
-    ServerSocket.bind(serverAddr.first).then((server) {
+      ServerSocket.bind(serverAddr.first, 0).then((server) {
       server.listen((socket) {
         socket.destroy();
         server.close();
@@ -39,7 +39,7 @@
 
 void testIPv6toIPv4() {
   InternetAddress.lookup("::1", type: ANY).then((clientAddr) {
-    ServerSocket.bind("127.0.0.1").then((server) {
+      ServerSocket.bind("127.0.0.1", 0).then((server) {
       server.listen((socket) {
         throw "Unexpected socket";
       });
@@ -51,7 +51,7 @@
 }
 
 void testIPv4toIPv4() {
-  ServerSocket.bind("127.0.0.1").then((server) {
+  ServerSocket.bind("127.0.0.1", 0).then((server) {
     server.listen((socket) {
       socket.destroy();
       server.close();
@@ -88,6 +88,21 @@
   });
 }
 
+void testIPv4toIPv6_IPV6Only() {
+  InternetAddress.lookup("::0", type: ANY)
+      .then((serverAddr) {
+        ServerSocket.bind(serverAddr.first, 0, v6Only: true)
+            .then((server) {
+              server.listen((socket) {
+                throw "Unexpcted socket";
+              });
+              Socket.connect("127.0.0.1", server.port).catchError((error) {
+                server.close();
+              });
+            });
+      });
+}
+
 void main() {
   testIPv6toIPv6();
   testIPv4toIPv6();
@@ -95,4 +110,6 @@
   testIPv4toIPv4();
   testIPv6Lookup();
   testIPv4Lookup();
+
+  testIPv4toIPv6_IPV6Only();
 }
diff --git a/tests/standalone/io/socket_port_test.dart b/tests/standalone/io/socket_port_test.dart
index d3c0179..d9c75d7 100644
--- a/tests/standalone/io/socket_port_test.dart
+++ b/tests/standalone/io/socket_port_test.dart
@@ -6,7 +6,7 @@
 import "dart:io";
 
 void testPort() {
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind("127.0.0.1", 0).then((server) {
     Socket.connect("127.0.0.1", server.port).then((clientSocket) {
       server.listen((Socket socket) {
           Expect.equals(socket.port, server.port);
diff --git a/tests/standalone/io/socket_test.dart b/tests/standalone/io/socket_test.dart
index 1385b67..e9f2077 100644
--- a/tests/standalone/io/socket_test.dart
+++ b/tests/standalone/io/socket_test.dart
@@ -15,12 +15,12 @@
 void testArguments() {
   Expect.throws(() => ServerSocket.bind("127.0.0.1", 65536));
   Expect.throws(() => ServerSocket.bind("127.0.0.1", -1));
-  Expect.throws(() => ServerSocket.bind("127.0.0.1", 0, -1));
+  Expect.throws(() => ServerSocket.bind("127.0.0.1", 0, backlog: -1));
 }
 
 void testSimpleBind() {
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((s) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((s) {
     Expect.isTrue(s.port > 0);
     port.close();
   });
@@ -32,7 +32,7 @@
   port.receive((_, __) { count++; if (count == 3) port.close(); });
 
   // Bind to a unknown DNS name.
-  ServerSocket.bind("ko.faar.__hest__")
+  ServerSocket.bind("ko.faar.__hest__", 0)
       .then((_) { Expect.fail("Failure expected"); } )
       .catchError((error) {
         Expect.isTrue(error is SocketIOException);
@@ -40,7 +40,7 @@
       });
 
   // Bind to an unavaliable IP-address.
-  ServerSocket.bind("8.8.8.8")
+  ServerSocket.bind("8.8.8.8", 0)
       .then((_) { Expect.fail("Failure expected"); } )
       .catchError((error) {
         Expect.isTrue(error is SocketIOException);
@@ -51,7 +51,7 @@
   // Either an error or a successful bind is allowed.
   // Windows platforms allow multiple binding to the same socket, with
   // unpredictable results.
-  ServerSocket.bind("127.0.0.1")
+  ServerSocket.bind("127.0.0.1", 0)
       .then((s) {
         ServerSocket.bind("127.0.0.1", s.port)
             .then((t) {
@@ -69,7 +69,7 @@
 
 void testConnectNoDestroy() {
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((_) { });
     Socket.connect("127.0.0.1", server.port).then((_) {
       server.close();
@@ -80,7 +80,7 @@
 
 void testConnectImmediateDestroy() {
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((_) { });
     Socket.connect("127.0.0.1", server.port).then((socket) {
       socket.destroy();
@@ -94,7 +94,7 @@
   // Connect socket then immediate close the consumer without
   // listening on the stream.
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((_) { });
     Socket.connect("127.0.0.1", server.port).then((socket) {
       socket.close();
@@ -111,7 +111,7 @@
   // Connect socket write some data immediate close the consumer
   // without listening on the stream.
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((_) { });
     Socket.connect("127.0.0.1", server.port).then((socket) {
       socket.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
@@ -129,7 +129,7 @@
   // Connect socket and listen on the stream. The server closes
   // immediately so only a done event is received.
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen((client) {
                     client.close();
                     client.done.then((_) => client.destroy());
@@ -153,7 +153,7 @@
   // and then closes so both data and a done event is received.
   List<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen(
         (client) {
           client.add(sendData);
@@ -184,7 +184,7 @@
 void testConnectStreamDataCloseCancel(bool useDestroy) {
   List<int> sendData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
   ReceivePort port = new ReceivePort();
-  ServerSocket.bind().then((server) {
+  ServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
     server.listen(
         (client) {
           client.add(sendData);
diff --git a/tests/standalone/io/socket_upgrade_to_secure_test.dart b/tests/standalone/io/socket_upgrade_to_secure_test.dart
index d4448ca..4cf55c8 100644
--- a/tests/standalone/io/socket_upgrade_to_secure_test.dart
+++ b/tests/standalone/io/socket_upgrade_to_secure_test.dart
@@ -12,7 +12,6 @@
 import "dart:io";
 import "dart:isolate";
 
-const HOST_IP = "127.0.0.1";
 const HOST_NAME = "localhost";
 const CERTIFICATE = "localhost_cert";
 
@@ -152,9 +151,8 @@
   }
 
   Future<SecureSocket> connectClient(int port) {
-    var host = hostnameInConnect ? HOST_NAME : HOST_IP;
     if (!handshakeBeforeSecure) {
-      return Socket.connect(host, port).then((socket) {
+      return Socket.connect(HOST_NAME, port).then((socket) {
         var future;
         if (hostnameInConnect) {
           future = SecureSocket.secure(socket);
@@ -167,7 +165,7 @@
         });
       });
     } else {
-      return Socket.connect(host, port).then((socket) {
+      return Socket.connect(HOST_NAME, port).then((socket) {
         return runClientHandshake(socket).then((_) {
             var future;
             if (hostnameInConnect) {
@@ -209,7 +207,7 @@
     });
   }
 
-  ServerSocket.bind(HOST_NAME, 0, 5).then(serverReady);
+  ServerSocket.bind(HOST_NAME, 0).then(serverReady);
 }
 
 main() {
diff --git a/tests/standalone/io/testing_server.dart b/tests/standalone/io/testing_server.dart
index 79f0175..c8bd2b6 100644
--- a/tests/standalone/io/testing_server.dart
+++ b/tests/standalone/io/testing_server.dart
@@ -21,7 +21,7 @@
 
   void dispatch(message, SendPort replyTo) {
     if (message == INIT) {
-      ServerSocket.bind(HOST, 0, 10).then((server) {
+      ServerSocket.bind(HOST, 0).then((server) {
         _server = server;
         _server.listen(
             onConnection,
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 5579e8f..4e5df10 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -32,7 +32,7 @@
                                      certificateName: CERT_NAME)
              : HttpServer.bind(HOST_NAME,
                                0,
-                               backlog);
+                               backlog: backlog);
 
   Future<WebSocket> createClient(int port) =>
     WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
@@ -365,7 +365,7 @@
                                onDone: completer.complete);
             });
 
-        futures.add(client.openUrl("GET", new Uri.fromString('${baseHttpUrl}'))
+        futures.add(client.openUrl("GET", Uri.parse('${baseHttpUrl}'))
              .then((request) => request.close())
              .then((response) {
                response.listen((_) { });
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 37eae94..f342f31 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -5,8 +5,11 @@
 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.
+# Fails because checked-in dart executable is not up to date.
+io/test_runner_test: Fail
+# Fails because checked-in dart executable is not up to date.
+# Skip this because it is leaving temp directories behind when it fails.
+io/skipping_dart2js_compilations_test: Skip
 
 [ $runtime == vm && ( $system == windows ) ]
 io/raw_socket_test: Pass, Fail # Issue 8901
diff --git a/tools/VERSION b/tools/VERSION
index 699b05f..8b16f58 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 5
-BUILD 3
+BUILD 4
 PATCH 0
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 6ecb34e..fb116d1 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -147,7 +147,7 @@
     dom_name = DartDomNameOfAttribute(attribute)
     attr_name = self._renamer.RenameMember(
       self._interface.id, attribute, dom_name, 'get:')
-    if not attr_name or self._IsPrivate(attr_name):
+    if not attr_name:
       return
 
     html_setter_name = self._renamer.RenameMember(
@@ -597,6 +597,3 @@
 
   def _DartType(self, type_name):
     return self._type_registry.DartType(type_name)
-
-  def _IsPrivate(self, name):
-    return name.startswith('_')
diff --git a/tools/dom/scripts/idlrenderer.py b/tools/dom/scripts/idlrenderer.py
index 7c5d634..3c71ff8 100755
--- a/tools/dom/scripts/idlrenderer.py
+++ b/tools/dom/scripts/idlrenderer.py
@@ -179,7 +179,10 @@
       wsp(node.ext_attrs)
       if (node.optional):
         w('optional ')
-      w('%s %s' % (node.type.id, node.id))
+      w(node.type.id)
+      if node.type.nullable:
+        w('?')
+      w(' %s' % node.id)
     else:
       raise TypeError("Expected str or IDLNode but %s found" %
         type(node))
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 130c933..bbd9be3 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -738,6 +738,9 @@
         if argument.ext_attrs.get('TreatNullAs') == 'NullString':
           return True
 
+        if argument.type.nullable:
+          return True
+
         if isinstance(argument, IDLArgument):
           if IsOptional(argument) and not self._IsArgumentOptionalInWebCore(node, argument):
             return True
diff --git a/tools/dom/src/dartium_KeyEvent.dart b/tools/dom/src/dartium_KeyEvent.dart
index 6f2cd78..b627b9c 100644
--- a/tools/dom/src/dartium_KeyEvent.dart
+++ b/tools/dom/src/dartium_KeyEvent.dart
@@ -10,6 +10,8 @@
  * on how we can make this class work with as many international keyboards as
  * possible. Bugs welcome!
  */
+part of html;
+
 class KeyEvent extends _WrappedEvent implements KeyboardEvent {
   /** The parent KeyboardEvent that this KeyEvent is wrapping and "fixing". */
   KeyboardEvent _parent;
diff --git a/tools/gyp/all.gypi b/tools/gyp/all.gypi
index 2d056e8..1e6b313 100644
--- a/tools/gyp/all.gypi
+++ b/tools/gyp/all.gypi
@@ -3,14 +3,13 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # A set of variables needed to build some of the Chrome based subparts of the
-# Dart project (e.g. V8). This is in no way a complete list of variables being
-# defined by Chrome, but just the minimally needed subset.
+# Dart project. This is in no way a complete list of variables being defined
+# by Chrome, but just the minimally needed subset.
 {
   'variables': {
     'library': 'static_library',
     'component': 'static_library',
     'target_arch': 'ia32',
-    'v8_location': '<(DEPTH)/third_party/v8',
     # Flag that tells us whether to build native support for dart:io.
     'dart_io_support': 1,
   },
diff --git a/tools/gyp/common.gypi b/tools/gyp/common.gypi
index 3988dfb..e7ac207 100644
--- a/tools/gyp/common.gypi
+++ b/tools/gyp/common.gypi
@@ -3,8 +3,8 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # A set of variables needed to build some of the Chrome based subparts of the
-# Dash project (e.g. V8). This is in no way a complete list of variables being
-# defined by Chrome, but just the minimally needed subset.
+# Dash project. This is in no way a complete list of variables being defined
+# by Chrome, but just the minimally needed subset.
 
 # Note: this file is similar to all.gypi, but is used when running gyp
 # from subproject directories.  This is deprecated, but still supported.
@@ -13,7 +13,6 @@
     'library': 'static_library',
     'component': 'static_library',
     'target_arch': 'ia32',
-    'v8_location': '<(DEPTH)/../third_party/v8',
     # Flag that tells us whether to build native support for dart:io.
     'dart_io_support': 1,
   },
diff --git a/tools/gyp/configurations.gypi b/tools/gyp/configurations.gypi
index f717f76..f6b1ed0 100644
--- a/tools/gyp/configurations.gypi
+++ b/tools/gyp/configurations.gypi
@@ -8,16 +8,11 @@
       '-Wall',
       '-Wextra', # Also known as -W.
       '-Wno-unused-parameter',
-      # TODO(v8-team): Fix V8 build.
-      #'-Wold-style-cast',
     ],
 
     # Default value.  This may be overridden in a containing project gyp.
     'target_arch%': 'ia32',
 
-    # Don't use separate host toolset for compiling V8.
-    'want_separate_host_toolset': 0,
-
   'conditions': [
     ['"<(target_arch)"=="ia32"', { 'dart_target_arch': 'IA32', }],
     ['"<(target_arch)"=="x64"', { 'dart_target_arch': 'X64', }],
diff --git a/tools/gyp/configurations_make.gypi b/tools/gyp/configurations_make.gypi
index a2b9e8a..abced4d 100644
--- a/tools/gyp/configurations_make.gypi
+++ b/tools/gyp/configurations_make.gypi
@@ -17,8 +17,7 @@
           '-Wnon-virtual-dtor',
           '-Wvla',
           '-Wno-conversion-null',
-          # TODO(v8-team): Fix V8 build.
-          #'-Woverloaded-virtual',
+          '-Woverloaded-virtual',
           '-g3',
           '-ggdb3',
           # TODO(iposva): Figure out if we need to pass anything else.
diff --git a/tools/gyp/configurations_xcode.gypi b/tools/gyp/configurations_xcode.gypi
index 9098beb..791a104 100644
--- a/tools/gyp/configurations_xcode.gypi
+++ b/tools/gyp/configurations_xcode.gypi
@@ -4,8 +4,7 @@
 
 # The purpose of this file and others in this directory is to simulate
 # the Chromium build enviroment. This file is included in all GYP
-# files that are used by the Dart project. This includes V8's GYP
-# files.
+# files that are used by the Dart project.
 
 # READ BEFORE EDITING:
 # Do not add Dart VM specific configuration to this file. Instead,
diff --git a/tools/gyp/find_mac_gcc_version.py b/tools/gyp/find_mac_gcc_version.py
index 0af8412..1f136dd 100755
--- a/tools/gyp/find_mac_gcc_version.py
+++ b/tools/gyp/find_mac_gcc_version.py
@@ -21,10 +21,13 @@
     major = int(matches[0][0])
     minor = int(matches[0][1])
 
-    if major >= 4:
-      return 'com.apple.compilers.llvmgcc42'
-    elif major == 3 and minor >= 1:
+    if major == 3 and minor >= 1:
       return '4.2'
+    elif major == 4 and minor < 5:
+      return 'com.apple.compilers.llvmgcc42'
+    elif major == 4 and minor >= 5:
+      # XCode seems to select the specific clang version automatically
+      return 'com.apple.compilers.llvm.clang.1_0'
     else:
       raise Exception('Unknown XCode Version "%s"' % version_match)
   else:
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index 659fef5..0c6b7a7 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -128,6 +128,15 @@
   return output;
 }
 
+String _buildSummaryEnd(int failedTests) {
+    if (failedTests == 0) {
+      return '\n===\n=== All tests succeeded\n===\n';
+    } else {
+      var pluralSuffix = failedTests != 1 ? 's' : '';
+      return '\n===\n=== ${failedTests} test$pluralSuffix failed\n===\n';
+    }
+}
+
 
 class EventListener {
   void testAdded() { }
@@ -324,12 +333,14 @@
   bool _printSummary;
   var _formatter;
   var _failureSummary = <String>[];
+  var _failedTests= 0;
 
   TestFailurePrinter(this._printSummary,
                      [this._formatter = const Formatter()]);
 
   void done(TestCase test) {
     if (test.lastCommandOutput.unexpectedOutput) {
+      _failedTests++;
       var lines = _buildFailureOutput(test, _formatter);
       for (var line in lines) {
         print(line);
@@ -350,6 +361,8 @@
           print(line);
         }
         print('');
+
+        print(_buildSummaryEnd(_failedTests));
       }
     }
   }
@@ -397,28 +410,9 @@
     _allTestsKnown = true;
   }
 
-  void allDone() {
-    _printStatus();
-  }
-
   void _printStartProgress(TestCase test) {}
   void _printDoneProgress(TestCase test) {}
 
-  void _printStatus() {
-    if (_failedTests == 0) {
-      print('\n===');
-      print('=== All tests succeeded');
-      print('===\n');
-    } else {
-      var pluralSuffix = _failedTests != 1 ? 's' : '';
-      print('\n===');
-      print('=== ${_failedTests} test$pluralSuffix failed');
-      print('===\n');
-    }
-  }
-
-  int get numFailedTests => _failedTests;
-
   int _completedTests() => _passedTests + _failedTests;
 
   int _foundTests = 0;
@@ -521,6 +515,6 @@
       }
       print('');
     }
-    super.allDone();
+    print(_buildSummaryEnd(_failedTests));
   }
 }
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index e888996..ea8877b 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -188,16 +188,6 @@
     }
   }
 
-  /**
-   * The file name of the d8 executable.
-   */
-  String get d8FileName {
-    var suffix = getExecutableSuffix('d8');
-    var d8 = '$buildDir/d8$suffix';
-    TestUtils.ensureExists(d8, configuration);
-    return d8;
-  }
-
   String get dartShellFileName {
     var name = configuration['dart'];
     if (name == '') {
@@ -208,6 +198,14 @@
     return name;
   }
 
+  String get d8FileName {
+    var suffix = getExecutableSuffix('d8');
+    var d8Dir = '${TestUtils.dartDir()}/third_party/d8';
+    var d8 = '$d8Dir/${Platform.operatingSystem}/d8$suffix';
+    TestUtils.ensureExists(d8, configuration);
+    return d8;
+  }
+
   String get jsShellFileName {
     var executableSuffix = getExecutableSuffix('jsshell');
     var executable = 'jsshell$executableSuffix';
diff --git a/utils/tests/testrunner/http_client_tests/http_client_test.dart b/utils/tests/testrunner/http_client_tests/http_client_test.dart
index b43b4c1..b46745a 100644
--- a/utils/tests/testrunner/http_client_tests/http_client_test.dart
+++ b/utils/tests/testrunner/http_client_tests/http_client_test.dart
@@ -13,7 +13,7 @@
   var get = (String what, int code, String text) {
     var c = new Completer();
     HttpClient client = new HttpClient();
-    client.getUrl(new Uri.fromString("http://127.0.0.1:3456/$what"))
+    client.getUrl(Uri.parse("http://127.0.0.1:3456/$what"))
     .then((HttpClientRequest request) {
       // Prepare the request then call close on it to send it.
       return request.close();