Version 0.8.10.0

svn merge -r 29655:29745 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@29746 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/barback/lib/barback.dart b/pkg/barback/lib/barback.dart
index 37c1506..25bb386 100644
--- a/pkg/barback/lib/barback.dart
+++ b/pkg/barback/lib/barback.dart
@@ -8,6 +8,7 @@
 export 'src/asset_id.dart';
 export 'src/asset_set.dart';
 export 'src/barback.dart';
+export 'src/barback_settings.dart';
 export 'src/build_result.dart';
 export 'src/errors.dart' hide flattenAggregateExceptions;
 export 'src/log.dart';
diff --git a/pkg/barback/lib/src/barback_settings.dart b/pkg/barback/lib/src/barback_settings.dart
new file mode 100644
index 0000000..80c276e
--- /dev/null
+++ b/pkg/barback/lib/src/barback_settings.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.barback_settings;
+
+/// A generic settings object for providing configuration details to
+/// [Transformer]s.
+///
+/// Barback does not specify *how* this is provided to transformers. It is up
+/// to a host application to handle this. (For example, pub passes this to the
+/// transformer's constructor.)
+class BarbackSettings {
+  /// An open-ended map of configuration properties specific to this
+  /// transformer.
+  ///
+  /// The contents of the map should be serializable across isolates, but
+  /// otherwise can contain whatever you want.
+  final Map configuration;
+
+  /// The mode that user is running Barback in.
+  ///
+  /// This will be the same for all transformers in a running instance of
+  /// Barback.
+  final BarbackMode mode;
+
+  BarbackSettings(this.configuration, this.mode);
+}
+
+/// Enum-like class for specifying a mode that transformers may be run in.
+///
+/// Note that this is not a *closed* set of enum values. Host applications may
+/// define their own values for this, so a transformer relying on it should
+/// ensure that it behaves sanely with unknown values.
+class BarbackMode {
+  /// The normal mode used during development.
+  static const DEBUG = const BarbackMode._("debug");
+
+  /// The normal mode used to build an application for deploying to production.
+  static const RELEASE = const BarbackMode._("release");
+
+  /// The name of the mode.
+  ///
+  /// By convention, this is a lowercase string.
+  final String name;
+
+  /// Create a mode named [name].
+  factory BarbackMode(String name) {
+    // Use canonical instances of known names.
+    switch (name) {
+      case "debug": return BarbackMode.DEBUG;
+      case "release": return BarbackMode.RELEASE;
+      default:
+        return new BarbackMode._(name);
+    }
+  }
+
+  const BarbackMode._(this.name);
+
+  String toString() => name;
+}
diff --git a/pkg/barback/lib/src/file_pool.dart b/pkg/barback/lib/src/file_pool.dart
index ace7ae4..b8dcc6a 100644
--- a/pkg/barback/lib/src/file_pool.dart
+++ b/pkg/barback/lib/src/file_pool.dart
@@ -32,7 +32,7 @@
   /// open, this will wait for a previously opened file to be closed and then
   /// try again.
   Stream<List<int>> openRead(File file) {
-    return futureStream(_pool.checkOut().then((resource) {
+    return futureStream(_pool.request().then((resource) {
       return file.openRead().transform(new StreamTransformer.fromHandlers(
           handleDone: (sink) {
         sink.close();
diff --git a/pkg/barback/lib/src/pool.dart b/pkg/barback/lib/src/pool.dart
index 3224fbe..23b878f 100644
--- a/pkg/barback/lib/src/pool.dart
+++ b/pkg/barback/lib/src/pool.dart
@@ -12,23 +12,23 @@
 /// Manages an abstract pool of resources with a limit on how many may be in use
 /// at once.
 ///
-/// When a resource is needed, the user should call [checkOut]. When the
-/// returned future completes with a [PoolResource], the resource may be
-/// allocated. Once the resource has been released, the user should call
-/// [PoolResource.release]. The pool will ensure that only a certain number of
-/// [PoolResource]s may be checked out at once.
+/// When a resource is needed, the user should call [request]. When the returned
+/// future completes with a [PoolResource], the resource may be allocated. Once
+/// the resource has been released, the user should call [PoolResource.release].
+/// The pool will ensure that only a certain number of [PoolResource]s may be
+/// allocated at once.
 class Pool {
-  /// Completers for checkouts beyond the first [_maxCheckedOutResources].
+  /// Completers for requests beyond the first [_maxAllocatedResources].
   ///
-  /// When an item is released, the next element of [_pendingResources] will be
-  /// completed.
-  final _pendingResources = new Queue<Completer<PoolResource>>();
+  /// When an item is released, the next element of [_requestedResources] will
+  /// be completed.
+  final _requestedResources = new Queue<Completer<PoolResource>>();
 
-  /// The maximum number of resources that may be checked out at once.
-  final int _maxCheckedOutResources;
+  /// The maximum number of resources that may be allocated at once.
+  final int _maxAllocatedResources;
 
-  /// The number of resources that are currently checked out.
-  int _checkedOutResources = 0;
+  /// The number of resources that are currently allocated.
+  int _allocatedResources = 0;
 
   /// The timeout timer.
   ///
@@ -43,43 +43,43 @@
   Duration _timeout;
 
   /// Creates a new pool with the given limit on how many resources may be
-  /// checked out at once.
+  /// allocated at once.
   ///
   /// If [timeout] is passed, then if that much time passes without any activity
-  /// all pending [checkOut] futures will throw an exception. This is indented
+  /// all pending [request] futures will throw an exception. This is indented
   /// to avoid deadlocks.
-  Pool(this._maxCheckedOutResources, {Duration timeout})
+  Pool(this._maxAllocatedResources, {Duration timeout})
       : _timeout = timeout;
 
-  /// Check out a [PoolResource].
+  /// Request a [PoolResource].
   ///
-  /// If the maximum number of resources is already checked out, this will delay
+  /// If the maximum number of resources is already allocated, this will delay
   /// until one of them is released.
-  Future<PoolResource> checkOut() {
-    if (_checkedOutResources < _maxCheckedOutResources) {
-      _checkedOutResources++;
+  Future<PoolResource> request() {
+    if (_allocatedResources < _maxAllocatedResources) {
+      _allocatedResources++;
       return new Future.value(new PoolResource._(this));
     } else {
       var completer = new Completer<PoolResource>();
-      _pendingResources.add(completer);
-      _heartbeat();
+      _requestedResources.add(completer);
+      _resetTimer();
       return completer.future;
     }
   }
 
-  /// Checks out a resource for the duration of [callback], which may return a
+  /// Requests a resource for the duration of [callback], which may return a
   /// Future.
   ///
   /// The return value of [callback] is piped to the returned Future.
   Future withResource(callback()) {
-    return checkOut().then((resource) =>
+    return request().then((resource) =>
         new Future.sync(callback).whenComplete(resource.release));
   }
 
-  /// If there are any pending checkouts, this will fire the oldest one.
+  /// If there are any pending requests, this will fire the oldest one.
   void _onResourceReleased() {
-    if (_pendingResources.isEmpty) {
-      _checkedOutResources--;
+    if (_requestedResources.isEmpty) {
+      _allocatedResources--;
       if (_timer != null) {
         _timer.cancel();
         _timer = null;
@@ -87,14 +87,13 @@
       return;
     }
 
-    _heartbeat();
-    var pending = _pendingResources.removeFirst();
+    _resetTimer();
+    var pending = _requestedResources.removeFirst();
     pending.complete(new PoolResource._(this));
   }
 
-  /// Indicates that some external action has occurred and the timer should be
-  /// restarted.
-  void _heartbeat() {
+  /// A resource has been requested, allocated, or released.
+  void _resetTimer() {
     if (_timer != null) _timer.cancel();
     if (_timeout == null) {
       _timer = null;
@@ -106,11 +105,11 @@
   /// Handles [_timer] timing out by causing all pending resource completers to
   /// emit exceptions.
   void _onTimeout() {
-    for (var completer in _pendingResources) {
+    for (var completer in _requestedResources) {
       completer.completeException("Pool deadlock: all resources have been "
-          "checked out for too long.", new Trace.current().vmTrace);
+          "allocated for too long.", new Trace.current().vmTrace);
     }
-    _pendingResources.clear();
+    _requestedResources.clear();
     _timer = null;
   }
 }
@@ -128,7 +127,7 @@
   PoolResource._(this._pool);
 
   /// Tells the parent [Pool] that the resource associated with this resource is
-  /// no longer allocated, and that a new [PoolResource] may be checked out.
+  /// no longer allocated, and that a new [PoolResource] may be allocated.
   void release() {
     if (_released) {
       throw new StateError("A PoolResource may only be released once.");
diff --git a/pkg/barback/test/barback_mode_test.dart b/pkg/barback/test/barback_mode_test.dart
new file mode 100644
index 0000000..2d18f09
--- /dev/null
+++ b/pkg/barback/test/barback_mode_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library barback.test.barback_mode_test;
+
+import 'package:barback/barback.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  initConfig();
+  test("constructor uses canonical instances for DEBUG and RELEASE", () {
+    expect(identical(BarbackMode.DEBUG,
+        new BarbackMode(BarbackMode.DEBUG.name)), isTrue);
+    expect(identical(BarbackMode.RELEASE,
+        new BarbackMode(BarbackMode.RELEASE.name)), isTrue);
+  });
+}
diff --git a/pkg/barback/test/package_graph/repetition_test.dart b/pkg/barback/test/package_graph/repetition_test.dart
index cd98440..48462d8 100644
--- a/pkg/barback/test/package_graph/repetition_test.dart
+++ b/pkg/barback/test/package_graph/repetition_test.dart
@@ -9,6 +9,12 @@
 
 import '../utils.dart';
 
+// This tests the behavior of barback under many operations happening in quick
+// succession. Since Barback is so asynchronous, it's easy for it to have subtle
+// dependencies on the commonly-used and -tested usage patterns. These tests
+// exist to stress-test less-common usage patterns in order to root out
+// additional bugs.
+
 main() {
   initConfig();
 
@@ -45,7 +51,7 @@
     initGraph(["app|foo.txt"], {"app": [[rewrite]]});
     updateSources(["app|foo.txt"]);
 
-    for (var i = 0; i < 1; i++) {
+    for (var i = 0; i < 1000; i++) {
       updateTransformers("app", [[rewrite]]);
     }
 
@@ -58,7 +64,7 @@
     initGraph(["app|foo.txt"], {"app": [[rewrite]]});
     updateSources(["app|foo.txt"]);
 
-    for (var i = 0; i < 1; i++) {
+    for (var i = 0; i < 1000; i++) {
       updateTransformers("app", [[rewrite]]);
       updateTransformers("app", [[]]);
     }
diff --git a/pkg/collection_helpers/lib/equality.dart b/pkg/collection_helpers/lib/equality.dart
index c52d30f..3b5f3b4 100644
--- a/pkg/collection_helpers/lib/equality.dart
+++ b/pkg/collection_helpers/lib/equality.dart
@@ -151,21 +151,13 @@
   bool isValidKey(Object o) => o is List<E>;
 }
 
-/**
- * Equality of the elements of two iterables without considering order.
- *
- * Two iterables are considered equal if they have the same number of elements,
- * and the elements of one set can be paired with the elements
- * of the other iterable, so that each pair are equal.
- */
-class UnorderedIterableEquality<E> implements Equality<Iterable<E>> {
+abstract class _UnorderedEquality<E, T extends Iterable<E>>
+    implements Equality<T> {
   final Equality<E> _elementEquality;
 
-  const UnorderedIterableEquality(
-      [Equality<E> elementEquality = const DefaultEquality()])
-      : _elementEquality = elementEquality;
+  const _UnorderedEquality(this._elementEquality);
 
-  bool equals(Iterable<E> e1, Iterable<E> e2) {
+  bool equals(T e1, T e2) {
     if (identical(e1, e2)) return true;
     if (e1 == null || e2 == null) return false;
     HashMap<E, int> counts = new HashMap(
@@ -173,13 +165,13 @@
         hashCode: _elementEquality.hash,
         isValidKey: _elementEquality.isValidKey);
     int length = 0;
-    for (E e in e1) {
+    for (var e in e1) {
       int count = counts[e];
       if (count == null) count = 0;
       counts[e] = count + 1;
       length++;
     }
-    for (E e in e2) {
+    for (var e in e2) {
       int count = counts[e];
       if (count == null || count == 0) return false;
       counts[e] = count - 1;
@@ -188,7 +180,7 @@
     return length == 0;
   }
 
-  int hash(Iterable<E> e) {
+  int hash(T e) {
     int hash = 0;
     for (E element in e) {
       int c = _elementEquality.hash(element);
@@ -199,6 +191,19 @@
     hash = (hash + (hash << 15)) & _HASH_MASK;
     return hash;
   }
+}
+
+/**
+ * Equality of the elements of two iterables without considering order.
+ *
+ * Two iterables are considered equal if they have the same number of elements,
+ * and the elements of one set can be paired with the elements
+ * of the other iterable, so that each pair are equal.
+ */
+class UnorderedIterableEquality<E> extends _UnorderedEquality<E, Iterable<E>> {
+  const UnorderedIterableEquality(
+      [Equality<E> elementEquality = const DefaultEquality()])
+      : super(elementEquality);
 
   bool isValidKey(Object o) => o is Iterable<E>;
 }
@@ -213,16 +218,11 @@
  * This equality behaves the same as [UnorderedIterableEquality] except that
  * it expects sets instead of iterables as arguments.
  */
-class SetEquality<E> extends UnorderedIterableEquality<E>
-                     implements Equality<Set<E>> {
+class SetEquality<E> extends _UnorderedEquality<E, Set<E>> {
   const SetEquality(
       [Equality<E> elementEquality = const DefaultEquality()])
       : super(elementEquality);
 
-  bool equals(Set<E> e1, Set<E> e2) => super.equals(e1, e2);
-
-  int hash(Set<E> e) => super.hash(e);
-
   bool isValidKey(Object o) => o is Set<E>;
 }
 
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 1d147c7..4c1f85d 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -249,11 +249,22 @@
   var libraries = !parseSdk ? _listLibraries(args) : _listSdk();
   if (libraries.isEmpty) throw new StateError('No Libraries.');
   // Finds the root of SDK library based off the location of docgen.
-  var sdkRoot = Platform.script.resolve('../../../sdk').toFilePath();
+
+  var root = findRootDirectory();
+  var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
   logger.info('SDK Root: ${sdkRoot}');
   return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot);
 }
 
+String findRootDirectory() {
+  var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
+  var root = scriptDir;
+  while(path.basename(root) != 'dart') {
+    root = path.dirname(root);
+  }
+  return root;
+}
+
 /**
  * Analyzes set of libraries and provides a mirror system which can be used
  * for static inspection of the source code.
@@ -478,9 +489,9 @@
   //Check if MDN is loaded.
   if (_mdn == null) {
     // Reading in MDN related json file.
-    var mdnDatabase =
-        Platform.script.resolve('../../../utils/apidoc/mdn/database.json');
-    _mdn = JSON.decode(new File(mdnDatabase.toFilePath()).readAsStringSync());
+    var root = findRootDirectory();
+    var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
+    _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
   }
   if (item.comment.isNotEmpty) return;
   var domAnnotation = item.annotations.firstWhere(
diff --git a/pkg/http/lib/src/byte_stream.dart b/pkg/http/lib/src/byte_stream.dart
index c75654a..a154757 100644
--- a/pkg/http/lib/src/byte_stream.dart
+++ b/pkg/http/lib/src/byte_stream.dart
@@ -23,11 +23,8 @@
 
   /// Collects the data of this stream in a [Uint8List].
   Future<Uint8List> toBytes() {
-    /// TODO(nweiz): use BufferList when issue 6409 is fixed.
-    return fold(<int>[], (buffer, chunk) {
-      buffer.addAll(chunk);
-      return buffer;
-    }).then(toUint8List);
+    return fold(new BytesBuilder(), (builder, chunk) => builder..add(chunk))
+      .then((builder) => builder.takeBytes());
   }
 
   /// Collect the data of this stream in a [String], decoded according to
diff --git a/pkg/polymer/lib/transformer.dart b/pkg/polymer/lib/transformer.dart
index a4f0e10..b9649ba 100644
--- a/pkg/polymer/lib/transformer.dart
+++ b/pkg/polymer/lib/transformer.dart
@@ -30,15 +30,19 @@
   PolymerTransformerGroup(TransformOptions options)
       : phases = _createDeployPhases(options);
 
-  PolymerTransformerGroup.asPlugin(Map args) : this(_parseArgs(args));
+  PolymerTransformerGroup.asPlugin(BarbackSettings settings)
+      : this(_parseSettings(settings));
 }
 
-
-TransformOptions _parseArgs(Map args) {
+TransformOptions _parseSettings(BarbackSettings settings) {
+  var args = settings.configuration;
+  bool release = settings.mode == BarbackMode.RELEASE;
+  bool jsOption = args['js'];
+  bool csp = args['csp'] == true; // defaults to false
   return new TransformOptions(
       entryPoints: _readEntrypoints(args['entry_points']),
-      directlyIncludeJS: args['js'] != false, // default to true
-      contentSecurityPolicy: args['csp'] == true); // default to false
+      directlyIncludeJS: jsOption == null ? release : jsOption,
+      contentSecurityPolicy: csp);
 }
 
 _readEntrypoints(value) {
diff --git a/runtime/lib/bool.cc b/runtime/lib/bool.cc
index ae4af27..d575745 100644
--- a/runtime/lib/bool.cc
+++ b/runtime/lib/bool.cc
@@ -24,17 +24,17 @@
   Dart_EnvironmentCallback callback = isolate->environment_callback();
   if (callback != NULL) {
     Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
-    if (Dart_IsError(result)) {
+    if (Dart_IsString(result)) {
+      const char *chars;
+      Dart_StringToCString(result, &chars);
+      if (strcmp("true", chars) == 0) return Bool::True().raw();
+      if (strcmp("false", chars) == 0) return Bool::False().raw();
+    } else if (Dart_IsError(result)) {
       const Object& error =
           Object::Handle(isolate, Api::UnwrapHandle(result));
       Exceptions::ThrowArgumentError(
           String::Handle(
               String::New(Error::Cast(error).ToErrorCString())));
-    } else if (Dart_IsString(result)) {
-      const char *chars;
-      Dart_StringToCString(result, &chars);
-      return (strcmp("true", chars) == 0)
-          ? Bool::True().raw() : Bool::False().raw();
     } else if (!Dart_IsNull(result)) {
       Exceptions::ThrowArgumentError(
           String::Handle(String::New("Illegal environment value")));
diff --git a/runtime/lib/bool_patch.dart b/runtime/lib/bool_patch.dart
index cd6b740..8259f2e 100644
--- a/runtime/lib/bool_patch.dart
+++ b/runtime/lib/bool_patch.dart
@@ -7,7 +7,7 @@
 patch class bool {
 
   /* patch */ const factory bool.fromEnvironment(String name,
-                                                 {bool defaultValue})
+                                                 {bool defaultValue: false})
       native "Bool_fromEnvironment";
 
   int get _identityHashCode {
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index 1d93b40..4e64ea5 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -191,8 +191,8 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
+static RawInteger* ParseInteger(const String& value) {
+  // Used by both Integer_parse and Integer_fromEnvironment.
   if (value.IsOneByteString()) {
     // Quick conversion for unpadded integers in strings.
     const intptr_t len = value.Length();
@@ -225,7 +225,13 @@
     return Integer::New(temp);
   }
 
-  return Object::null();
+  return Integer::null();
+}
+
+
+DEFINE_NATIVE_ENTRY(Integer_parse, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
+  return ParseInteger(value);
 }
 
 
@@ -235,47 +241,22 @@
   // Call the embedder to supply us with the environment.
   Dart_EnvironmentCallback callback = isolate->environment_callback();
   if (callback != NULL) {
-    Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
-    if (Dart_IsError(result)) {
+    Dart_Handle response = callback(Api::NewHandle(isolate, name.raw()));
+    if (Dart_IsString(response)) {
+      const String& value = String::Cast(
+          Object::Handle(isolate, Api::UnwrapHandle(response)));
+      const Integer& result = Integer::Handle(ParseInteger(value));
+      if (!result.IsNull()) {
+        if (result.IsSmi()) return result.raw();
+        return result.CheckAndCanonicalize(NULL);
+      }
+    } else if (Dart_IsError(response)) {
       const Object& error =
-          Object::Handle(isolate, Api::UnwrapHandle(result));
+          Object::Handle(isolate, Api::UnwrapHandle(response));
       Exceptions::ThrowArgumentError(
           String::Handle(
               String::New(Error::Cast(error).ToErrorCString())));
-    } else if (Dart_IsString(result)) {
-      uint8_t* digits;
-      intptr_t digits_len;
-      Dart_StringToUTF8(result, &digits, &digits_len);
-      if (digits_len > 0) {
-        // Check for valid integer literal before constructing integer object.
-        // Skip leading minus if present.
-        if (digits[0] == '-') {
-          digits++;
-          digits_len--;
-        }
-        // Check remaining string for decimal or hex-decimal literal.
-        bool is_number = true;
-        if (digits_len > 2 &&
-            digits[0] == '0' &&
-            (digits[1] == 'x' || digits[1] == 'X')) {
-          for (int i = 2; i < digits_len && is_number; i++) {
-            is_number = ('0' <= digits[i] && digits[i] <= '9') ||
-                        ('A' <= digits[i] && digits[i] <= 'F') ||
-                        ('a' <= digits[i] && digits[i] <= 'f');
-          }
-        } else {
-          for (int i = 0; i < digits_len && is_number; i++) {
-            is_number = '0' <= digits[i] && digits[i] <= '9';
-          }
-        }
-        if (digits_len > 0 && is_number) {
-          const Object& value =
-              Object::Handle(isolate, Api::UnwrapHandle(result));
-          ASSERT(value.IsString());
-          return Integer::NewCanonical(String::Cast(value));
-        }
-      }
-    } else if (!Dart_IsNull(result)) {
+    } else  if (!Dart_IsNull(response)) {
       Exceptions::ThrowArgumentError(
           String::Handle(String::New("Illegal environment value")));
     }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index ab7f258..df716fc 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -60,8 +60,7 @@
                                    class_name,
                                    function_name,
                                    kNumArguments,
-                                   Object::empty_array(),
-                                   Resolver::kIsQualified);
+                                   Object::empty_array());
     ASSERT(!func.IsNull());
     isolate->object_store()->set_receive_port_create_function(func);
   }
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index c11ea61..22b2d47 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -20,6 +20,9 @@
     "Wrap compilation errors that occur during reflective access in a "
     "MirroredCompilationError, rather than suspending the isolate.");
 
+DEFINE_FLAG(bool, support_find_in_context, false,
+    "Experimental support for ClosureMirror.findInContext.");
+
 static RawInstance* CreateMirror(const String& mirror_class_name,
                                  const Array& constructor_arguments) {
   const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary());
@@ -721,12 +724,8 @@
     return result.raw();
   }
 
-  Function& func = Function::Handle();
-  Class& lookup_class = Class::Handle(klass.raw());
-  while (func.IsNull() && !lookup_class.IsNull()) {
-    func ^= lookup_class.LookupStaticFunction(lookup_name);
-    lookup_class = lookup_class.SuperClass();
-  }
+  const Function& func =
+      Function::Handle(klass.LookupStaticFunction(lookup_name));
   if (!func.IsNull()) {
     const Function& closure_function = Function::Handle(
         func.ImplicitClosureFunction());
@@ -1376,31 +1375,12 @@
   GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
   GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
 
-  String& internal_setter_name =
+  const Class& klass = Class::Handle(reflectee.clazz());
+  const String& internal_setter_name =
       String::Handle(Field::SetterName(setter_name));
-  Function& setter = Function::Handle();
+  const Function& setter = Function::Handle(
+      Resolver::ResolveDynamicAnyArgs(klass, internal_setter_name));
 
-  Class& klass = Class::Handle(reflectee.clazz());
-  Field& field = Field::Handle();
-
-  while (!klass.IsNull()) {
-    field = klass.LookupInstanceField(setter_name);
-    if (!field.IsNull() && field.is_final()) {
-      const String& message = String::Handle(
-          String::NewFormatted("%s: cannot set final field '%s'.",
-                               "InstanceMirror_invokeSetter",
-                               setter_name.ToCString()));
-      ThrowMirroredCompilationError(message);
-      UNREACHABLE();
-    }
-    setter = klass.LookupDynamicFunction(internal_setter_name);
-    if (!setter.IsNull()) {
-      break;
-    }
-    klass = klass.SuperClass();
-  }
-
-  // Invoke the setter and return the result.
   const int kNumArgs = 2;
   const Array& args = Array::Handle(Array::New(kNumArgs));
   args.SetAt(0, reflectee);
@@ -1443,6 +1423,10 @@
 
 
 DEFINE_NATIVE_ENTRY(ClosureMirror_find_in_context, 2) {
+  if (!FLAG_support_find_in_context) {
+    return Object::empty_array().raw();
+  }
+
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Array, lookup_parts, arguments->NativeArgAt(1));
   ASSERT(lookup_parts.Length() >= 1 && lookup_parts.Length() <= 3);
@@ -1596,11 +1580,12 @@
 
   // Check for real fields and user-defined setters.
   const Field& field = Field::Handle(klass.LookupStaticField(setter_name));
+  Function& setter = Function::Handle();
   if (field.IsNull()) {
     const String& internal_setter_name = String::Handle(
       Field::SetterName(setter_name));
-    const Function& setter = Function::Handle(
-      klass.LookupStaticFunction(internal_setter_name));
+
+    setter = klass.LookupStaticFunction(internal_setter_name);
 
     if (setter.IsNull() || !setter.is_visible()) {
       ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
@@ -1626,11 +1611,11 @@
   }
 
   if (field.is_final()) {
-    const String& message = String::Handle(
-        String::NewFormatted("%s: cannot set final field '%s'.",
-                             "ClassMirror_invokeSetter",
-                             setter_name.ToCString()));
-    ThrowMirroredCompilationError(message);
+    ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
+                      setter_name,
+                      setter,
+                      InvocationMirror::kStatic,
+                      InvocationMirror::kSetter);
     UNREACHABLE();
   }
 
@@ -1848,12 +1833,13 @@
   // library or in the field's owner class, depending.
   const Field& field = Field::Handle(
       library.LookupLocalField(setter_name));
+  Function& setter = Function::Handle();
 
   if (field.IsNull()) {
     const String& internal_setter_name =
         String::Handle(Field::SetterName(setter_name));
-    const Function& setter = Function::Handle(
-        library.LookupLocalFunction(internal_setter_name));
+
+    setter = library.LookupLocalFunction(internal_setter_name);
     if (setter.IsNull() || !setter.is_visible()) {
       ThrowNoSuchMethod(Instance::null_instance(),
                         setter_name,
@@ -1877,11 +1863,11 @@
   }
 
   if (field.is_final()) {
-    const String& message = String::Handle(
-      String::NewFormatted("%s: cannot set final top-level variable '%s'.",
-                           "LibraryMirror_invokeSetter",
-                           setter_name.ToCString()));
-    ThrowMirroredCompilationError(message);
+    ThrowNoSuchMethod(Instance::null_instance(),
+                      setter_name,
+                      setter,
+                      InvocationMirror::kTopLevel,
+                      InvocationMirror::kSetter);
     UNREACHABLE();
   }
 
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 85bbae8..6f76866 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -121,40 +121,6 @@
 List _metadata(reflectee)
   native 'DeclarationMirror_metadata';
 
-// This will verify the argument types, unwrap them, and ensure we have a fixed
-// array.
-List _unwrapAsyncPositionals(wrappedArgs) {
-  List unwrappedArgs = new List(wrappedArgs.length);
-  for(int i = 0; i < wrappedArgs.length; i++){
-    var wrappedArg = wrappedArgs[i];
-    if(_isSimpleValue(wrappedArg)) {
-      unwrappedArgs[i] = wrappedArg;
-    } else if(wrappedArg is InstanceMirror) {
-      unwrappedArgs[i] = wrappedArg._reflectee;
-    } else {
-      throw "positional argument $i ($wrappedArg) was "
-            "not a simple value or InstanceMirror";
-    }
-  }
-  return unwrappedArgs;
-}
-
-Map _unwrapAsyncNamed(wrappedArgs) {
-  if (wrappedArgs==null) return null;
-  Map unwrappedArgs = new Map();
-  wrappedArgs.forEach((name, wrappedArg){
-    if(_isSimpleValue(wrappedArg)) {
-      unwrappedArgs[name] = wrappedArg;
-    } else if(wrappedArg is InstanceMirror) {
-      unwrappedArgs[name] = wrappedArg._reflectee;
-    } else {
-      throw "named argument ${_n(name)} ($wrappedArg) was "
-            "not a simple value or InstanceMirror";
-    }
-  });
-  return unwrappedArgs;
-}
-
 class _LocalMirrorSystemImpl extends MirrorSystem {
   // Change parameter back to "this.libraries" when native code is changed.
   _LocalMirrorSystemImpl(List<LibraryMirror> libraries, this.isolate)
@@ -183,11 +149,7 @@
   String toString() => "MirrorSystem for isolate '${isolate.debugName}'";
 }
 
-abstract class _LocalMirrorImpl implements Mirror {
-  // Local mirrors always return the same MirrorSystem.  This field
-  // is more interesting once we implement remote mirrors.
-  MirrorSystem get mirrors => _Mirrors.currentMirrorSystem();
-}
+abstract class _LocalMirrorImpl implements Mirror {}
 
 class _LocalIsolateMirrorImpl extends _LocalMirrorImpl
     implements IsolateMirror {
@@ -255,47 +217,6 @@
     return reflect(value);
   }
 
-  Future<InstanceMirror> invokeAsync(Symbol memberName,
-                                     List positionalArguments,
-                                     [Map<Symbol, dynamic> namedArguments]) {
-    return new Future(() {
-      return this.invoke(memberName,
-                         _unwrapAsyncPositionals(positionalArguments),
-                         _unwrapAsyncNamed(namedArguments));
-    });
-  }
-
-  Future<InstanceMirror> getFieldAsync(Symbol memberName) {
-   try {
-      var result = this._invokeGetter(_reflectee,
-                                      _n(memberName));
-      return new Future.value(reflect(result));
-    } catch(e) {
-      return new Future.error(e);
-    }
-  }
-
-  Future<InstanceMirror> setFieldAsync(Symbol memberName, Object value) {
-    try {
-      var unwrappedValue;
-      if(_isSimpleValue(value)) {
-        unwrappedValue = value;
-      } else if(value is InstanceMirror) {
-        unwrappedValue = value._reflectee;
-      } else {
-        throw "setter argument ($value) must be"
-              "a simple value or InstanceMirror";
-      }
-
-      this._invokeSetter(_reflectee,
-                         _n(memberName),
-                         unwrappedValue);
-      return new Future.value(reflect(unwrappedValue));
-    } catch(e) {
-      return new Future.error(e);
-    }
-  }
-
   static _validateArgument(int i, Object arg)
   {
     if (arg is Mirror) {
@@ -469,6 +390,10 @@
       throw new ArgumentError("Invalid symbol: ${name}");
     }
     List tuple = _computeFindInContext(_reflectee, parts);
+    if (tuple.length == 0) {
+      throw new UnsupportedError(
+          "ClosureMirror.findInContext not yet supported");
+    }
     if (tuple[0]) {
       return reflect(tuple[1]);
     }
@@ -550,11 +475,6 @@
     throw new UnimplementedError('ClassMirror.location is not implemented');
   }
 
-  // TODO(rmacnak): Remove these left-overs from the days of separate interfaces
-  // once we send out a breaking change.
-  bool get isClass => true;
-  ClassMirror get defaultFactory => null;
-
   ClassMirror _trueSuperclassField;
   ClassMirror get _trueSuperclass {
     if (_trueSuperclassField == null) {
@@ -1528,21 +1448,6 @@
     return _currentMirrorSystem;
   }
 
-  static Future<MirrorSystem> mirrorSystemOf(SendPort port) {
-    if (isLocalPort(port)) {
-      // Make a local mirror system.
-      try {
-        return new Future<MirrorSystem>.value(currentMirrorSystem());
-      } catch (exception) {
-        return new Future<MirrorSystem>.error(exception);
-      }
-    } else {
-      // Make a remote mirror system
-      throw new UnimplementedError(
-          'Remote mirror support is not implemented');
-    }
-  }
-
   // Creates a new local mirror for some Object.
   static InstanceMirror reflect(Object reflectee) {
     return reflectee is Function
diff --git a/runtime/lib/mirrors_patch.dart b/runtime/lib/mirrors_patch.dart
index b3f2d4d..200b1b0 100644
--- a/runtime/lib/mirrors_patch.dart
+++ b/runtime/lib/mirrors_patch.dart
@@ -14,14 +14,6 @@
 }
 
 /**
- * Creates a [MirrorSystem] for the isolate which is listening on
- * the [SendPort].
- */
-Future<MirrorSystem> mirrorSystemOf(SendPort port) {
-  return _Mirrors.mirrorSystemOf(port);
-}
-
-/**
  * Returns an [InstanceMirror] for some Dart language object.
  *
  * This only works if this mirror system is associated with the
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 8f3cc3e..d2aaf68 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -11,6 +11,18 @@
 
 namespace dart {
 
+static void ThrowMaskRangeException(int64_t m) {
+  if ((m < 0) || (m > 255)) {
+    const String& error = String::Handle(
+      String::NewFormatted("mask (%" Pd64 ") must be in the range [0..256)",
+                           m));
+    const Array& args = Array::Handle(Array::New(1));
+    args.SetAt(0, error);
+    Exceptions::ThrowByType(Exceptions::kRange, args);
+  }
+}
+
+
 DEFINE_NATIVE_ENTRY(Float32x4_fromDoubles, 5) {
   ASSERT(AbstractTypeArguments::CheckedHandle(
       arguments->NativeArgAt(0)).IsNull());
@@ -263,14 +275,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
   int64_t m = mask.AsInt64Value();
-  if (m < 0 || m > 255) {
-    const String& error = String::Handle(
-      String::NewFormatted("mask (%" Pd64 ") must be in the range [0..256)",
-                           m));
-    const Array& args = Array::Handle(Array::New(1));
-    args.SetAt(0, error);
-    Exceptions::ThrowByType(Exceptions::kRange, args);
-  }
+  ThrowMaskRangeException(m);
   float data[4] = { self.x(), self.y(), self.z(), self.w() };
   float _x = data[m & 0x3];
   float _y = data[(m >> 2) & 0x3];
@@ -280,57 +285,18 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Float32x4_withZWInXY, 2) {
+DEFINE_NATIVE_ENTRY(Float32x4_shuffleMix, 3) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
-  float _x = other.z();
-  float _y = other.w();
-  float _z = self.z();
-  float _w = self.w();
-  return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveXY, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
-  float _x = self.x();
-  float _y = other.x();
-  float _z = self.y();
-  float _w = other.y();
-  return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveZW, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
-  float _x = self.z();
-  float _y = other.z();
-  float _z = self.w();
-  float _w = other.w();
-  return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveXYPairs, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
-  float _x = self.x();
-  float _y = self.y();
-  float _z = other.x();
-  float _w = other.y();
-  return Float32x4::New(_x, _y, _z, _w);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_interleaveZWPairs, 2) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, other, arguments->NativeArgAt(1));
-  float _x = self.z();
-  float _y = self.w();
-  float _z = other.z();
-  float _w = other.w();
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
+  int64_t m = mask.AsInt64Value();
+  ThrowMaskRangeException(m);
+  float data[4] = { self.x(), self.y(), self.z(), self.w() };
+  float other_data[4] = { other.x(), other.y(), other.z(), other.w() };
+  float _x = data[m & 0x3];
+  float _y = data[(m >> 2) & 0x3];
+  float _z = other_data[(m >> 4) & 0x3];
+  float _w = other_data[(m >> 6) & 0x3];
   return Float32x4::New(_x, _y, _z, _w);
 }
 
@@ -552,6 +518,36 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Uint32x4_shuffle, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
+  int64_t m = mask.AsInt64Value();
+  ThrowMaskRangeException(m);
+  uint32_t data[4] = { self.x(), self.y(), self.z(), self.w() };
+  uint32_t _x = data[m & 0x3];
+  uint32_t _y = data[(m >> 2) & 0x3];
+  uint32_t _z = data[(m >> 4) & 0x3];
+  uint32_t _w = data[(m >> 6) & 0x3];
+  return Uint32x4::New(_x, _y, _z, _w);
+}
+
+
+DEFINE_NATIVE_ENTRY(Uint32x4_shuffleMix, 3) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, zw, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2));
+  int64_t m = mask.AsInt64Value();
+  ThrowMaskRangeException(m);
+  uint32_t data[4] = { self.x(), self.y(), self.z(), self.w() };
+  uint32_t zw_data[4] = { zw.x(), zw.y(), zw.z(), zw.w() };
+  uint32_t _x = data[m & 0x3];
+  uint32_t _y = data[(m >> 2) & 0x3];
+  uint32_t _z = zw_data[(m >> 4) & 0x3];
+  uint32_t _w = zw_data[(m >> 6) & 0x3];
+  return Uint32x4::New(_x, _y, _z, _w);
+}
+
+
 DEFINE_NATIVE_ENTRY(Uint32x4_setX, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Uint32x4, self, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, x, arguments->NativeArgAt(1));
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index ba42a57..ea67ae2 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -22,16 +22,16 @@
   Dart_EnvironmentCallback callback = isolate->environment_callback();
   if (callback != NULL) {
     Dart_Handle result = callback(Api::NewHandle(isolate, name.raw()));
-    if (Dart_IsError(result)) {
+    if (Dart_IsString(result)) {
+      const Object& value =
+          Object::Handle(isolate, Api::UnwrapHandle(result));
+      return Symbols::New(String::Cast(value));
+    } else if (Dart_IsError(result)) {
       const Object& error =
           Object::Handle(isolate, Api::UnwrapHandle(result));
       Exceptions::ThrowArgumentError(
           String::Handle(
               String::New(Error::Cast(error).ToErrorCString())));
-    } else if (Dart_IsString(result)) {
-      const Object& value =
-          Object::Handle(isolate, Api::UnwrapHandle(result));
-      return Symbols::New(String::Cast(value));
     } else if (!Dart_IsNull(result)) {
       Exceptions::ThrowArgumentError(
           String::Handle(String::New("Illegal environment value")));
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index aeb2150..5339da4 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -602,6 +602,28 @@
     return super.indexOf(pattern, start);
   }
 
+  bool contains(Pattern pattern, [int start = 0]) {
+    final pCid = pattern._cid;
+    if ((pCid == _OneByteString._classId) ||
+        (pCid == _TwoByteString._classId) ||
+        (pCid == _ExternalOneByteString._classId)) {
+      final len = this.length;
+      if ((pattern.length == 1) && (start >= 0) && (start < len)) {
+        final patternCu0 = pattern.codeUnitAt(0);
+        if (patternCu0 > 0xFF) {
+          return false;
+        }
+        for (int i = start; i < len; i++) {
+          if (this.codeUnitAt(i) == patternCu0) {
+            return true;
+          }
+        }
+        return false;
+      }
+    }
+    return super.contains(pattern, start);
+  }
+
   // Allocates a string of given length, expecting its content to be
   // set using _setAt.
   static _OneByteString _allocate(int length) native "OneByteString_allocate";
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index 2c1123a..27a41f5 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -2168,14 +2168,7 @@
   int get signMask native "Float32x4_getSignMask";
 
   Float32x4 shuffle(int mask) native "Float32x4_shuffle";
-
-  Float32x4 withZWInXY(Float32x4 other) native "Float32x4_withZWInXY";
-  Float32x4 interleaveXY(Float32x4 other) native "Float32x4_interleaveXY";
-  Float32x4 interleaveZW(Float32x4 other) native "Float32x4_interleaveZW";
-  Float32x4 interleaveXYPairs(Float32x4 other)
-      native "Float32x4_interleaveXYPairs";
-  Float32x4 interleaveZWPairs(Float32x4 other)
-      native "Float32x4_interleaveZWPairs";
+  Float32x4 shuffleMix(Float32x4 zw, int mask) native "Float32x4_shuffleMix";
 
   Float32x4 withX(double x) native "Float32x4_setX";
   Float32x4 withY(double y) native "Float32x4_setY";
@@ -2236,6 +2229,8 @@
   int get z native "Uint32x4_getZ";
   int get w native "Uint32x4_getW";
   int get signMask native "Uint32x4_getSignMask";
+  Uint32x4 shuffle(int mask) native "Uint32x4_shuffle";
+  Uint32x4 shuffleMix(Uint32x4 zw, int mask) native "Uint32x4_shuffleMix";
   Uint32x4 withX(int x) native "Uint32x4_setX";
   Uint32x4 withY(int y) native "Uint32x4_setY";
   Uint32x4 withZ(int z) native "Uint32x4_setZ";
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
deleted file mode 100644
index e5ca82e..0000000
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// Dart test program for checking implemention of MirrorSystem when
-// inspecting the current isolate.
-//
-// VMOptions=--enable_type_checks
-
-library isolate_mirror_local_test;
-
-import "package:expect/expect.dart";
-import 'dart:async';
-import 'dart:isolate';
-import 'dart:mirrors';
-
-ReceivePort exit_port;
-Set expectedTests;
-
-void testDone(String test) {
-  if (!expectedTests.contains(test)) {
-    throw "Unexpected test name '$test'";
-  }
-  expectedTests.remove(test);
-  if (expectedTests.isEmpty) {
-    // All tests are done.
-    exit_port.close();
-  }
-}
-
-int global_var = 0;
-final int final_global_var = 0;
-
-// Top-level getter and setter.
-int get myVar { return 5; }
-void set myVar(x) {}
-
-// This function will be invoked reflectively.
-int function(int x) {
-  global_var = x;
-  return x + 1;
-}
-
-typedef void FuncType(String a);
-
-FuncType myFunc = null;
-
-_stringCompare(String a, String b) => a.compareTo(b);
-sort(list) => list.sort(_stringCompare);
-
-String buildMethodString(MethodMirror func) {
-  var result = '${MirrorSystem.getName(func.simpleName)} '
-      'return(${MirrorSystem.getName(func.returnType.simpleName)})';
-  if (func.isPrivate) {
-    result = '$result private';
-  }
-  if (func.isTopLevel) {
-    result = '$result toplevel';
-  }
-  if (func.isStatic) {
-    result = '$result static';
-  }
-  if (func.isAbstract) {
-    result = '$result abstract';
-  }
-  if (func.isRegularMethod) {
-    result = '$result method';
-  }
-  if (func.isGetter) {
-    result = '$result getter';
-  }
-  if (func.isSetter) {
-    result = '$result setter';
-  }
-  if (func.isConstructor) {
-    result = '$result constructor';
-  }
-  if (func.isConstConstructor) {
-    result = '$result const';
-  }
-  if (func.isGenerativeConstructor) {
-    result = '$result generative';
-  }
-  if (func.isRedirectingConstructor) {
-    result = '$result redirecting';
-  }
-  if (func.isFactoryConstructor) {
-    result = '$result factory';
-  }
-  return result;
-}
-
-String buildVariableString(VariableMirror variable) {
-  var result = '${MirrorSystem.getName(variable.simpleName)} '
-      'type(${MirrorSystem.getName(variable.type.simpleName)})';
-  if (variable.isPrivate) {
-    result = '$result private';
-  }
-  if (variable.isTopLevel) {
-    result = '$result toplevel';
-  }
-  if (variable.isStatic) {
-    result = '$result static';
-  }
-  if (variable.isFinal) {
-    result = '$result final';
-  }
-  return result;
-}
-
-void testRootLibraryMirror(LibraryMirror lib_mirror) {
-  Expect.equals(const Symbol('isolate_mirror_local_test'),
-                lib_mirror.simpleName);
-  Expect.equals(const Symbol('isolate_mirror_local_test'),
-                lib_mirror.qualifiedName);
-  Expect.equals(null, lib_mirror.owner);
-  Expect.isFalse(lib_mirror.isPrivate);
-  Expect.isTrue(lib_mirror.uri.path.contains('isolate_mirror_local_test.dart'));
-  Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
-                lib_mirror.toString());
-
-  // Test library invocation by calling function(123).
-  Expect.equals(0, global_var);
-  lib_mirror.invokeAsync(const Symbol('function'), [123]).then(
-      (InstanceMirror retval) {
-        Expect.equals(123, global_var);
-        testImplements(retval.type, #int);
-        Expect.isTrue(retval.hasReflectee);
-        Expect.equals(124, retval.reflectee);
-        testDone('testRootLibraryMirror');
-      });
-
-  // Check that the members map is complete.
-  List keys = lib_mirror.members.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  Expect.equals('['
-                'FuncType, '
-                'GenericClass, '
-                'MyClass, '
-                'MyException, '
-                'MyInterface, '
-                'MySuperClass, '
-                '_stringCompare, '
-                'buildMethodString, '
-                'buildVariableString, '
-                'exit_port, '
-                'expectedTests, '
-                'final_global_var, '
-                'function, '
-                'global_var, '
-                'main, '
-                'myFunc, '
-                'myVar, '
-                'myVar=, '
-                'sort, '
-                'testBoolInstanceMirror, '
-                'testCustomInstanceMirror, '
-                'testDone, '
-                'testImplements, '
-                'testIntegerInstanceMirror, '
-                'testLibrariesMap, '
-                'testMirrorSystem, '
-                'testNullInstanceMirror, '
-                'testRootLibraryMirror, '
-                'testStringInstanceMirror]',
-                '$keys');
-
-  // Check that the classes map is complete.
-  keys = lib_mirror.classes.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  print(keys);
-  Expect.equals('['
-                'GenericClass, '
-                'MyClass, '
-                'MyException, '
-                'MyInterface, '
-                'MySuperClass]',
-                '$keys');
-
-  // Check that the types map is complete.
-  keys = lib_mirror.types.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  print(keys);
-  Expect.equals('['
-                'FuncType, '
-                'GenericClass, '
-                'MyClass, '
-                'MyException, '
-                'MyInterface, '
-                'MySuperClass]',
-                '$keys');
-
-  // Check that the functions map is complete.
-  keys = lib_mirror.functions.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  Expect.equals('['
-                '_stringCompare, '
-                'buildMethodString, '
-                'buildVariableString, '
-                'function, '
-                'main, '
-                'myVar, '
-                'myVar=, '
-                'sort, '
-                'testBoolInstanceMirror, '
-                'testCustomInstanceMirror, '
-                'testDone, '
-                'testImplements, '
-                'testIntegerInstanceMirror, '
-                'testLibrariesMap, '
-                'testMirrorSystem, '
-                'testNullInstanceMirror, '
-                'testRootLibraryMirror, '
-                'testStringInstanceMirror]',
-                '$keys');
-
-  // Check that the getters map is complete.
-  keys = lib_mirror.getters.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  Expect.equals('[myVar]', '$keys');
-
-  // Check that the setters map is complete.
-  keys = lib_mirror.setters.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  Expect.equals('[myVar=]', '$keys');
-
-  // Check that the variables map is complete.
-  keys = lib_mirror.variables.keys.map(MirrorSystem.getName).toList();
-  sort(keys);
-  Expect.equals('['
-                'exit_port, '
-                'expectedTests, '
-                'final_global_var, '
-                'global_var, '
-                'myFunc]',
-                '$keys');
-
-  ClassMirror cls_mirror = lib_mirror.members[const Symbol('MyClass')];
-  ClassMirror generic_cls_mirror =
-      lib_mirror.members[const Symbol('GenericClass')];
-
-  // Test function mirrors.
-  MethodMirror func = lib_mirror.members[const Symbol('function')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('function return(int) toplevel static method',
-                buildMethodString(func));
-
-  func = lib_mirror.members[const Symbol('myVar')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('myVar return(int) toplevel static getter',
-                buildMethodString(func));
-
-  func = lib_mirror.members[const Symbol('myVar=')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('myVar= return(void) toplevel static setter',
-                buildMethodString(func));
-
-  func = cls_mirror.members[const Symbol('method')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('method return(int) method', buildMethodString(func));
-
-  func = cls_mirror.constructors[const Symbol('MyClass')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('MyClass return(MyClass) constructor generative',
-                buildMethodString(func));
-
-  func = cls_mirror.constructors[const Symbol('MyClass.named')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('MyClass.named return(MyClass) constructor generative',
-                buildMethodString(func));
-
-  func = generic_cls_mirror.members[const Symbol('method')];
-  Expect.isTrue(func is MethodMirror);
-  Expect.equals('method return(T) method', buildMethodString(func));
-
-  // Test variable mirrors.
-  VariableMirror variable = lib_mirror.members[const Symbol('global_var')];
-  Expect.isTrue(variable is VariableMirror);
-  Expect.equals('global_var type(int) toplevel static',
-                buildVariableString(variable));
-
-  variable = lib_mirror.members[const Symbol('final_global_var')];
-  Expect.isTrue(variable is VariableMirror);
-  Expect.equals('final_global_var type(int) toplevel static final',
-                buildVariableString(variable));
-
-  variable = cls_mirror.members[const Symbol('value')];
-  Expect.isTrue(variable is VariableMirror);
-  Expect.equals('value type(dynamic) final', buildVariableString(variable));
-
-  // Test type variable mirrors.
-  var type_var = generic_cls_mirror.members[const Symbol('method')].returnType;
-  Expect.isTrue(type_var is TypeVariableMirror);
-  Expect.equals(const Symbol('GenericClass'), type_var.owner.simpleName);
-  Expect.equals(const Symbol('Object'), type_var.upperBound.simpleName);
-
-  // Test typedef mirrors.
-  var typedef_mirror = lib_mirror.members[const Symbol('myFunc')].type;
-  Expect.isTrue(typedef_mirror is TypedefMirror);
-  Expect.equals(const Symbol('isolate_mirror_local_test'),
-                typedef_mirror.owner.simpleName);
-
-  // Test function type mirrors.
-  var func_cls_mirror = typedef_mirror.referent;
-  Expect.isTrue(func_cls_mirror is FunctionTypeMirror);
-  // Expect.equals('void (dart.core.String)', func_cls_mirror.simpleName);
-  Expect.equals(const Symbol('void'), func_cls_mirror.returnType.simpleName);
-}
-
-void testLibrariesMap(Map libraries) {
-  // Just look for a couple of well-known libs.
-  LibraryMirror core_lib = libraries[Uri.parse('dart:core')];
-  Expect.isTrue(core_lib is LibraryMirror);
-
-  LibraryMirror mirror_lib = libraries[Uri.parse('dart:mirrors')];
-  Expect.isTrue(mirror_lib is LibraryMirror);
-
-  // Lookup an interface from a library and make sure it is sane.
-  ClassMirror list_intf = core_lib.members[const Symbol('List')];
-  Expect.isTrue(list_intf is ClassMirror);
-  Expect.equals(const Symbol('List'), list_intf.simpleName);
-  Expect.equals(const Symbol('dart.core.List'), list_intf.qualifiedName);
-  Expect.isFalse(list_intf.isPrivate);
-  Expect.equals(const Symbol('Object'), list_intf.superclass.simpleName);
-  Expect.equals(const Symbol('dart.core'), list_intf.owner.simpleName);
-  Expect.isTrue(list_intf.isClass);
-  Expect.equals(const Symbol('Iterable'),
-                list_intf.superinterfaces[0].simpleName);
-  Expect.equals("ClassMirror on 'List'", list_intf.toString());
-
-  // Lookup a class from a library and make sure it is sane.
-  ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')];
-  Expect.isTrue(oom_cls is ClassMirror);
-  Expect.equals(const Symbol('OutOfMemoryError'), oom_cls.simpleName);
-  Expect.equals(const Symbol('dart.core.OutOfMemoryError'),
-                oom_cls.qualifiedName);
-  Expect.isFalse(oom_cls.isPrivate);
-  Expect.equals(const Symbol('Object'), oom_cls.superclass.simpleName);
-  Expect.isTrue(oom_cls.defaultFactory == null);
-  Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName);
-  Expect.isTrue(oom_cls.isClass);
-  Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName);
-  Expect.equals("ClassMirror on 'OutOfMemoryError'",
-                oom_cls.toString());
-  testDone('testLibrariesMap');
-}
-
-void testMirrorSystem(MirrorSystem mirrors) {
-  Expect.isTrue(mirrors.isolate.debugName.contains('main'));
-  testRootLibraryMirror(mirrors.isolate.rootLibrary);
-  testLibrariesMap(mirrors.libraries);
-  Expect.equals(const Symbol('void'), mirrors.voidType.simpleName);
-  Expect.equals(const Symbol('dynamic'), mirrors.dynamicType.simpleName);
-  Expect.isTrue(mirrors.voidType is TypeMirror);
-  Expect.isTrue(mirrors.dynamicType is TypeMirror);
-  Expect.isFalse(mirrors.voidType is ClassMirror);
-  Expect.isFalse(mirrors.dynamicType is ClassMirror);
-  testDone('testMirrorSystem');
-}
-
-void testImplements(klass, intfName) {
-  bool foundInterface = false;
-  for (ClassMirror cm = klass; cm != null; cm = cm.superclass) {
-    if (cm.simpleName == intfName) foundInterface = true;
-    cm.superinterfaces.forEach((intf) {
-      if (intf.simpleName == intfName) foundInterface = true;
-    });
-  }
-  Expect.isTrue(foundInterface, '$klass should implement $intfName');
-}
-
-void testIntegerInstanceMirror(InstanceMirror mirror) {
-  testImplements(mirror.type, #int);
-  Expect.isTrue(mirror.hasReflectee);
-  Expect.equals(1001, mirror.reflectee);
-  Expect.equals("InstanceMirror on 1001", mirror.toString());
-
-  // Invoke (mirror + mirror).
-  mirror.invokeAsync(const Symbol('+'), [ mirror ]).then(
-      (InstanceMirror retval) {
-        testImplements(retval.type, #int);
-        Expect.isTrue(retval.hasReflectee);
-        Expect.equals(2002, retval.reflectee);
-        testDone('testIntegerInstanceMirror');
-      });
-}
-
-void testStringInstanceMirror(InstanceMirror mirror) {
-  testImplements(mirror.type, #String);
-  Expect.isTrue(mirror.hasReflectee);
-  Expect.equals('This\nis\na\nString', mirror.reflectee);
-  Expect.equals('InstanceMirror on "This\\nis\\na\\nString"',
-                mirror.toString());
-
-  // Invoke mirror[0].
-  mirror.invokeAsync(const Symbol('[]'), [ 0 ]).then(
-      (InstanceMirror retval) {
-        testImplements(retval.type, #String);
-        Expect.isTrue(retval.hasReflectee);
-        Expect.equals('T', retval.reflectee);
-        testDone('testStringInstanceMirror');
-      });
-}
-
-void testBoolInstanceMirror(InstanceMirror mirror) {
-  testImplements(mirror.type, #bool);
-  Expect.isTrue(mirror.hasReflectee);
-  Expect.equals(true, mirror.reflectee);
-  Expect.equals("InstanceMirror on true", mirror.toString());
-  testDone('testBoolInstanceMirror');
-}
-
-void testNullInstanceMirror(InstanceMirror mirror) {
-  testImplements(mirror.type, #Null);
-  Expect.isTrue(mirror.hasReflectee);
-  Expect.equals(null, mirror.reflectee);
-  Expect.equals("InstanceMirror on null", mirror.toString());
-  testDone('testNullInstanceMirror');
-}
-
-class MySuperClass {
-}
-
-class MyInterface {
-}
-
-class MyClass extends MySuperClass implements MyInterface {
-  MyClass(this.value) {}
-  MyClass.named() {}
-
-  final value;
-
-  int method(int arg) {
-    return arg + value;
-  }
-}
-
-class GenericClass<T> {
-  T method(int arg) {
-    return null;
-  }
-}
-
-void testCustomInstanceMirror(InstanceMirror mirror) {
-  Expect.isTrue(mirror.hasReflectee);
-  bool saw_exception = false;
-  try {
-    mirror.reflectee;
-  } on MirrorException catch (me) {
-    saw_exception = true;
-  }
-  Expect.isFalse(saw_exception);
-  Expect.equals("InstanceMirror on Instance of 'MyClass'",
-                mirror.toString());
-
-  ClassMirror cls = mirror.type;
-  Expect.isTrue(cls is ClassMirror);
-  Expect.equals(const Symbol('MyClass'), cls.simpleName);
-  Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName);
-  Expect.isTrue(cls.defaultFactory == null);
-  Expect.equals(const Symbol('isolate_mirror_local_test'),
-                cls.owner.simpleName);
-  Expect.isTrue(cls.isClass);
-  Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName);
-  Expect.equals("ClassMirror on 'MyClass'", cls.toString());
-
-  // Invoke mirror.method(1000).
-  mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then(
-      (InstanceMirror retval) {
-        testImplements(retval.type, #int);
-        Expect.isTrue(retval.hasReflectee);
-        Expect.equals(1017, retval.reflectee);
-        testDone('testCustomInstanceMirror');
-      });
-
-}
-
-class MyException implements Exception {
-  MyException(this._message);
-  final String _message;
-  String toString() { return 'MyException: $_message'; }
-}
-
-void main() {
-  // When all of the expected tests complete, the exit_port is closed,
-  // allowing the program to terminate.
-  exit_port = new ReceivePort();
-  expectedTests = new Set<String>.from(['testRootLibraryMirror',
-                                        'testLibrariesMap',
-                                        'testMirrorSystem',
-                                        'testIntegerInstanceMirror',
-                                        'testStringInstanceMirror',
-                                        'testBoolInstanceMirror',
-                                        'testNullInstanceMirror',
-                                        'testCustomInstanceMirror']);
-
-  // Test that an isolate can reflect on itself.
-  mirrorSystemOf(exit_port.sendPort).then(testMirrorSystem);
-
-  testIntegerInstanceMirror(reflect(1001));
-  testStringInstanceMirror(reflect('This\nis\na\nString'));
-  testBoolInstanceMirror(reflect(true));
-  testNullInstanceMirror(reflect(null));
-  testCustomInstanceMirror(reflect(new MyClass(17)));
-}
diff --git a/runtime/tests/vm/dart/isolate_mirror_remote_test.dart b/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
deleted file mode 100644
index 7b36cfd..0000000
--- a/runtime/tests/vm/dart/isolate_mirror_remote_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// Dart test program for checking implemention of MirrorSystem when
-// inspecting a remote isolate.
-
-library isolate_mirror_local_test;
-
-import "package:expect/expect.dart";
-import 'dart:isolate';
-import 'dart:mirrors';
-
-void isolateMain(SendPort replyTo) {
-  var port = new ReceivePort();
-  replyTo.send(port.sendPort);
-}
-
-void testMirrorSystem(MirrorSystem mirror) {
-  Expect.fail('Should not reach here.  Remote isolates not implemented.');
-}
-
-void main() {
-  var response = new ReceivePort();
-  Isolate.spawn(isolateMain, response.sendPort);
-  response.first.then((sp) {
-    try {
-      mirrorSystemOf(sp).then(testMirrorSystem);
-      Expect.fail('Should not reach here.  Remote isolates not implemented.');
-    } catch (exception) {
-      Expect.isTrue(exception is UnimplementedError);
-    }
-  });
-}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 704bfec..07c7ffc 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -27,12 +27,10 @@
 [ $compiler == dart2js ]
 dart/mirrored_compilation_error_test: Skip # VM-specific flag
 dart/redirection_type_shuffling_test: Skip # Depends on lazy enforcement of type bounds
-dart/isolate_mirror*: Skip # compilers not aware of dart:mirrors
 dart/byte_array_test: Skip # compilers not aware of byte arrays
 dart/byte_array_optimized_test: Skip # compilers not aware of byte arrays
 dart/simd128float32_array_test: Skip # compilers not aware of Simd128
 dart/simd128float32_test: Skip # compilers not aware of Simd128
-dart/isolate_unhandled*: Skip
 
 [ $compiler == dart2js ]
 # The source positions do not match with dart2js.
@@ -47,31 +45,15 @@
 # Skip until we stabilize language tests.
 *: Skip
 
-[ $arch == simarm ]
-dart/isolate_mirror_local_test: Skip
-
-[ $arch == simmips || $arch == mips ]
-dart/isolate_mirror_local_test: Pass, Crash
-
 [ $arch == mips ]
 cc/Sdc1Ldc1: Crash # Illegal instructions
 cc/Cop1CvtDL: Crash
 cc/Cop1CvtDL_neg: Crash
 
-[ $compiler == none && $runtime == drt ]
-dart/isolate_mirror_local_test: Skip
-
-[ $compiler == none && $runtime == dartium ]
-dart/isolate_mirror_local_test: Fail # Issue 13719: Please triage this failure.
-
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
-dart/isolate_mirror_remote_test: Fail # Issue 13921
-dart/isolate_unhandled_exception_test: Fail # Issue 13921
 dart/mirrored_compilation_error_test: Skip # Can't pass needed VM flag
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 dart/optimized_stacktrace_test: StaticWarning
 
-dart/isolate_mirror_local_test: Fail, OK # API being removed.
-dart/isolate_mirror_remote_test: Fail, OK # API being removed.
 dart/mirrored_compilation_error_test: CompileTimeError, OK # This test intentionally includes invalid method bodies.
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index fa0b058..550efdd 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -216,11 +216,7 @@
   V(Float32x4_getW, 1)                                                         \
   V(Float32x4_getSignMask, 1)                                                  \
   V(Float32x4_shuffle, 2)                                                      \
-  V(Float32x4_withZWInXY, 2)                                                   \
-  V(Float32x4_interleaveXY, 2)                                                 \
-  V(Float32x4_interleaveZW, 2)                                                 \
-  V(Float32x4_interleaveXYPairs, 2)                                            \
-  V(Float32x4_interleaveZWPairs, 2)                                            \
+  V(Float32x4_shuffleMix, 3)                                                   \
   V(Float32x4_setX, 2)                                                         \
   V(Float32x4_setY, 2)                                                         \
   V(Float32x4_setZ, 2)                                                         \
@@ -247,6 +243,8 @@
   V(Uint32x4_setZ, 2)                                                          \
   V(Uint32x4_setW, 2)                                                          \
   V(Uint32x4_getSignMask, 1)                                                   \
+  V(Uint32x4_shuffle, 2)                                                       \
+  V(Uint32x4_shuffleMix, 3)                                                    \
   V(Uint32x4_getFlagX, 1)                                                      \
   V(Uint32x4_getFlagY, 1)                                                      \
   V(Uint32x4_getFlagZ, 1)                                                      \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 22ac5db..4d384a4 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1218,6 +1218,19 @@
           getter.set_result_type(type);
           cls.AddFunction(getter);
           field.set_value(Instance::Handle(Object::sentinel().raw()));
+
+          // Create initializer function.
+          // We don't have the start position of the initializer expression
+          // here, but can compute it from the field identifier position:
+          // The initializer expression starts after the assignment token at +2.
+          const intptr_t initializer_pos = field.token_pos() + 2;
+          const Function& init_function = Function::ZoneHandle(
+              Function::NewStaticInitializer(
+                  String::Handle(field.name()),
+                  type,
+                  cls,
+                  initializer_pos));
+          cls.AddFunction(init_function);
         }
       }
     }
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index a3f0c83..ae577df 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1694,31 +1694,6 @@
 }
 
 
-static intptr_t GetListLength(const Object& value) {
-  const intptr_t cid = value.GetClassId();
-  ASSERT(RawObject::IsBuiltinListClassId(cid));
-  // Extract list length.
-  if (value.IsTypedData()) {
-    const TypedData& list = TypedData::Cast(value);
-    return list.Length();
-  } else if (value.IsArray()) {
-    const Array& list = Array::Cast(value);
-    return list.Length();
-  } else if (value.IsGrowableObjectArray()) {
-    // List length is variable.
-    return Field::kNoFixedLength;
-  } else if (value.IsExternalTypedData()) {
-    // TODO(johnmccutchan): Enable for external typed data.
-    return Field::kNoFixedLength;
-  } else if (RawObject::IsTypedDataViewClassId(cid)) {
-    // TODO(johnmccutchan): Enable for typed data views.
-    return Field::kNoFixedLength;
-  }
-  UNIMPLEMENTED();
-  return Field::kNoFixedLength;
-}
-
-
 // Update global type feedback recorded for a field recording the assignment
 // of the given value.
 //   Arg0: Field object;
@@ -1726,14 +1701,7 @@
 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) {
   const Field& field = Field::CheckedHandle(arguments.ArgAt(0));
   const Object& value = Object::Handle(arguments.ArgAt(1));
-  const intptr_t cid = value.GetClassId();
-  field.UpdateCid(cid);
-  intptr_t list_length = Field::kNoFixedLength;
-  if ((field.guarded_cid() != kDynamicCid) &&
-      field.is_final() && RawObject::IsBuiltinListClassId(cid)) {
-    list_length = GetListLength(value);
-  }
-  field.UpdateLength(list_length);
+  field.UpdateGuardedCidAndLength(value);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 6cbfac4..6e61697 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -892,7 +892,7 @@
     const char* kEvalConst = "eval_const";
     const Function& func = Function::ZoneHandle(Function::New(
         String::Handle(Symbols::New(kEvalConst)),
-        RawFunction::kImplicitStaticFinalGetter,
+        RawFunction::kRegularFunction,
         true,  // static function.
         false,  // not const function.
         false,  // not abstract
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b3b9ce4..5faea45 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1080,8 +1080,7 @@
                               class_name,
                               function_name,
                               kNumArguments,
-                              Object::empty_array(),
-                              Resolver::kIsQualified));
+                              Object::empty_array()));
   ASSERT(!function.IsNull());
   const Array& args = Array::Handle(isolate, Array::New(kNumArguments));
   args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id)));
@@ -3105,8 +3104,7 @@
         Resolver::ResolveStatic(cls,
                                 function_name,
                                 number_of_arguments,
-                                Object::empty_array(),
-                                Resolver::kIsQualified));
+                                Object::empty_array()));
     if (function.IsNull()) {
       const String& cls_name = String::Handle(isolate, cls.Name());
       return Api::NewError("%s: did not find static method '%s.%s'.",
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 332965e..39e53aa 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -123,9 +123,7 @@
   const String& function_name =
       String::Handle(core_lib.PrivateName(Symbols::AllocateInvocationMirror()));
   const Function& allocation_function = Function::Handle(
-      Resolver::ResolveStaticByName(invocation_mirror_class,
-                                    function_name,
-                                    Resolver::kIsQualified));
+      invocation_mirror_class.LookupStaticFunction(function_name));
   ASSERT(!allocation_function.IsNull());
   const int kNumAllocationArgs = 4;
   const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs));
@@ -390,8 +388,7 @@
                                        class_name,
                                        function_name,
                                        kNumArguments,
-                                       Object::empty_array(),
-                                       Resolver::kIsQualified);
+                                       Object::empty_array());
     ASSERT(!function.IsNull());
     isolate->object_store()->set_lookup_receive_port_function(function);
   }
@@ -422,8 +419,7 @@
                                        class_name,
                                        function_name,
                                        kNumArguments,
-                                       Object::empty_array(),
-                                       Resolver::kIsQualified);
+                                       Object::empty_array());
     ASSERT(!function.IsNull());
     isolate->object_store()->set_handle_message_function(function);
   }
@@ -457,8 +453,7 @@
                               class_name,
                               function_name,
                               kNumArguments,
-                              Object::empty_array(),
-                              Resolver::kIsQualified));
+                              Object::empty_array()));
   ASSERT(!function.IsNull());
   const Array& args = Array::Handle(Array::New(kNumArguments));
   args.SetAt(0, Integer::Handle(Integer::New(port_id)));
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 67b1c0de..5e023b4 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1777,6 +1777,7 @@
   if ((fkind == RawFunction::kImplicitGetter) ||
       (fkind == RawFunction::kImplicitSetter) ||
       (fkind == RawFunction::kImplicitStaticFinalGetter) ||
+      (fkind == RawFunction::kStaticInitializer) ||
       (fkind == RawFunction::kMethodExtractor) ||
       (fkind == RawFunction::kNoSuchMethodDispatcher) ||
       (fkind == RawFunction::kInvokeFieldDispatcher)) {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 53e0394..fb82608 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -27,6 +27,7 @@
 DEFINE_FLAG(bool, eliminate_type_checks, true,
             "Eliminate type checks when allowed by static type analysis.");
 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
+DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
 DEFINE_FLAG(bool, print_flow_graph_optimized, false,
             "Print the IR flow graph when optimizing.");
@@ -930,7 +931,8 @@
                        for_value.value(),
                        node->type(),
                        node->dst_name())) {
-    checked_value = for_value.value()->definition();  // No check needed.
+    // Drop the value and 0 additional temporaries.
+    checked_value = new DropTempsInstr(0, for_value.value());
   } else {
     checked_value = BuildAssertAssignable(node->expr()->token_pos(),
                                           for_value.value(),
@@ -1301,12 +1303,17 @@
   ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
   ValueGraphVisitor for_value(owner(), temp_index());
   node->left()->Visit(&for_value);
+  Append(for_value);
   const String& dst_name = String::ZoneHandle(
       Symbols::New(Exceptions::kCastErrorDstName));
-  if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) {
-    Append(for_value);
-    Do(BuildAssertAssignable(
-        node->token_pos(), for_value.value(), type, dst_name));
+  if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) {
+    // Drop the value and 0 additional temporaries.
+    Do(new DropTempsInstr(0, for_value.value()));
+  } else {
+    Do(BuildAssertAssignable(node->token_pos(),
+                             for_value.value(),
+                             type,
+                             dst_name));
   }
 }
 
@@ -3716,8 +3723,7 @@
       Resolver::ResolveStatic(cls,
                               Library::PrivateCoreLibName(Symbols::ThrowNew()),
                               arguments->length(),
-                              Object::null_array(),
-                              Resolver::kIsQualified));
+                              Object::null_array()));
   ASSERT(!func.IsNull());
   return new StaticCallInstr(token_pos,
                              func,
@@ -3800,6 +3806,9 @@
     // Print the function ast before IL generation.
     AstPrinter::PrintFunctionNodes(*parsed_function());
   }
+  if (FLAG_print_scopes) {
+    AstPrinter::PrintFunctionScope(*parsed_function());
+  }
   const Function& function = parsed_function()->function();
   TargetEntryInstr* normal_entry =
       new TargetEntryInstr(AllocateBlockId(),
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 3ce60f9..199b4f3 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -22,7 +22,6 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
 DECLARE_FLAG(bool, code_comments);
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, intrinsify);
@@ -645,7 +644,7 @@
   }
   // Even if an intrinsified version of the function was successfully
   // generated, it may fall through to the non-intrinsified method body.
-  return Intrinsifier::Intrinsify(parsed_function().function(), assembler());
+  Intrinsifier::Intrinsify(parsed_function().function(), assembler());
 }
 
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index a635ad0..244c211 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -24,8 +24,6 @@
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, eliminate_type_checks);
 
@@ -1007,6 +1005,7 @@
   // LR: return address.
   // SP: receiver.
   // Sequence node has one return node, its input is load field node.
+  __ Comment("Inlined Getter");
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadFromOffset(kWord, R0, R0, offset - kHeapObjectTag);
   __ Ret();
@@ -1018,6 +1017,7 @@
   // SP+1: receiver.
   // SP+0: value.
   // Sequence node has one store node and one return NULL node.
+  __ Comment("Inlined Setter");
   __ ldr(R0, Address(SP, 1 * kWordSize));  // Receiver.
   __ ldr(R1, Address(SP, 0 * kWordSize));  // Value.
   __ StoreIntoObject(R0, FieldAddress(R0, offset), R1);
@@ -1162,16 +1162,6 @@
     }
   }
 
-  if (FLAG_print_scopes) {
-    // Print the function scope (again) after generating the prologue in order
-    // to see annotations such as allocation indices of locals.
-    if (FLAG_print_ast) {
-      // Second printing.
-      OS::Print("Annotated ");
-    }
-    AstPrinter::PrintFunctionScope(parsed_function());
-  }
-
   VisitBlocks();
 
   __ bkpt(0);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 74dda26..f97dda7 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -25,8 +25,6 @@
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, eliminate_type_checks);
 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
@@ -1030,6 +1028,7 @@
   // TOS: return address.
   // +1 : receiver.
   // Sequence node has one return node, its input is load field node.
+  __ Comment("Inlined Getter");
   __ movl(EAX, Address(ESP, 1 * kWordSize));
   __ movl(EAX, FieldAddress(EAX, offset));
   __ ret();
@@ -1041,6 +1040,7 @@
   // +1 : value
   // +2 : receiver.
   // Sequence node has one store node and one return NULL node.
+  __ Comment("Inlined Setter");
   __ movl(EAX, Address(ESP, 2 * kWordSize));  // Receiver.
   __ movl(EBX, Address(ESP, 1 * kWordSize));  // Value.
   __ StoreIntoObject(EAX, FieldAddress(EAX, offset), EBX);
@@ -1170,16 +1170,6 @@
     }
   }
 
-  if (FLAG_print_scopes) {
-    // Print the function scope (again) after generating the prologue in order
-    // to see annotations such as allocation indices of locals.
-    if (FLAG_print_ast) {
-      // Second printing.
-      OS::Print("Annotated ");
-    }
-    AstPrinter::PrintFunctionScope(parsed_function());
-  }
-
   ASSERT(!block_order().is_empty());
   VisitBlocks();
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 2cd1ddf..e13470f 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -24,8 +24,6 @@
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, eliminate_type_checks);
 
@@ -1035,6 +1033,7 @@
   // RA: return address.
   // SP: receiver.
   // Sequence node has one return node, its input is load field node.
+  __ Comment("Inlined Getter");
   __ lw(V0, Address(SP, 0 * kWordSize));
   __ lw(V0, Address(V0, offset - kHeapObjectTag));
   __ Ret();
@@ -1046,6 +1045,7 @@
   // SP+1: receiver.
   // SP+0: value.
   // Sequence node has one store node and one return NULL node.
+  __ Comment("Inlined Setter");
   __ lw(T0, Address(SP, 1 * kWordSize));  // Receiver.
   __ lw(T1, Address(SP, 0 * kWordSize));  // Value.
   __ StoreIntoObject(T0, FieldAddress(T0, offset), T1);
@@ -1203,16 +1203,6 @@
     }
   }
 
-  if (FLAG_print_scopes) {
-    // Print the function scope (again) after generating the prologue in order
-    // to see annotations such as allocation indices of locals.
-    if (FLAG_print_ast) {
-      // Second printing.
-      OS::Print("Annotated ");
-    }
-    AstPrinter::PrintFunctionScope(parsed_function());
-  }
-
   VisitBlocks();
 
   __ break_(0);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 56f2bc8..9b67e17 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -24,8 +24,6 @@
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(int, reoptimization_counter_threshold);
-DECLARE_FLAG(bool, print_ast);
-DECLARE_FLAG(bool, print_scopes);
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, eliminate_type_checks);
 
@@ -1014,6 +1012,7 @@
   // TOS: return address.
   // +1 : receiver.
   // Sequence node has one return node, its input is load field node.
+  __ Comment("Inlined Getter");
   __ movq(RAX, Address(RSP, 1 * kWordSize));
   __ movq(RAX, FieldAddress(RAX, offset));
   __ ret();
@@ -1025,6 +1024,7 @@
   // +1 : value
   // +2 : receiver.
   // Sequence node has one store node and one return NULL node.
+  __ Comment("Inlined Setter");
   __ movq(RAX, Address(RSP, 2 * kWordSize));  // Receiver.
   __ movq(RBX, Address(RSP, 1 * kWordSize));  // Value.
   __ StoreIntoObject(RAX, FieldAddress(RAX, offset), RBX);
@@ -1201,16 +1201,6 @@
     }
   }
 
-  if (FLAG_print_scopes) {
-    // Print the function scope (again) after generating the prologue in order
-    // to see annotations such as allocation indices of locals.
-    if (FLAG_print_ast) {
-      // Second printing.
-      OS::Print("Annotated ");
-    }
-    AstPrinter::PrintFunctionScope(parsed_function());
-  }
-
   ASSERT(!block_order().is_empty());
   VisitBlocks();
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index bf34043..79fcd02 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -1460,14 +1460,18 @@
 }
 
 
+static uint16_t ClampUint16(intptr_t v) {
+  return (v > 0xFFFF) ? 0xFFFF : static_cast<uint16_t>(v);
+}
+
+
 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph) {
   GraphInfoCollector info;
   info.Collect(*flow_graph);
   const Function& function = flow_graph->parsed_function().function();
   function.set_optimized_instruction_count(
-    static_cast<uint16_t>(info.instruction_count()));
-  function.set_optimized_call_site_count(
-    static_cast<uint16_t>(info.call_site_count()));
+      ClampUint16(info.instruction_count()));
+  function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
 }
 
 
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 78815e2..cda4032 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1692,24 +1692,30 @@
                 call->env(),
                 call);
   intptr_t mask = 0;
-  if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+  if ((getter == MethodRecognizer::kFloat32x4Shuffle) ||
+      (getter == MethodRecognizer::kFloat32x4ShuffleMix)) {
     // Extract shuffle mask.
-    ASSERT(call->ArgumentCount() == 2);
-    Definition* mask_definition = call->ArgumentAt(1);
+    Definition* mask_definition = NULL;
+    if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+      ASSERT(call->ArgumentCount() == 2);
+      mask_definition = call->ArgumentAt(1);
+    } else {
+      ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix);
+      ASSERT(call->ArgumentCount() == 3);
+      mask_definition = call->ArgumentAt(2);
+    }
     if (!mask_definition->IsConstant()) {
-      // Not a constant.
       return false;
     }
     ASSERT(mask_definition->IsConstant());
     ConstantInstr* constant_instruction = mask_definition->AsConstant();
     const Object& constant_mask = constant_instruction->value();
     if (!constant_mask.IsSmi()) {
-      // Not a smi.
       return false;
     }
     ASSERT(constant_mask.IsSmi());
     mask = Smi::Cast(constant_mask).Value();
-    if (mask < 0 || mask > 255) {
+    if ((mask < 0) || (mask > 255)) {
       // Not a valid mask.
       return false;
     }
@@ -1721,13 +1727,22 @@
         call->deopt_id());
     ReplaceCall(call, instr);
     return true;
+  } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) {
+    Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        new Value(call->ArgumentAt(1)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
   } else {
     ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle)  ||
            (getter == MethodRecognizer::kFloat32x4ShuffleX) ||
            (getter == MethodRecognizer::kFloat32x4ShuffleY) ||
            (getter == MethodRecognizer::kFloat32x4ShuffleZ) ||
            (getter == MethodRecognizer::kFloat32x4ShuffleW));
-    Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
+    Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr(
         getter,
         new Value(call->ArgumentAt(0)),
         mask,
@@ -1751,6 +1766,35 @@
                 call->deopt_id(),
                 call->env(),
                 call);
+  intptr_t mask = 0;
+  if ((getter == MethodRecognizer::kUint32x4Shuffle) ||
+      (getter == MethodRecognizer::kUint32x4ShuffleMix)) {
+    // Extract shuffle mask.
+    Definition* mask_definition = NULL;
+    if (getter == MethodRecognizer::kUint32x4Shuffle) {
+      ASSERT(call->ArgumentCount() == 2);
+      mask_definition = call->ArgumentAt(1);
+    } else {
+      ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix);
+      ASSERT(call->ArgumentCount() == 3);
+      mask_definition = call->ArgumentAt(2);
+    }
+    if (!mask_definition->IsConstant()) {
+      return false;
+    }
+    ASSERT(mask_definition->IsConstant());
+    ConstantInstr* constant_instruction = mask_definition->AsConstant();
+    const Object& constant_mask = constant_instruction->value();
+    if (!constant_mask.IsSmi()) {
+      return false;
+    }
+    ASSERT(constant_mask.IsSmi());
+    mask = Smi::Cast(constant_mask).Value();
+    if ((mask < 0) || (mask > 255)) {
+      // Not a valid mask.
+      return false;
+    }
+  }
   if (getter == MethodRecognizer::kUint32x4GetSignMask) {
     Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr(
         getter,
@@ -1758,6 +1802,23 @@
         call->deopt_id());
     ReplaceCall(call, instr);
     return true;
+  } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) {
+    Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        new Value(call->ArgumentAt(1)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else if (getter == MethodRecognizer::kUint32x4Shuffle) {
+    Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr(
+        getter,
+        new Value(call->ArgumentAt(0)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
   } else {
     Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr(
         getter,
@@ -2320,26 +2381,6 @@
       ReplaceCall(call, minmax);
       return true;
     }
-    case MethodRecognizer::kFloat32x4WithZWInXY:
-    case MethodRecognizer::kFloat32x4InterleaveXY:
-    case MethodRecognizer::kFloat32x4InterleaveZW:
-    case MethodRecognizer::kFloat32x4InterleaveXYPairs:
-    case MethodRecognizer::kFloat32x4InterleaveZWPairs: {
-      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);
-      Float32x4TwoArgShuffleInstr* two_arg_shuffle =
-          new Float32x4TwoArgShuffleInstr(recognized_kind, new Value(left),
-                                          new Value(right), call->deopt_id());
-      ReplaceCall(call, two_arg_shuffle);
-      return true;
-    }
     case MethodRecognizer::kFloat32x4Scale: {
       Definition* left = call->ArgumentAt(0);
       Definition* right = call->ArgumentAt(1);
@@ -2429,6 +2470,7 @@
       ReplaceCall(call, clamp);
       return true;
     }
+    case MethodRecognizer::kFloat32x4ShuffleMix:
     case MethodRecognizer::kFloat32x4Shuffle: {
       return InlineFloat32x4Getter(call, recognized_kind);
     }
@@ -2446,6 +2488,8 @@
   }
   ASSERT(call->HasICData());
   switch (recognized_kind) {
+    case MethodRecognizer::kUint32x4ShuffleMix:
+    case MethodRecognizer::kUint32x4Shuffle:
     case MethodRecognizer::kUint32x4GetFlagX:
     case MethodRecognizer::kUint32x4GetFlagY:
     case MethodRecognizer::kUint32x4GetFlagZ:
@@ -4194,10 +4238,20 @@
 }
 
 
+// Load instructions handled by load elimination.
+static bool IsCandidateLoad(Instruction* instr) {
+  return instr->IsLoadField()
+      || instr->IsLoadIndexed()
+      || instr->IsLoadStaticField()
+      || instr->IsCurrentContext();
+}
+
+
 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets,
                                 intptr_t loop_header_index,
                                 Instruction* instr) {
-  return (sets != NULL) &&
+  return IsCandidateLoad(instr) &&
+      (sets != NULL) &&
       instr->HasPlaceId() &&
       ((*sets)[loop_header_index] != NULL) &&
       (*sets)[loop_header_index]->Contains(instr->place_id());
@@ -6482,6 +6536,8 @@
   ASSERT(field.is_static());
   if (field.is_final()) {
     Instance& obj = Instance::Handle(field.value());
+    ASSERT(obj.raw() != Object::sentinel().raw());
+    ASSERT(obj.raw() != Object::transition_sentinel().raw());
     if (obj.IsSmi() || obj.IsOld()) {
       SetValue(instr, obj);
       return;
@@ -6873,7 +6929,13 @@
 }
 
 
-void ConstantPropagator::VisitFloat32x4Shuffle(Float32x4ShuffleInstr* instr) {
+void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitSimd32x4ShuffleMix(
+    Simd32x4ShuffleMixInstr* instr) {
   SetValue(instr, non_constant_);
 }
 
@@ -6936,12 +6998,6 @@
 }
 
 
-void ConstantPropagator::VisitFloat32x4TwoArgShuffle(
-    Float32x4TwoArgShuffleInstr* instr) {
-  SetValue(instr, non_constant_);
-}
-
-
 void ConstantPropagator::VisitUint32x4BoolConstructor(
     Uint32x4BoolConstructorInstr* instr) {
   SetValue(instr, non_constant_);
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 791d97a..6dc3a61 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -1049,13 +1049,26 @@
 }
 
 
-CompileType Float32x4ShuffleInstr::ComputeType() const {
+CompileType Simd32x4ShuffleInstr::ComputeType() const {
   if ((op_kind() == MethodRecognizer::kFloat32x4ShuffleX) ||
       (op_kind() == MethodRecognizer::kFloat32x4ShuffleY) ||
       (op_kind() == MethodRecognizer::kFloat32x4ShuffleZ) ||
       (op_kind() == MethodRecognizer::kFloat32x4ShuffleW)) {
     return CompileType::FromCid(kDoubleCid);
   }
+  if ((op_kind() == MethodRecognizer::kUint32x4Shuffle)) {
+    return CompileType::FromCid(kUint32x4Cid);
+  }
+  ASSERT((op_kind() == MethodRecognizer::kFloat32x4Shuffle));
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Simd32x4ShuffleMixInstr::ComputeType() const {
+  if (op_kind() == MethodRecognizer::kUint32x4ShuffleMix) {
+    return CompileType::FromCid(kUint32x4Cid);
+  }
+  ASSERT((op_kind() == MethodRecognizer::kFloat32x4ShuffleMix));
   return CompileType::FromCid(kFloat32x4Cid);
 }
 
@@ -1120,11 +1133,6 @@
 }
 
 
-CompileType Float32x4TwoArgShuffleInstr::ComputeType() const {
-  return CompileType::FromCid(kFloat32x4Cid);
-}
-
-
 CompileType Uint32x4BoolConstructorInstr::ComputeType() const {
   return CompileType::FromCid(kUint32x4Cid);
 }
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index d0587ff..cfeca9b 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -607,12 +607,19 @@
 }
 
 
-void Float32x4ShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
+void Simd32x4ShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
   // TODO(johnmccutchan): Add proper string enumeration of shuffle.
-  f->Print("SHUFFLE ");
+  f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
   value()->PrintTo(f);
 }
 
+void Simd32x4ShuffleMixInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
+  xy()->PrintTo(f);
+  f->Print(", ");
+  zw()->PrintTo(f);
+}
+
 
 void Simd32x4GetSignMaskInstr::PrintOperandsTo(BufferFormatter* f) const {
   if (op_kind() == MethodRecognizer::kFloat32x4GetSignMask) {
@@ -706,12 +713,7 @@
 }
 
 
-void Float32x4TwoArgShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%s, ", MethodRecognizer::KindToCString(op_kind()));
-  left()->PrintTo(f);
-  f->Print(", ");
-  right()->PrintTo(f);
-}
+
 
 
 void Uint32x4BoolConstructorInstr::PrintOperandsTo(BufferFormatter* f) const {
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 2da67b0..50e3caf 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -425,7 +425,7 @@
     ASSERT(function.CheckSourceFingerprint(fp));                               \
     return true;                                                               \
   }
-POLYMORPHC_TARGET_LIST(RECOGNIZE_FUNCTION)
+POLYMORPHIC_TARGET_LIST(RECOGNIZE_FUNCTION)
 #undef RECOGNIZE_FUNCTION
   return false;
 }
@@ -2721,8 +2721,7 @@
             cls,
             Library::PrivateCoreLibName(Symbols::Interpolate()),
             kNumberOfArguments,
-            kNoArgumentNames,
-            Resolver::kIsQualified);
+            kNoArgumentNames);
   }
   ASSERT(!function_.IsNull());
   return function_;
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 53e8e49..b4e6878 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -95,6 +95,7 @@
   V(Float32x4, Float32x4.fromUint32x4Bits, Float32x4FromUint32x4Bits,          \
       770033146)                                                               \
   V(_Float32x4, shuffle, Float32x4Shuffle, 1178727105)                         \
+  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 927956119)                    \
   V(_Float32x4, get:x, Float32x4ShuffleX, 1351717838)                          \
   V(_Float32x4, get:y, Float32x4ShuffleY, 217386410)                           \
   V(_Float32x4, get:z, Float32x4ShuffleZ, 2144923721)                          \
@@ -119,11 +120,6 @@
   V(_Float32x4, withY, Float32x4WithY, 1806065938)                             \
   V(_Float32x4, withZ, Float32x4WithZ, 320659034)                              \
   V(_Float32x4, withW, Float32x4WithW, 1108437255)                             \
-  V(_Float32x4, withZWInXY, Float32x4WithZWInXY, 1198101679)                   \
-  V(_Float32x4, interleaveXY, Float32x4InterleaveXY, 2001324072)               \
-  V(_Float32x4, interleaveZW, Float32x4InterleaveZW, 928280031)                \
-  V(_Float32x4, interleaveXYPairs, Float32x4InterleaveXYPairs, 1046078993)     \
-  V(_Float32x4, interleaveZWPairs, Float32x4InterleaveZWPairs, 1001751955)     \
   V(Uint32x4, Uint32x4.bool, Uint32x4BoolConstructor, 517444095)               \
   V(Uint32x4, Uint32x4.fromFloat32x4Bits, Uint32x4FromFloat32x4Bits,           \
       1080034855)                                                              \
@@ -132,6 +128,8 @@
   V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 944733935)                         \
   V(_Uint32x4, get:flagW, Uint32x4GetFlagW, 22746169)                          \
   V(_Uint32x4, get:signMask, Uint32x4GetSignMask, 1858144083)                  \
+  V(_Uint32x4, shuffle, Uint32x4Shuffle, 146209630)                            \
+  V(_Uint32x4, shuffleMix, Uint32x4ShuffleMix, 1251494596)                     \
   V(_Uint32x4, select, Uint32x4Select, 72244182)                               \
   V(_Uint32x4, withFlagX, Uint32x4WithFlagX, 1475542073)                       \
   V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988)                        \
@@ -184,7 +182,7 @@
   V(_GrowableList, forEach, GrowableArrayForEach, 1675430533)                  \
 
 // A list of core functions that internally dispatch based on received id.
-#define POLYMORPHC_TARGET_LIST(V)                                              \
+#define POLYMORPHIC_TARGET_LIST(V)                                             \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802)                     \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841)                   \
   V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1832126257)                  \
@@ -194,7 +192,7 @@
   V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 185163470)               \
   V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1356392173)              \
   V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1239681356)          \
-  V(_TypedList, _getUint32x4, ByteArrayBaseGetUint32x4, 1239681356)          \
+  V(_TypedList, _getUint32x4, ByteArrayBaseGetUint32x4, 1499091330)            \
 
 // Class that recognizes the name and owner of a function and returns the
 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -677,7 +675,8 @@
   M(GuardField)                                                                \
   M(IfThenElse)                                                                \
   M(BinaryFloat32x4Op)                                                         \
-  M(Float32x4Shuffle)                                                          \
+  M(Simd32x4Shuffle)                                                           \
+  M(Simd32x4ShuffleMix)                                                        \
   M(Simd32x4GetSignMask)                                                       \
   M(Float32x4Constructor)                                                      \
   M(Float32x4Zero)                                                             \
@@ -690,7 +689,6 @@
   M(Float32x4Clamp)                                                            \
   M(Float32x4With)                                                             \
   M(Float32x4ToUint32x4)                                                       \
-  M(Float32x4TwoArgShuffle)                                                    \
   M(MaterializeObject)                                                         \
   M(Uint32x4BoolConstructor)                                                   \
   M(Uint32x4GetFlag)                                                           \
@@ -967,7 +965,8 @@
   friend class BinaryFloat32x4OpInstr;
   friend class Float32x4ZeroInstr;
   friend class Float32x4SplatInstr;
-  friend class Float32x4ShuffleInstr;
+  friend class Simd32x4ShuffleInstr;
+  friend class Simd32x4ShuffleMixInstr;
   friend class Simd32x4GetSignMaskInstr;
   friend class Float32x4ConstructorInstr;
   friend class Float32x4ComparisonInstr;
@@ -978,7 +977,6 @@
   friend class Float32x4ClampInstr;
   friend class Float32x4WithInstr;
   friend class Float32x4ToUint32x4Instr;
-  friend class Float32x4TwoArgShuffleInstr;
   friend class Uint32x4BoolConstructorInstr;
   friend class Uint32x4GetFlagInstr;
   friend class Uint32x4SetFlagInstr;
@@ -4996,11 +4994,11 @@
 };
 
 
-class Float32x4ShuffleInstr : public TemplateDefinition<1> {
+class Simd32x4ShuffleInstr : public TemplateDefinition<1> {
  public:
-  Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
-                        intptr_t mask,
-                        intptr_t deopt_id)
+  Simd32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
+                       intptr_t mask,
+                       intptr_t deopt_id)
       : op_kind_(op_kind), mask_(mask) {
     SetInputAt(0, value);
     deopt_id_ = deopt_id;
@@ -5023,11 +5021,88 @@
         (op_kind_ == MethodRecognizer::kFloat32x4ShuffleW)) {
       return kUnboxedDouble;
     }
+    if ((op_kind_ == MethodRecognizer::kUint32x4Shuffle)) {
+      return kUnboxedUint32x4;
+    }
+    ASSERT((op_kind_ == MethodRecognizer::kFloat32x4Shuffle));
     return kUnboxedFloat32x4;
   }
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT(idx == 0);
+    if ((op_kind_ == MethodRecognizer::kFloat32x4ShuffleX) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4ShuffleY) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4ShuffleZ) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4ShuffleW) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4Shuffle)) {
+      return kUnboxedFloat32x4;
+    }
+    ASSERT((op_kind_ == MethodRecognizer::kUint32x4Shuffle));
+    return kUnboxedUint32x4;
+  }
+
+  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(Simd32x4Shuffle)
+  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->AsSimd32x4Shuffle()->op_kind()) &&
+           (mask() == other->AsSimd32x4Shuffle()->mask());
+  }
+
+  virtual bool MayThrow() const { return false; }
+
+ private:
+  const MethodRecognizer::Kind op_kind_;
+  const intptr_t mask_;
+
+  DISALLOW_COPY_AND_ASSIGN(Simd32x4ShuffleInstr);
+};
+
+
+class Simd32x4ShuffleMixInstr : public TemplateDefinition<2> {
+ public:
+  Simd32x4ShuffleMixInstr(MethodRecognizer::Kind op_kind, Value* xy,
+                           Value* zw, intptr_t mask, intptr_t deopt_id)
+      : op_kind_(op_kind), mask_(mask) {
+    SetInputAt(0, xy);
+    SetInputAt(1, zw);
+    deopt_id_ = deopt_id;
+  }
+
+  Value* xy() const { return inputs_[0]; }
+  Value* zw() const { return inputs_[1]; }
+
+  MethodRecognizer::Kind op_kind() const { return op_kind_; }
+
+  intptr_t mask() const { return mask_; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual Representation representation() const {
+    if (op_kind() == MethodRecognizer::kUint32x4ShuffleMix) {
+      return kUnboxedUint32x4;
+    }
+    ASSERT(op_kind() == MethodRecognizer::kFloat32x4ShuffleMix);
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT((idx == 0) || (idx == 1));
+    if (op_kind() == MethodRecognizer::kUint32x4ShuffleMix) {
+      return kUnboxedUint32x4;
+    }
+    ASSERT(op_kind() == MethodRecognizer::kFloat32x4ShuffleMix);
     return kUnboxedFloat32x4;
   }
 
@@ -5037,15 +5112,15 @@
     return deopt_id_;
   }
 
-  DECLARE_INSTRUCTION(Float32x4Shuffle)
+  DECLARE_INSTRUCTION(Simd32x4ShuffleMix)
   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->AsFloat32x4Shuffle()->op_kind() &&
-           mask() == other->AsFloat32x4Shuffle()->mask();
+    return (op_kind() == other->AsSimd32x4ShuffleMix()->op_kind()) &&
+           (mask() == other->AsSimd32x4ShuffleMix()->mask());
   }
 
   virtual bool MayThrow() const { return false; }
@@ -5054,7 +5129,7 @@
   const MethodRecognizer::Kind op_kind_;
   const intptr_t mask_;
 
-  DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr);
+  DISALLOW_COPY_AND_ASSIGN(Simd32x4ShuffleMixInstr);
 };
 
 
@@ -5757,59 +5832,6 @@
 };
 
 
-class Float32x4TwoArgShuffleInstr : public TemplateDefinition<2> {
- public:
-  Float32x4TwoArgShuffleInstr(MethodRecognizer::Kind op_kind, Value* left,
-                              Value* right, intptr_t deopt_id)
-      : op_kind_(op_kind) {
-    SetInputAt(0, left);
-    SetInputAt(1, right);
-    deopt_id_ = deopt_id;
-  }
-
-  Value* left() const { return inputs_[0]; }
-  Value* right() const { return inputs_[1]; }
-
-  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));
-    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(Float32x4TwoArgShuffle)
-  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->AsFloat32x4TwoArgShuffle()->op_kind();
-  }
-
-  virtual bool MayThrow() const { return false; }
-
- private:
-  const MethodRecognizer::Kind op_kind_;
-
-  DISALLOW_COPY_AND_ASSIGN(Float32x4TwoArgShuffleInstr);
-};
-
-
 class Uint32x4SelectInstr : public TemplateDefinition<3> {
  public:
   Uint32x4SelectInstr(Value* mask, Value* trueValue, Value* falseValue,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index e9d032e..3c613e8 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -3043,7 +3043,7 @@
 }
 
 
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary =
@@ -3055,7 +3055,7 @@
 }
 
 
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   QRegister value = locs()->in(0).fpu_reg();
   QRegister result = locs()->out().fpu_reg();
   DRegister dresult0 = EvenDRegisterOf(result);
@@ -3073,6 +3073,7 @@
 
   // For some cases the vdup instruction requires fewer
   // instructions. For arbitrary shuffles, use vtbl.
+
   switch (op_kind()) {
     case MethodRecognizer::kFloat32x4ShuffleX:
       __ vdup(kWord, result, dvalue0, 0);
@@ -3090,6 +3091,7 @@
       __ vdup(kWord, result, dvalue1, 1);
       __ vcvtds(dresult0, sresult0);
       break;
+    case MethodRecognizer::kUint32x4Shuffle:
     case MethodRecognizer::kFloat32x4Shuffle:
       if (mask_ == 0x00) {
         __ vdup(kWord, result, dvalue0, 0);
@@ -3100,6 +3102,8 @@
       } else  if (mask_ == 0xFF) {
         __ vdup(kWord, result, dvalue1, 1);
       } else {
+        // TODO(zra): Investigate better instruction sequences for other
+        // shuffle masks.
         SRegister svalues[4];
 
         svalues[0] = EvenSRegisterOf(dtemp0);
@@ -3119,6 +3123,62 @@
 }
 
 
+LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions.
+  summary->set_in(0, Location::FpuRegisterLocation(Q4));
+  summary->set_in(1, Location::FpuRegisterLocation(Q5));
+  summary->set_out(Location::FpuRegisterLocation(Q6));
+  return summary;
+}
+
+
+void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  QRegister left = locs()->in(0).fpu_reg();
+  QRegister right = locs()->in(1).fpu_reg();
+  QRegister result = locs()->out().fpu_reg();
+
+  DRegister dresult0 = EvenDRegisterOf(result);
+  DRegister dresult1 = OddDRegisterOf(result);
+  SRegister sresult0 = EvenSRegisterOf(dresult0);
+  SRegister sresult1 = OddSRegisterOf(dresult0);
+  SRegister sresult2 = EvenSRegisterOf(dresult1);
+  SRegister sresult3 = OddSRegisterOf(dresult1);
+
+  DRegister dleft0 = EvenDRegisterOf(left);
+  DRegister dleft1 = OddDRegisterOf(left);
+  DRegister dright0 = EvenDRegisterOf(right);
+  DRegister dright1 = OddDRegisterOf(right);
+
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4ShuffleMix:
+    case MethodRecognizer::kUint32x4ShuffleMix:
+      // TODO(zra): Investigate better instruction sequences for shuffle masks.
+      SRegister left_svalues[4];
+      SRegister right_svalues[4];
+
+      left_svalues[0] = EvenSRegisterOf(dleft0);
+      left_svalues[1] = OddSRegisterOf(dleft0);
+      left_svalues[2] = EvenSRegisterOf(dleft1);
+      left_svalues[3] = OddSRegisterOf(dleft1);
+      right_svalues[0] = EvenSRegisterOf(dright0);
+      right_svalues[1] = OddSRegisterOf(dright0);
+      right_svalues[2] = EvenSRegisterOf(dright1);
+      right_svalues[3] = OddSRegisterOf(dright1);
+
+      __ vmovs(sresult0, left_svalues[mask_ & 0x3]);
+      __ vmovs(sresult1, left_svalues[(mask_ >> 2) & 0x3]);
+      __ vmovs(sresult2, right_svalues[(mask_ >> 4) & 0x3]);
+      __ vmovs(sresult3, right_svalues[(mask_ >> 6) & 0x3]);
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 1;
@@ -3485,56 +3545,6 @@
 }
 
 
-LocationSummary* Float32x4TwoArgShuffleInstr::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 Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  QRegister left = locs()->in(0).fpu_reg();
-  QRegister right = locs()->in(1).fpu_reg();
-  QRegister result = locs()->out().fpu_reg();
-
-  ASSERT(result == left);
-
-  DRegister dleft0 = EvenDRegisterOf(left);
-  DRegister dleft1 = OddDRegisterOf(left);
-  DRegister dright0 = EvenDRegisterOf(right);
-  DRegister dright1 = OddDRegisterOf(right);
-
-  switch (op_kind()) {
-    case MethodRecognizer::kFloat32x4WithZWInXY:
-      __ vmovd(dleft0, dright1);
-      break;
-    case MethodRecognizer::kFloat32x4InterleaveXY:
-      __ vmovq(QTMP, right);
-      __ vzipqw(left, QTMP);
-      break;
-    case MethodRecognizer::kFloat32x4InterleaveZW:
-      __ vmovq(QTMP, right);
-      __ vzipqw(left, QTMP);
-      __ vmovq(left, QTMP);
-      break;
-    case MethodRecognizer::kFloat32x4InterleaveXYPairs:
-      __ vmovd(dleft1, dright0);
-      break;
-    case MethodRecognizer::kFloat32x4InterleaveZWPairs:
-      __ vmovq(QTMP, right);
-      __ vmovd(EvenDRegisterOf(QTMP), dleft1);
-      __ vmovq(result, QTMP);
-      break;
-    default: UNREACHABLE();
-  }
-}
-
-
 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 4;
   const intptr_t kNumTemps = 1;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index b2c3e55..ba97036 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -3135,7 +3135,7 @@
 }
 
 
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary =
@@ -3146,7 +3146,7 @@
 }
 
 
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   XmmRegister value = locs()->in(0).fpu_reg();
 
   ASSERT(locs()->out().fpu_reg() == value);
@@ -3169,6 +3169,7 @@
       __ cvtss2sd(value, value);
       break;
     case MethodRecognizer::kFloat32x4Shuffle:
+    case MethodRecognizer::kUint32x4Shuffle:
       __ shufps(value, value, Immediate(mask_));
       break;
     default: UNREACHABLE();
@@ -3176,6 +3177,33 @@
 }
 
 
+LocationSummary* Simd32x4ShuffleMixInstr::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 Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister left = locs()->in(0).fpu_reg();
+  XmmRegister right = locs()->in(1).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == left);
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4ShuffleMix:
+    case MethodRecognizer::kUint32x4ShuffleMix:
+      __ shufps(left, right, Immediate(mask_));
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -3537,45 +3565,6 @@
 }
 
 
-LocationSummary* Float32x4TwoArgShuffleInstr::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 Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  XmmRegister left = locs()->in(0).fpu_reg();
-  XmmRegister right = locs()->in(1).fpu_reg();
-
-  ASSERT(locs()->out().fpu_reg() == left);
-
-  switch (op_kind()) {
-    case MethodRecognizer::kFloat32x4WithZWInXY:
-      __ movhlps(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveXY:
-      __ unpcklps(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveZW:
-      __ unpckhps(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveXYPairs:
-      __ unpcklpd(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveZWPairs:
-      __ unpckhpd(left, right);
-    break;
-    default: UNREACHABLE();
-  }
-}
-
-
 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 4;
   const intptr_t kNumTemps = 0;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 636dbf5..ae873ee 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -2969,13 +2969,25 @@
 }
 
 
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
 }
 
 
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+
+LocationSummary* Simd32x4ShuffleMixInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   UNIMPLEMENTED();
 }
 
@@ -3101,17 +3113,6 @@
 }
 
 
-LocationSummary* Float32x4TwoArgShuffleInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 574c51a..fcf2db7 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -3151,7 +3151,7 @@
 }
 
 
-LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+LocationSummary* Simd32x4ShuffleInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary =
@@ -3162,7 +3162,7 @@
 }
 
 
-void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void Simd32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   XmmRegister value = locs()->in(0).fpu_reg();
 
   ASSERT(locs()->out().fpu_reg() == value);
@@ -3185,6 +3185,7 @@
       __ cvtss2sd(value, value);
       break;
     case MethodRecognizer::kFloat32x4Shuffle:
+    case MethodRecognizer::kUint32x4Shuffle:
       __ shufps(value, value, Immediate(mask_));
       break;
     default: UNREACHABLE();
@@ -3192,6 +3193,33 @@
 }
 
 
+LocationSummary* Simd32x4ShuffleMixInstr::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 Simd32x4ShuffleMixInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister left = locs()->in(0).fpu_reg();
+  XmmRegister right = locs()->in(1).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == left);
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4ShuffleMix:
+    case MethodRecognizer::kUint32x4ShuffleMix:
+      __ shufps(left, right, Immediate(mask_));
+      break;
+    default: UNREACHABLE();
+  }
+}
+
+
 LocationSummary* Simd32x4GetSignMaskInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -3553,45 +3581,6 @@
 }
 
 
-LocationSummary* Float32x4TwoArgShuffleInstr::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 Float32x4TwoArgShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  XmmRegister left = locs()->in(0).fpu_reg();
-  XmmRegister right = locs()->in(1).fpu_reg();
-
-  ASSERT(locs()->out().fpu_reg() == left);
-
-  switch (op_kind()) {
-    case MethodRecognizer::kFloat32x4WithZWInXY:
-      __ movhlps(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveXY:
-      __ unpcklps(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveZW:
-      __ unpckhps(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveXYPairs:
-      __ unpcklpd(left, right);
-    break;
-    case MethodRecognizer::kFloat32x4InterleaveZWPairs:
-      __ unpckhpd(left, right);
-    break;
-    default: UNREACHABLE();
-  }
-}
-
-
 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 4;
   const intptr_t kNumTemps = 1;
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index fa3992b..a405284 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 // Class for intrinsifying functions.
 
+#include "vm/assembler.h"
 #include "vm/intrinsifier.h"
 #include "vm/flags.h"
 #include "vm/object.h"
@@ -154,7 +155,9 @@
                    class_name, function_name,                                  \
                    #test_class_name, #test_function_name)) {                   \
     ASSERT(function.CheckSourceFingerprint(fp));                               \
-    return destination(assembler);                                             \
+    assembler->Comment("Intrinsic");                                           \
+    destination(assembler);                                                    \
+    return;                                                                    \
   }                                                                            \
 
   if (lib.raw() == Library::CoreLibrary()) {
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index bae81da..63ccb89 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1575,7 +1575,7 @@
 }
 
 
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver).
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
@@ -1587,6 +1587,10 @@
 
   __ ldr(R2, Address(SP, kEndIndexOffset));
   __ ldr(TMP, Address(SP, kStartIndexOffset));
+  __ orr(R3, R2,  ShifterOperand(TMP));
+  __ tst(R3, ShifterOperand(kSmiTagMask));
+  __ b(&fall_through, NE);  // 'start', 'end' not Smi.
+
   __ sub(R2, R2, ShifterOperand(TMP));
   TryAllocateOnebyteString(assembler, &ok, &fall_through);
   __ Bind(&ok);
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index c334b91..8130965 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1668,7 +1668,7 @@
 }
 
 
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver)
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
@@ -1677,7 +1677,12 @@
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
   Label fall_through, ok;
+  __ movl(EAX, Address(ESP, + kStartIndexOffset));
   __ movl(EDI, Address(ESP, + kEndIndexOffset));
+  __ orl(EAX, EDI);
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through);  // 'start', 'end' not Smi.
+
   __ subl(EDI, Address(ESP, + kStartIndexOffset));
   TryAllocateOnebyteString(assembler, &ok, &fall_through, EDI);
   __ Bind(&ok);
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index d150f52..de170c9 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -1659,7 +1659,7 @@
 }
 
 
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver).
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
@@ -1671,6 +1671,10 @@
 
   __ lw(T2, Address(SP, kEndIndexOffset));
   __ lw(TMP, Address(SP, kStartIndexOffset));
+  __ or_(CMPRES, T2, TMP);
+  __ andi(CMPRES, CMPRES, Immediate(kSmiTagMask));
+  __ bne(CMPRES, ZR, &fall_through);  // 'start', 'end' not Smi.
+
   __ subu(T2, T2, TMP);
   TryAllocateOnebyteString(assembler, &ok, &fall_through);
   __ Bind(&ok);
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 62b2f5c..cd3c79f 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1579,7 +1579,7 @@
 }
 
 
-// Arg0: Onebyte String
+// Arg0: OneByteString (receiver).
 // Arg1: Start index as Smi.
 // Arg2: End index as Smi.
 // The indexes must be valid.
@@ -1588,7 +1588,12 @@
   const intptr_t kStartIndexOffset = 2 * kWordSize;
   const intptr_t kEndIndexOffset = 1 * kWordSize;
   Label fall_through, ok;
+  __ movq(RSI, Address(RSP, + kEndIndexOffset));
   __ movq(RDI, Address(RSP, + kEndIndexOffset));
+  __ orq(RSI, RDI);
+  __ testq(RSI, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &fall_through);  // 'start', 'end' not Smi.
+
   __ subq(RDI, Address(RSP, + kStartIndexOffset));
   TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
   __ Bind(&ok);
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index 1ab2323..ce15960 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -93,6 +93,7 @@
         if (func.kind() == RawFunction::kImplicitGetter ||
             func.kind() == RawFunction::kImplicitSetter ||
             func.kind() == RawFunction::kImplicitStaticFinalGetter ||
+            func.kind() == RawFunction::kStaticInitializer ||
             func.kind() == RawFunction::kMethodExtractor ||
             func.kind() == RawFunction::kNoSuchMethodDispatcher) {
           continue;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b638aef..0d4c8530 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1739,6 +1739,31 @@
 }
 
 
+RawArray* Class::OffsetToFieldMap() const {
+  Array& array = Array::Handle(raw_ptr()->offset_in_words_to_field_);
+  if (array.IsNull()) {
+    ASSERT(is_finalized());
+    const intptr_t length = raw_ptr()->instance_size_in_words_;
+    array = Array::New(length, Heap::kOld);
+    Class& cls = Class::Handle(this->raw());
+    Array& fields = Array::Handle();
+    Field& f = Field::Handle();
+    while (!cls.IsNull()) {
+      fields = cls.fields();
+      for (intptr_t i = 0; i < fields.Length(); ++i) {
+        f ^= fields.At(i);
+        if (!f.is_static()) {
+          array.SetAt(f.Offset() >> kWordSizeLog2, f);
+        }
+      }
+      cls = cls.SuperClass();
+    }
+    StorePointer(&raw_ptr()->offset_in_words_to_field_, array.raw());
+  }
+  return array.raw();
+}
+
+
 bool Class::HasInstanceFields() const {
   const Array& field_array = Array::Handle(fields());
   Field& field = Field::Handle();
@@ -4224,7 +4249,9 @@
 
 
 RawFunction* Function::implicit_closure_function() const {
-  if (IsClosureFunction() || IsSignatureFunction()) {
+  if (IsClosureFunction() ||
+      IsSignatureFunction() ||
+      IsStaticInitializerFunction()) {
     return Function::null();
   }
   const Object& obj = Object::Handle(raw_ptr()->data_);
@@ -5427,6 +5454,35 @@
 }
 
 
+RawFunction* Function::NewStaticInitializer(const String& field_name,
+                                            const AbstractType& result_type,
+                                            const Class& cls,
+                                            intptr_t initializer_pos) {
+  const String& init_name =
+      String::Handle(Symbols::New(String::Handle(
+          String::Concat(Symbols::InitPrefix(), field_name))));
+  const Function& init_function = Function::ZoneHandle(
+      Function::New(init_name,
+                    RawFunction::kStaticInitializer,
+                    true,  // static
+                    false,  // !const
+                    false,  // !abstract
+                    false,  // !external
+                    cls,
+                    initializer_pos));
+  init_function.set_result_type(result_type);
+  // Static initializer functions are generated by the VM and are therfore
+  // hidden from the user. Since they are only executed once, we avoid
+  // optimizing and inlining them. After the field is initialized, the
+  // optimizing compiler can eliminate the call to the static initializer
+  // via constant folding.
+  init_function.set_is_visible(false);
+  init_function.set_is_optimizable(false);
+  init_function.set_is_inlinable(false);
+  return init_function.raw();
+}
+
+
 const char* Function::ToCString() const {
   const char* static_str = is_static() ? " static" : "";
   const char* abstract_str = is_abstract() ? " abstract" : "";
@@ -5451,6 +5507,9 @@
     case RawFunction::kImplicitSetter:
       kind_str = " setter";
       break;
+    case RawFunction::kStaticInitializer:
+      kind_str = " static-initializer";
+      break;
     case RawFunction::kImplicitStaticFinalGetter:
       kind_str = " static-final-getter";
       break;
@@ -5522,6 +5581,9 @@
       case RawFunction::kConstructor:
         kind_string = "constructor";
         break;
+      case RawFunction::kStaticInitializer:
+        kind_string = "static initializer";
+        break;
       case RawFunction::kImplicitStaticFinalGetter:
         kind_string = "static final getter";
         break;
@@ -5960,17 +6022,58 @@
 }
 
 
-void Field::UpdateCid(intptr_t cid) const {
+static intptr_t GetListLength(const Object& value) {
+  const intptr_t cid = value.GetClassId();
+  ASSERT(RawObject::IsBuiltinListClassId(cid));
+  // Extract list length.
+  if (value.IsTypedData()) {
+    const TypedData& list = TypedData::Cast(value);
+    return list.Length();
+  } else if (value.IsArray()) {
+    const Array& list = Array::Cast(value);
+    return list.Length();
+  } else if (value.IsGrowableObjectArray()) {
+    // List length is variable.
+    return Field::kNoFixedLength;
+  } else if (value.IsExternalTypedData()) {
+    // TODO(johnmccutchan): Enable for external typed data.
+    return Field::kNoFixedLength;
+  } else if (RawObject::IsTypedDataViewClassId(cid)) {
+    // TODO(johnmccutchan): Enable for typed data views.
+    return Field::kNoFixedLength;
+  }
+  UNIMPLEMENTED();
+  return Field::kNoFixedLength;
+}
+
+
+bool Field::UpdateGuardedCidAndLength(const Object& value) const {
+  const intptr_t cid = value.GetClassId();
+  bool deoptimize = UpdateCid(cid);
+  intptr_t list_length = Field::kNoFixedLength;
+  if ((guarded_cid() != kDynamicCid) &&
+      is_final() && RawObject::IsBuiltinListClassId(cid)) {
+    list_length = GetListLength(value);
+  }
+  deoptimize = UpdateLength(list_length) || deoptimize;
+  if (deoptimize) {
+    DeoptimizeDependentCode();
+  }
+  return deoptimize;
+}
+
+
+bool Field::UpdateCid(intptr_t cid) const {
   if (guarded_cid() == kIllegalCid) {
     // Field is assigned first time.
     set_guarded_cid(cid);
     set_is_nullable(cid == kNullCid);
-    return;
+    return false;
   }
 
   if ((cid == guarded_cid()) || ((cid == kNullCid) && is_nullable())) {
     // Class id of the assigned value matches expected class id and nullability.
-    return;
+    return false;
   }
 
   if ((cid == kNullCid) && !is_nullable()) {
@@ -5989,11 +6092,11 @@
   }
 
   // Expected class id or nullability of the field changed.
-  DeoptimizeDependentCode();
+  return true;
 }
 
 
-void Field::UpdateLength(intptr_t list_length) const {
+bool Field::UpdateLength(intptr_t list_length) const {
   ASSERT(is_final() || (!is_final() &&
                         (list_length < Field::kUnknownFixedLength)));
   ASSERT((list_length == Field::kNoFixedLength) ||
@@ -6010,16 +6113,16 @@
   if (list_length_unknown && list_length_changed && !force_invalidate) {
     // List length set for first time.
     set_guarded_list_length(list_length);
-    return;
+    return false;
   }
 
   if (!list_length_changed && !force_invalidate) {
     // List length unchanged.
-    return;
+    return false;
   }
   // Multiple list lengths assigned here, stop tracking length.
   set_guarded_list_length(Field::kNoFixedLength);
-  DeoptimizeDependentCode();
+  return true;
 }
 
 
@@ -8345,6 +8448,7 @@
   all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
   RECOGNIZED_LIST(CHECK_FINGERPRINTS);
   INLINE_WHITE_LIST(CHECK_FINGERPRINTS);
+  POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS);
 
   all_libs.Clear();
   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 81de3ce..75ba0b8 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -863,6 +863,10 @@
   RawArray* fields() const { return raw_ptr()->fields_; }
   void SetFields(const Array& value) const;
 
+  // Returns an array of all fields of this class and its superclasses indexed
+  // by offset in words.
+  RawArray* OffsetToFieldMap() const;
+
   // Returns true if non-static fields are defined.
   bool HasInstanceFields() const;
 
@@ -1589,6 +1593,7 @@
       case RawFunction::kClosureFunction:
       case RawFunction::kConstructor:
       case RawFunction::kImplicitStaticFinalGetter:
+      case RawFunction::kStaticInitializer:
         return false;
       default:
         UNREACHABLE();
@@ -1606,6 +1611,7 @@
       case RawFunction::kImplicitGetter:
       case RawFunction::kImplicitSetter:
       case RawFunction::kImplicitStaticFinalGetter:
+      case RawFunction::kStaticInitializer:
         return true;
       case RawFunction::kClosureFunction:
       case RawFunction::kConstructor:
@@ -1809,6 +1815,11 @@
     return kind() == RawFunction::kImplicitSetter;
   }
 
+  // Returns true if this function represents an static initializer function.
+  bool IsStaticInitializerFunction() const {
+    return kind() == RawFunction::kStaticInitializer;
+  }
+
   // Returns true if this function represents a (possibly implicit) closure
   // function.
   bool IsClosureFunction() const {
@@ -1867,6 +1878,13 @@
                                          const Function& parent,
                                          intptr_t token_pos);
 
+  // Creates a new static initializer function which is invoked in the implicit
+  // static getter function.
+  static RawFunction* NewStaticInitializer(const String& field_name,
+                                           const AbstractType& result_type,
+                                           const Class& cls,
+                                           intptr_t token_pos);
+
   // Allocate new function object, clone values from this function. The
   // owner of the clone is new_owner.
   RawFunction* Clone(const Class& new_owner) const;
@@ -2124,13 +2142,9 @@
     return OFFSET_OF(RawField, is_nullable_);
   }
 
-  // Update guarded class id and nullability of the field to reflect assignment
-  // of the value with the given class id to this field. May trigger
-  // deoptimization of dependent code.
-  void UpdateCid(intptr_t cid) const;
-  // Update guarded class length of the field to reflect assignment of the
-  // value with the given length. May trigger deoptimization of dependent code.
-  void UpdateLength(intptr_t length) const;
+  // Update guarded cid and guarded length for this field. May trigger
+  // deoptimization of dependent optimized code.
+  bool UpdateGuardedCidAndLength(const Object& value) const;
 
   // Return the list of optimized code objects that were optimized under
   // assumptions about guarded class id and nullability of this field.
@@ -2169,6 +2183,16 @@
   class FinalBit : public BitField<bool, kFinalBit, 1> {};
   class HasInitializerBit : public BitField<bool, kHasInitializerBit, 1> {};
 
+  // Update guarded class id and nullability of the field to reflect assignment
+  // of the value with the given class id to this field. Returns true, if
+  // deoptimization of dependent code is required.
+  bool UpdateCid(intptr_t cid) const;
+
+  // Update guarded class length of the field to reflect assignment of the
+  // value with the given length. Returns true if deoptimization of dependent
+  // code is required.
+  bool UpdateLength(intptr_t length) const;
+
   void set_name(const String& value) const;
   void set_is_static(bool is_static) const {
     set_kind_bits(StaticBit::update(is_static, raw_ptr()->kind_bits_));
@@ -3828,6 +3852,7 @@
   }
 
   void SetField(const Field& field, const Object& value) const {
+    field.UpdateGuardedCidAndLength(value);
     StorePointer(FieldAddr(field), value.raw());
   }
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 5f27790..6ff23a5 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -781,6 +781,9 @@
     case RawFunction::kImplicitStaticFinalGetter:
       node_sequence = parser.ParseStaticFinalGetter(func);
       break;
+    case RawFunction::kStaticInitializer:
+      node_sequence = parser.ParseStaticInitializer(func);
+      break;
     case RawFunction::kMethodExtractor:
       node_sequence = parser.ParseMethodExtractor(func);
       break;
@@ -878,7 +881,44 @@
             (LookaheadToken(5) == Token::kLPAREN))) {
       expr = ParseNewOperator(Token::kCONST);
     } else {
-      expr = ParsePrimary();
+      // Can be x, C.x, or L.C.x.
+      expr = ParsePrimary();  // Consumes x, C or L.C.
+      Class& cls = Class::Handle();
+      if (expr->IsPrimaryNode()) {
+        PrimaryNode* primary_node = expr->AsPrimaryNode();
+        if (primary_node->primary().IsClass()) {
+          // If the primary node referred to a class we are loading a
+          // qualified static field.
+          cls ^= primary_node->primary().raw();
+        } else {
+          ErrorMsg(expr_pos, "Metadata expressions must refer to a const field "
+                             "or constructor");
+        }
+      }
+      if (CurrentToken() == Token::kPERIOD) {
+        // C.x or L.C.X.
+        if (cls.IsNull()) {
+          ErrorMsg(expr_pos, "Metadata expressions must refer to a const field "
+                             "or constructor");
+        }
+        ConsumeToken();
+        const intptr_t ident_pos = TokenPos();
+        String* ident = ExpectIdentifier("identifier expected");
+        const Field& field = Field::Handle(cls.LookupStaticField(*ident));
+        if (field.IsNull()) {
+          ErrorMsg(ident_pos,
+                   "Class '%s' has no field '%s'",
+                   cls.ToCString(),
+                   ident->ToCString());
+        }
+        if (!field.is_const()) {
+          ErrorMsg(ident_pos,
+                   "Field '%s' of class '%s' is not const",
+                   ident->ToCString(),
+                   cls.ToCString());
+        }
+        expr = GenerateStaticFieldLookup(field, TokenPos());
+      }
     }
     if (expr->EvalConstExpr() == NULL) {
       ErrorMsg(expr_pos, "expression must be a compile-time constant");
@@ -907,33 +947,17 @@
   const Field& field =
       Field::ZoneHandle(field_class.LookupStaticField(field_name));
 
-  if (!field.is_const() &&
-      (field.value() != Object::transition_sentinel().raw()) &&
-      (field.value() != Object::sentinel().raw())) {
-    // The field has already been initialized at compile time (this can
-    // happen, e.g., if we are recompiling for optimization).  There is no
-    // need to check for initialization and compile the potentially very
-    // large initialization code.  By skipping this code, the deoptimization
-    // ids will not line up with the original code, but this is safe because
-    // LoadStaticField does not deoptimize.
-    LoadStaticFieldNode* load_node = new LoadStaticFieldNode(ident_pos, field);
-    ReturnNode* return_node = new ReturnNode(ident_pos, load_node);
-    current_block_->statements->Add(return_node);
-    return CloseBlock();
-  }
-
-  // Static const fields must have an initializer.
+  // Static final fields must have an initializer.
   ExpectToken(Token::kASSIGN);
 
-  // We don't want to use ParseConstExpr() here because we don't want
-  // the constant folding code to create, compile and execute a code
-  // fragment to evaluate the expression. Instead, we just make sure
-  // the static const field initializer is a constant expression and
-  // leave the evaluation to the getter function.
   const intptr_t expr_pos = TokenPos();
-  AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
-
   if (field.is_const()) {
+    // We don't want to use ParseConstExpr() here because we don't want
+    // the constant folding code to create, compile and execute a code
+    // fragment to evaluate the expression. Instead, we just make sure
+    // the static const field initializer is a constant expression and
+    // leave the evaluation to the getter function.
+    AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
     // This getter will only be called once at compile time.
     if (expr->EvalConstExpr() == NULL) {
       ErrorMsg(expr_pos, "initializer is not a valid compile-time constant");
@@ -995,7 +1019,19 @@
     // we leave the field value as 'transition_sentinel', which is wrong.
     // A second reference to the field later throws a circular dependency
     // exception. The field should instead be set to null after an exception.
-    initialize_field->Add(new StoreStaticFieldNode(ident_pos, field, expr));
+    const String& init_name =
+        String::Handle(Symbols::New(String::Handle(
+        String::Concat(Symbols::InitPrefix(), String::Handle(field.name())))));
+    const Function& init_function = Function::ZoneHandle(
+        field_class.LookupStaticFunction(init_name));
+    ASSERT(!init_function.IsNull());
+    ArgumentListNode* arguments = new ArgumentListNode(expr_pos);
+    StaticCallNode* init_call =
+        new StaticCallNode(expr_pos, init_function, arguments);
+
+    initialize_field->Add(new StoreStaticFieldNode(ident_pos,
+                                                   field,
+                                                   init_call));
     AstNode* uninitialized_check =
         new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL);
     current_block_->statements->Add(uninitialized_check);
@@ -1010,6 +1046,25 @@
 }
 
 
+SequenceNode* Parser::ParseStaticInitializer(const Function& func) {
+  TRACE_PARSER("ParseStaticInitializer");
+  ParamList params;
+  ASSERT(func.num_fixed_parameters() == 0);  // static.
+  ASSERT(!func.HasOptionalParameters());
+  ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
+
+  // Build local scope for function and populate with the formal parameters.
+  OpenFunctionBlock(func);
+  AddFormalParamsToScope(&params, current_block_->scope);
+
+  intptr_t expr_pos = func.token_pos();
+  AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
+  ReturnNode* return_node = new ReturnNode(expr_pos, expr);
+  current_block_->statements->Add(return_node);
+  return CloseBlock();
+}
+
+
 // Create AstNodes for an implicit instance getter method:
 //   LoadLocalNode 0 ('this');
 //   LoadInstanceFieldNode (field_name);
@@ -2091,8 +2146,7 @@
 
     if (found) continue;
 
-    field.UpdateCid(kNullCid);
-    field.UpdateLength(Field::kNoFixedLength);
+    field.UpdateGuardedCidAndLength(Object::Handle());
   }
 }
 
@@ -3253,6 +3307,7 @@
   Function& setter = Function::Handle();
   Field& class_field = Field::ZoneHandle();
   Instance& init_value = Instance::Handle();
+  intptr_t expr_pos = -1;
   while (true) {
     bool has_initializer = CurrentToken() == Token::kASSIGN;
     bool has_simple_literal = false;
@@ -3277,6 +3332,7 @@
           (LookaheadToken(1) == Token::kSEMICOLON)) {
         has_simple_literal = IsSimpleLiteral(*field->type, &init_value);
       }
+      expr_pos = TokenPos();
       SkipExpr();
     } else {
       // Static const and static final fields must have an initializer.
@@ -3320,6 +3376,14 @@
                                field->name_pos);
         getter.set_result_type(*field->type);
         members->AddFunction(getter);
+
+        // Create initializer function.
+        const Function& init_function = Function::ZoneHandle(
+            Function::NewStaticInitializer(*field->name,
+                                           *field->type,
+                                           current_class(),
+                                           expr_pos));
+        members->AddFunction(init_function);
       }
     }
 
@@ -4429,6 +4493,7 @@
       if ((is_const || is_final) && (LookaheadToken(1) == Token::kSEMICOLON)) {
         has_simple_literal = IsSimpleLiteral(type, &field_value);
       }
+      const intptr_t expr_pos = TokenPos();
       SkipExpr();
       field.set_value(field_value);
       if (!has_simple_literal) {
@@ -4444,6 +4509,14 @@
                                name_pos);
         getter.set_result_type(type);
         top_level->functions.Add(getter);
+
+        // Create initializer function.
+        const Function& init_function = Function::ZoneHandle(
+            Function::NewStaticInitializer(var_name,
+                                           type,
+                                           current_class(),
+                                           expr_pos));
+        top_level->functions.Add(init_function);
       }
     } else if (is_final) {
       ErrorMsg(name_pos, "missing initializer for final or const variable");
@@ -6441,8 +6514,7 @@
       Resolver::ResolveStatic(cls,
                               func_name,
                               arguments->length(),
-                              arguments->names(),
-                              Resolver::kIsQualified));
+                              arguments->names()));
   ASSERT(!func.IsNull());
   return new StaticCallNode(arguments->token_pos(), func, arguments);
 }
@@ -7963,8 +8035,7 @@
       Resolver::ResolveStatic(cls,
                               func_name,
                               num_arguments,
-                              arguments->names(),
-                              Resolver::kIsQualified));
+                              arguments->names()));
   if (func.IsNull()) {
     // Check if there is a static field of the same name, it could be a closure
     // and so we try and invoke the closure.
@@ -7979,8 +8050,7 @@
       func = Resolver::ResolveStatic(cls,
                                      getter_name,
                                      kNumArguments,
-                                     Object::empty_array(),
-                                     Resolver::kIsQualified);
+                                     Object::empty_array());
       if (!func.IsNull()) {
         ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter);
         EnsureSavedCurrentContext();
@@ -8088,8 +8158,7 @@
     func = Resolver::ResolveStatic(cls,
                                    getter_name,
                                    kNumArguments,
-                                   Object::empty_array(),
-                                   Resolver::kIsQualified);
+                                   Object::empty_array());
     if (func.IsNull()) {
       // We might be referring to an implicit closure, check to see if
       // there is a function of the same name.
@@ -8659,8 +8728,7 @@
           Function::Handle(Resolver::ResolveStatic(field_owner,
                                                    getter_name,
                                                    kNumArguments,
-                                                   Object::empty_array(),
-                                                   Resolver::kIsQualified));
+                                                   Object::empty_array()));
       ASSERT(!func.IsNull());
       ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter);
       Object& const_value = Object::Handle(
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 5ccaca5..41798e3 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -464,6 +464,7 @@
   SequenceNode* ParseInstanceGetter(const Function& func);
   SequenceNode* ParseInstanceSetter(const Function& func);
   SequenceNode* ParseStaticFinalGetter(const Function& func);
+  SequenceNode* ParseStaticInitializer(const Function& func);
   SequenceNode* ParseMethodExtractor(const Function& func);
   SequenceNode* ParseNoSuchMethodDispatcher(const Function& func,
                                             Array& default_values);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ee59096..0eb68b8 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -477,6 +477,7 @@
   RawString* name_;
   RawArray* functions_;
   RawArray* fields_;
+  RawArray* offset_in_words_to_field_;
   RawGrowableObjectArray* closure_functions_;  // Local functions and literals.
   RawArray* interfaces_;  // Array of AbstractType.
   RawGrowableObjectArray* direct_subclasses_;  // Array of Class.
@@ -602,6 +603,7 @@
     kImplicitSetter,     // represents an implicit setter for fields.
     kImplicitStaticFinalGetter,  // represents an implicit getter for static
                                  // final fields (incl. static const fields).
+    kStaticInitializer,  // used in implicit static getters.
     kMethodExtractor,  // converts method into implicit closure on the receiver.
     kNoSuchMethodDispatcher,  // invokes noSuchMethod.
     kInvokeFieldDispatcher,  // invokes a field as a closure.
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index e714f44..27ad524 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -2654,7 +2654,14 @@
 void RawMirrorReference::WriteTo(SnapshotWriter* writer,
                                  intptr_t object_id,
                                  Snapshot::Kind kind) {
-  UNREACHABLE();
+  if (kind == Snapshot::kMessage) {
+    // We do not allow objects with native fields in an isolate message.
+    writer->SetWriteException(Exceptions::kArgument,
+                              "Illegal argument in isolate message"
+                              " : (object is a MirrorReference)");
+  } else {
+    UNREACHABLE();
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 1b43064..211c15e 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -144,8 +144,7 @@
                                      const String& class_name,
                                      const String& function_name,
                                      intptr_t num_arguments,
-                                     const Array& argument_names,
-                                     StaticResolveType resolve_type) {
+                                     const Array& argument_names) {
   ASSERT(!library.IsNull());
   Function& function = Function::Handle();
   if (class_name.IsNull() || (class_name.Length() == 0)) {
@@ -181,8 +180,7 @@
       function = ResolveStatic(cls,
                                function_name,
                                num_arguments,
-                               argument_names,
-                               resolve_type);
+                               argument_names);
     }
     if (FLAG_trace_resolving && function.IsNull()) {
       OS::Print("ResolveStatic error: function '%s.%s' not found.\n",
@@ -194,41 +192,16 @@
 }
 
 
-RawFunction* Resolver::ResolveStaticByName(const Class&  cls,
-                                           const String& function_name,
-                                           StaticResolveType resolve_type) {
-  ASSERT(!cls.IsNull());
-
-  if (FLAG_trace_resolving) {
-    OS::Print("ResolveStatic '%s'\n", function_name.ToCString());
-  }
-
-  // Now look for a static function whose name matches function_name
-  // in the class.
-  Function& function =
-      Function::Handle(cls.LookupStaticFunction(function_name));
-  if (resolve_type == kNotQualified) {
-    // Walk the hierarchy.
-    Class& super_class = Class::Handle(cls.SuperClass());
-    while (function.IsNull()) {
-      function = super_class.LookupStaticFunction(function_name);
-      super_class = super_class.SuperClass();
-      if (super_class.IsNull()) break;
-    }
-  }
-  return function.raw();
-}
-
-
-
 RawFunction* Resolver::ResolveStatic(const Class&  cls,
                                      const String& function_name,
                                      intptr_t num_arguments,
-                                     const Array& argument_names,
-                                     StaticResolveType resolve_type) {
+                                     const Array& argument_names) {
   ASSERT(!cls.IsNull());
-  const Function& function = Function::Handle(
-      ResolveStaticByName(cls, function_name, resolve_type));
+  if (FLAG_trace_resolving) {
+    OS::Print("ResolveStatic '%s'\n", function_name.ToCString());
+  }
+  const Function& function =
+      Function::Handle(cls.LookupStaticFunction(function_name));
   if (function.IsNull() ||
       !function.AreValidArguments(num_arguments, argument_names, NULL)) {
     // Return a null function to signal to the upper levels to throw a
diff --git a/runtime/vm/resolver.h b/runtime/vm/resolver.h
index a0f2b33..32ef3bc 100644
--- a/runtime/vm/resolver.h
+++ b/runtime/vm/resolver.h
@@ -37,11 +37,6 @@
       const Class& receiver_class,
       const String& function_name);
 
-  enum StaticResolveType {
-    kIsQualified,
-    kNotQualified
-  };
-
   // Resolve specified dart static function. If library.IsNull, use
   // either application library or core library if no application library
   // exists. Passing negative num_arguments means that the function
@@ -52,20 +47,13 @@
                                     const String& cls_name,
                                     const String& function_name,
                                     intptr_t num_arguments,
-                                    const Array& argument_names,
-                                    StaticResolveType resolve_type);
-
-  // Resolve specified dart static function.
-  static RawFunction* ResolveStaticByName(const Class&  cls,
-                                          const String& function_name,
-                                          StaticResolveType resolve_type);
+                                    const Array& argument_names);
 
   // Resolve specified dart static function with specified arity.
   static RawFunction* ResolveStatic(const Class&  cls,
                                     const String& function_name,
                                     intptr_t num_arguments,
-                                    const Array& argument_names,
-                                    StaticResolveType resolve_type);
+                                    const Array& argument_names);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index 6ede57c..22c4dd5 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -79,7 +79,6 @@
   const char* test_class_name = "A";
   const char* test_static_function_name = "static_foo";
   const int kTestValue = 42;
-  const Resolver::StaticResolveType kResolveType = Resolver::kIsQualified;
 
   // Setup a static function which can be invoked.
   SetupStaticFunction(test_library_name,
@@ -101,8 +100,7 @@
                                 class_name,
                                 static_function_name,
                                 kNumArguments,
-                                Object::empty_array(),
-                                kResolveType));
+                                Object::empty_array()));
     EXPECT(!function.IsNull());  // No ambiguity error expected.
     const Array& args = Array::Handle(Array::New(kNumArguments));
     const String& arg0 = String::Handle(String::New("junk"));
@@ -122,8 +120,7 @@
                                 class_name,
                                 static_function_name,
                                 kNumArguments,
-                                Object::empty_array(),
-                                kResolveType));
+                                Object::empty_array()));
     EXPECT(bad_function.IsNull());  // No ambiguity error expected.
   }
 
@@ -138,8 +135,7 @@
                                 super_class_name,
                                 super_static_function_name,
                                 kNumArguments,
-                                Object::empty_array(),
-                                kResolveType));
+                                Object::empty_array()));
     EXPECT(!super_function.IsNull());  // No ambiguity error expected.
   }
 }
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 6df4672..5584104 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -150,6 +150,8 @@
       isolate_(isolate),
       cls_(Class::Handle()),
       obj_(Object::Handle()),
+      array_(Array::Handle()),
+      field_(Field::Handle()),
       str_(String::Handle()),
       library_(Library::Handle()),
       type_(AbstractType::Handle()),
@@ -789,9 +791,26 @@
       instance_size = cls_.instance_size();
     }
     intptr_t offset = Object::InstanceSize();
+    intptr_t result_cid = result->GetClassId();
     while (offset < instance_size) {
       obj_ = ReadObjectRef();
       result->SetFieldAtOffset(offset, obj_);
+      if (kind_ == Snapshot::kMessage) {
+        // TODO(fschneider): Consider hoisting these lookups out of the loop.
+        // This would involve creating a handle, since cls_ can't be reused
+        // across the call to ReadObjectRef.
+        cls_ = isolate()->class_table()->At(result_cid);
+        array_ = cls_.OffsetToFieldMap();
+        field_ ^= array_.At(offset >> kWordSizeLog2);
+        // Entries can be null because offset can be outside of instance fields
+        // due to rounded allocation size.
+        if (!field_.IsNull()) {
+          ASSERT(field_.Offset() == offset);
+          field_.UpdateGuardedCidAndLength(obj_);
+        }
+      }
+      // TODO(fschneider): Verify the guarded cid and length for other kinds of
+      // snapshot (kFull, kScript) with asserts.
       offset += kWordSize;
     }
     if (kind_ == Snapshot::kFull) {
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 4643a51..ff65e52 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -320,6 +320,8 @@
   Isolate* isolate_;  // Current isolate.
   Class& cls_;  // Temporary Class handle.
   Object& obj_;  // Temporary Object handle.
+  Array& array_;  // Temporary Array handle.
+  Field& field_;  // Temporary Field handle.
   String& str_;  // Temporary String handle.
   Library& library_;  // Temporary library handle.
   AbstractType& type_;  // Temporary type handle.
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index d52e244..a9a3095 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -261,6 +261,7 @@
   V(_as, "_as")                                                                \
   V(GetterPrefix, "get:")                                                      \
   V(SetterPrefix, "set:")                                                      \
+  V(InitPrefix, "init:")                                                       \
   V(PrivateGetterPrefix, "get:_")                                              \
   V(PrivateSetterPrefix, "set:_")                                              \
   V(_New, "_new")                                                              \
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index b6e5394..e40c74a 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -85,8 +85,9 @@
                        Uri packageRoot,
                        CompilerInputProvider inputProvider,
                        DiagnosticHandler handler,
-                       [List<String> options = const [],
-                        CompilerOutputProvider outputProvider]) {
+                       [List<String> options = const [], 
+                        CompilerOutputProvider outputProvider,
+                        Map<String, dynamic> environment = const {}]) {
   if (!libraryRoot.path.endsWith("/")) {
     throw new ArgumentError("libraryRoot must end with a /");
   }
@@ -100,7 +101,8 @@
                                    handler,
                                    libraryRoot,
                                    packageRoot,
-                                   options);
+                                   options,
+                                   environment);
   // TODO(ahe): Use the value of the future (which signals success or failure).
   return compiler.run(script).then((_) {
     String code = compiler.assembledCode;
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 022acb4..cc8be6e 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -20,6 +20,7 @@
   final Uri libraryRoot;
   final Uri packageRoot;
   List<String> options;
+  Map<String, dynamic> environment;
   bool mockableLibraryUsed = false;
   final Set<String> allowedLibraryCategories;
 
@@ -28,7 +29,8 @@
            this.handler,
            this.libraryRoot,
            this.packageRoot,
-           List<String> options)
+           List<String> options,
+           this.environment)
       : this.options = options,
         this.allowedLibraryCategories = getAllowedLibraryCategories(options),
         super(
@@ -329,4 +331,6 @@
     print('$message: ${tryToString(exception)}');
     print(tryToString(stackTrace));
   }
+
+  fromEnvironment(String name) => environment[name];
 }
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 7f666d3..5141109 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -149,7 +149,7 @@
 // more general solution.
 class BoxElement extends ElementX {
   BoxElement(String name, Element enclosingElement)
-      : super(name, ElementKind.VARIABLE, enclosingElement);
+      : super(name, ElementKind.VARIABLE_LIST, enclosingElement);
 
   DartType computeType(Compiler compiler) => compiler.types.dynamicType;
 }
@@ -389,7 +389,7 @@
           // A boxed element.
           freeVariableMapping[fromElement] = updatedElement;
           Element boxElement = updatedElement.enclosingElement;
-          assert(boxElement.kind == ElementKind.VARIABLE);
+          assert(boxElement is BoxElement);
           boxes.add(boxElement);
         }
       });
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 735d2f1..e7d3b79 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -634,7 +634,77 @@
       return evaluateArgumentsToConstructor(
           node, selector, send.arguments, constructor);
     }
-    return makeConstructedConstant(node, type, constructor, evaluateArguments);
+
+    if (constructor == compiler.intEnvironment
+        || constructor == compiler.boolEnvironment
+        || constructor == compiler.stringEnvironment) {
+      List<Constant> arguments = evaluateArguments(constructor.implementation);
+      var firstArgument = arguments[0];
+      Constant defaultValue = arguments[1];
+
+      if (firstArgument is NullConstant) {
+        compiler.reportFatalError(
+            send.arguments.head, MessageKind.NULL_NOT_ALLOWED);
+      }
+
+      if (firstArgument is! StringConstant) {
+        DartType type = defaultValue.computeType(compiler);
+        compiler.reportFatalError(
+            send.arguments.head, MessageKind.NOT_ASSIGNABLE.error,
+            {'fromType': type, 'toType': compiler.stringClass.rawType});
+      }
+
+      if (constructor == compiler.intEnvironment
+          && !(defaultValue is NullConstant || defaultValue is IntConstant)) {
+        DartType type = defaultValue.computeType(compiler);
+        compiler.reportFatalError(
+            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+            {'fromType': type, 'toType': compiler.intClass.rawType});
+      }
+
+      if (constructor == compiler.boolEnvironment
+          && !(defaultValue is NullConstant || defaultValue is BoolConstant)) {
+        DartType type = defaultValue.computeType(compiler);
+        compiler.reportFatalError(
+            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+            {'fromType': type, 'toType': compiler.boolClass.rawType});
+      }
+
+      if (constructor == compiler.stringEnvironment
+          && !(defaultValue is NullConstant
+               || defaultValue is StringConstant)) {
+        DartType type = defaultValue.computeType(compiler);
+        compiler.reportFatalError(
+            send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE.error,
+            {'fromType': type, 'toType': compiler.stringClass.rawType});
+      }
+
+      String value =
+          compiler.fromEnvironment(firstArgument.value.slowToString());
+
+      if (value == null) {
+        return defaultValue;
+      } else if (constructor == compiler.intEnvironment) {
+        int number = int.parse(value, onError: (_) => null);
+        return (number == null)
+            ? defaultValue
+            : constantSystem.createInt(number);
+      } else if (constructor == compiler.boolEnvironment) {
+        if (value == 'true') {
+          return constantSystem.createBool(true);
+        } else if (value == 'false') {
+          return constantSystem.createBool(false);
+        } else {
+          return defaultValue;
+        }
+      } else {
+        assert(constructor == compiler.stringEnvironment);
+        return constantSystem.createString(new DartString.literal(value), node);
+      }
+    } else {
+      return makeConstructedConstant(
+          node, type, constructor, evaluateArguments);
+    }
   }
 
   Constant makeConstructedConstant(
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index d0d79d3..067ee88 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -473,6 +473,11 @@
   Element identicalFunction;
   Element functionApplyMethod;
   Element invokeOnMethod;
+  Element intEnvironment;
+  Element boolEnvironment;
+  Element stringEnvironment;
+
+  fromEnvironment(String name) => null;
 
   Element get currentElement => _currentElement;
 
@@ -571,6 +576,8 @@
       Compiler.NO_SUCH_METHOD, null, Compiler.NO_SUCH_METHOD_ARG_COUNT);
   final Selector symbolValidatedConstructorSelector = new Selector.call(
       'validated', null, 1);
+  final Selector fromEnvironmentSelector = new Selector.callConstructor(
+      'fromEnvironment', null, 2);
 
   bool enabledNoSuchMethod = false;
   bool enabledRuntimeType = false;
@@ -852,6 +859,13 @@
           symbolValidatedConstructorSelector);
     } else if (mirrorsUsedClass == cls) {
       mirrorsUsedConstructor = cls.constructors.head;
+    } else if (intClass == cls) {
+      intEnvironment = intClass.lookupConstructor(fromEnvironmentSelector);
+    } else if (stringClass == cls) {
+      stringEnvironment =
+          stringClass.lookupConstructor(fromEnvironmentSelector);
+    } else if (boolClass == cls) {
+      boolEnvironment = boolClass.lookupConstructor(fromEnvironmentSelector);
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 2990a9e..7869913 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -112,6 +112,7 @@
   // TODO(johnniwinther): Measure time for reading files.
   SourceFileProvider inputProvider = new CompilerSourceFileProvider();
   diagnosticHandler = new FormattingDiagnosticHandler(inputProvider);
+  Map<String, dynamic> environment = new Map<String, dynamic>();
 
   passThrough(String argument) => options.add(argument);
 
@@ -174,6 +175,13 @@
     passThrough('--verbose');
   }
 
+  addInEnvironment(String argument) {
+    int eqIndex = argument.indexOf('=');
+    String name = argument.substring(2, eqIndex);
+    String value = argument.substring(eqIndex + 1);
+    environment[name] = value;
+  }
+
   setCategories(String argument) {
     List<String> categories = extractParameter(argument).split(',');
     Set<String> allowedCategories =
@@ -275,6 +283,7 @@
     new OptionHandler('--terse', passThrough),
     new OptionHandler('--disallow-unsafe-eval',
                       (_) => hasDisallowUnsafeEval = true),
+    new OptionHandler('-D.+=.*', addInEnvironment),
 
     // The following two options must come last.
     new OptionHandler('-.*', (String argument) {
@@ -411,7 +420,7 @@
 
   return api.compile(uri, libraryRoot, packageRoot,
               inputProvider, diagnosticHandler,
-              options, outputProvider)
+              options, outputProvider, environment)
             .then(compilationDone);
 }
 
@@ -494,6 +503,9 @@
   -v, --verbose
     Display verbose information.
 
+  -D<name>=<value>
+    Define an environment variable.
+
   --version
     Display version information.
 
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 36ce3e4..8af9dfc 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -552,6 +552,16 @@
         && node.arguments.tail.tail.isEmpty;
   }
 
+  static bool isConstructorOfTypedArraySubclass(Element element,
+                                                Compiler compiler) {
+    if (compiler.typedDataClass == null) return false;
+    ClassElement cls = element.getEnclosingClass();
+    if (cls == null || !element.isConstructor()) return false;
+    return compiler.world.isSubclass(compiler.typedDataClass, cls)
+        && cls.getLibrary() == compiler.typedDataLibrary
+        && element.name == '';
+  }
+
   static bool switchStatementHasContinue(SwitchStatement node,
                                          TreeElements elements) {
     for (SwitchCase switchCase in node.cases) {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
index 9be28ab..d433dd5 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -149,6 +149,11 @@
   T typeOfElement(Element element);
 
   /**
+   * Returns the return type of [element].
+   */
+  T returnTypeOfElement(Element element);
+
+  /**
    * Records that [node] sets final field [element] to be of type [type].
    *
    * [nodeHolder] is the element holder of [node].
@@ -845,6 +850,18 @@
           node, () => types.allocateContainer(
               types.fixedListType, node, outermostElement,
               elementType, initialLength));
+    } else if (Elements.isConstructorOfTypedArraySubclass(element, compiler)) {
+      int initialLength;
+      LiteralInt length = node.arguments.head.asLiteralInt();
+      if (length != null) {
+        initialLength = length.value;
+      }
+      T elementType = inferrer.returnTypeOfElement(
+          element.getEnclosingClass().lookupMember('[]'));
+      return inferrer.concreteTypes.putIfAbsent(
+        node, () => types.allocateContainer(
+          types.nonNullExact(element.getEnclosingClass()), node,
+          outermostElement, elementType, initialLength));
     } else if (element.isFunction() || element.isConstructor()) {
       return returnType;
     } else {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index 13ccddc..6b39f4c 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -253,16 +253,23 @@
                                     Node node,
                                     Element enclosing,
                                     [TypeInformation elementType, int length]) {
+    bool isTypedArray = (compiler.typedDataClass != null)
+        && type.type.satisfies(compiler.typedDataClass, compiler);
     bool isConst = (type.type == compiler.typesTask.constListType);
-    bool isFixed = (type.type == compiler.typesTask.fixedListType) || isConst;
+    bool isFixed = (type.type == compiler.typesTask.fixedListType)
+        || isConst
+        || isTypedArray;
+    bool isElementInferred = isConst || isTypedArray;
 
     int inferredLength = isFixed ? length : null;
-    TypeMask elementTypeMask = isConst ? elementType.type : dynamicType.type;
+    TypeMask elementTypeMask = isElementInferred
+        ? elementType.type
+        : dynamicType.type;
     ContainerTypeMask mask = new ContainerTypeMask(
         type.type, node, enclosing, elementTypeMask, inferredLength);
     ElementInContainerTypeInformation element =
         new ElementInContainerTypeInformation(elementType);
-    element.inferred = isConst;
+    element.inferred = isElementInferred;
 
     allocatedTypes.add(element);
     return allocatedContainers[node] =
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
index 3afb829..b6a2cab 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_nodes.dart
@@ -197,7 +197,7 @@
  * return type.
  *
  * Note that a few elements of these kinds must be treated specially,
- * and they are dealt in [ElementTypeInformation.handleSpecialCase]:
+ * and they are dealt in [ElementTypeInformation.handleSpecialCases]:
  *
  * - Parameters of closures, [noSuchMethod] and [call] instance
  *   methods: we currently do not infer types for those.
@@ -298,6 +298,18 @@
         }
       }
     }
+
+    Compiler compiler = inferrer.compiler;
+    if (element.declaration == compiler.intEnvironment) {
+      giveUp(inferrer);
+      return compiler.typesTask.intType.nullable();
+    } else if (element.declaration == compiler.boolEnvironment) {
+      giveUp(inferrer);
+      return compiler.typesTask.boolType.nullable();
+    } else if (element.declaration == compiler.stringEnvironment) {
+      giveUp(inferrer);
+      return compiler.typesTask.stringType.nullable();
+    }
     return null;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 4a94609..cdceeec 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -5,10 +5,8 @@
 part of js_backend;
 
 class JavaScriptItemCompilationContext extends ItemCompilationContext {
-  final Set<HInstruction> boundsChecked;
-
-  JavaScriptItemCompilationContext()
-      : boundsChecked = new Set<HInstruction>();
+  final Set<HInstruction> boundsChecked = new Set<HInstruction>();
+  final Set<HInstruction> allocatedFixedLists = new Set<HInstruction>();
 }
 
 class CheckedModeHelper {
@@ -207,20 +205,21 @@
    */
   Element mapTypeToInterceptor;
 
-  HType stringType;
-  HType doubleType;
-  HType intType;
-  HType numType;
-  HType boolType;
-  HType indexablePrimitiveType;
-  HType readableArrayType;
-  HType mutableArrayType;
-  HType fixedArrayType;
-  HType extendableArrayType;
-  HType nonNullType;
-  HType dynamicType;
-  HType nullType = const HBoundedType(const TypeMask.empty());
-  HType emptyType = const HBoundedType(const TypeMask.nonNullEmpty());
+  TypeMask get stringType => compiler.typesTask.stringType;
+  TypeMask get doubleType => compiler.typesTask.doubleType;
+  TypeMask get intType => compiler.typesTask.intType;
+  TypeMask get numType => compiler.typesTask.numType;
+  TypeMask get boolType => compiler.typesTask.boolType;
+  TypeMask get dynamicType => compiler.typesTask.dynamicType;
+  TypeMask get nullType => compiler.typesTask.nullType;
+  TypeMask get emptyType => const TypeMask.nonNullEmpty();
+  TypeMask indexablePrimitiveType;
+  TypeMask readableArrayType;
+  TypeMask mutableArrayType;
+  TypeMask fixedArrayType;
+  TypeMask extendableArrayType;
+  TypeMask nonNullType;
+
 
   Element getNativeInterceptorMethod;
   bool needToInitializeDispatchProperty = false;
@@ -613,32 +612,14 @@
 
     validateInterceptorImplementsAllObjectMethods(jsInterceptorClass);
 
-    stringType = new HBoundedType(
-        new TypeMask.nonNullExact(jsStringClass));
-    doubleType = new HBoundedType(
-        new TypeMask.nonNullExact(jsDoubleClass));
-    intType = new HBoundedType(
-        new TypeMask.nonNullExact(jsIntClass));
-    numType = new HBoundedType(
-        new TypeMask.nonNullSubclass(jsNumberClass));
-    boolType = new HBoundedType(
-        new TypeMask.nonNullExact(jsBoolClass));
-    indexablePrimitiveType = new HBoundedType(
-        new TypeMask.nonNullSubtype(jsIndexableClass));
-    readableArrayType = new HBoundedType(
-        new TypeMask.nonNullSubclass(jsArrayClass));
-    mutableArrayType = new HBoundedType(
-        new TypeMask.nonNullSubclass(jsMutableArrayClass));
-    fixedArrayType = new HBoundedType(
-        new TypeMask.nonNullExact(jsFixedArrayClass));
-    extendableArrayType = new HBoundedType(
-        new TypeMask.nonNullExact(jsExtendableArrayClass));
-    nonNullType = new HBoundedType(
-        compiler.typesTask.dynamicType.nonNullable());
-    dynamicType = new HBoundedType(
-        compiler.typesTask.dynamicType);
-
     typeVariableClass = compiler.findHelper('TypeVariable');
+
+    indexablePrimitiveType = new TypeMask.nonNullSubtype(jsIndexableClass);
+    readableArrayType = new TypeMask.nonNullSubclass(jsArrayClass);
+    mutableArrayType = new TypeMask.nonNullSubclass(jsMutableArrayClass);
+    fixedArrayType = new TypeMask.nonNullExact(jsFixedArrayClass);
+    extendableArrayType = new TypeMask.nonNullExact(jsExtendableArrayClass);
+    nonNullType = compiler.typesTask.dynamicType.nonNullable();
   }
 
   void validateInterceptorImplementsAllObjectMethods(
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
index 6ea330e..888447e 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/class_emitter.dart
@@ -355,11 +355,15 @@
       if (!backend.isNeededForReflection(classElement)) {
         buffer.write(',$n$n"+$reflectionName": 0');
       } else {
-        List<int> interfaces = <int>[];
-        for (DartType interface in classElement.interfaces) {
-          interfaces.add(task.metadataEmitter.reifyType(interface));
+        List<int> types = <int>[];
+        if (classElement.supertype != null) {
+          types.add(
+              task.metadataEmitter.reifyType(classElement.supertype));
         }
-        buffer.write(',$n$n"+$reflectionName": $interfaces');
+        for (DartType interface in classElement.interfaces) {
+          types.add(task.metadataEmitter.reifyType(interface));
+        }
+        buffer.write(',$n$n"+$reflectionName": $types');
       }
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
index d90caf6..373b65d 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/reflection_data_parser.dart
@@ -23,7 +23,7 @@
   if (!init.mangledNames) init.mangledNames = map();
   if (!init.mangledGlobalNames) init.mangledGlobalNames = map();
   if (!init.statics) init.statics = map();
-  if (!init.interfaces) init.interfaces = map();
+  if (!init.typeInformation) init.typeInformation = map();
   if (!init.globalFunctions) init.globalFunctions = map();
   var libraries = init.libraries;
   var mangledNames = init.mangledNames;
@@ -65,7 +65,7 @@
           if (descriptor[property] == 1) ''' // Break long line.
 '''descriptor[previousProperty].$reflectableField = 1;
           if (element && element.length) ''' // Break long line.
-'''init.interfaces[previousProperty] = element;
+'''init.typeInformation[previousProperty] = element;
         } else if (firstChar === "@") {
           property = property.substring(1);
           ${namer.CURRENT_ISOLATE}[property][$metadataField] = element;
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index 94ace737..987b996 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -223,7 +223,9 @@
   Compiler compiler = new apiimpl.Compiler(inputProvider,
                                            null,
                                            internalDiagnosticHandler,
-                                           libraryRoot, packageRoot, options);
+                                           libraryRoot, packageRoot,
+                                           options,
+                                           const {});
   compiler.librariesToAnalyzeWhenRun = libraries;
   return compiler.run(null).then((bool success) {
     if (success && !compilationFailed) {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 20259e7..40703cf 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -4073,30 +4073,38 @@
    * first.
    */
   void calculateAllSupertypes(ClassElement cls) {
-    // TODO(karlklose): Check if type arguments match, if a class
-    // element occurs more than once in the supertypes.
     if (cls.allSupertypes != null) return;
     final DartType supertype = cls.supertype;
     if (supertype != null) {
+      Map<Element, DartType> instantiations = new Map<Element, DartType>();
       LinkBuilder<DartType> allSupertypes = new LinkBuilder<DartType>();
 
-      void add(DartType type) {
+      void addSupertype(DartType type) {
+        DartType existing =
+            instantiations.putIfAbsent(type.element, () => type);
+        if (existing != null && existing != type) {
+          compiler.reportError(cls,
+              MessageKind.MULTI_INHERITANCE,
+              {'thisType': cls.computeType(compiler),
+               'firstType': existing,
+               'secondType': type});
+        }
         if (type.element != compiler.objectClass) {
           allSupertypes.addLast(type);
         }
       }
 
-      add(supertype);
+      addSupertype(supertype);
       for (Link<DartType> interfaces = cls.interfaces;
           !interfaces.isEmpty;
           interfaces = interfaces.tail) {
-        add(interfaces.head);
+        addSupertype(interfaces.head);
       }
-      addAllSupertypes(allSupertypes, supertype);
+      addAllSupertypes(addSupertype, supertype);
       for (Link<DartType> interfaces = cls.interfaces;
            !interfaces.isEmpty;
            interfaces = interfaces.tail) {
-        addAllSupertypes(allSupertypes, interfaces.head);
+        addAllSupertypes(addSupertype, interfaces.head);
       }
 
       allSupertypes.addLast(compiler.objectClass.rawType);
@@ -4111,7 +4119,7 @@
    * Adds [type] and all supertypes of [type] to [allSupertypes] while
    * substituting type variables.
    */
-  void addAllSupertypes(LinkBuilder<DartType> allSupertypes,
+  void addAllSupertypes(void addSupertype(DartType supertype),
                         InterfaceType type) {
     Link<DartType> typeArguments = type.typeArguments;
     ClassElement classElement = type.element;
@@ -4124,7 +4132,7 @@
       DartType supertype = supertypes.head;
       if (supertype.element != compiler.objectClass) {
         DartType substituted = supertype.subst(typeArguments, typeVariables);
-        allSupertypes.addLast(substituted);
+        addSupertype(substituted);
       }
       supertypes = supertypes.tail;
     }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
deleted file mode 100644
index e69de29..0000000
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ /dev/null
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 650a69d..2519c4f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -239,7 +239,7 @@
         }
         HInstruction parameter = builder.addParameter(
             parameterElement,
-            new HType.inferredTypeForElement(parameterElement, compiler));
+            TypeMaskFactory.inferredTypeForElement(parameterElement, compiler));
         builder.parameters[parameterElement] = parameter;
         directLocals[parameterElement] = parameter;
       });
@@ -303,7 +303,7 @@
       // Unlike `this`, receiver is nullable since direct calls to generative
       // constructor call the constructor with `null`.
       HParameterValue value =
-          new HParameterValue(parameter, new HType.exact(cls, compiler));
+          new HParameterValue(parameter, new TypeMask.exact(cls));
       builder.graph.explicitReceiverParameter = value;
       builder.graph.entry.addAtEntry(value);
     }
@@ -369,8 +369,12 @@
     } else if (isStoredInClosureField(element)) {
       Element redirect = redirectionMapping[element];
       HInstruction receiver = readLocal(closureData.closureElement);
-      HInstruction fieldGet = new HFieldGet(
-          redirect, receiver, builder.getTypeOfCapturedVariable(redirect));
+      TypeMask type = (element.kind == ElementKind.VARIABLE_LIST)
+          ? builder.backend.nonNullType
+          : builder.getTypeOfCapturedVariable(redirect);
+      assert(element.kind != ElementKind.VARIABLE_LIST
+             || element is BoxElement);
+      HInstruction fieldGet = new HFieldGet(redirect, receiver, type);
       builder.add(fieldGet);
       return fieldGet;
     } else if (isBoxed(element)) {
@@ -380,7 +384,7 @@
       // accessed through a closure-field.
       // Calling [readLocal] makes sure we generate the correct code to get
       // the box.
-      assert(redirect.enclosingElement.isVariable());
+      assert(redirect.enclosingElement is BoxElement);
       HInstruction box = readLocal(redirect.enclosingElement);
       HInstruction lookup = new HFieldGet(
           redirect, box, builder.getTypeOfCapturedVariable(redirect));
@@ -434,7 +438,7 @@
       // is captured will be boxed, but the box itself will be a local.
       // Inside the closure the box is stored in a closure-field and cannot
       // be accessed directly.
-      assert(redirect.enclosingElement.isVariable());
+      assert(redirect.enclosingElement is BoxElement);
       HInstruction box = readLocal(redirect.enclosingElement);
       builder.add(new HFieldSet(redirect, box, value));
     } else {
@@ -1000,10 +1004,10 @@
     return initialValue == null;
   }
 
-  HType cachedTypeOfThis;
+  TypeMask cachedTypeOfThis;
 
-  HType getTypeOfThis() {
-    HType result = cachedTypeOfThis;
+  TypeMask getTypeOfThis() {
+    TypeMask result = cachedTypeOfThis;
     if (result == null) {
       Element element = localsHandler.closureData.thisElement;
       ClassElement cls = element.enclosingElement.getEnclosingClass();
@@ -1012,22 +1016,22 @@
         // of the class that mixins the enclosing class. These two
         // classes do not have a subclass relationship, so, for
         // simplicity, we mark the type as an interface type.
-        result = new HType.nonNullSubtype(cls, compiler);
+        result = new TypeMask.nonNullSubtype(cls.declaration);
       } else {
-        result = new HType.nonNullSubclass(cls, compiler);
+        result = new TypeMask.nonNullSubclass(cls.declaration);
       }
       cachedTypeOfThis = result;
     }
     return result;
   }
 
-  Map<Element, HType> cachedTypesOfCapturedVariables =
-      new Map<Element, HType>();
+  Map<Element, TypeMask> cachedTypesOfCapturedVariables =
+      new Map<Element, TypeMask>();
 
-  HType getTypeOfCapturedVariable(Element element) {
+  TypeMask getTypeOfCapturedVariable(Element element) {
     assert(element.isField());
     return cachedTypesOfCapturedVariables.putIfAbsent(element, () {
-      return new HType.inferredTypeForElement(element, compiler);
+      return TypeMaskFactory.inferredTypeForElement(element, compiler);
     });
   }
 
@@ -1122,7 +1126,7 @@
     return bodyElement;
   }
 
-  HParameterValue addParameter(Element element, HType type) {
+  HParameterValue addParameter(Element element, TypeMask type) {
     assert(inliningStack.isEmpty);
     HParameterValue result = new HParameterValue(element, type);
     if (lastAddedParameter == null) {
@@ -1713,7 +1717,7 @@
         includeSuperAndInjectedMembers: true);
 
     InterfaceType type = classElement.computeType(compiler);
-    HType ssaType = new HType.nonNullExact(classElement, compiler);
+    TypeMask ssaType = new TypeMask.nonNullExact(classElement.declaration);
     List<DartType> instantiatedTypes;
     addInlinedInstantiation(type);
     if (!currentInlinedInstantiations.isEmpty) {
@@ -1886,13 +1890,13 @@
     if (type == null) return original;
     type = type.unalias(compiler);
     if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) {
-      HType subtype = new HType.subtype(type.element, compiler);
+      TypeMask subtype = new TypeMask.subtype(type.element);
       HInstruction representations = buildTypeArgumentRepresentations(type);
       add(representations);
       return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
           original, representations);
     } else if (type.kind == TypeKind.TYPE_VARIABLE) {
-      HType subtype = original.instructionType;
+      TypeMask subtype = original.instructionType;
       HInstruction typeVariable = addTypeVariableReference(type);
       return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
           original, typeVariable);
@@ -1900,7 +1904,7 @@
       if (backend.rti.isSimpleFunctionType(type)) {
         return original.convertType(compiler, type, kind);
       }
-      HType subtype = original.instructionType;
+      TypeMask subtype = original.instructionType;
       if (type.containsTypeVariables) {
         bool contextIsTypeArguments = false;
         HInstruction context;
@@ -2600,7 +2604,7 @@
       }
     });
 
-    HType type = new HType.nonNullExact(compiler.functionClass, compiler);
+    TypeMask type = new TypeMask.nonNullExact(compiler.functionClass);
     push(new HForeignNew(closureClassElement, type, capturedVariables));
 
     Element methodElement = nestedClosureData.closureElement;
@@ -2740,12 +2744,13 @@
         // The inferrer may have found a better type than the constant
         // handler in the case of lists, because the constant handler
         // does not look at elements in the list.
-        HType type = new HType.inferredTypeForElement(element, compiler);
+        TypeMask type =
+            TypeMaskFactory.inferredTypeForElement(element, compiler);
         if (!type.containsAll(compiler)) instruction.instructionType = type;
       } else if (element.isField() && isLazilyInitialized(element)) {
         HInstruction instruction = new HLazyStatic(
             element,
-            new HType.inferredTypeForElement(element, compiler));
+            TypeMaskFactory.inferredTypeForElement(element, compiler));
         push(instruction);
       } else {
         if (element.isGetter()) {
@@ -2755,7 +2760,7 @@
           // creating an [HStatic].
           HInstruction instruction = new HStatic(
               element.declaration,
-              new HType.inferredTypeForElement(element, compiler));
+              TypeMaskFactory.inferredTypeForElement(element, compiler));
           push(instruction);
         }
       }
@@ -2848,7 +2853,7 @@
   }
 
   HForeign createForeign(js.Expression code,
-                         HType type,
+                         TypeMask type,
                          List<HInstruction> inputs) {
     return new HForeign(code, type, inputs);
   }
@@ -3151,7 +3156,8 @@
     List<HInstruction> inputs = <HInstruction>[];
     addGenericSendArgumentsToList(link.tail.tail, inputs);
 
-    HType ssaType = new HType.fromNativeBehavior(nativeBehavior, compiler);
+    TypeMask ssaType =
+        TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
     push(new HForeign(nativeBehavior.codeAst, ssaType, inputs,
                       effects: nativeBehavior.sideEffects,
                       nativeBehavior: nativeBehavior));
@@ -3652,31 +3658,42 @@
   handleNewSend(NewExpression node) {
     Send send = node.send;
     bool isListConstructor = false;
+    bool isFixedList = false;
 
-    HType computeType(element) {
+    TypeMask computeType(element) {
       Element originalElement = elements[send];
       if (Elements.isFixedListConstructorCall(originalElement, send, compiler)
           || Elements.isFilledListConstructorCall(
                   originalElement, send, compiler)) {
         isListConstructor = true;
-        HType inferred =
-            new HType.inferredForNode(currentElement, send, compiler);
+        isFixedList = true;
+        TypeMask inferred =
+            TypeMaskFactory.inferredForNode(currentElement, send, compiler);
         return inferred.containsAll(compiler)
             ? backend.fixedArrayType
             : inferred;
       } else if (Elements.isGrowableListConstructorCall(
                     originalElement, send, compiler)) {
         isListConstructor = true;
-        HType inferred =
-            new HType.inferredForNode(currentElement, send, compiler);
+        TypeMask inferred =
+            TypeMaskFactory.inferredForNode(currentElement, send, compiler);
         return inferred.containsAll(compiler)
             ? backend.extendableArrayType
             : inferred;
+      } else if (Elements.isConstructorOfTypedArraySubclass(
+                    originalElement, compiler)) {
+        isFixedList = true;
+        TypeMask inferred =
+            TypeMaskFactory.inferredForNode(currentElement, send, compiler);
+        ClassElement cls = element.getEnclosingClass();
+        return inferred.containsAll(compiler)
+            ? new TypeMask.nonNullExact(cls.thisType.element)
+            : inferred;
       } else if (element.isGenerativeConstructor()) {
         ClassElement cls = element.getEnclosingClass();
-        return new HType.nonNullExact(cls.thisType.element, compiler);
+        return new TypeMask.nonNullExact(cls.thisType.element);
       } else {
-        return new HType.inferredReturnTypeForElement(
+        return TypeMaskFactory.inferredReturnTypeForElement(
             originalElement, compiler);
       }
     }
@@ -3740,12 +3757,17 @@
     if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
       compiler.enqueuer.codegen.registerFactoryWithTypeArguments(elements);
     }
-    HType elementType = computeType(constructor);
+    TypeMask elementType = computeType(constructor);
     addInlinedInstantiation(expectedType);
     pushInvokeStatic(node, constructor, inputs, elementType);
     removeInlinedInstantiation(expectedType);
     HInstruction newInstance = stack.last;
 
+    if (isFixedList) {
+      JavaScriptItemCompilationContext context = work.compilationContext;
+      context.allocatedFixedLists.add(newInstance);
+    }
+
     // The List constructor forwards to a Dart static method that does
     // not know about the type argument. Therefore we special case
     // this constructor to have the setRuntimeTypeInfo called where
@@ -4049,13 +4071,13 @@
       bool isLength = selector.isGetter()
           && selector.name == "length";
       if (isLength || selector.isIndex()) {
-        HType type = new HType.nonNullExact(
-            element.getEnclosingClass(), compiler);
-        return type.isIndexable(compiler);
+        TypeMask type = new TypeMask.nonNullExact(
+            element.getEnclosingClass().declaration);
+        return type.satisfies(backend.jsIndexableClass, compiler);
       } else if (selector.isIndexSet()) {
-        HType type = new HType.nonNullExact(
-            element.getEnclosingClass(), compiler);
-        return type.isMutableIndexable(compiler);
+        TypeMask type = new TypeMask.nonNullExact(
+            element.getEnclosingClass().declaration);
+        return type.satisfies(backend.jsMutableIndexableClass, compiler);
       } else {
         return false;
       }
@@ -4095,7 +4117,7 @@
       inputs.add(invokeInterceptor(receiver));
     }
     inputs.addAll(arguments);
-    HType type = new HType.inferredTypeForSelector(selector, compiler);
+    TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, compiler);
     if (selector.isGetter()) {
       bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
       pushWithPosition(
@@ -4116,13 +4138,13 @@
   void pushInvokeStatic(Node location,
                         Element element,
                         List<HInstruction> arguments,
-                        [HType type = null]) {
+                        [TypeMask type = null]) {
     if (tryInlineMethod(element, null, arguments, location)) {
       return;
     }
 
     if (type == null) {
-      type = new HType.inferredReturnTypeForElement(element, compiler);
+      type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
     }
     // TODO(5346): Try to avoid the need for calling [declaration] before
     // creating an [HInvokeStatic].
@@ -4152,11 +4174,11 @@
     }
     inputs.add(receiver);
     inputs.addAll(arguments);
-    HType type;
+    TypeMask type;
     if (!element.isGetter() && selector.isGetter()) {
-      type = new HType.inferredTypeForElement(element, compiler);
+      type = TypeMaskFactory.inferredTypeForElement(element, compiler);
     } else {
-      type = new HType.inferredReturnTypeForElement(element, compiler);
+      type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
     }
     HInstruction instruction = new HInvokeSuper(
         element,
@@ -4514,7 +4536,8 @@
       add(instruction);
     }
 
-    HType type = new HType.inferredForNode(currentElement, node, compiler);
+    TypeMask type =
+        TypeMaskFactory.inferredForNode(currentElement, node, compiler);
     if (!type.containsAll(compiler)) instruction.instructionType = type;
     stack.add(instruction);
   }
@@ -4711,7 +4734,7 @@
     }
     HLiteralList keyValuePairs = buildLiteralList(inputs);
     add(keyValuePairs);
-    HType mapType = new HType.nonNullSubtype(backend.mapLiteralClass, compiler);
+    TypeMask mapType = new TypeMask.nonNullSubtype(backend.mapLiteralClass);
     pushInvokeStatic(node, backend.getMapMaker(), [keyValuePairs], mapType);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 017889f..ffd4236 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -1536,10 +1536,8 @@
       // type because our optimizations might end up in a state where the
       // invoke dynamic knows more than the receiver.
       ClassElement enclosing = node.element.getEnclosingClass();
-      HType receiverType = new HType.fromMask(
-          new TypeMask.nonNullExact(enclosing.declaration),
-          compiler);
-      return receiverType.refine(selector, compiler);
+      TypeMask receiverType = new TypeMask.nonNullExact(enclosing.declaration);
+      return new TypedSelector(receiverType, selector);
     }
     // If [JSInvocationMirror._invokeOn] is enabled, and this call
     // might hit a `noSuchMethod`, we register an untyped selector.
@@ -1566,9 +1564,6 @@
   void registerSetter(HInvokeDynamic node) {
     Selector selector = getOptimizedSelectorFor(node, node.selector);
     world.registerDynamicSetter(selector);
-    HType valueType = node.isInterceptedCall
-        ? node.inputs[2].instructionType
-        : node.inputs[1].instructionType;
   }
 
   void registerGetter(HInvokeDynamic node) {
@@ -1667,21 +1662,27 @@
       // We're accessing a native JavaScript property called 'length'
       // on a JS String or a JS array. Therefore, the name of that
       // property should not be mangled.
-      if (backend.isTypedArray(
-            node.receiver.instructionType.computeMask(compiler))) {
+      if (backend.isTypedArray(node.receiver.instructionType)) {
         // TODO(12929): Remove this custom code for typed arrays once V8
         // optimizes their length access.
         // Do a call to `fetchLength` instead of accessing `length`
         // directly. Because `fetchLength` is a constant we use its
         // constant value instead.
-        Element element = compiler.findRequiredElement(
-            compiler.typedDataLibrary, 'fetchLength');
-        Constant constant =
-            compiler.constantHandler.getConstantForVariable(element);
-        assert(invariant(element, constant != null,
-            message: 'No constant computed for $element'));
-        var jsConstant = backend.emitter.constantReference(constant);
-        push(new js.Call(jsConstant, [pop()]), node);
+        if (node.usedBy.isEmpty) {
+          // The length access has not been removed because it is
+          // acting as a null check. For a faster null check, we use
+          // toString.
+          push(new js.PropertyAccess.field(pop(), 'toString'), node);
+        } else {
+          Element element = compiler.findRequiredElement(
+              compiler.typedDataLibrary, 'fetchLength');
+          Constant constant =
+              compiler.constantHandler.getConstantForVariable(element);
+          assert(invariant(element, constant != null,
+              message: 'No constant computed for $element'));
+          var jsConstant = backend.emitter.constantReference(constant);
+          push(new js.Call(jsConstant, [pop()]), node);
+        }
       } else {
         push(new js.PropertyAccess.field(pop(), 'length'), node);
       }
@@ -2428,40 +2429,40 @@
     }
   }
 
-  js.Expression generateTest(HInstruction input, HType checkedType) {
-    TypeMask receiver = input.instructionType.computeMask(compiler);
-    TypeMask mask = checkedType.computeMask(compiler);
+  js.Expression generateTest(HInstruction input, TypeMask checkedType) {
+    TypeMask receiver = input.instructionType;
     // Figure out if it is beneficial to turn this into a null check.
     // V8 generally prefers 'typeof' checks, but for integers and
     // indexable primitives we cannot compile this test into a single
     // typeof check so the null check is cheaper.
     bool turnIntoNumCheck = input.isIntegerOrNull(compiler)
-        && checkedType.isInteger(compiler);
+        && checkedType.containsOnlyInt(compiler);
     bool turnIntoNullCheck = !turnIntoNumCheck
-        && (mask.nullable() == receiver)
-        && (checkedType.isInteger(compiler)
-            || checkedType.isIndexablePrimitive(compiler));
+        && (checkedType.nullable() == receiver)
+        && (checkedType.containsOnlyInt(compiler)
+            || checkedType.satisfies(backend.jsIndexableClass, compiler));
     js.Expression test;
     if (turnIntoNullCheck) {
       use(input);
       test = new js.Binary("==", pop(), new js.LiteralNull());
-    } else if (checkedType.isInteger(compiler) && !turnIntoNumCheck) {
+    } else if (checkedType.containsOnlyInt(compiler) && !turnIntoNumCheck) {
       // input is !int
       checkInt(input, '!==');
       test = pop();
-    } else if (checkedType.isNumber(compiler) || turnIntoNumCheck) {
+    } else if (checkedType.containsOnlyNum(compiler) || turnIntoNumCheck) {
       // input is !num
       checkNum(input, '!==');
       test = pop();
-    } else if (checkedType.isBoolean(compiler)) {
+    } else if (checkedType.containsOnlyBool(compiler)) {
       // input is !bool
       checkBool(input, '!==');
       test = pop();
-    } else if (checkedType.isString(compiler)) {
+    } else if (checkedType.containsOnlyString(compiler)) {
       // input is !string
       checkString(input, '!==');
       test = pop();
-    } else if (checkedType.isExtendableArray(compiler)) {
+    } else if (checkedType.satisfies(backend.jsExtendableArrayClass,
+                                     compiler)) {
       // input is !Object || input is !Array || input.isFixed
       checkObject(input, '!==');
       js.Expression objectTest = pop();
@@ -2470,7 +2471,7 @@
       checkFixedArray(input);
       test = new js.Binary('||', objectTest, arrayTest);
       test = new js.Binary('||', test, pop());
-    } else if (checkedType.isMutableArray(compiler)) {
+    } else if (checkedType.satisfies(backend.jsMutableArrayClass, compiler)) {
       // input is !Object
       // || ((input is !Array || input.isImmutable)
       //     && input is !JsIndexingBehavior)
@@ -2485,7 +2486,7 @@
           ? new js.Binary('&&', notArrayOrImmutable, pop())
           : notArrayOrImmutable;
       test = new js.Binary('||', objectTest, notIndexing);
-    } else if (checkedType.isReadableArray(compiler)) {
+    } else if (checkedType.satisfies(backend.jsArrayClass, compiler)) {
       // input is !Object
       // || (input is !Array && input is !JsIndexingBehavior)
       checkObject(input, '!==');
@@ -2497,7 +2498,7 @@
           ? new js.Binary('&&', arrayTest, pop())
           : arrayTest;
       test = new js.Binary('||', objectTest, notIndexing);
-    } else if (checkedType.isIndexablePrimitive(compiler)) {
+    } else if (checkedType.satisfies(backend.jsIndexableClass, compiler)) {
       // input is !String
       // && (input is !Object
       //     || (input is !Array && input is !JsIndexingBehavior))
@@ -2524,8 +2525,8 @@
     if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
       // An int check if the input is not int or null, is not
       // sufficient for doing a argument or receiver check.
-      assert(!node.checkedType.isInteger(compiler) ||
-          node.checkedInput.isIntegerOrNull(compiler));
+      assert(!node.checkedType.containsOnlyInt(compiler) ||
+             node.checkedInput.isIntegerOrNull(compiler));
       js.Expression test = generateTest(node.checkedInput, node.checkedType);
       js.Block oldContainer = currentContainer;
       js.Statement body = new js.Block.empty();
@@ -2582,11 +2583,10 @@
   // complex expression is required.
   if ((left.isConstant() && left.isConstantSentinel()) ||
       (right.isConstant() && right.isConstantSentinel())) return '===';
-  HType leftType = left.instructionType;
-  HType rightType = right.instructionType;
-  if (leftType.canBeNull() && rightType.canBeNull()) {
+  if (left.canBeNull() && right.canBeNull()) {
     if (left.isConstantNull() || right.isConstantNull() ||
-        (leftType.isPrimitive(compiler) && leftType == rightType)) {
+        (left.isPrimitive(compiler) &&
+         left.instructionType == right.instructionType)) {
       return '==';
     }
     return null;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index 0f89282..a0bfc14 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -64,14 +64,14 @@
     return false;
   }
 
-  bool canUseSelfForInterceptor(HType receiverType,
+  bool canUseSelfForInterceptor(HInstruction instruction,
                                 Set<ClassElement> interceptedClasses) {
     JavaScriptBackend backend = compiler.backend;
-    if (receiverType.canBePrimitive(compiler)) {
+    if (instruction.canBePrimitive(compiler)) {
       // Primitives always need interceptors.
       return false;
     }
-    if (receiverType.canBeNull()
+    if (instruction.canBeNull()
         && interceptedClasses.contains(backend.jsNullClass)) {
       // Need the JSNull interceptor.
       return false;
@@ -80,14 +80,13 @@
     // [interceptedClasses] is sparse - it is just the classes that define some
     // intercepted method.  Their subclasses (that inherit the method) are
     // implicit, so we have to extend them.
-
-    TypeMask receiverMask = receiverType.computeMask(compiler);
+    TypeMask receiverType = instruction.instructionType;
     return interceptedClasses
         .where((cls) => cls != compiler.objectClass)
         .map((cls) => backend.classesMixedIntoNativeClasses.contains(cls)
             ? new TypeMask.subtype(cls)
             : new TypeMask.subclass(cls))
-        .every((mask) => receiverMask.intersection(mask, compiler).isEmpty);
+        .every((mask) => receiverType.intersection(mask, compiler).isEmpty);
   }
 
   HInstruction tryComputeConstantInterceptor(
@@ -100,24 +99,23 @@
       return graph.thisInstruction;
     }
 
-    HType type = input.instructionType;
     ClassElement constantInterceptor;
     JavaScriptBackend backend = compiler.backend;
-    if (type.canBeNull()) {
-      if (type.isNull()) {
+    if (input.canBeNull()) {
+      if (input.isNull()) {
         constantInterceptor = backend.jsNullClass;
       }
-    } else if (type.isInteger(compiler)) {
+    } else if (input.isInteger(compiler)) {
       constantInterceptor = backend.jsIntClass;
-    } else if (type.isDouble(compiler)) {
+    } else if (input.isDouble(compiler)) {
       constantInterceptor = backend.jsDoubleClass;
-    } else if (type.isBoolean(compiler)) {
+    } else if (input.isBoolean(compiler)) {
       constantInterceptor = backend.jsBoolClass;
-    } else if (type.isString(compiler)) {
+    } else if (input.isString(compiler)) {
       constantInterceptor = backend.jsStringClass;
-    } else if (type.isArray(compiler)) {
+    } else if (input.isArray(compiler)) {
       constantInterceptor = backend.jsArrayClass;
-    } else if (type.isNumber(compiler)
+    } else if (input.isNumber(compiler)
         && !interceptedClasses.contains(backend.jsIntClass)
         && !interceptedClasses.contains(backend.jsDoubleClass)) {
       // If the method being intercepted is not defined in [int] or [double] we
@@ -136,7 +134,7 @@
       // for a subclass or call methods defined on a subclass.  Provided the
       // code is completely insensitive to the specific instance subclasses, we
       // can use the non-leaf class directly.
-      ClassElement element = type.computeMask(compiler).singleClass(compiler);
+      ClassElement element = input.instructionType.singleClass(compiler);
       if (element != null && element.isNative()) {
         constantInterceptor = element;
       }
@@ -216,8 +214,7 @@
     }
 
     HInstruction receiver = node.receiver;
-    HType instructionType = receiver.instructionType;
-    if (canUseSelfForInterceptor(instructionType, interceptedClasses)) {
+    if (canUseSelfForInterceptor(receiver, interceptedClasses)) {
       node.block.rewrite(node, receiver);
       return false;
     }
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 d2e54d0..b0ed907 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/invoke_dynamic_specializers.dart
@@ -13,10 +13,10 @@
 class InvokeDynamicSpecializer {
   const InvokeDynamicSpecializer();
 
-  HType computeTypeFromInputTypes(HInvokeDynamic instruction,
-                                  Compiler compiler) {
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
     Selector selector = instruction.selector;
-    HType type = new HType.inferredTypeForSelector(selector, compiler);
+    TypeMask type = TypeMaskFactory.inferredTypeForSelector(selector, 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
@@ -108,15 +108,16 @@
 
   HInstruction tryConvertToBuiltin(HInvokeDynamic instruction,
                                    Compiler compiler) {
-    if (!instruction.inputs[1].isIndexable(compiler)) return null;
+    if (!instruction.inputs[1].isIndexablePrimitive(compiler)) return null;
     if (!instruction.inputs[2].isInteger(compiler)
         && compiler.enableTypeAssertions) {
       // We want the right checked mode error.
       return null;
     }
-    HType receiverType = instruction.getDartReceiver(compiler).instructionType;
-    Selector refined = receiverType.refine(instruction.selector, compiler);
-    HType type = new HType.inferredTypeForSelector(refined, compiler);
+    TypeMask receiverType =
+        instruction.getDartReceiver(compiler).instructionType;
+    Selector refined = new TypedSelector(receiverType, instruction.selector);
+    TypeMask type = TypeMaskFactory.inferredTypeForSelector(refined, compiler);
     return new HIndex(
         instruction.inputs[1], instruction.inputs[2],
         instruction.selector, type);
@@ -130,8 +131,8 @@
     return constantSystem.bitNot;
   }
 
-  HType computeTypeFromInputTypes(HInvokeDynamic instruction,
-                                  Compiler compiler) {
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
     // All bitwise operations on primitive types either produce an
     // integer or throw an error.
     JavaScriptBackend backend = compiler.backend;
@@ -159,10 +160,10 @@
     return constantSystem.negate;
   }
 
-  HType computeTypeFromInputTypes(HInvokeDynamic instruction,
-                                  Compiler compiler) {
-    HType operandType = instruction.inputs[1].instructionType;
-    if (operandType.isNumberOrNull(compiler)) return operandType;
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
+    TypeMask operandType = instruction.inputs[1].instructionType;
+    if (instruction.inputs[1].isNumberOrNull(compiler)) return operandType;
     return super.computeTypeFromInputTypes(instruction, compiler);
   }
 
@@ -179,8 +180,8 @@
 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
   const BinaryArithmeticSpecializer();
 
-  HType computeTypeFromInputTypes(HInvokeDynamic instruction,
-                                  Compiler compiler) {
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
     JavaScriptBackend backend = compiler.backend;
@@ -241,8 +242,8 @@
     return constantSystem.divide;
   }
 
-  HType computeTypeFromInputTypes(HInstruction instruction,
-                                  Compiler compiler) {
+  TypeMask computeTypeFromInputTypes(HInstruction instruction,
+                                     Compiler compiler) {
     HInstruction left = instruction.inputs[1];
     JavaScriptBackend backend = compiler.backend;
     if (left.isNumberOrNull(compiler)) {
@@ -321,8 +322,8 @@
 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
   const BinaryBitOpSpecializer();
 
-  HType computeTypeFromInputTypes(HInvokeDynamic instruction,
-                                  Compiler compiler) {
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
     // All bitwise operations on primitive types either produce an
     // integer or throw an error.
     HInstruction left = instruction.inputs[1];
@@ -434,10 +435,10 @@
 abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
   const RelationalSpecializer();
 
-  HType computeTypeFromInputTypes(HInvokeDynamic instruction,
-                                  Compiler compiler) {
+  TypeMask computeTypeFromInputTypes(HInvokeDynamic instruction,
+                                     Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
-    if (instruction.inputs[1].instructionType.isPrimitiveOrNull(compiler)) {
+    if (instruction.inputs[1].isPrimitiveOrNull(compiler)) {
       return backend.boolType;
     }
     return super.computeTypeFromInputTypes(instruction, compiler);
@@ -463,11 +464,12 @@
                                    Compiler compiler) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
-    HType instructionType = left.instructionType;
-    if (right.isConstantNull() || instructionType.isPrimitiveOrNull(compiler)) {
+    TypeMask instructionType = left.instructionType;
+    if (right.isConstantNull() || left.isPrimitiveOrNull(compiler)) {
       return newBuiltinVariant(instruction, compiler);
     }
-    Selector selector = instructionType.refine(instruction.selector, compiler);
+    Selector selector =
+        new TypedSelector(instructionType, instruction.selector);
     World world = compiler.world;
     JavaScriptBackend backend = compiler.backend;
     Iterable<Element> matches = world.allFunctions.filter(selector);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 3282eb0..cdc75a2 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -161,7 +161,8 @@
     return result;
   }
 
-  static HType mapConstantTypeToSsaType(Constant constant, Compiler compiler) {
+  static TypeMask mapConstantTypeToSsaType(Constant constant,
+                                           Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     if (constant.isNull()) return backend.nullType;
     if (constant.isBool()) return backend.boolType;
@@ -177,14 +178,13 @@
     if (backend.isInterceptorClass(objectConstant.type.element)) {
       return backend.nonNullType;
     }
-    TypeMask mask = new TypeMask.nonNullExact(objectConstant.type.element);
-    return new HBoundedType(mask);
+    return new TypeMask.nonNullExact(objectConstant.type.element);
   }
 
   HConstant addConstant(Constant constant, Compiler compiler) {
     HConstant result = constants[constant];
     if (result == null) {
-      HType type = mapConstantTypeToSsaType(constant, compiler);
+      TypeMask type = mapConstantTypeToSsaType(constant, compiler);
       result = new HConstant.internal(constant, type);
       entry.addAtExit(result);
       constants[constant] = result;
@@ -752,8 +752,6 @@
   }
 }
 
-const HType EMPTY_TYPE = const HBoundedType(const TypeMask.nonNullEmpty());
-
 abstract class HInstruction implements Spannable {
   Element sourceElement;
   SourceFileLocation sourcePosition;
@@ -840,57 +838,136 @@
   // Does this node potentially affect control flow.
   bool isControlFlow() => false;
 
-  // All isFunctions work on the propagated types.
-  bool isArray(Compiler compiler) =>
-      instructionType.isArray(compiler);
-  bool isReadableArray(Compiler compiler) =>
-      instructionType.isReadableArray(compiler);
-  bool isMutableArray(Compiler compiler) =>
-      instructionType.isMutableArray(compiler);
-  bool isExtendableArray(Compiler compiler) =>
-      instructionType.isExtendableArray(compiler);
-  bool isFixedArray(Compiler compiler) =>
-      instructionType.isFixedArray(compiler);
-  bool isString(Compiler compiler) =>
-      instructionType.isString(compiler);
-  bool isPrimitive(Compiler compiler) =>
-      instructionType.isPrimitive(compiler);
-  bool isPrimitiveOrNull(Compiler compiler) =>
-      instructionType.isPrimitiveOrNull(compiler);
-  bool isBoolean(Compiler compiler) =>
-      instructionType.isBoolean(compiler);
-  bool isInteger(Compiler compiler) =>
-      instructionType.isInteger(compiler);
-  bool isIntegerOrNull(Compiler compiler) =>
-      instructionType.isIntegerOrNull(compiler);
-  bool isDouble(Compiler compiler) =>
-      instructionType.isDouble(compiler);
-  bool isDoubleOrNull(Compiler compiler) =>
-      instructionType.isDoubleOrNull(compiler);
-  bool isNumber(Compiler compiler) =>
-      instructionType.isNumber(compiler);
-  bool isNumberOrNull(Compiler compiler) =>
-      instructionType.isNumberOrNull(compiler);
-  bool isNull() => instructionType.isNull();
-  bool canBeNull() => instructionType.canBeNull();
-  bool canBePrimitive(Compiler compiler) =>
-      instructionType.canBePrimitive(compiler);
-  bool canBePrimitiveArray(Compiler compiler) =>
-      instructionType.canBePrimitiveArray(compiler);
+  bool isExact() => instructionType.isExact || isNull();
 
-  bool isIndexable(Compiler compiler) =>
-      instructionType.isIndexable(compiler);
-  bool isMutableIndexable(Compiler compiler) =>
-      instructionType.isMutableIndexable(compiler);
+  bool canBeNull() => instructionType.isNullable;
 
-  // TODO(kasperl): Get rid of this one.
-  bool isIndexablePrimitive(Compiler compiler) =>
-      instructionType.isIndexablePrimitive(compiler);
+  bool isNull() => instructionType.isEmpty && instructionType.isNullable;
+  bool isConflicting() {
+    return instructionType.isEmpty && !instructionType.isNullable;
+  }
+
+  bool canBePrimitive(Compiler compiler) {
+    return canBePrimitiveNumber(compiler)
+        || canBePrimitiveArray(compiler)
+        || canBePrimitiveBoolean(compiler)
+        || canBePrimitiveString(compiler)
+        || isNull();
+  }
+
+  bool canBePrimitiveNumber(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.contains(backend.jsNumberClass, compiler)
+        || instructionType.contains(backend.jsIntClass, compiler)
+        || instructionType.contains(backend.jsDoubleClass, compiler);
+  }
+
+  bool canBePrimitiveBoolean(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.contains(backend.jsBoolClass, compiler);
+  }
+
+  bool canBePrimitiveArray(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.contains(backend.jsArrayClass, compiler)
+        || instructionType.contains(backend.jsFixedArrayClass, compiler)
+        || instructionType.contains(backend.jsExtendableArrayClass, compiler);
+  }
+
+  bool isIndexablePrimitive(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.containsOnlyString(compiler)
+        || instructionType.satisfies(backend.jsIndexableClass, compiler);
+  }
+
+  bool isFixedArray(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.containsOnly(backend.jsFixedArrayClass);
+  }
+
+  bool isExtendableArray(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.containsOnly(backend.jsExtendableArrayClass);
+  }
+
+  bool isMutableArray(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.satisfies(backend.jsMutableArrayClass, compiler);
+  }
+
+  bool isReadableArray(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.satisfies(backend.jsArrayClass, compiler);
+  }
+
+  bool isMutableIndexable(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.satisfies(backend.jsMutableIndexableClass, compiler);
+  }
+
+  bool isArray(Compiler compiler) => isReadableArray(compiler);
+
+  bool canBePrimitiveString(Compiler compiler) {
+    JavaScriptBackend backend = compiler.backend;
+    return instructionType.contains(backend.jsStringClass, compiler);
+  }
+
+  bool isInteger(Compiler compiler) {
+    return instructionType.containsOnlyInt(compiler)
+        && !instructionType.isNullable;
+  }
+
+  bool isIntegerOrNull(Compiler compiler) {
+    return instructionType.containsOnlyInt(compiler);
+  }
+
+  bool isNumber(Compiler compiler) {
+    return instructionType.containsOnlyNum(compiler)
+        && !instructionType.isNullable;
+  }
+
+  bool isNumberOrNull(Compiler compiler) {
+    return instructionType.containsOnlyNum(compiler);
+  }
+
+  bool isDouble(Compiler compiler) {
+    return instructionType.containsOnlyDouble(compiler)
+        && !instructionType.isNullable;
+  }
+
+  bool isDoubleOrNull(Compiler compiler) {
+    return instructionType.containsOnlyDouble(compiler);
+  }
+
+  bool isBoolean(Compiler compiler) {
+    return instructionType.containsOnlyBool(compiler)
+        && !instructionType.isNullable;
+  }
+
+  bool isBooleanOrNull(Compiler compiler) {
+    return instructionType.containsOnlyBool(compiler);
+  }
+
+  bool isString(Compiler compiler) {
+    return instructionType.containsOnlyString(compiler);
+  }
+
+  bool isPrimitive(Compiler compiler) {
+    return (isPrimitiveOrNull(compiler) && !instructionType.isNullable)
+        || isNull();
+  }
+
+  bool isPrimitiveOrNull(Compiler compiler) {
+    return isIndexablePrimitive(compiler)
+        || isNumberOrNull(compiler)
+        || isBooleanOrNull(compiler)
+        || isNull();
+  }
 
   /**
    * Type of the unstruction.
    */
-  HType instructionType;
+  TypeMask instructionType;
 
   Selector get selector => null;
   HInstruction getDartReceiver(Compiler compiler) => null;
@@ -1140,7 +1217,7 @@
     } else if (kind == HTypeConversion.CHECKED_MODE_CHECK && !type.treatAsRaw) {
       throw 'creating compound check to $type (this = ${this})';
     } else {
-      HType subtype = new HType.subtype(element, compiler);
+      TypeMask subtype = new TypeMask.subtype(element.declaration);
       return new HTypeConversion(type, kind, subtype, this);
     }
   }
@@ -1155,7 +1232,7 @@
 }
 
 class HBoolify extends HInstruction {
-  HBoolify(HInstruction value, HType type)
+  HBoolify(HInstruction value, TypeMask type)
       : super(<HInstruction>[value], type) {
     setUseGvn();
   }
@@ -1218,7 +1295,7 @@
 }
 
 abstract class HControlFlow extends HInstruction {
-  HControlFlow(inputs) : super(inputs, EMPTY_TYPE);
+  HControlFlow(inputs) : super(inputs, const TypeMask.nonNullEmpty());
   bool isControlFlow() => true;
   bool isJsStatement() => true;
 }
@@ -1255,7 +1332,7 @@
   HInvokeDynamic(Selector selector,
                  this.element,
                  List<HInstruction> inputs,
-                 HType type,
+                 TypeMask type,
                  [bool isIntercepted = false])
     : super(inputs, type),
       this.selector = selector,
@@ -1287,7 +1364,7 @@
 }
 
 class HInvokeClosure extends HInvokeDynamic {
-  HInvokeClosure(Selector selector, List<HInstruction> inputs, HType type)
+  HInvokeClosure(Selector selector, List<HInstruction> inputs, TypeMask type)
     : super(selector, null, inputs, type) {
     assert(selector.isClosureCall());
   }
@@ -1297,7 +1374,7 @@
 class HInvokeDynamicMethod extends HInvokeDynamic {
   HInvokeDynamicMethod(Selector selector,
                        List<HInstruction> inputs,
-                       HType type,
+                       TypeMask type,
                        [bool isIntercepted = false])
     : super(selector, null, inputs, type, isIntercepted);
 
@@ -1316,7 +1393,7 @@
   final bool isSideEffectFree;
   HInvokeDynamicField(
       Selector selector, Element element, List<HInstruction> inputs,
-      HType type, this.isSideEffectFree)
+      TypeMask type, this.isSideEffectFree)
       : super(selector, element, inputs, type);
   toString() => 'invoke dynamic field: $selector';
 }
@@ -1362,7 +1439,7 @@
   List<DartType> instantiatedTypes;
 
   /** The first input must be the target. */
-  HInvokeStatic(this.element, inputs, HType type) : super(inputs, type);
+  HInvokeStatic(this.element, inputs, TypeMask type) : super(inputs, type);
 
   toString() => 'invoke static: ${element.name}';
   accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
@@ -1406,7 +1483,7 @@
 abstract class HFieldAccess extends HInstruction {
   final Element element;
 
-  HFieldAccess(Element element, List<HInstruction> inputs, HType type)
+  HFieldAccess(Element element, List<HInstruction> inputs, TypeMask type)
       : this.element = element, super(inputs, type);
 
   HInstruction get receiver => inputs[0];
@@ -1417,7 +1494,7 @@
 
   HFieldGet(Element element,
             HInstruction receiver,
-            HType type,
+            TypeMask type,
             {bool isAssignable})
       : this.isAssignable = (isAssignable != null)
             ? isAssignable
@@ -1459,7 +1536,8 @@
   HFieldSet(Element element,
             HInstruction receiver,
             HInstruction value)
-      : super(element, <HInstruction>[receiver, value], EMPTY_TYPE) {
+      : super(element, <HInstruction>[receiver, value],
+              const TypeMask.nonNullEmpty()) {
     sideEffects.clearAllSideEffects();
     sideEffects.setChangesInstanceProperty();
   }
@@ -1479,7 +1557,7 @@
 class HLocalGet extends HFieldAccess {
   // No need to use GVN for a [HLocalGet], it is just a local
   // access.
-  HLocalGet(Element element, HLocalValue local, HType type)
+  HLocalGet(Element element, HLocalValue local, TypeMask type)
       : super(element, <HInstruction>[local], type);
 
   accept(HVisitor visitor) => visitor.visitLocalGet(this);
@@ -1489,7 +1567,8 @@
 
 class HLocalSet extends HFieldAccess {
   HLocalSet(Element element, HLocalValue local, HInstruction value)
-      : super(element, <HInstruction>[local, value], EMPTY_TYPE);
+      : super(element, <HInstruction>[local, value],
+              const TypeMask.nonNullEmpty());
 
   accept(HVisitor visitor) => visitor.visitLocalSet(this);
 
@@ -1504,7 +1583,7 @@
   final native.NativeBehavior nativeBehavior;
 
   HForeign(this.codeAst,
-           HType type,
+           TypeMask type,
            List<HInstruction> inputs,
            {this.isStatement: false,
             SideEffects effects,
@@ -1519,7 +1598,7 @@
   HForeign.statement(codeAst, List<HInstruction> inputs,
                      SideEffects effects,
                      native.NativeBehavior nativeBehavior,
-                     HType type)
+                     TypeMask type)
       : this(codeAst, type, inputs, isStatement: true,
              effects: effects, nativeBehavior: nativeBehavior);
 
@@ -1540,7 +1619,7 @@
   /// the type arguments.  See also [SsaBuilder.currentInlinedInstantiations].
   List<DartType> instantiatedTypes;
 
-  HForeignNew(this.element, HType type, List<HInstruction> inputs,
+  HForeignNew(this.element, TypeMask type, List<HInstruction> inputs,
               [this.instantiatedTypes])
       : super(null, type, inputs);
 
@@ -1835,7 +1914,7 @@
 
 class HConstant extends HInstruction {
   final Constant constant;
-  HConstant.internal(this.constant, HType constantType)
+  HConstant.internal(this.constant, TypeMask constantType)
       : super(<HInstruction>[], constantType);
 
   toString() => 'literal: $constant';
@@ -1860,7 +1939,7 @@
 }
 
 class HNot extends HInstruction {
-  HNot(HInstruction value, HType type) : super(<HInstruction>[value], type) {
+  HNot(HInstruction value, TypeMask type) : super(<HInstruction>[value], type) {
     setUseGvn();
   }
 
@@ -1876,7 +1955,7 @@
   * value from the start, whereas [HLocalValue]s need to be initialized first.
   */
 class HLocalValue extends HInstruction {
-  HLocalValue(Element element, HType type) : super(<HInstruction>[], type) {
+  HLocalValue(Element element, TypeMask type) : super(<HInstruction>[], type) {
     sourceElement = element;
   }
 
@@ -1892,7 +1971,7 @@
 }
 
 class HThis extends HParameterValue {
-  HThis(Element element, HType type) : super(element, type);
+  HThis(Element element, TypeMask type) : super(element, type);
   toString() => 'this';
   accept(HVisitor visitor) => visitor.visitThis(this);
   bool isCodeMotionInvariant() => true;
@@ -1912,15 +1991,15 @@
   // The order of the [inputs] must correspond to the order of the
   // predecessor-edges. That is if an input comes from the first predecessor
   // of the surrounding block, then the input must be the first in the [HPhi].
-  HPhi(Element element, List<HInstruction> inputs, HType type)
+  HPhi(Element element, List<HInstruction> inputs, TypeMask type)
       : super(inputs, type) {
     sourceElement = element;
   }
-  HPhi.noInputs(Element element, HType type)
+  HPhi.noInputs(Element element, TypeMask type)
       : this(element, <HInstruction>[], type);
-  HPhi.singleInput(Element element, HInstruction input, HType type)
+  HPhi.singleInput(Element element, HInstruction input, TypeMask type)
       : this(element, <HInstruction>[input], type);
-  HPhi.manyInputs(Element element, List<HInstruction> inputs, HType type)
+  HPhi.manyInputs(Element element, List<HInstruction> inputs, TypeMask type)
       : this(element, inputs, type);
 
   void addInput(HInstruction input) {
@@ -2011,7 +2090,8 @@
 }
 
 class HThrowExpression extends HInstruction {
-  HThrowExpression(value) : super(<HInstruction>[value], EMPTY_TYPE);
+  HThrowExpression(value)
+      : super(<HInstruction>[value], const TypeMask.nonNullEmpty());
   toString() => 'throw expression';
   accept(HVisitor visitor) => visitor.visitThrowExpression(this);
   bool canThrow() => true;
@@ -2049,7 +2129,7 @@
   // This field should originally be null to allow GVN'ing all
   // [HInterceptor] on the same input.
   Set<ClassElement> interceptedClasses;
-  HInterceptor(HInstruction receiver, HType type)
+  HInterceptor(HInstruction receiver, TypeMask type)
       : super(<HInstruction>[receiver], type) {
     sideEffects.clearAllSideEffects();
     setUseGvn();
@@ -2081,11 +2161,11 @@
   Set<ClassElement> interceptedClasses;
   HOneShotInterceptor(Selector selector,
                       List<HInstruction> inputs,
-                      HType type,
+                      TypeMask type,
                       this.interceptedClasses)
       : super(selector, null, inputs, type, true) {
     assert(inputs[0] is HConstant);
-    assert(inputs[0].instructionType.isNull());
+    assert(inputs[0].isNull());
   }
   bool isCallOnInterceptor(Compiler compiler) => true;
 
@@ -2115,7 +2195,7 @@
 class HStaticStore extends HInstruction {
   Element element;
   HStaticStore(this.element, HInstruction value)
-      : super(<HInstruction>[value], EMPTY_TYPE) {
+      : super(<HInstruction>[value], const TypeMask.nonNullEmpty()) {
     sideEffects.clearAllSideEffects();
     sideEffects.setChangesStaticProperty();
   }
@@ -2129,7 +2209,7 @@
 }
 
 class HLiteralList extends HInstruction {
-  HLiteralList(List<HInstruction> inputs, HType type) : super(inputs, type);
+  HLiteralList(List<HInstruction> inputs, TypeMask type) : super(inputs, type);
   toString() => 'literal list';
   accept(HVisitor visitor) => visitor.visitLiteralList(this);
 }
@@ -2171,7 +2251,8 @@
                HInstruction index,
                HInstruction value,
                this.selector)
-      : super(<HInstruction>[receiver, index, value], EMPTY_TYPE) {
+      : super(<HInstruction>[receiver, index, value],
+              const TypeMask.nonNullEmpty()) {
     sideEffects.clearAllSideEffects();
     sideEffects.setChangesIndex();
   }
@@ -2199,26 +2280,26 @@
 
   HIs.direct(DartType typeExpression,
              HInstruction expression,
-             HType type)
+             TypeMask type)
       : this.internal(typeExpression, [expression], RAW_CHECK, type);
 
   HIs.raw(DartType typeExpression,
           HInstruction expression,
           HInterceptor interceptor,
-          HType type)
+          TypeMask type)
       : this.internal(
             typeExpression, [expression, interceptor], RAW_CHECK, type);
 
   HIs.compound(DartType typeExpression,
                HInstruction expression,
                HInstruction call,
-               HType type)
+               TypeMask type)
       : this.internal(typeExpression, [expression, call], COMPOUND_CHECK, type);
 
   HIs.variable(DartType typeExpression,
                HInstruction expression,
                HInstruction call,
-               HType type)
+               TypeMask type)
       : this.internal(typeExpression, [expression, call], VARIABLE_CHECK, type);
 
   HIs.internal(this.typeExpression, List<HInstruction> inputs, this.kind, type)
@@ -2262,7 +2343,7 @@
   final int kind;
   final Selector receiverTypeCheckSelector;
   final bool contextIsTypeArguments;
-  HType checkedType;  // Not final because we refine it.
+  TypeMask checkedType;  // Not final because we refine it.
 
   static const int CHECKED_MODE_CHECK = 0;
   static const int ARGUMENT_TYPE_CHECK = 1;
@@ -2271,7 +2352,7 @@
   static const int RECEIVER_TYPE_CHECK = 4;
 
   HTypeConversion(this.typeExpression, this.kind,
-                  HType type, HInstruction input,
+                  TypeMask type, HInstruction input,
                   [this.receiverTypeCheckSelector])
       : contextIsTypeArguments = false,
         checkedType = type,
@@ -2283,7 +2364,7 @@
   }
 
   HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind,
-                                         HType type, HInstruction input,
+                                         TypeMask type, HInstruction input,
                                          HInstruction typeRepresentation)
       : contextIsTypeArguments = false,
         checkedType = type,
@@ -2294,7 +2375,7 @@
   }
 
   HTypeConversion.withContext(this.typeExpression, this.kind,
-                              HType type, HInstruction input,
+                              TypeMask type, HInstruction input,
                               HInstruction context,
                               {bool this.contextIsTypeArguments})
       : super(<HInstruction>[input, context], type),
@@ -2346,8 +2427,8 @@
 
 /// The [HTypeKnown] instruction marks a value with a refined type.
 class HTypeKnown extends HCheck {
-  HType knownType;
-  HTypeKnown(HType knownType, HInstruction input)
+  TypeMask knownType;
+  HTypeKnown(TypeMask knownType, HInstruction input)
       : this.knownType = knownType,
         super(<HInstruction>[input], knownType);
   toString() => 'TypeKnown $knownType';
@@ -2377,7 +2458,7 @@
 
 class HStringConcat extends HInstruction {
   final Node node;
-  HStringConcat(HInstruction left, HInstruction right, this.node, HType type)
+  HStringConcat(HInstruction left, HInstruction right, this.node, TypeMask type)
       : super(<HInstruction>[left, right], type) {
     // TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the
     // concats bunched with stringified inputs for much better looking code with
@@ -2398,7 +2479,7 @@
  */
 class HStringify extends HInstruction {
   final Node node;
-  HStringify(HInstruction input, this.node, HType type)
+  HStringify(HInstruction input, this.node, TypeMask type)
       : super(<HInstruction>[input], type) {
     sideEffects.setAllSideEffects();
     sideEffects.setDependsOnSomething();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index d3e21fd..6b83cda 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -109,7 +109,7 @@
 
         // If we can replace [instruction] with [replacement], then
         // [replacement]'s type can be narrowed.
-        HType newType = replacement.instructionType.intersection(
+        TypeMask newType = replacement.instructionType.intersection(
             instruction.instructionType, compiler);
         replacement.instructionType = newType;
 
@@ -145,13 +145,10 @@
     List<HInstruction> inputs = node.inputs;
     assert(inputs.length == 1);
     HInstruction input = inputs[0];
-    HType type = input.instructionType;
-    if (type.isBoolean(compiler)) return input;
+    if (input.isBoolean(compiler)) return input;
     // All values that cannot be 'true' are boolified to false.
-    TypeMask mask = type.computeMask(compiler);
-    // TODO(kasperl): Get rid of the null check here once all HTypes
-    // have a proper mask.
-    if (mask != null && !mask.contains(backend.jsBoolClass, compiler)) {
+    TypeMask mask = input.instructionType;
+    if (!mask.contains(backend.jsBoolClass, compiler)) {
       return graph.addConstantBool(false, compiler);
     }
     return node;
@@ -188,7 +185,7 @@
 
   HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) {
     HInstruction actualReceiver = node.inputs[1];
-    if (actualReceiver.isIndexable(compiler)) {
+    if (actualReceiver.isIndexablePrimitive(compiler)) {
       if (actualReceiver.isConstantString()) {
         HConstant constantInput = actualReceiver;
         StringConstant constant = constantInput.constant;
@@ -199,10 +196,19 @@
         return graph.addConstantInt(constant.length, compiler);
       }
       Element element = backend.jsIndexableLength;
-      bool isAssignable = !actualReceiver.isFixedArray(compiler) &&
-          !actualReceiver.isString(compiler);
+      var mask = actualReceiver.instructionType;
+      bool isFixedLength = false;
+      if (mask.isContainer && mask.length != null) {
+        // A container on which we have inferred the length.
+        isFixedLength = true;
+      } else if (mask.containsOnly(backend.jsFixedArrayClass)
+                 || mask.containsOnlyString(compiler)
+                 || backend.isTypedArray(mask)) {
+        isFixedLength = true;
+      }
       HFieldGet result = new HFieldGet(
-          element, actualReceiver, backend.intType, isAssignable: isAssignable);
+          element, actualReceiver, backend.intType,
+          isAssignable: !isFixedLength);
       return result;
     } else if (actualReceiver.isConstantMap()) {
       HConstant constantInput = actualReceiver;
@@ -292,8 +298,8 @@
       if (folded != node) return folded;
     }
 
-    HType receiverType = node.getDartReceiver(compiler).instructionType;
-    Selector selector = receiverType.refine(node.selector, compiler);
+    TypeMask receiverType = node.getDartReceiver(compiler).instructionType;
+    Selector selector = new TypedSelector(receiverType, node.selector);
     Element element = compiler.world.locateSingleElement(selector);
     // TODO(ngeoffray): Also fold if it's a getter or variable.
     if (element != null
@@ -368,12 +374,12 @@
 
     if (!canInline) return null;
 
-
     // Strengthen instruction type from annotations to help optimize
     // dependent instructions.
     native.NativeBehavior nativeBehavior =
         native.NativeBehavior.ofMethod(method, compiler);
-    HType returnType = new HType.fromNativeBehavior(nativeBehavior, compiler);
+    TypeMask returnType =
+        TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
     HInvokeDynamicMethod result =
         new HInvokeDynamicMethod(node.selector, inputs, returnType);
     result.element = method;
@@ -437,14 +443,16 @@
   HInstruction handleIdentityCheck(HRelational node) {
     HInstruction left = node.left;
     HInstruction right = node.right;
-    HType leftType = left.instructionType;
-    HType rightType = right.instructionType;
+    TypeMask leftType = left.instructionType;
+    TypeMask rightType = right.instructionType;
 
     // Intersection of int and double return conflicting, so
     // we don't optimize on numbers to preserve the runtime semantics.
-    if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler)) &&
-        leftType.intersection(rightType, compiler).isConflicting()) {
-      return graph.addConstantBool(false, compiler);
+    if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) {
+      TypeMask intersection = leftType.intersection(rightType, compiler);
+      if (intersection.isEmpty && !intersection.isNullable) {
+        return graph.addConstantBool(false, compiler);
+      }
     }
 
     if (left.isNull() && right.isNull()) {
@@ -527,8 +535,8 @@
       return graph.addConstantBool(true, compiler);
     }
 
-    HType expressionType = node.expression.instructionType;
-    if (expressionType.isInteger(compiler)) {
+    HInstruction expression = node.expression;
+    if (expression.isInteger(compiler)) {
       if (identical(element, compiler.intClass)
           || identical(element, compiler.numClass)
           || Elements.isNumberOrStringSupertype(element, compiler)) {
@@ -540,7 +548,7 @@
       } else {
         return graph.addConstantBool(false, compiler);
       }
-    } else if (expressionType.isDouble(compiler)) {
+    } else if (expression.isDouble(compiler)) {
       if (identical(element, compiler.doubleClass)
           || identical(element, compiler.numClass)
           || Elements.isNumberOrStringSupertype(element, compiler)) {
@@ -553,14 +561,14 @@
       } else {
         return graph.addConstantBool(false, compiler);
       }
-    } else if (expressionType.isNumber(compiler)) {
+    } else if (expression.isNumber(compiler)) {
       if (identical(element, compiler.numClass)) {
         return graph.addConstantBool(true, compiler);
       } else {
         // We cannot just return false, because the expression may be of
         // type int or double.
       }
-    } else if (expressionType.canBePrimitiveNumber(compiler)
+    } else if (expression.canBePrimitiveNumber(compiler)
                && identical(element, compiler.intClass)) {
       // We let the JS semantics decide for that check.
       return node;
@@ -569,7 +577,7 @@
     // a class [:A<T>:], is currently always considered to have the
     // raw type.
     } else if (!RuntimeTypes.hasTypeArguments(type)) {
-      TypeMask expressionMask = expressionType.computeMask(compiler);
+      TypeMask expressionMask = expression.instructionType;
       TypeMask typeMask = (element == compiler.nullClass)
           ? new TypeMask.subtype(element)
           : new TypeMask.nonNullSubtype(element);
@@ -601,41 +609,36 @@
     return removeIfCheckAlwaysSucceeds(node, node.knownType);
   }
 
-  HInstruction removeIfCheckAlwaysSucceeds(HCheck node, HType checkedType) {
+  HInstruction removeIfCheckAlwaysSucceeds(HCheck node, TypeMask checkedType) {
     if (checkedType.containsAll(compiler)) return node;
     HInstruction input = node.checkedInput;
-    HType inputType = input.instructionType;
-    HType filteredType = inputType.intersection(checkedType, compiler);
-    return (inputType == filteredType) ? input : node;
+    TypeMask inputType = input.instructionType;
+    return inputType.isInMask(checkedType, compiler) ? input : node;
   }
 
   Element findConcreteFieldForDynamicAccess(HInstruction receiver,
                                             Selector selector) {
-    HType receiverType = receiver.instructionType;
+    TypeMask receiverType = receiver.instructionType;
     return compiler.world.locateSingleField(
-        receiverType.refine(selector, compiler));
+        new TypedSelector(receiverType, selector));
   }
 
   HInstruction visitFieldGet(HFieldGet node) {
     var receiver = node.receiver;
     if (node.element == backend.jsIndexableLength) {
-      if (receiver is HInvokeStatic) {
-        // Try to recognize the length getter with input
-        // [:new List(int):].
-        Element element = receiver.element;
+      JavaScriptItemCompilationContext context = work.compilationContext;
+      if (context.allocatedFixedLists.contains(receiver)) {
         // TODO(ngeoffray): checking if the second input is an integer
         // should not be necessary but it currently makes it easier for
         // other optimizations to reason about a fixed length constructor
         // that we know takes an int.
-        if (element == compiler.unnamedListConstructor
-            && receiver.inputs.length == 1
-            && receiver.inputs[0].isInteger(compiler)) {
+        if (receiver.inputs[0].isInteger(compiler)) {
           return receiver.inputs[0];
         }
       } else if (receiver.isConstantList() || receiver.isConstantString()) {
         return graph.addConstantInt(receiver.constant.length, compiler);
       } else {
-        var type = receiver.instructionType.computeMask(compiler);
+        var type = receiver.instructionType;
         if (type.isContainer && type.length != null) {
           HInstruction constant = graph.addConstantInt(type.length, compiler);
           if (type.isNullable) {
@@ -694,13 +697,13 @@
       isAssignable = true;
     }
 
-    HType type;
+    TypeMask type;
     if (field.getEnclosingClass().isNative()) {
-      type = new HType.fromNativeBehavior(
+      type = TypeMaskFactory.fromNativeBehavior(
           native.NativeBehavior.ofFieldLoad(field, compiler),
           compiler);
     } else {
-      type = new HType.inferredTypeForElement(field, compiler);
+      type = TypeMaskFactory.inferredTypeForElement(field, compiler);
     }
 
     return new HFieldGet(
@@ -1467,7 +1470,7 @@
   // to use [newInput] instead.
   void changeUsesDominatedBy(HBasicBlock dominator,
                              HInstruction input,
-                             HType convertedType) {
+                             TypeMask convertedType) {
     Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first);
     if (dominatedUsers.isEmpty) return;
 
@@ -1501,7 +1504,7 @@
 
     if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
 
-    HType convertedType = new HType.nonNullSubtype(element, compiler);
+    TypeMask convertedType = new TypeMask.nonNullSubtype(element);
     HInstruction input = instruction.expression;
     for (HIf ifUser in ifUsers) {
       changeUsesDominatedBy(ifUser.thenBlock, input, convertedType);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
index f62a343..3a86a9d 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
@@ -174,36 +174,35 @@
 
   HInstructionStringifier(this.context, this.currentBlock, this.compiler);
 
-  visit(HInstruction node) => node.accept(this);
+  visit(HInstruction node) => '${node.accept(this)} ${node.instructionType}';
 
   String temporaryId(HInstruction instruction) {
     String prefix;
-    HType type = instruction.instructionType;
-    if (type.isNull()) {
+    if (instruction.isNull()) {
       prefix = 'u';
-    } else if (type.isConflicting()) {
+    } else if (instruction.isConflicting()) {
       prefix = 'c';
-    } else if (type.isExtendableArray(compiler)) {
+    } else if (instruction.isExtendableArray(compiler)) {
       prefix = 'e';
-    } else if (type.isFixedArray(compiler)) {
+    } else if (instruction.isFixedArray(compiler)) {
       prefix = 'f';
-    } else if (type.isMutableArray(compiler)) {
+    } else if (instruction.isMutableArray(compiler)) {
       prefix = 'm';
-    } else if (type.isReadableArray(compiler)) {
+    } else if (instruction.isReadableArray(compiler)) {
       prefix = 'a';
-    } else if (type.isString(compiler)) {
+    } else if (instruction.isString(compiler)) {
       prefix = 's';
-    } else if (type.isIndexable(compiler)) {
+    } else if (instruction.isIndexablePrimitive(compiler)) {
       prefix = 'r';
-    } else if (type.isBoolean(compiler)) {
+    } else if (instruction.isBoolean(compiler)) {
       prefix = 'b';
-    } else if (type.isInteger(compiler)) {
+    } else if (instruction.isInteger(compiler)) {
       prefix = 'i';
-    } else if (type.isDouble(compiler)) {
+    } else if (instruction.isDouble(compiler)) {
       prefix = 'd';
-    } else if (type.isNumber(compiler)) {
+    } else if (instruction.isNumber(compiler)) {
       prefix = 'n';
-    } else if (type.containsAll(compiler)) {
+    } else if (instruction.instructionType.containsAll(compiler)) {
       prefix = 'v';
     } else {
       prefix = 'U';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index a8e4238..4df5830 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -4,136 +4,56 @@
 
 part of ssa;
 
-abstract class HType {
-  const HType();
-
-  /**
-   * Returns an [HType] with the given type mask. The factory method
-   * takes care to track whether or not the resulting type may be a
-   * primitive type.
-   */
-  factory HType.fromMask(TypeMask mask, Compiler compiler) {
-    bool isNullable = mask.isNullable;
-    JavaScriptBackend backend = compiler.backend;
-    if (mask.isEmpty) {
-      return isNullable ? backend.nullType : backend.emptyType;
-    }
-
-    if (mask.containsOnlyInt(compiler)) {
-      return mask.isNullable
-          ? new HBoundedType(new TypeMask.exact(backend.jsIntClass))
-          : backend.intType;
-    } else if (mask.containsOnlyDouble(compiler)) {
-      return mask.isNullable
-          ? new HBoundedType(new TypeMask.exact(backend.jsDoubleClass))
-          : backend.doubleType;
-    } else if (mask.containsOnlyNum(compiler)
-               || mask.satisfies(backend.jsNumberClass, compiler)) {
-      return mask.isNullable
-          ? new HBoundedType(new TypeMask.subclass(backend.jsNumberClass))
-          : backend.numType;
-    } else if (mask.containsOnlyString(compiler)) {
-      // TODO(ngeoffray): Avoid creating [TypeMask]s with the string
-      // class as base.
-      return isNullable
-          ? new HBoundedType(new TypeMask.exact(backend.jsStringClass))
-          : backend.stringType;
-    } else if (mask.containsOnlyBool(compiler)) {
-      return isNullable
-          ? new HBoundedType(new TypeMask.exact(backend.jsBoolClass))
-          : backend.boolType;
-    } else if (mask.containsOnlyNull(compiler)) {
-      return backend.nullType;
-    }
-
-    // TODO(kasperl): A lot of the code in the system currently
-    // expects the top type to be 'unknown'. I'll rework this.
-    if (mask.containsAll(compiler)) {
-      return isNullable ? backend.dynamicType : backend.nonNullType;
-    }
-
-    return new HBoundedType(mask);
-  }
-
-  factory HType.exact(ClassElement type, Compiler compiler) {
-    TypeMask mask = new TypeMask.exact(type.declaration);
-    return new HType.fromMask(mask, compiler);
-  }
-
-  factory HType.subclass(ClassElement type, Compiler compiler) {
-    TypeMask mask = new TypeMask.subclass(type.declaration);
-    return new HType.fromMask(mask, compiler);
-  }
-
-  factory HType.subtype(ClassElement type, Compiler compiler) {
-    TypeMask mask = new TypeMask.subtype(type.declaration);
-    return new HType.fromMask(mask, compiler);
-  }
-
-  factory HType.nonNullExact(ClassElement type, Compiler compiler) {
-    TypeMask mask = new TypeMask.nonNullExact(type.declaration);
-    return new HType.fromMask(mask, compiler);
-  }
-
-  factory HType.nonNullSubclass(ClassElement type, Compiler compiler) {
-    TypeMask mask = new TypeMask.nonNullSubclass(type.declaration);
-    return new HType.fromMask(mask, compiler);
-  }
-
-  factory HType.nonNullSubtype(ClassElement type, Compiler compiler) {
-    TypeMask mask = new TypeMask.nonNullSubtype(type.declaration);
-    return new HType.fromMask(mask, compiler);
-  }
-
-  factory HType.fromInferredType(TypeMask mask, Compiler compiler) {
+class TypeMaskFactory {
+  static TypeMask fromInferredType(TypeMask mask, Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     if (mask == null) return backend.dynamicType;
-    return new HType.fromMask(mask, compiler);
+    return mask;
   }
 
-  factory HType.inferredReturnTypeForElement(
+  static TypeMask inferredReturnTypeForElement(
       Element element, Compiler compiler) {
-    return new HType.fromInferredType(
+    return fromInferredType(
         compiler.typesTask.getGuaranteedReturnTypeOfElement(element),
         compiler);
   }
 
-  factory HType.inferredTypeForElement(Element element, Compiler compiler) {
-    return new HType.fromInferredType(
+  static TypeMask inferredTypeForElement(Element element, Compiler compiler) {
+    return fromInferredType(
         compiler.typesTask.getGuaranteedTypeOfElement(element),
         compiler);
   }
 
-  factory HType.inferredTypeForSelector(Selector selector, Compiler compiler) {
-    return new HType.fromInferredType(
+  static TypeMask inferredTypeForSelector(Selector selector, Compiler compiler) {
+    return fromInferredType(
         compiler.typesTask.getGuaranteedTypeOfSelector(selector),
         compiler);
   }
 
-  factory HType.inferredForNode(Element owner, Node node, Compiler compiler) {
-    return new HType.fromInferredType(
+  static TypeMask inferredForNode(Element owner, Node node, Compiler compiler) {
+    return fromInferredType(
         compiler.typesTask.getGuaranteedTypeOfNode(owner, node),
         compiler);
   }
 
-  factory HType.fromNativeBehavior(native.NativeBehavior nativeBehavior,
-                                   Compiler compiler) {
+  static TypeMask fromNativeBehavior(native.NativeBehavior nativeBehavior,
+                                     Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     if (nativeBehavior.typesReturned.isEmpty) return backend.dynamicType;
 
-    HType result = nativeBehavior.typesReturned
+    TypeMask result = nativeBehavior.typesReturned
         .map((type) => fromNativeType(type, compiler))
         .reduce((t1, t2) => t1.union(t2, compiler));
-    assert(!result.isConflicting());
+    assert(!(result.isEmpty && !result.isNullable));
     return result;
   }
 
   // [type] is either an instance of [DartType] or special objects
   // like [native.SpecialType.JsObject].
-  static HType fromNativeType(type, Compiler compiler) {
+  static TypeMask fromNativeType(type, Compiler compiler) {
     JavaScriptBackend backend = compiler.backend;
     if (type == native.SpecialType.JsObject) {
-      return new HType.nonNullExact(compiler.objectClass, compiler);
+      return new TypeMask.nonNullExact(compiler.objectClass);
     } else if (type.isVoid) {
       return backend.nullType;
     } else if (type.element == compiler.nullClass) {
@@ -141,254 +61,11 @@
     } else if (type.treatAsDynamic) {
       return backend.dynamicType;
     } else if (compiler.world.hasAnySubtype(type.element)) {
-      return new HType.nonNullSubtype(type.element, compiler);
+      return new TypeMask.nonNullSubtype(type.element);
     } else if (compiler.world.hasAnySubclass(type.element)) {
-      return new HType.nonNullSubclass(type.element, compiler);
+      return new TypeMask.nonNullSubclass(type.element);
     } else {
-      return new HType.nonNullExact(type.element, compiler);
+      return new TypeMask.nonNullExact(type.element);
     }
   }
-
-  bool isConflicting() => false;
-  bool isExact() => false;
-  bool isNull() => false;
-  bool isBoolean(Compiler compiler) => false;
-  bool isNumber(Compiler compiler) => false;
-  bool isInteger(Compiler compiler) => false;
-  bool isDouble(Compiler compiler) => false;
-
-  bool isString(Compiler compiler) => false;
-  bool isFixedArray(Compiler compiler) => false;
-  bool isReadableArray(Compiler compiler) => false;
-  bool isMutableArray(Compiler compiler) => false;
-  bool isExtendableArray(Compiler compiler) => false;
-  bool isPrimitive(Compiler compiler) => false;
-  bool isPrimitiveOrNull(Compiler compiler) => false;
-
-  bool isBooleanOrNull(Compiler compiler) => false;
-  bool isNumberOrNull(Compiler compiler) => false;
-  bool isIntegerOrNull(Compiler compiler) => false;
-  bool isDoubleOrNull(Compiler compiler) => false;
-
-  // TODO(kasperl): Get rid of this one.
-  bool isIndexablePrimitive(Compiler compiler) => false;
-
-  bool isIndexable(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return implementsInterface(backend.jsIndexableClass, compiler);
-  }
-
-  bool isMutableIndexable(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return implementsInterface(backend.jsMutableIndexableClass, compiler);
-  }
-
-  bool implementsInterface(ClassElement interfaceElement, Compiler compiler) {
-    TypeMask mask = new TypeMask.subtype(interfaceElement);
-    return mask == mask.union(computeMask(compiler), compiler);
-  }
-
-  bool canBeNull() => false;
-  bool canBePrimitive(Compiler compiler) => false;
-  bool canBePrimitiveNumber(Compiler compiler) => false;
-  bool canBePrimitiveString(Compiler compiler) => false;
-  bool canBePrimitiveArray(Compiler compiler) => false;
-  bool canBePrimitiveBoolean(Compiler compiler) => false;
-
-  /** Alias for isReadableArray. */
-  bool isArray(Compiler compiler) => isReadableArray(compiler);
-
-  TypeMask computeMask(Compiler compiler);
-
-  Selector refine(Selector selector, Compiler compiler) {
-    // TODO(kasperl): Should we check if the refinement really is more
-    // specialized than the starting point?
-    TypeMask mask = computeMask(compiler);
-    if (selector.mask == mask) return selector;
-    return new TypedSelector(mask, selector);
-  }
-
-  /**
-   * The intersection of two types is the intersection of its values. For
-   * example:
-   *   * INTEGER.intersect(NUMBER) => INTEGER.
-   *   * DOUBLE.intersect(INTEGER) => CONFLICTING.
-   *   * MUTABLE_ARRAY.intersect(READABLE_ARRAY) => MUTABLE_ARRAY.
-   *
-   * When there is no predefined type to represent the intersection returns
-   * [CONFLICTING].
-   *
-   * An intersection with [UNKNOWN] returns the non-UNKNOWN type. An
-   * intersection with [CONFLICTING] returns [CONFLICTING].
-   */
-  HType intersection(HType other, Compiler compiler) {
-    TypeMask mask = computeMask(compiler);
-    TypeMask otherMask = other.computeMask(compiler);
-    TypeMask intersection = mask.intersection(otherMask, compiler);
-    return new HType.fromMask(intersection, compiler);
-  }
-
-  /**
-   * The union of two types is the union of its values. For example:
-   *   * INTEGER.union(NUMBER) => NUMBER.
-   *   * DOUBLE.union(INTEGER) => NUMBER.
-   *   * MUTABLE_ARRAY.union(READABLE_ARRAY) => READABLE_ARRAY.
-   *
-   * When there is no predefined type to represent the union returns
-   * [UNKNOWN].
-   *
-   * A union with [UNKNOWN] returns [UNKNOWN].
-   * A union of [CONFLICTING] with any other types returns the other type.
-   */
-  HType union(HType other, Compiler compiler) {
-    TypeMask mask = computeMask(compiler);
-    TypeMask otherMask = other.computeMask(compiler);
-    TypeMask union = mask.union(otherMask, compiler);
-    return new HType.fromMask(union, compiler);
-  }
-
-  HType simplify(Compiler compiler) => this;
-
-  HType nonNullable(compiler) {
-    return new HType.fromMask(computeMask(compiler).nonNullable(), compiler);
-  }
-
-  bool containsAll(Compiler compiler) {
-    return computeMask(compiler).containsAll(compiler);
-  }
-}
-
-class HBoundedType extends HType {
-  final TypeMask mask;
-  const HBoundedType(this.mask);
-
-  bool isExact() => mask.isExact || isNull();
-
-  bool canBeNull() => mask.isNullable;
-
-  bool isNull() => mask.isEmpty && mask.isNullable;
-  bool isConflicting() => mask.isEmpty && !mask.isNullable;
-
-  bool canBePrimitive(Compiler compiler) {
-    return canBePrimitiveNumber(compiler)
-        || canBePrimitiveArray(compiler)
-        || canBePrimitiveBoolean(compiler)
-        || canBePrimitiveString(compiler)
-        || isNull();
-  }
-
-  bool canBePrimitiveNumber(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.contains(backend.jsNumberClass, compiler)
-        || mask.contains(backend.jsIntClass, compiler)
-        || mask.contains(backend.jsDoubleClass, compiler);
-  }
-
-  bool canBePrimitiveBoolean(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.contains(backend.jsBoolClass, compiler);
-  }
-
-  bool canBePrimitiveArray(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.contains(backend.jsArrayClass, compiler)
-        || mask.contains(backend.jsFixedArrayClass, compiler)
-        || mask.contains(backend.jsExtendableArrayClass, compiler);
-  }
-
-  bool isIndexablePrimitive(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.satisfies(backend.jsIndexableClass, compiler);
-  }
-
-  bool isFixedArray(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.containsOnly(backend.jsFixedArrayClass);
-  }
-
-  bool isExtendableArray(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.containsOnly(backend.jsExtendableArrayClass);
-  }
-
-  bool isMutableArray(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.satisfies(backend.jsMutableArrayClass, compiler);
-  }
-
-  bool isReadableArray(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.satisfies(backend.jsArrayClass, compiler);
-  }
-
-  bool canBePrimitiveString(Compiler compiler) {
-    JavaScriptBackend backend = compiler.backend;
-    return mask.contains(backend.jsStringClass, compiler);
-  }
-
-  TypeMask computeMask(Compiler compiler) => mask;
-
-  HType simplify(Compiler compiler) {
-    return new HType.fromMask(mask.simplify(compiler), compiler);
-  }
-
-  bool isInteger(Compiler compiler) {
-    return mask.containsOnlyInt(compiler) && !mask.isNullable;
-  }
-
-  bool isIntegerOrNull(Compiler compiler) {
-    return mask.containsOnlyInt(compiler);
-  }
-
-  bool isNumber(Compiler compiler) {
-    return mask.containsOnlyNum(compiler) && !mask.isNullable;
-  }
-
-  bool isNumberOrNull(Compiler compiler) {
-    return mask.containsOnlyNum(compiler);
-  }
-
-  bool isDouble(Compiler compiler) {
-    return mask.containsOnlyDouble(compiler) && !mask.isNullable;
-  }
-
-  bool isDoubleOrNull(Compiler compiler) {
-    return mask.containsOnlyDouble(compiler);
-  }
-
-  bool isBoolean(Compiler compiler) {
-    return mask.containsOnlyBool(compiler) && !mask.isNullable;
-  }
-
-  bool isBooleanOrNull(Compiler compiler) {
-    return mask.containsOnlyBool(compiler);
-  }
-
-  bool isString(Compiler compiler) {
-    return mask.containsOnlyString(compiler);
-  }
-
-  bool isPrimitive(Compiler compiler) {
-    return (isPrimitiveOrNull(compiler) && !mask.isNullable)
-        || isNull();
-  }
-
-  bool isPrimitiveOrNull(Compiler compiler) {
-    return isIndexablePrimitive(compiler)
-        || isNumberOrNull(compiler)
-        || isBooleanOrNull(compiler)
-        || isNull();
-  }
-
-  bool operator ==(other) {
-    if (other is !HBoundedType) return false;
-    HBoundedType bounded = other;
-    return mask == bounded.mask;
-  }
-
-  int get hashCode => mask.hashCode;
-
-  String toString() {
-    return 'BoundedType(mask=$mask)';
-  }
 }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
index 60e6744..9ff28dc 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types_propagation.dart
@@ -15,7 +15,7 @@
 
   SsaTypePropagator(this.compiler);
 
-  HType computeType(HInstruction instruction) {
+  TypeMask computeType(HInstruction instruction) {
     return instruction.accept(this);
   }
 
@@ -23,8 +23,8 @@
   // whether or not the type was changed.
   bool updateType(HInstruction instruction) {
     // Compute old and new types.
-    HType oldType = instruction.instructionType;
-    HType newType = computeType(instruction);
+    TypeMask oldType = instruction.instructionType;
+    TypeMask newType = computeType(instruction);
     assert(newType != null);
     // We unconditionally replace the propagated type with the new type. The
     // computeType must make sure that we eventually reach a stable state.
@@ -96,7 +96,7 @@
     }
   }
 
-  HType visitBinaryArithmetic(HBinaryArithmetic instruction) {
+  TypeMask visitBinaryArithmetic(HBinaryArithmetic instruction) {
     HInstruction left = instruction.left;
     HInstruction right = instruction.right;
     JavaScriptBackend backend = compiler.backend;    
@@ -107,55 +107,55 @@
     return backend.numType;
   }
 
-  HType visitNegate(HNegate instruction) {
+  TypeMask visitNegate(HNegate instruction) {
     return instruction.operand.instructionType;
   }
 
-  HType visitInstruction(HInstruction instruction) {
+  TypeMask visitInstruction(HInstruction instruction) {
     assert(instruction.instructionType != null);
     return instruction.instructionType;
   }
 
-  HType visitPhi(HPhi phi) {
+  TypeMask visitPhi(HPhi phi) {
     JavaScriptBackend backend = compiler.backend;    
-    HType candidateType = backend.emptyType;
+    TypeMask candidateType = backend.emptyType;
     for (int i = 0, length = phi.inputs.length; i < length; i++) {
-      HType inputType = phi.inputs[i].instructionType;
+      TypeMask inputType = phi.inputs[i].instructionType;
       candidateType = candidateType.union(inputType, compiler);
     }
     return candidateType;
   }
 
-  HType visitTypeConversion(HTypeConversion instruction) {
-    HType inputType = instruction.checkedInput.instructionType;
-    HType checkedType = instruction.checkedType;
+  TypeMask visitTypeConversion(HTypeConversion instruction) {
+    HInstruction input = instruction.checkedInput;
+    TypeMask inputType = input.instructionType;
+    TypeMask checkedType = instruction.checkedType;
     JavaScriptBackend backend = compiler.backend;
     if (instruction.isArgumentTypeCheck || instruction.isReceiverTypeCheck) {
       // We must make sure a type conversion for receiver or argument check
       // does not try to do an int check, because an int check is not enough.
       // We only do an int check if the input is integer or null.
-      if (checkedType.isNumber(compiler)
-          && !checkedType.isDouble(compiler)
-          && inputType.isIntegerOrNull(compiler)) {
+      if (checkedType.containsOnlyNum(compiler)
+          && !checkedType.containsOnlyDouble(compiler)
+          && input.isIntegerOrNull(compiler)) {
         instruction.checkedType = backend.intType;
-      } else if (checkedType.isInteger(compiler)
-                 && !inputType.isIntegerOrNull(compiler)) {
+      } else if (checkedType.containsOnlyInt(compiler)
+                 && !input.isIntegerOrNull(compiler)) {
         instruction.checkedType = backend.numType;
       }
     }
 
-    HType outputType = checkedType.intersection(inputType, compiler);
-    if (outputType.isConflicting()) {
+    TypeMask outputType = checkedType.intersection(inputType, compiler);
+    if (outputType.isEmpty && !outputType.isNullable) {
       // Intersection of double and integer conflicts (is empty), but JS numbers
       // can be both int and double at the same time.  For example, the input
       // can be a literal double '8.0' that is marked as an integer (because 'is
       // int' will return 'true').  What we really need to do is make the
-      // overlap between int and double values explicit in the HType system.
-      if (inputType.isIntegerOrNull(compiler)
-          && checkedType.isDoubleOrNull(compiler)) {
-        if (inputType.canBeNull() && checkedType.canBeNull()) {
-          outputType =
-              new HBoundedType(new TypeMask.exact(backend.jsDoubleClass));
+      // overlap between int and double values explicit in the TypeMask system.
+      if (inputType.containsOnlyInt(compiler)
+          && checkedType.containsOnlyDouble(compiler)) {
+        if (inputType.isNullable && checkedType.isNullable) {
+          outputType = backend.doubleType.nullable();
         } else {
           outputType = backend.doubleType;
         }
@@ -164,14 +164,14 @@
     return outputType;
   }
 
-  HType visitTypeKnown(HTypeKnown instruction) {
+  TypeMask visitTypeKnown(HTypeKnown instruction) {
     HInstruction input = instruction.checkedInput;
     return instruction.knownType.intersection(input.instructionType, compiler);
   }
 
   void convertInput(HInvokeDynamic instruction,
                     HInstruction input,
-                    HType type,
+                    TypeMask type,
                     int kind) {
     Selector selector = (kind == HTypeConversion.RECEIVER_TYPE_CHECK)
         ? instruction.selector
@@ -183,15 +183,15 @@
   }
 
   bool isCheckEnoughForNsmOrAe(HInstruction instruction,
-                               HType type) {
+                               TypeMask type) {
     // In some cases, we want the receiver to be an integer,
     // but that does not mean we will get a NoSuchMethodError
     // if it's not: the receiver could be a double.
-    if (type.isInteger(compiler)) {
+    if (type.containsOnlyInt(compiler)) {
       // If the instruction's type is integer or null, the codegen
       // will emit a null check, which is enough to know if it will
       // hit a noSuchMethod.
-      return instruction.instructionType.isIntegerOrNull(compiler);
+      return instruction.isIntegerOrNull(compiler);
     }
     return true;
   }
@@ -205,7 +205,7 @@
     if (receiver.isNumberOrNull(compiler)) {
       convertInput(instruction,
                    receiver,
-                   receiver.instructionType.nonNullable(compiler),
+                   receiver.instructionType.nonNullable(),
                    HTypeConversion.RECEIVER_TYPE_CHECK);
       return true;
     } else if (instruction.element == null) {
@@ -214,10 +214,15 @@
       if (targets.length == 1) {
         Element target = targets.first;
         ClassElement cls = target.getEnclosingClass();
-        HType type = new HType.nonNullSubclass(cls, compiler);
+        TypeMask type = new TypeMask.nonNullSubclass(cls.declaration);
         // TODO(ngeoffray): We currently only optimize on primitive
         // types.
-        if (!type.isPrimitive(compiler)) return false;
+        JavaScriptBackend backend = compiler.backend;    
+        if (!type.satisfies(backend.jsIndexableClass, compiler)
+            && !type.containsOnlyNum(compiler)
+            && !type.containsOnlyBool(compiler)) {
+          return false;
+        }
         if (!isCheckEnoughForNsmOrAe(receiver, type)) return false;
         instruction.element = target;
         convertInput(instruction,
@@ -237,14 +242,13 @@
     // We want the right error in checked mode.
     if (compiler.enableTypeAssertions) return false;
     HInstruction left = instruction.inputs[1];
-    HType receiverType = left.instructionType;
-
     HInstruction right = instruction.inputs[2];
+
     Selector selector = instruction.selector;
-    if (selector.isOperator() && receiverType.isNumber(compiler)) {
+    if (selector.isOperator() && left.isNumber(compiler)) {
       if (right.isNumber(compiler)) return false;
       JavaScriptBackend backend = compiler.backend;    
-      HType type = right.isIntegerOrNull(compiler)
+      TypeMask type = right.isIntegerOrNull(compiler)
           ? backend.intType
           : backend.numType;
       // TODO(ngeoffray): Some number operations don't have a builtin
@@ -279,7 +283,7 @@
     });
   }
 
-  HType visitInvokeDynamic(HInvokeDynamic instruction) {
+  TypeMask visitInvokeDynamic(HInvokeDynamic instruction) {
     if (instruction.isInterceptedCall) {
       // We cannot do the following optimization now, because we have
       // to wait for the type propagation to be stable. The receiver
@@ -298,36 +302,33 @@
     }
 
     HInstruction receiver = instruction.getDartReceiver(compiler);
-    HType receiverType = receiver.instructionType;
-    Selector selector = receiverType.refine(instruction.selector, compiler);
+    TypeMask receiverType = receiver.instructionType;
+    Selector selector = new TypedSelector(receiverType, instruction.selector);
     instruction.selector = selector;
 
     // Try to specialize the receiver after this call.
     if (receiver.dominatedUsers(instruction).length != 1
         && !selector.isClosureCall()) {
-      TypeMask oldMask = receiverType.computeMask(compiler);
-      TypeMask newMask = compiler.world.allFunctions.receiverType(selector);
-      newMask = newMask.intersection(oldMask, compiler);
-
-      if (newMask != oldMask) {
-        HType newType = new HType.fromMask(newMask, compiler);
-        var next = instruction.next;
-        if (next is HTypeKnown && next.checkedInput == receiver) {
-          // We already have refined [receiver].
-          HType nextType = next.instructionType;
-          if (nextType != newType) {
-            next.knownType = next.instructionType = newType;
-            addDependentInstructionsToWorkList(next);
-          }
-        } else {
-          // Insert a refinement node after the call and update all
-          // users dominated by the call to use that node instead of
-          // [receiver].
-          HTypeKnown converted = new HTypeKnown(newType, receiver);
-          instruction.block.addBefore(instruction.next, converted);
-          receiver.replaceAllUsersDominatedBy(converted.next, converted);
-          addDependentInstructionsToWorkList(converted);
+      TypeMask newType = compiler.world.allFunctions.receiverType(selector);
+      newType = newType.intersection(receiverType, compiler);
+      var next = instruction.next;
+      if (next is HTypeKnown && next.checkedInput == receiver) {
+        // We already have refined [receiver]. We still update the
+        // type of the [HTypeKnown] instruction because it may have
+        // been refined with a correct type at the time, but
+        // incorrect now.
+        if (next.instructionType != newType) {
+          next.knownType = next.instructionType = newType;
+          addDependentInstructionsToWorkList(next);
         }
+      } else if (newType != receiverType) {
+        // Insert a refinement node after the call and update all
+        // users dominated by the call to use that node instead of
+        // [receiver].
+        HTypeKnown converted = new HTypeKnown(newType, receiver);
+        instruction.block.addBefore(instruction.next, converted);
+        receiver.replaceAllUsersDominatedBy(converted.next, converted);
+        addDependentInstructionsToWorkList(converted);
       }
     }
 
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 829012d..e36bec1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
@@ -677,9 +677,11 @@
 
   Range visitFieldGet(HFieldGet fieldGet) {
     if (!fieldGet.isInteger(compiler)) return info.newUnboundRange();
-    if (!fieldGet.receiver.isIndexable(compiler)) {
+    if (!fieldGet.receiver.isIndexablePrimitive(compiler)) {
       return visitInstruction(fieldGet);
     }
+    JavaScriptBackend backend = compiler.backend;
+    assert(fieldGet.element == backend.jsIndexableLength);
     LengthValue value = info.newLengthValue(fieldGet);
     // We know this range is above zero. To simplify the analysis, we
     // put the zero value as the lower bound of this range. This
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 ac39ab2..d210715 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -572,6 +572,14 @@
   bool needsNoSuchMethodHandling(Selector selector, Compiler compiler) {
     throw new UnsupportedError("");
   }
+
+  bool isInMask(TypeMask other, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
+
+  bool containsMask(TypeMask other, Compiler compiler) {
+    throw new UnsupportedError("");
+  }
 }
 
 /**
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index c58baef..ec7ba94 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -82,6 +82,20 @@
     }
   }
 
+  bool isInMask(other, Compiler compiler) {
+    if (isEmpty) {
+      return isNullable ? other.isNullable : true;
+    }
+    if (other.isEmpty) return false;
+    if (isNullable && !other.isNullable) return false;
+    if (other is! FlatTypeMask) return other.containsMask(this, compiler);
+    return satisfies(other.base, compiler);
+  }
+
+  bool containsMask(TypeMask other, Compiler compiler) {
+    return other.isInMask(this, compiler);
+  }
+
   bool containsOnlyInt(Compiler compiler) {
     return base == compiler.intClass
         || base == compiler.backend.intImplementation;
@@ -122,7 +136,29 @@
   bool satisfies(ClassElement cls, Compiler compiler) {
     assert(cls.isDeclaration);
     if (isEmpty) return false;
-    return base == cls || isSubtypeOf(base, cls, compiler);
+    if (base == cls) return true;
+    if (isSubtypeOf(base, cls, compiler)) return true;
+
+    // Special case basic types so that, for example, String satisfies
+    // JSString.
+    // The general optimization is to realize there is only one class that
+    // implements [base] and [base] is not instantiated. We however do
+    // not track correctly the list of truly instantiated classes.
+    Backend backend = compiler.backend;
+    if (containsOnlyString(compiler)) {
+      return cls == compiler.stringClass || cls == backend.stringImplementation;
+    }
+    if (containsOnlyBool(compiler)) {
+      return cls == compiler.boolClass || cls == backend.boolImplementation;
+    }
+    if (containsOnlyInt(compiler)) {
+      return cls == compiler.intClass || cls == backend.intImplementation;
+    }
+    if (containsOnlyDouble(compiler)) {
+      return cls == compiler.doubleClass
+          || cls == compiler.backend.doubleImplementation;
+    }
+    return false;
   }
 
   /**
@@ -194,7 +230,7 @@
   TypeMask unionSubclass(FlatTypeMask other, Compiler compiler) {
     assert(isSubclassOf(other.base, base, compiler));
     int combined;
-    if (isExact && other.isExact) {
+    if ((isExact && other.isExact) || base == compiler.objectClass) {
       // Since the other mask is a subclass of this mask, we need the
       // resulting union to be a subclass too. If either one of the
       // masks are nullable the result should be nullable too.
diff --git a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
index 8f4c05f..bb7b7a9 100644
--- a/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/forwarding_type_mask.dart
@@ -22,6 +22,14 @@
   bool get isContainer => false;
   bool get isForwarding => true;
 
+  bool isInMask(TypeMask other, Compiler compiler) {
+    return forwardTo.isInMask(other, compiler);
+  }
+
+  bool containsMask(TypeMask other, Compiler compiler) {
+    return forwardTo.containsMask(other, compiler);
+  }
+
   bool containsOnlyInt(Compiler compiler) {
     return forwardTo.containsOnlyInt(compiler);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
index 27e2df5..e99a8f4 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_mask.dart
@@ -63,6 +63,16 @@
   bool containsOnly(ClassElement element);
 
   /**
+   * Returns whether this type mask is a subtype of [other].
+   */
+  bool isInMask(TypeMask other, Compiler compiler);
+
+  /**
+   * Returns whether [other] is a subtype of this type mask.
+   */
+  bool containsMask(TypeMask other, Compiler compiler);
+
+  /**
    * Returns whether this type mask is an instance of [cls].
    */
   bool satisfies(ClassElement cls, Compiler compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 1a47e3b..e754376 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -180,7 +180,7 @@
   TypeMask get nullType {
     if (nullTypeCache == null) {
       // TODO(johnniwinther): Assert that the null type has been resolved.
-      nullTypeCache = new TypeMask.empty();
+      nullTypeCache = const TypeMask.empty();
     }
     return nullTypeCache;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index e6232cc..de7fc8f 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -197,6 +197,14 @@
   bool get isContainer => false;
   bool get isForwarding => false;
 
+  bool isInMask(TypeMask other, Compiler compiler) {
+    return disjointMasks.every((mask) => mask.isInMask(other, compiler));
+  }
+
+  bool containsMask(TypeMask other, Compiler compiler) {
+    return disjointMasks.any((mask) => mask.containsMask(other, compiler));
+  }
+
   bool containsOnlyInt(Compiler compiler) {
     return disjointMasks.every((mask) => mask.containsOnlyInt(compiler));
   }
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 5c0c9da..73bbb9f 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -622,6 +622,7 @@
       new Map<Selector, Map<TypeMask, TypedSelector>>();
 
   factory TypedSelector(TypeMask mask, Selector selector) {
+    if (selector.mask == mask) return selector;
     Selector untyped = selector.asUntyped;
     Map<TypeMask, TypedSelector> map = canonicalizedValues.putIfAbsent(untyped,
         () => new Map<TypeMask, TypedSelector>());
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index fe12176..052d223 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -819,6 +819,11 @@
       "Error: '#{type}' must not occur more than once "
       "in the implements clause.");
 
+  static const MessageKind MULTI_INHERITANCE = const MessageKind(
+      "Internal Error: Inheritance of the same class with different type "
+      "arguments is not supported: Both #{firstType} and #{secondType} are "
+      "supertypes of #{thisType}.");
+
   static const MessageKind ILLEGAL_SUPER_SEND = const MessageKind(
       "Error: '#{name}' cannot be called on super.");
 
@@ -974,6 +979,9 @@
           "foo(void x) {} main() { foo(null); }",
       ]);
 
+  static const MessageKind NULL_NOT_ALLOWED = const MessageKind(
+      "Error: `null` can't be used here.");
+
   static const MessageKind BEFORE_TOP_LEVEL = const MessageKind(
       "Error: Part header must come before top-level definitions.");
 
diff --git a/sdk/lib/_internal/compiler/implementation/world.dart b/sdk/lib/_internal/compiler/implementation/world.dart
index 722688d..971ac69 100644
--- a/sdk/lib/_internal/compiler/implementation/world.dart
+++ b/sdk/lib/_internal/compiler/implementation/world.dart
@@ -181,6 +181,11 @@
     return subtypes != null && subtypes.contains(test.declaration);
   }
 
+  bool isSubclass(ClassElement superclass, ClassElement test) {
+    Set<ClassElement> subclasses = subclassesOf(superclass);
+    return subclasses != null && subclasses.contains(test.declaration);
+  }
+
   void registerUsedElement(Element element) {
     if (element.isInstanceMember() && !element.isAbstract(compiler)) {
       allFunctions.add(element);
diff --git a/sdk/lib/_internal/lib/core_patch.dart b/sdk/lib/_internal/lib/core_patch.dart
index 8e5bec0..601149a 100644
--- a/sdk/lib/_internal/lib/core_patch.dart
+++ b/sdk/lib/_internal/lib/core_patch.dart
@@ -105,7 +105,7 @@
 
   patch factory int.fromEnvironment(String name, {int defaultValue}) {
     throw new UnsupportedError(
-        'int.fromEnvironement can only be used as a const constructor');
+        'int.fromEnvironment can only be used as a const constructor');
   }
 }
 
@@ -227,14 +227,14 @@
 
   patch factory String.fromEnvironment(String name, {String defaultValue}) {
     throw new UnsupportedError(
-        'String.fromEnvironement can only be used as a const constructor');
+        'String.fromEnvironment can only be used as a const constructor');
   }
 }
 
 patch class bool {
-  patch factory bool.fromEnvironment(String name, {bool defaultValue}) {
+  patch factory bool.fromEnvironment(String name, {bool defaultValue: false}) {
     throw new UnsupportedError(
-        'bool.fromEnvironement can only be used as a const constructor');
+        'bool.fromEnvironment can only be used as a const constructor');
   }
 }
 
diff --git a/sdk/lib/_internal/lib/interceptors.dart b/sdk/lib/_internal/lib/interceptors.dart
index c5e340e..23955bb 100644
--- a/sdk/lib/_internal/lib/interceptors.dart
+++ b/sdk/lib/_internal/lib/interceptors.dart
@@ -11,6 +11,7 @@
                               Null,
                               JSSyntaxRegExp,
                               Primitives,
+                              checkInt,
                               checkNull,
                               checkNum,
                               checkString,
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 96671cd..802563e 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -207,7 +207,7 @@
   TypeMirror get upperBound {
     if (_cachedUpperBound != null) return _cachedUpperBound;
     return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
-        JS('', 'init.metadata[#]', _typeVariable.bound));
+        owner, getMetadata(_typeVariable.bound));
   }
 }
 
@@ -502,8 +502,7 @@
   if (constructorOrInterceptor == null) {
     int index = JS('int|Null', 'init.functionAliases[#]', mangledName);
     if (index != null) {
-      mirror = new JsTypedefMirror(
-          symbol, mangledName, JS('=Object', 'init.metadata[#]', index));
+      mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index));
       JsCache.update(classMirrors, mangledName, mirror);
       return mirror;
     }
@@ -675,15 +674,6 @@
         "Can't instantiate mixin application '${n(qualifiedName)}'");
   }
 
-  Future<InstanceMirror> newInstanceAsync(
-      Symbol constructorName,
-      List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    return new Future<InstanceMirror>(
-        () => this.newInstance(
-            constructorName, positionalArguments, namedArguments));
-  }
-
   bool get isOriginalDeclaration => true;
 
   ClassMirror get originalDeclaration => this;
@@ -697,20 +687,6 @@
 }
 
 abstract class JsObjectMirror implements ObjectMirror {
-  Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
-    return new Future<InstanceMirror>(() => this.setField(fieldName, value));
-  }
-
-  Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
-    return new Future<InstanceMirror>(() => this.getField(fieldName));
-  }
-
-  Future<InstanceMirror> invokeAsync(Symbol memberName,
-                                     List positionalArguments,
-                                     [Map<Symbol, dynamic> namedArguments]) {
-    return new Future<InstanceMirror>(
-        () => this.invoke(memberName, positionalArguments, namedArguments));
-  }
 }
 
 class JsInstanceMirror extends JsObjectMirror implements InstanceMirror {
@@ -722,14 +698,6 @@
 
   ClassMirror get type => reflectType(reflectee.runtimeType);
 
-  Future<InstanceMirror> invokeAsync(Symbol memberName,
-                                     List<Object> positionalArguments,
-                                     [Map<Symbol, dynamic> namedArguments]) {
-    return
-        new Future<InstanceMirror>(
-            () => invoke(memberName, positionalArguments, namedArguments));
-  }
-
   InstanceMirror invoke(Symbol memberName,
                         List positionalArguments,
                         [Map<Symbol,dynamic> namedArguments]) {
@@ -748,7 +716,7 @@
       var defaultValueIndices =
           JS('List|Null', '#[#].\$defaultValues', reflectee, mangledName);
       var defaultValues =
-          defaultValueIndices.map((int i) => JS('', 'init.metadata[#]', i))
+          defaultValueIndices.map((int i) => getMetadata(i))
           .iterator;
       var defaultArguments = new Map();
       reflectiveName = mangledNames[mangledName];
@@ -882,30 +850,36 @@
    * When instantiated this field will hold a string representing the list of
    * type arguments for the class, i.e. what is inside the outermost angle
    * brackets. Then, when get typeArguments is called the first time, the string
-   * is parsed into the actual list of TypeMirrors, and the field is overridden
-   * with this value.
+   * is parsed into the actual list of TypeMirrors, and stored in
+   * [_cachedTypeArguments]. Due to type substitution of, for instance,
+   * superclasses the mangled name of the class and hence this string is needed
+   * after [_cachedTypeArguments] has been computed.
    *
    * If an integer is encountered as a type argument, it represents the type
    * variable at the corresponding entry in [emitter.globalMetadata].
    */
-  var _typeArguments;
+  String _typeArguments;
 
+  UnmodifiableListView<TypeMirror> _cachedTypeArguments;
   Map<Symbol, VariableMirror> _cachedVariables;
   Map<Symbol, MethodMirror> _cachedGetters;
   Map<Symbol, MethodMirror> _cachedSetters;
   Map<Symbol, MethodMirror> _cachedMethodsMap;
   List<JsMethodMirror> _cachedMethods;
+  ClassMirror _superclass;
+  List<ClassMirror> _cachedSuperinterfaces;
 
   JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments)
-      : _class = originalDeclaration, 
+      : _class = originalDeclaration,
         super(originalDeclaration.simpleName);
 
   String get _prettyName => 'ClassMirror';
-  
+  String get _mangledName => '${_class._mangledName}<$_typeArguments>';
+
   List<TypeVariableMirror> get typeVariables => _class.typeVariables;
 
   List<TypeMirror> get typeArguments {
-    if (_typeArguments is! String) return _typeArguments;
+    if (_cachedTypeArguments != null) return _cachedTypeArguments;
     List result = new List();
 
     addTypeArgument(String typeArgument) {
@@ -913,7 +887,7 @@
       if (parsedIndex == -1) {
         result.add(reflectClassByMangledName(typeArgument.trim()));
       } else {
-        TypeVariable typeVariable = JS('', 'init.metadata[#]', parsedIndex);
+        TypeVariable typeVariable = getMetadata(parsedIndex);
         TypeMirror owner = reflectClass(typeVariable.owner);
         TypeVariableMirror typeMirror =
             new JsTypeVariableMirror(typeVariable, owner);
@@ -950,7 +924,7 @@
       }
       addTypeArgument(currentTypeArgument);
     }
-    return _typeArguments = new UnmodifiableListView(result);
+    return _cachedTypeArguments = new UnmodifiableListView(result);
   }
 
   Map<Symbol, MethodMirror> get constructors => _class.constructors;
@@ -1004,20 +978,19 @@
                               namedArguments);
   }
 
-  Future<InstanceMirror> newInstanceAsync(
-      Symbol constructorName,
-      List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    return _class.newInstanceAsync(constructorName,
-                                   positionalArguments,
-                                   namedArguments);
-  }
-
   JsLibraryMirror get owner => _class.owner;
 
   List<InstanceMirror> get metadata => _class.metadata;
 
-  ClassMirror get superclass => _class.superclass;
+  ClassMirror get superclass {
+    if (_superclass != null) return _superclass;
+
+    List<int> typeInformation =
+        JS('List|Null', 'init.typeInformation[#]', _class._mangledName);
+    assert(typeInformation != null);
+    var type = getMetadata(typeInformation[0]);
+    return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
+  }
 
   InstanceMirror invoke(Symbol memberName,
                         List positionalArguments,
@@ -1029,20 +1002,13 @@
 
   ClassMirror get originalDeclaration => _class;
 
-  List<ClassMirror> get superinterfaces => _class.superinterfaces;
-
-  Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
-    return _class.getFieldAsync(fieldName);
+  List<ClassMirror> get superinterfaces {
+    if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
+    return _cachedSuperinterfaces = _class._getSuperinterfacesWithOwner(this);
   }
 
   bool get hasReflectedType => _class.hasReflectedType;
 
-  Future<InstanceMirror> invokeAsync(Symbol memberName,
-                                     List positionalArguments,
-                                     [Map<Symbol, dynamic> namedArguments]) {
-    return _class.invokeAsync(memberName, positionalArguments, namedArguments);
-  }
-
   bool get isPrivate => _class.isPrivate;
 
   bool get isTopLevel => _class.isTopLevel;
@@ -1055,10 +1021,6 @@
 
   Type get reflectedType => _class.reflectedType;
 
-  Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
-    return _class.setFieldAsync(fieldName, value);
-  }
-
   Symbol get simpleName => _class.simpleName;
 }
 
@@ -1313,18 +1275,6 @@
     return reflect(mirror._invoke(positionalArguments, namedArguments));
   }
 
-  Future<InstanceMirror> newInstanceAsync(
-      Symbol constructorName,
-      List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    if (namedArguments != null && !namedArguments.isEmpty) {
-      throw new UnsupportedError('Named arguments are not implemented.');
-    }
-    return new Future<InstanceMirror>(
-        () => newInstance(
-            constructorName, positionalArguments, namedArguments));
-  }
-
   JsLibraryMirror get owner {
     if (_owner == null) {
       if (_jsConstructorOrInterceptor is Interceptor) {
@@ -1357,19 +1307,28 @@
 
   ClassMirror get superclass {
     if (_superclass == null) {
-      var superclassName = _fieldsDescriptor.split(';')[0];
-      var mixins = superclassName.split('+');
-      if (mixins.length > 1) {
-        if (mixins.length != 2) {
-          throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
-        }
-        _superclass = reflectClassByMangledName(mixins[0]);
+      List<int> typeInformation =
+          JS('List|Null', 'init.typeInformation[#]', _mangledName);
+      if (typeInformation != null) {
+        var type = getMetadata(typeInformation[0]);
+        _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
       } else {
-        // Use _superclass == this to represent class with no superclass (Object).
-        _superclass = (superclassName == '')
-            ? this : reflectClassByMangledName(superclassName);
+        var superclassName = _fieldsDescriptor.split(';')[0];
+        // TODO(zarah): Remove special handing of mixins.
+        var mixins = superclassName.split('+');
+        if (mixins.length > 1) {
+          if (mixins.length != 2) {
+            throw new RuntimeError('Strange mixin: $_fieldsDescriptor');
+          }
+          _superclass = reflectClassByMangledName(mixins[0]);
+        } else {
+          // Use _superclass == this to represent class with no superclass
+          // (Object).
+          _superclass = (superclassName == '')
+              ? this : reflectClassByMangledName(superclassName);
+          }
+        }
       }
-    }
     return _superclass == this ? null : _superclass;
   }
 
@@ -1398,19 +1357,26 @@
 
   ClassMirror get originalDeclaration => this;
 
+  List<ClassMirror> _getSuperinterfacesWithOwner(DeclarationMirror owner) {
+    List<int> typeInformation =
+        JS('List|Null', 'init.typeInformation[#]', _mangledName);
+    List<ClassMirror> result = const <ClassMirror>[];
+    if (typeInformation != null) {
+      ClassMirror lookupType(int i) {
+        var type = getMetadata(i);
+        return typeMirrorFromRuntimeTypeRepresentation(owner, type);
+      }
+
+      //We skip the first since it is the supertype.
+      result = typeInformation.skip(1).map(lookupType).toList();
+    }
+
+    return new UnmodifiableListView<ClassMirror>(result);
+  }
+
   List<ClassMirror> get superinterfaces {
     if (_cachedSuperinterfaces != null) return _cachedSuperinterfaces;
-    List<int> interfaces = JS('List|Null', 'init.interfaces[#]', _mangledName);
-    var result = const [];
-    if (interfaces != null) {
-      ClassMirror lookupType(int i) {
-        var type = JS('=Object', 'init.metadata[#]', i);
-        return typeMirrorFromRuntimeTypeRepresentation(type);
-      }
-      result = interfaces.map(lookupType).toList();
-    }
-    return _cachedSuperinterfaces =
-        new UnmodifiableListView<ClassMirror>(result);
+    return _cachedSuperinterfaces = _getSuperinterfacesWithOwner(this);
   }
 
   List<TypeVariableMirror> get typeVariables {
@@ -1420,7 +1386,7 @@
         JS('JSExtendableArray|Null', '#.prototype["<>"]', _jsConstructor);
     if (typeVariables == null) return result;
     for (int i = 0; i < typeVariables.length; i++) {
-      TypeVariable typeVariable = JS('', 'init.metadata[#]', typeVariables[i]);
+      TypeVariable typeVariable = getMetadata(typeVariables[i]);
       result.add(new JsTypeVariableMirror(typeVariable, this));
     }
     return _cachedTypeVariables = new UnmodifiableListView(result);
@@ -1583,18 +1549,13 @@
         Function.apply(reflectee, positionalArguments, namedArguments));
   }
 
-  Future<InstanceMirror> applyAsync(List positionalArguments,
-                                    [Map<Symbol, dynamic> namedArguments]) {
-    return new Future<InstanceMirror>(
-        () => apply(positionalArguments, namedArguments));
-  }
-
   String toString() => "ClosureMirror on '${Error.safeToString(reflectee)}'";
 
   // TODO(ahe): Implement these.
   String get source => throw new UnimplementedError();
-  Future<InstanceMirror> findInContext(Symbol name)
-      => throw new UnimplementedError();
+  InstanceMirror findInContext(Symbol name) {
+    throw new UnsupportedError("ClosureMirror.findInContext not yet supported");
+  }
 }
 
 class JsMethodMirror extends JsDeclarationMirror implements MethodMirror {
@@ -1663,7 +1624,7 @@
 
   TypeMirror get returnType {
     metadata; // Compute _returnType as a side-effect of extracting metadata.
-    return computeTypeMirror(owner, _returnType);
+    return typeMirrorFromRuntimeTypeRepresentation(owner, _returnType);
   }
 
   List<InstanceMirror> get metadata {
@@ -1762,7 +1723,7 @@
   String get _prettyName => 'ParameterMirror';
 
   TypeMirror get type {
-    return computeTypeMirror(owner, _type);
+    return typeMirrorFromRuntimeTypeRepresentation(owner, _type);
   }
 
   // Only true for static fields, never for a parameter.
@@ -1823,13 +1784,14 @@
 
   bool get _hasNamedArguments => JS('bool', '"named" in #', _typeData);
   get _namedArguments => JS('=Object', '#.named', _typeData);
+  bool get isOriginalDeclaration => true;
 
   TypeMirror get returnType {
     if (_cachedReturnType != null) return _cachedReturnType;
     if (_isVoid) return _cachedReturnType = JsMirrorSystem._voidType;
     if (!_hasReturnType) return _cachedReturnType = JsMirrorSystem._dynamicType;
     return _cachedReturnType =
-        typeMirrorFromRuntimeTypeRepresentation(_returnType);
+          typeMirrorFromRuntimeTypeRepresentation(this, _returnType);
   }
 
   List<ParameterMirror> get parameters {
@@ -1902,18 +1864,20 @@
   }
 }
 
-TypeMirror typeMirrorFromRuntimeTypeRepresentation(type) {
-  if (type == null) return JsMirrorSystem._dynamicType;
-  String representation = runtimeTypeToString(type);
-  if (representation == null) return reflectClass(Function);
-  return reflectType(createRuntimeType(representation));
+int findTypeVariableIndex(List<TypeVariableMirror> typeVariables, String name) {
+  for (int i = 0; i < typeVariables.length; i++) {
+    if (typeVariables[i].simpleName == s(name)) {
+      return i;
+    }
+  }
+  throw new ArgumentError('Type variable not present in list.');
 }
 
-TypeMirror computeTypeMirror(DeclarationMirror owner, var type) {
-  if (type is! int) {
-    return typeMirrorFromRuntimeTypeRepresentation(type);
-  }
-  
+getMetadata(int index) => JS('', 'init.metadata[#]', index);
+
+TypeMirror typeMirrorFromRuntimeTypeRepresentation(
+    DeclarationMirror owner,
+    var /*int|List|JsFunction*/ type) {
   ClassMirror ownerClass;
   DeclarationMirror context = owner;
     while(context != null) {
@@ -1923,19 +1887,42 @@
     }
     context = context.owner;
   }
- 
-  TypeVariable typeVariable = JS('', 'init.metadata[#]', type);
-  Symbol name = new Symbol(typeVariable.name);
-  List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
-  for (int i = 0; i < typeVariables.length; i++) {
-    if (typeVariables[i].simpleName == name) {
-      if (ownerClass.isOriginalDeclaration) {
-        return typeVariables[i];
-      } else {
-        return ownerClass.typeArguments[i];
-      }
+
+  String representation;
+  if (type == null){
+    return JsMirrorSystem._dynamicType;
+  } else if (ownerClass == null) {
+    representation = runtimeTypeToString(type);
+  } else if (ownerClass.isOriginalDeclaration) {
+    if (type is int) {
+      // [type] represents a type variable so in the context of an original
+      // declaration the corresponding type variable should be returned.
+      TypeVariable typeVariable = getMetadata(type);
+      List<TypeVariableMirror> typeVariables = ownerClass.typeVariables;
+      int index = findTypeVariableIndex(typeVariables, typeVariable.name);
+      return typeVariables[index];
+    } else {
+      // Nested type variables will be retrieved lazily (the integer
+      // representation is kept in the string) so they are not processed here.
+      representation = runtimeTypeToString(type);
     }
+  } else {
+    String substituteTypeVariable(int index) {
+      TypeVariable typeVariable = getMetadata(index);
+      int variableIndex =
+          findTypeVariableIndex(ownerClass.typeVariables, typeVariable.name);
+      var typeArgument = ownerClass.typeArguments[variableIndex];
+      assert(typeArgument is JsClassMirror ||
+             typeArgument is JsTypeBoundClassMirror);
+      return typeArgument._mangledName;
+    }
+    representation =
+        runtimeTypeToString(type, onTypeVariable: substituteTypeVariable);
   }
+  if (representation != null) {
+    return reflectType(createRuntimeType(representation));
+  }
+  return reflectClass(Function);
 }
 
 Symbol computeQualifiedName(DeclarationMirror owner, Symbol simpleName) {
@@ -1955,7 +1942,7 @@
   index++;
   int endQuote = source.indexOf('"', index);
   return source.substring(index, endQuote).split(',').map(int.parse).map(
-      (int i) => JS('', 'init.metadata[#]', i)).toList();
+      (int i) => getMetadata(i)).toList();
 }
 
 List<JsVariableMirror> parseCompactFieldSpecification(
diff --git a/sdk/lib/_internal/lib/js_rti.dart b/sdk/lib/_internal/lib/js_rti.dart
index 3670841..67dd441 100644
--- a/sdk/lib/_internal/lib/js_rti.dart
+++ b/sdk/lib/_internal/lib/js_rti.dart
@@ -134,10 +134,11 @@
  * of type 4, the JavaScript array, where the first element represents the class
  * and the remaining elements represent the type arguments.
  */
-String getRuntimeTypeAsString(var runtimeType) {
+String getRuntimeTypeAsString(var runtimeType, {String onTypeVariable(int i)}) {
   assert(isJsArray(runtimeType));
   String className = getConstructorName(getIndex(runtimeType, 0));
-  return '$className${joinArguments(runtimeType, 1)}';
+  return '$className'
+         '${joinArguments(runtimeType, 1, onTypeVariable: onTypeVariable)}';
 }
 
 /**
@@ -149,17 +150,21 @@
 /**
  * Returns a human-readable representation of the type representation [type].
  */
-String runtimeTypeToString(var type) {
+String runtimeTypeToString(var type , {String onTypeVariable(int i)}) {
   if (isNull(type)) {
     return 'dynamic';
   } else if (isJsArray(type)) {
     // A list representing a type with arguments.
-    return getRuntimeTypeAsString(type);
+    return getRuntimeTypeAsString(type, onTypeVariable: onTypeVariable);
   } else if (isJsFunction(type)) {
     // A reference to the constructor.
     return getConstructorName(type);
   } else if (type is int) {
-    return type.toString();
+    if (onTypeVariable == null) {
+      return type.toString();
+    } else {
+      return onTypeVariable(type);
+    }
   } else {
     return null;
   }
@@ -170,7 +175,8 @@
  * type representations in the JavaScript array [types] starting at index
  * [startIndex].
  */
-String joinArguments(var types, int startIndex) {
+String joinArguments(var types, int startIndex,
+                     {String onTypeVariable(int i)}) {
   if (isNull(types)) return '';
   assert(isJsArray(types));
   bool firstArgument = true;
@@ -186,7 +192,7 @@
     if (argument != null) {
       allDynamic = false;
     }
-    buffer.write(runtimeTypeToString(argument));
+    buffer.write(runtimeTypeToString(argument, onTypeVariable: onTypeVariable));
   }
   return allDynamic ? '' : '<$buffer>';
 }
diff --git a/sdk/lib/_internal/lib/js_string.dart b/sdk/lib/_internal/lib/js_string.dart
index 8a8ac16..0dd8066 100644
--- a/sdk/lib/_internal/lib/js_string.dart
+++ b/sdk/lib/_internal/lib/js_string.dart
@@ -14,7 +14,7 @@
   const JSString();
 
   int codeUnitAt(int index) {
-    if (index is !num) throw new ArgumentError(index);
+    if (index is !int) throw new ArgumentError(index);
     if (index < 0) throw new RangeError.value(index);
     if (index >= length) throw new RangeError.value(index);
     return JS('int', r'#.charCodeAt(#)', this, index);
@@ -84,6 +84,7 @@
   }
 
   bool startsWith(Pattern pattern, [int index = 0]) {
+    checkInt(index);
     if (index < 0 || index > this.length) {
       throw new RangeError.range(index, 0, this.length);
     }
@@ -92,16 +93,15 @@
       int otherLength = other.length;
       int endIndex = index + otherLength;
       if (endIndex > length) return false;
-      return JS('bool', r'# == #', other,
-                JS('String', r'#.substring(#, #)', this, index, endIndex));
+      return other == JS('String', r'#.substring(#, #)', this, index, endIndex);
     }
     return pattern.matchAsPrefix(this, index) != null;
   }
 
   String substring(int startIndex, [int endIndex]) {
-    checkNum(startIndex);
+    checkInt(startIndex);
     if (endIndex == null) endIndex = length;
-    checkNum(endIndex);
+    checkInt(endIndex);
     if (startIndex < 0 ) throw new RangeError.value(startIndex);
     if (startIndex > endIndex) throw new RangeError.value(startIndex);
     if (endIndex > length) throw new RangeError.value(endIndex);
diff --git a/sdk/lib/_internal/lib/native_helper.dart b/sdk/lib/_internal/lib/native_helper.dart
index 03b0ef5..799960e 100644
--- a/sdk/lib/_internal/lib/native_helper.dart
+++ b/sdk/lib/_internal/lib/native_helper.dart
@@ -46,7 +46,7 @@
 /**
  * Returns a String tag identifying the type of the native object, or `null`.
  * The tag is not the name of the type, but usually the name of the JavaScript
- * constructor function.
+ * constructor function.  Initialized by [initHooks].
  */
 Function getTagFunction;
 
@@ -54,10 +54,18 @@
  * If a lookup via [getTagFunction] on an object [object] that has [tag] fails,
  * this function is called to provide an alternate tag.  This allows us to fail
  * gracefully if we can make a good guess, for example, when browsers add novel
- * kinds of HTMLElement that we have never heard of.
+ * kinds of HTMLElement that we have never heard of.  Initialized by
+ * [initHooks].
  */
 Function alternateTagFunction;
 
+/**
+ * Returns the prototype for the JavaScript constructor named by an input tag.
+ * Returns `null` if there is no such constructor, or if pre-patching of the
+ * constructor is to be avoided.  Initialized by [initHooks].
+ */
+Function prototypeForTagFunction;
+
 
 String toStringForNativeObject(var obj) {
   // TODO(sra): Is this code dead?
@@ -303,15 +311,12 @@
     var context = JS('=Object', 'window');
     for (int i = 0; i < tags.length; i++) {
       var tag = tags[i];
-      if (JS('bool', 'typeof (#[#]) == "function"', context, tag)) {
-        var constructor = JS('', '#[#]', context, tag);
-        var proto = JS('', '#.prototype', constructor);
-        if (proto != null) {  // E.g. window.mozRTCIceCandidate.prototype
-          var interceptorClass = JS('', '#[#]', map, tag);
-          var record = makeDefaultDispatchRecord(tag, interceptorClass, proto);
-          if (record != null) {
-            setDispatchProperty(proto, record);
-          }
+      var proto = prototypeForTagFunction(tag);
+      if (proto != null) {
+        var interceptorClass = JS('', '#[#]', map, tag);
+        var record = makeDefaultDispatchRecord(tag, interceptorClass, proto);
+        if (record != null) {
+          setDispatchProperty(proto, record);
         }
       }
     }
@@ -347,12 +352,15 @@
  *
  *     { getTag: function(obj) {...},
  *       getUnknownTag: function(obj, tag) {...},
+ *       prototypeForTag: function(tag) {...},
  *       discriminator: function(tag) {...},
  *      }
  *
  * * getTag(obj) returns the dispatch tag, or `null`.
  * * getUnknownTag(obj, tag) returns a tag when [getTag] fails.
- * * discriminator returns a function TBD.
+ * * prototypeForTag(tag) returns the prototype of the constructor for tag,
+ *   or `null` if not available or prepatching is undesirable.
+ * * discriminator(tag) returns a function TBD.
  *
  * The web site can adapt a dart2js application by loading code ahead of the
  * dart2js application that defines hook transformers to be after the built in
@@ -408,10 +416,13 @@
 
   var getTag = JS('', '#.getTag', hooks);
   var getUnknownTag = JS('', '#.getUnknownTag', hooks);
+  var prototypeForTag = JS('', '#.prototypeForTag', hooks);
 
   getTagFunction = (o) => JS('String|Null', '#(#)', getTag, o);
   alternateTagFunction =
       (o, String tag) => JS('String|Null', '#(#, #)', getUnknownTag, o, tag);
+  prototypeForTagFunction =
+      (String tag) => JS('', '#(#)', prototypeForTag, tag);
 }
 
 applyHooksTransformer(transformer, hooks) {
@@ -419,7 +430,6 @@
   return JS('', '# || #', newHooks, hooks);
 }
 
-
 // JavaScript code fragments.
 //
 // This is a temporary place for the JavaScript code.
@@ -445,6 +455,13 @@
     if (object instanceof HTMLElement) return "HTMLElement";
     return getUnknownTag(object, tag);
   }
+  function prototypeForTag(tag) {
+    if (typeof window == "undefined") return null;
+    if (typeof window[tag] == "undefined") return null;
+    var constructor = window[tag];
+    if (typeof constructor != "function") return null;
+    return constructor.prototype;
+  }
   function discriminator(tag) { return null; }
 
   var isBrowser = typeof navigator == "object";
@@ -452,6 +469,7 @@
   return {
     getTag: typeNameInChrome,
     getUnknownTag: isBrowser ? getUnknownTagGenericBrowser : getUnknownTag,
+    prototypeForTag: prototypeForTag,
     discriminator: discriminator };
 }''');
 
@@ -544,7 +562,15 @@
     return tag;
   }
 
+  function prototypeForTagIE(tag) {
+    if (tag == "Document") return null;  // Do not pre-patch Document.
+    var constructor = window[tag];
+    if (constructor == null) return null;
+    return constructor.prototype;
+  }
+
   hooks.getTag = getTagIE;
+  hooks.prototypeForTag = prototypeForTagIE;
 }''');
 
 
diff --git a/sdk/lib/_internal/pub/lib/src/barback.dart b/sdk/lib/_internal/pub/lib/src/barback.dart
index 84a069a..7e317f63 100644
--- a/sdk/lib/_internal/pub/lib/src/barback.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback.dart
@@ -23,11 +23,10 @@
 /// It's possible that the library identified by [this] defines multiple
 /// transformers. If so, [configuration] will be passed to all of them.
 class TransformerId {
-  /// The package containing the library that this transformer identifies.
+  /// The package containing the library where the transformer is defined.
   final String package;
 
-  /// The `/`-separated path identifying the library that contains this
-  /// transformer.
+  /// The `/`-separated path to the library that contains this transformer.
   ///
   /// This is relative to the `lib/` directory in [package], and doesn't end in
   /// `.dart`.
@@ -108,7 +107,8 @@
 /// monitor the app and its dependencies for any updates. Otherwise the state of
 /// the app when the server is started will be maintained.
 Future<BarbackServer> createServer(String host, int port, PackageGraph graph,
-    {Iterable<Transformer> builtInTransformers, bool watchForUpdates: true}) {
+    BarbackMode mode, {Iterable<Transformer> builtInTransformers,
+    bool watchForUpdates: true}) {
   var provider = new PubPackageProvider(graph);
   var barback = new Barback(provider);
 
@@ -140,7 +140,7 @@
         })
       ];
 
-      loadAllTransformers(server, graph, builtInTransformers).then((_) {
+      loadAllTransformers(server, graph, mode, builtInTransformers).then((_) {
         if (!completer.isCompleted) completer.complete(server);
       }).catchError((error, stackTrace) {
         if (!completer.isCompleted) completer.completeError(error, stackTrace);
@@ -302,4 +302,4 @@
       log.message("$prefix\n$message");
       break;
   }
-}
\ No newline at end of file
+}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
index ff9f1ac..ed36c55 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart
@@ -23,7 +23,7 @@
 /// Any [builtInTransformers] that are provided will automatically be added to
 /// the end of every package's cascade.
 Future loadAllTransformers(BarbackServer server, PackageGraph graph,
-                           [Iterable<Transformer> builtInTransformers]) {
+    BarbackMode mode, Iterable<Transformer> builtInTransformers) {
   // In order to determine in what order we should load transformers, we need to
   // know which transformers depend on which others. This is different than
   // normal package dependencies. Let's begin with some terminology:
@@ -62,7 +62,7 @@
   var orderingDeps = _computeOrderingDeps(graph);
   var packageTransformers = _computePackageTransformers(graph);
 
-  var loader = new _TransformerLoader(server, graph);
+  var loader = new _TransformerLoader(server, mode, graph);
 
   // The packages on which no packages have ordering dependencies -- that is,
   // the packages that don't need to be loaded before any other packages. These
@@ -206,6 +206,9 @@
 class _TransformerLoader {
   final BarbackServer _server;
 
+  /// The mode that pub is running barback in.
+  final BarbackMode _mode;
+
   /// The loaded transformers defined in the library identified by each
   /// transformer id.
   final _transformers = new Map<TransformerId, Set<Transformer>>();
@@ -215,7 +218,7 @@
   /// Used for error reporting.
   final _transformerUsers = new Map<Pair<String, String>, Set<String>>();
 
-  _TransformerLoader(this._server, PackageGraph graph) {
+  _TransformerLoader(this._server, this._mode, PackageGraph graph) {
     for (var package in graph.packages.values) {
       for (var id in unionAll(package.pubspec.transformers)) {
         _transformerUsers.putIfAbsent(
@@ -235,7 +238,7 @@
 
     // TODO(nweiz): load multiple instances of the same transformer from the
     // same isolate rather than spinning up a separate isolate for each one.
-    return loadTransformers(_server, id).then((transformers) {
+    return loadTransformers(_server, _mode, id).then((transformers) {
       if (!transformers.isEmpty) {
         _transformers[id] = transformers;
         return;
diff --git a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
index 2552b09..38938be 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/load_transformers.dart
@@ -39,7 +39,8 @@
     _respond(wrappedMessage, (message) {
       var library = Uri.parse(message['library']);
       var configuration = JSON.decode(message['configuration']);
-      return initialize(library, configuration).
+      var mode = new BarbackMode(message['mode']);
+      return initialize(library, configuration, mode).
           map(_serializeTransformerOrGroup).toList();
     });
   });
@@ -48,9 +49,8 @@
 /// Loads all the transformers and groups defined in [uri].
 ///
 /// Loads the library, finds any Transformer or TransformerGroup subclasses in
-/// it, instantiates them (with [configuration] if it's non-null), and returns
-/// them.
-Iterable initialize(Uri uri, Map configuration) {
+/// it, instantiates them with [configuration] and [mode], and returns them.
+Iterable initialize(Uri uri, Map configuration, BarbackMode mode) {
   var mirrors = currentMirrorSystem();
   var transformerClass = reflectClass(Transformer);
   var groupClass = reflectClass(TransformerGroup);
@@ -77,10 +77,8 @@
     // to an empty map.
     if (configuration == null) configuration = {};
 
-    // TODO(nweiz): if the constructor accepts named parameters, automatically
-    // destructure the configuration map.
-    return classMirror.newInstance(const Symbol('asPlugin'), [configuration])
-        .reflectee;
+    return classMirror.newInstance(const Symbol('asPlugin'),
+        [new BarbackSettings(configuration, mode)]).reflectee;
   }).where((classMirror) => classMirror != null);
 }
 
@@ -444,7 +442,8 @@
 /// [id].
 ///
 /// [server] is used to serve any Dart files needed to load the transformers.
-Future<Set> loadTransformers(BarbackServer server, TransformerId id) {
+Future<Set> loadTransformers(BarbackServer server, BarbackMode mode,
+    TransformerId id) {
   return id.getAssetId(server.barback).then((assetId) {
     var path = assetId.path.replaceFirst('lib/', '');
     // TODO(nweiz): load from a "package:" URI when issue 12474 is fixed.
@@ -460,6 +459,7 @@
         .then((sendPort) {
       return _call(sendPort, {
         'library': uri,
+        'mode': mode.name,
         // TODO(nweiz): support non-JSON-encodable configuration maps.
         'configuration': JSON.encode(id.configuration)
       }).then((transformers) {
@@ -552,7 +552,7 @@
 
       if (message['type'] == 'addOutput') {
         transform.addOutput(_deserializeAsset(message['output']));
-        return;
+        return null;
       }
 
       assert(message['type'] == 'log');
diff --git a/sdk/lib/_internal/pub/lib/src/command/build.dart b/sdk/lib/_internal/pub/lib/src/command/build.dart
index 93dee74..12dccf0 100644
--- a/sdk/lib/_internal/pub/lib/src/command/build.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/build.dart
@@ -58,7 +58,8 @@
       // Since this server will only be hit by the transformer loader and isn't
       // user-facing, just use an IPv4 address to avoid a weird bug on the
       // OS X buildbots.
-      return barback.createServer("127.0.0.1", 0, graph,
+      // TODO(rnystrom): Allow specifying mode.
+      return barback.createServer("127.0.0.1", 0, graph, BarbackMode.RELEASE,
           builtInTransformers: [dart2jsTransformer],
           watchForUpdates: false);
     }).then((server) {
diff --git a/sdk/lib/_internal/pub/lib/src/command/serve.dart b/sdk/lib/_internal/pub/lib/src/command/serve.dart
index 0d7adfc..d3df35a 100644
--- a/sdk/lib/_internal/pub/lib/src/command/serve.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/serve.dart
@@ -6,6 +6,8 @@
 
 import 'dart:async';
 
+import 'package:barback/barback.dart';
+
 import '../barback/dart_forwarding_transformer.dart';
 import '../barback/dart2js_transformer.dart';
 import '../barback/pub_package_provider.dart';
@@ -75,7 +77,8 @@
         ];
       }
 
-      return barback.createServer(hostname, port, graph,
+      // TODO(rnystrom): Allow specifying other modes.
+      return barback.createServer(hostname, port, graph, BarbackMode.DEBUG,
           builtInTransformers: builtInTransformers);
     }).then((server) {
       /// This completer is used to keep pub running (by not completing) and
diff --git a/sdk/lib/_internal/pub/test/serve/utils.dart b/sdk/lib/_internal/pub/test/serve/utils.dart
index 1013aec..eb412a7 100644
--- a/sdk/lib/_internal/pub/test/serve/utils.dart
+++ b/sdk/lib/_internal/pub/test/serve/utils.dart
@@ -187,7 +187,7 @@
 void waitForBuildSuccess() {
   nextLine() {
     return _pubServer.nextLine().then((line) {
-      if (line.contains("successfully")) return;
+      if (line.contains("successfully")) return null;
 
       // This line wasn't it, so ignore it and keep trying.
       return nextLine();
diff --git a/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart b/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart
index e842245..e2f0511 100644
--- a/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/configuration/configuration_defaults_to_empty_map_test.dart
@@ -17,16 +17,17 @@
 import 'package:barback/barback.dart';
 
 class ConfigTransformer extends Transformer {
-  final Map configuration;
+  final BarbackSettings settings;
 
-  ConfigTransformer.asPlugin(this.configuration);
+  ConfigTransformer.asPlugin(this.settings);
 
   String get allowedExtensions => '.txt';
 
   Future apply(Transform transform) {
     return transform.primaryInput.readAsString().then((contents) {
       var id = transform.primaryInput.id.changeExtension(".json");
-      transform.addOutput(new Asset.fromString(id, JSON.encode(configuration)));
+      transform.addOutput(
+          new Asset.fromString(id, JSON.encode(settings.configuration)));
     });
   }
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart b/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart
index 321dc3d..1a040b6 100644
--- a/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/configuration/passes_configuration_to_a_transformer_test.dart
@@ -17,16 +17,17 @@
 import 'package:barback/barback.dart';
 
 class ConfigTransformer extends Transformer {
-  final Map configuration;
+  final BarbackSettings settings;
 
-  ConfigTransformer.asPlugin(this.configuration);
+  ConfigTransformer.asPlugin(this.settings);
 
   String get allowedExtensions => '.txt';
 
   Future apply(Transform transform) {
     return transform.primaryInput.readAsString().then((contents) {
       var id = transform.primaryInput.id.changeExtension(".json");
-      transform.addOutput(new Asset.fromString(id, JSON.encode(configuration)));
+      transform.addOutput(
+        new Asset.fromString(id, JSON.encode(settings.configuration)));
     });
   }
 }
diff --git a/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart b/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart
index 36e7d47..3f0a195 100644
--- a/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/configuration/with_configuration_only_instantiates_configurable_transformers_test.dart
@@ -17,16 +17,17 @@
 import 'package:barback/barback.dart';
 
 class ConfigTransformer extends Transformer {
-  final Map configuration;
+  final BarbackSettings settings;
 
-  ConfigTransformer.asPlugin(this.configuration);
+  ConfigTransformer.asPlugin(this.settings);
 
   String get allowedExtensions => '.txt';
 
   Future apply(Transform transform) {
     return transform.primaryInput.readAsString().then((contents) {
       var id = transform.primaryInput.id.changeExtension(".json");
-      transform.addOutput(new Asset.fromString(id, JSON.encode(configuration)));
+      transform.addOutput(
+          new Asset.fromString(id, JSON.encode(settings.configuration)));
     });
   }
 }
@@ -71,4 +72,4 @@
     requestShould404("foo.out");
     endPubServe();
   });
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart b/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
index 9bf0185..350a58c 100644
--- a/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
+++ b/sdk/lib/_internal/pub/test/transformer/fails_to_load_an_unconfigurable_transformer_when_config_is_passed_test.dart
@@ -32,4 +32,4 @@
         'accept configuration were defined in ')));
     pub.shouldExit(1);
   });
-}
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_debug_in_serve_test.dart b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_debug_in_serve_test.dart
new file mode 100644
index 0000000..f45b8da
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_debug_in_serve_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import 'dart:convert';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import '../serve/utils.dart';
+
+final transformer = """
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:barback/barback.dart';
+
+class ModeTransformer extends Transformer {
+  final BarbackSettings settings;
+
+  ModeTransformer.asPlugin(this.settings);
+
+  String get allowedExtensions => '.txt';
+
+  Future apply(Transform transform) {
+    return transform.primaryInput.readAsString().then((contents) {
+      transform.addOutput(
+          new Asset.fromString(transform.primaryInput.id, settings.mode.name));
+    });
+  }
+}
+""";
+
+main() {
+  initConfig();
+  integration("mode defaults to 'debug' in pub serve", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": ["myapp/src/transformer"]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", transformer)
+      ])]),
+      d.dir("web", [
+        d.file("foo.txt", "foo")
+      ])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    var server = startPubServe();
+    requestShouldSucceed("foo.txt", "debug");
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_release_in_build_test.dart b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_release_in_build_test.dart
new file mode 100644
index 0000000..5109c82
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/mode_defaults_to_release_in_build_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS d.file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library pub_tests;
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+
+final transformer = """
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+
+class ModeTransformer extends Transformer {
+  final BarbackSettings settings;
+
+  ModeTransformer.asPlugin(this.settings);
+
+  String get allowedExtensions => '.txt';
+
+  Future apply(Transform transform) {
+    return transform.primaryInput.readAsString().then((contents) {
+      transform.addOutput(
+          new Asset.fromString(transform.primaryInput.id, settings.mode.name));
+    });
+  }
+}
+""";
+
+main() {
+  initConfig();
+  integration("mode defaults to 'release' in pub build", () {
+    d.dir(appPath, [
+      d.pubspec({
+        "name": "myapp",
+        "transformers": ["myapp/src/transformer"]
+      }),
+      d.dir("lib", [d.dir("src", [
+        d.file("transformer.dart", transformer)
+      ])]),
+      d.dir("web", [
+        d.file("foo.txt", "foo")
+      ])
+    ]).create();
+
+    createLockFile('myapp', pkg: ['barback']);
+
+    schedulePub(args: ["build"],
+        output: new RegExp(r"Built 1 file!"),
+        exitCode: 0);
+
+    d.dir(appPath, [
+      d.dir('build', [
+        d.file('foo.txt', 'release')
+      ])
+    ]).validate();
+  });
+}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index d0f39fb..e299eb0 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -67,8 +67,8 @@
         controller.add(value);
         controller.close();
       },
-      onError: (error) {
-        controller.addError(error);
+      onError: (error, stackTrace) {
+        controller.addError(error, stackTrace);
         controller.close();
       });
     return controller.stream;
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index d86a993..685e682 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -656,7 +656,7 @@
   _StreamSinkWrapper(this._target);
   void add(T data) { _target.add(data); }
   void addError(Object error, [StackTrace stackTrace]) {
-    _target.addError(error);
+    _target.addError(error, stackTrace);
   }
   Future close() => _target.close();
   Future addStream(Stream<T> source) => _target.addStream(source);
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 75f232e..efac7ac 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -86,7 +86,7 @@
    *
    * The default [reviver] (when not provided) is the identity function.
    */
-  Object decode(String source, {reviver(var key, var value)}) {
+  dynamic decode(String source, {reviver(var key, var value)}) {
     if (reviver == null) return decoder.convert(source);
     return new JsonDecoder(reviver).convert(source);
   }
@@ -102,7 +102,7 @@
    * If [toEncodable] is omitted, it defaults to calling `.toJson()` on the
    * unencodable object.
    */
-  Object encode(Object value, {toEncodable(var object)}) {
+  String encode(Object value, {toEncodable(var object)}) {
     if (toEncodable == null) return encoder.convert(value);
     return new JsonEncoder(toEncodable).convert(value);
   }
@@ -117,7 +117,7 @@
   final _Reviver _reviver;
   _ReviverJsonCodec(this._reviver);
 
-  Object decode(String source, {reviver(var key, var value)}) {
+  dynamic decode(String source, {reviver(var key, var value)}) {
     if (reviver == null) reviver = _reviver;
     return new JsonDecoder(reviver).convert(source);
   }
@@ -256,7 +256,7 @@
    *
    * Throws [FormatException] if the input is not valid JSON text.
    */
-  Object convert(String input) => _parseJson(input, _reviver);
+  dynamic convert(String input) => _parseJson(input, _reviver);
 
   /**
    * Starts a conversion from a chunked JSON string to its corresponding
diff --git a/sdk/lib/core/annotations.dart b/sdk/lib/core/annotations.dart
index f7c412c..68ba572 100644
--- a/sdk/lib/core/annotations.dart
+++ b/sdk/lib/core/annotations.dart
@@ -79,7 +79,7 @@
 /**
  * Marks a feature as [Deprecated] until the next release.
  */
-const deprecated = const Deprecated("next release");
+const Deprecated deprecated = const Deprecated("next release");
 
 /*
  * The annotation `@override` marks an instance member as overriding a
@@ -106,7 +106,7 @@
  * For example, the annotation is intentionally not used in the Dart platform
  * libraries, since they only depend on themselves.
  */
-const override = const _Override();
+const Object override = const _Override();
 
 class _Proxy {
   const _Proxy();
@@ -130,4 +130,4 @@
  * The intent of the `@proxy` notation is to avoid irrelevant warnings when
  * a class implements its interface through `noSuchMethod`.
  */
-const proxy = const _Proxy();
+const Object proxy = const _Proxy();
diff --git a/sdk/lib/core/bool.dart b/sdk/lib/core/bool.dart
index c4348b7..8150219 100644
--- a/sdk/lib/core/bool.dart
+++ b/sdk/lib/core/bool.dart
@@ -13,10 +13,25 @@
  */
 class bool {
   /**
-   * Returns the boolean for the given environment variable [name] or
-   * [defaultValue] if [name] is not present.
+   * Returns the boolean value of the environment declaration [name].
+   *
+   * The boolean value of the declaration is `true` if the declared value is
+   * the string `"true"`, and `false` if the value is `"false"`.
+   *
+   * In all other cases, including when there is no declaration for `name`,
+   * the result is the [defaultValue].
+   *
+   * Example:
+   *
+   *     const loggingFlag = const bool.fromEnvironment("logging");
+   *
+   * If you want to use a different truth-string, you can use the
+   * [String.fromEnvironment] constructor directly:
+   *
+   *     const isLoggingOn = (const String.fromEnvironment("logging") == "on");
    */
-  external const factory bool.fromEnvironment(String name, {bool defaultValue});
+  external const factory bool.fromEnvironment(String name,
+                                              {bool defaultValue: false});
 
   /**
    * Returns [:"true":] if the receiver is [:true:], or [:"false":] if the
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 1c17a31..c06a3ee 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -19,6 +19,20 @@
  */
 abstract class int extends num {
   /**
+   * Returns the integer value of the given environment declaration [name].
+   *
+   * The result is the same as would be returned by:
+   *
+   *     int.parse(const String.fromEnvironment(name, defaultValue: ""),
+   *               (_) => defaultValue)
+   *
+   * Example:
+   *
+   *     const int.fromEnvironment("defaultPort", defaultValue: 80)
+   */
+  external const factory int.fromEnvironment(String name, {int defaultValue});
+
+  /**
    * Bit-wise and operator.
    *
    * Treating both `this` and [other] as sufficiently large two's component
@@ -252,12 +266,4 @@
   external static int parse(String source,
                             { int radix,
                               int onError(String source) });
-
-  /**
-   * Returns the integer value for the given environment variable
-   * [name] or [defaultValue] if [name] is not present. If the value
-   * of the environment variable is not a valid integer literal a
-   * [FormatException] is thrown.
-   */
-  external const factory int.fromEnvironment(String name, {int defaultValue});
 }
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index 8da434e..799a2a9 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -125,8 +125,22 @@
   }
 
   /**
-   * Returns the string for the given environment variable [name] or
-   * [defaultValue] if [name] is not present.
+   * Returns the string value of the environment declaration [name].
+   *
+   * Environment declarations are provided by the surrounding system compiling
+   * or running the Dart program. Declarations map a string key to a string
+   * value.
+   *
+   * If [name] is not declared in the environment, the result is instead
+   * [defaultValue].
+   *
+   * Example of getting a value:
+   *
+   *     const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
+   *
+   * Example of checking whether a declaration is there at all:
+   *
+   *     var isDeclared = const String.fromEnvironment("maybeDeclared") != null;
    */
   external const factory String.fromEnvironment(String name,
                                                 {String defaultValue});
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 62b96f2..3a6983a 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -12601,37 +12601,58 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * A utility for retrieving data from a URL.
- *
- * HttpRequest can be used to obtain data from http, ftp, and file
- * protocols.
- *
- * For example, suppose we're developing these API docs, and we
- * wish to retrieve the HTML of the top-level page and print it out.
- * The easiest way to do that would be:
- *
- *     HttpRequest.getString('http://api.dartlang.org').then((response) {
- *       print(response);
- *     });
- *
- * **Important**: With the default behavior of this class, your
- * code making the request should be served from the same origin (domain name,
- * port, and application layer protocol) as the URL you are trying to access
- * with HttpRequest. However, there are ways to
- * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#note-on-jsonp).
- *
- * See also:
- *
- * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
- * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
- * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ /**
+  * A client-side XHR request for getting data from a URL,
+  * formally known as XMLHttpRequest.
+  *
+  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+  * and is useful for AJAX-style page updates.
+  *
+  * The simplest way to get the contents of a text file, such as a
+  * JSON-formatted file, is with [getString].
+  * For example, the following code gets the contents of a JSON file
+  * and prints its length:
+  *
+  *     var path = 'myData.json';
+  *     HttpRequest.getString(path)
+  *         .then((String fileContents) {
+  *           print(fileContents.length);
+  *         })
+  *         .catchError((Error error) {
+  *           print(error.toString());
+  *         });
+  *
+  * ## Fetching data from other servers
+  *
+  * For security reasons, browsers impose restrictions on requests
+  * made by embedded apps.
+  * With the default behavior of this class,
+  * the code making the request must be served from the same origin
+  * (domain name, port, and application layer protocol)
+  * as the requested resource.
+  * In the example above, the myData.json file must be co-located with the
+  * app that uses it.
+  * You might be able to
+  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+  * by using CORS headers or JSONP.
+  *
+  * ## Other resources
+  *
+  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+  * a tutorial from _A Game of Darts_,
+  * shows two different ways to use HttpRequest to get a JSON file.
+  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+  * another tutorial from _A Game of Darts_,
+  * shows using HttpRequest with a custom server.
+  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
  */
 @DomName('XMLHttpRequest')
 class HttpRequest extends HttpRequestEventTarget native "XMLHttpRequest" {
 
   /**
-   * Creates a URL get request for the specified [url].
+   * Creates a GET request for the specified [url].
    *
    * The server response must be a `text/` mime type for this request to
    * succeed.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 302dad6..51bfff9 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -13142,37 +13142,58 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-/**
- * A utility for retrieving data from a URL.
- *
- * HttpRequest can be used to obtain data from http, ftp, and file
- * protocols.
- *
- * For example, suppose we're developing these API docs, and we
- * wish to retrieve the HTML of the top-level page and print it out.
- * The easiest way to do that would be:
- *
- *     HttpRequest.getString('http://api.dartlang.org').then((response) {
- *       print(response);
- *     });
- *
- * **Important**: With the default behavior of this class, your
- * code making the request should be served from the same origin (domain name,
- * port, and application layer protocol) as the URL you are trying to access
- * with HttpRequest. However, there are ways to
- * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#note-on-jsonp).
- *
- * See also:
- *
- * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
- * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
- * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ /**
+  * A client-side XHR request for getting data from a URL,
+  * formally known as XMLHttpRequest.
+  *
+  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+  * and is useful for AJAX-style page updates.
+  *
+  * The simplest way to get the contents of a text file, such as a
+  * JSON-formatted file, is with [getString].
+  * For example, the following code gets the contents of a JSON file
+  * and prints its length:
+  *
+  *     var path = 'myData.json';
+  *     HttpRequest.getString(path)
+  *         .then((String fileContents) {
+  *           print(fileContents.length);
+  *         })
+  *         .catchError((Error error) {
+  *           print(error.toString());
+  *         });
+  *
+  * ## Fetching data from other servers
+  *
+  * For security reasons, browsers impose restrictions on requests
+  * made by embedded apps.
+  * With the default behavior of this class,
+  * the code making the request must be served from the same origin
+  * (domain name, port, and application layer protocol)
+  * as the requested resource.
+  * In the example above, the myData.json file must be co-located with the
+  * app that uses it.
+  * You might be able to
+  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+  * by using CORS headers or JSONP.
+  *
+  * ## Other resources
+  *
+  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+  * a tutorial from _A Game of Darts_,
+  * shows two different ways to use HttpRequest to get a JSON file.
+  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+  * another tutorial from _A Game of Darts_,
+  * shows using HttpRequest with a custom server.
+  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
  */
 @DomName('XMLHttpRequest')
 class HttpRequest extends HttpRequestEventTarget {
 
   /**
-   * Creates a URL get request for the specified [url].
+   * Creates a GET request for the specified [url].
    *
    * The server response must be a `text/` mime type for this request to
    * succeed.
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 12375dd..1063952 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -539,20 +539,7 @@
                        [Map<Symbol, dynamic> namedArguments]);
 
   /**
-   * Looks up the value of a name in the scope of the closure. The
-   * result is a mirror on that value.
-   *
-   * Let *s* be the contents of the string used to construct the symbol [name].
-   *
-   * If the expression *s* occurs within the source code of the reflectee,
-   * and if any such occurrence refers to a declaration outside the reflectee,
-   * then let *v* be the result of evaluating the expression *s* at such
-   * an occurrence.
-   * If *s = this*, and the reflectee was defined within the instance scope of
-   * an object *o*, then let *v* be *o*.
-   *
-   * The returned value is the result of invoking the method [reflect] on
-   * *v*.
+   * Not yet supported. Calling this method throws an [UnsupportedError].
    */
   InstanceMirror findInContext(Symbol name, {ifAbsent: null});
 }
diff --git a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
index 57c371e..e354001 100644
--- a/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
+++ b/sdk/lib/typed_data/dart2js/typed_data_dart2js.dart
@@ -1097,7 +1097,7 @@
     return mx | my << 1 | mz << 2 | mw << 3;
   }
 
-  /// Mask passed to [shuffle].
+  /// Mask passed to [shuffle] and [shuffleMix].
   static const int XXXX = 0x0;
   static const int XXXY = 0x40;
   static const int XXXZ = 0x80;
@@ -1357,7 +1357,7 @@
 
   /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
   Float32x4 shuffle(int m) {
-    if (m < 0 || m > 255) {
+    if ((m < 0) || (m > 255)) {
       throw new RangeError('mask $m must be in the range [0..256)');
     }
     double _x = _storage[m & 0x3];
@@ -1367,53 +1367,17 @@
     return new Float32x4(_x, _y, _z, _w);
   }
 
-  /// Returns a new [Float32x4] with values in the X and Y lanes
-  /// replaced with the values in the Z and W lanes of [other].
-  Float32x4 withZWInXY(Float32x4 other) {
-    double _x = other._storage[2];
-    double _y = other._storage[3];
-    double _z = _storage[2];
-    double _w = _storage[3];
-    return new Float32x4(_x, _y, _z, _w);
-  }
-
-  /// Returns a new [Float32x4] with the X and Y lane values
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveXY(Float32x4 other) {
-    double _x = _storage[0];
-    double _y = other._storage[0];
-    double _z = _storage[1];
-    double _w = other._storage[1];
-    return new Float32x4(_x, _y, _z, _w);
-  }
-
-  /// Returns a new [Float32x4] with the Z and W lane values
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveZW(Float32x4 other) {
-    double _x = _storage[2];
-    double _y = other._storage[2];
-    double _z = _storage[3];
-    double _w = other._storage[3];
-    return new Float32x4(_x, _y, _z, _w);
-  }
-
-  /// Returns a new [Float32x4] with the X and Y lane value pairs
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveXYPairs(Float32x4 other) {
-    double _x = _storage[0];
-    double _y = _storage[1];
-    double _z = other._storage[0];
-    double _w = other._storage[1];
-    return new Float32x4(_x, _y, _z, _w);
-  }
-
-  /// Returns a new [Float32x4] with the Z and W lane value pairs
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveZWPairs(Float32x4 other) {
-    double _x = _storage[2];
-    double _y = _storage[3];
-    double _z = other._storage[2];
-    double _w = other._storage[3];
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Float32x4 shuffleMix(Float32x4 other, int m) {
+    if ((m < 0) || (m > 255)) {
+      throw new RangeError('mask $m must be in the range [0..256)');
+    }
+    double _x = _storage[m & 0x3];
+    double _y = _storage[(m >> 2) & 0x3];
+    double _z = other._storage[(m >> 4) & 0x3];
+    double _w = other._storage[(m >> 6) & 0x3];
     return new Float32x4(_x, _y, _z, _w);
   }
 
@@ -1597,6 +1561,290 @@
     return mx | my << 1 | mz << 2 | mw << 3;
   }
 
+  /// Mask passed to [shuffle] and [shuffleMix].
+  static const int XXXX = 0x0;
+  static const int XXXY = 0x40;
+  static const int XXXZ = 0x80;
+  static const int XXXW = 0xC0;
+  static const int XXYX = 0x10;
+  static const int XXYY = 0x50;
+  static const int XXYZ = 0x90;
+  static const int XXYW = 0xD0;
+  static const int XXZX = 0x20;
+  static const int XXZY = 0x60;
+  static const int XXZZ = 0xA0;
+  static const int XXZW = 0xE0;
+  static const int XXWX = 0x30;
+  static const int XXWY = 0x70;
+  static const int XXWZ = 0xB0;
+  static const int XXWW = 0xF0;
+  static const int XYXX = 0x4;
+  static const int XYXY = 0x44;
+  static const int XYXZ = 0x84;
+  static const int XYXW = 0xC4;
+  static const int XYYX = 0x14;
+  static const int XYYY = 0x54;
+  static const int XYYZ = 0x94;
+  static const int XYYW = 0xD4;
+  static const int XYZX = 0x24;
+  static const int XYZY = 0x64;
+  static const int XYZZ = 0xA4;
+  static const int XYZW = 0xE4;
+  static const int XYWX = 0x34;
+  static const int XYWY = 0x74;
+  static const int XYWZ = 0xB4;
+  static const int XYWW = 0xF4;
+  static const int XZXX = 0x8;
+  static const int XZXY = 0x48;
+  static const int XZXZ = 0x88;
+  static const int XZXW = 0xC8;
+  static const int XZYX = 0x18;
+  static const int XZYY = 0x58;
+  static const int XZYZ = 0x98;
+  static const int XZYW = 0xD8;
+  static const int XZZX = 0x28;
+  static const int XZZY = 0x68;
+  static const int XZZZ = 0xA8;
+  static const int XZZW = 0xE8;
+  static const int XZWX = 0x38;
+  static const int XZWY = 0x78;
+  static const int XZWZ = 0xB8;
+  static const int XZWW = 0xF8;
+  static const int XWXX = 0xC;
+  static const int XWXY = 0x4C;
+  static const int XWXZ = 0x8C;
+  static const int XWXW = 0xCC;
+  static const int XWYX = 0x1C;
+  static const int XWYY = 0x5C;
+  static const int XWYZ = 0x9C;
+  static const int XWYW = 0xDC;
+  static const int XWZX = 0x2C;
+  static const int XWZY = 0x6C;
+  static const int XWZZ = 0xAC;
+  static const int XWZW = 0xEC;
+  static const int XWWX = 0x3C;
+  static const int XWWY = 0x7C;
+  static const int XWWZ = 0xBC;
+  static const int XWWW = 0xFC;
+  static const int YXXX = 0x1;
+  static const int YXXY = 0x41;
+  static const int YXXZ = 0x81;
+  static const int YXXW = 0xC1;
+  static const int YXYX = 0x11;
+  static const int YXYY = 0x51;
+  static const int YXYZ = 0x91;
+  static const int YXYW = 0xD1;
+  static const int YXZX = 0x21;
+  static const int YXZY = 0x61;
+  static const int YXZZ = 0xA1;
+  static const int YXZW = 0xE1;
+  static const int YXWX = 0x31;
+  static const int YXWY = 0x71;
+  static const int YXWZ = 0xB1;
+  static const int YXWW = 0xF1;
+  static const int YYXX = 0x5;
+  static const int YYXY = 0x45;
+  static const int YYXZ = 0x85;
+  static const int YYXW = 0xC5;
+  static const int YYYX = 0x15;
+  static const int YYYY = 0x55;
+  static const int YYYZ = 0x95;
+  static const int YYYW = 0xD5;
+  static const int YYZX = 0x25;
+  static const int YYZY = 0x65;
+  static const int YYZZ = 0xA5;
+  static const int YYZW = 0xE5;
+  static const int YYWX = 0x35;
+  static const int YYWY = 0x75;
+  static const int YYWZ = 0xB5;
+  static const int YYWW = 0xF5;
+  static const int YZXX = 0x9;
+  static const int YZXY = 0x49;
+  static const int YZXZ = 0x89;
+  static const int YZXW = 0xC9;
+  static const int YZYX = 0x19;
+  static const int YZYY = 0x59;
+  static const int YZYZ = 0x99;
+  static const int YZYW = 0xD9;
+  static const int YZZX = 0x29;
+  static const int YZZY = 0x69;
+  static const int YZZZ = 0xA9;
+  static const int YZZW = 0xE9;
+  static const int YZWX = 0x39;
+  static const int YZWY = 0x79;
+  static const int YZWZ = 0xB9;
+  static const int YZWW = 0xF9;
+  static const int YWXX = 0xD;
+  static const int YWXY = 0x4D;
+  static const int YWXZ = 0x8D;
+  static const int YWXW = 0xCD;
+  static const int YWYX = 0x1D;
+  static const int YWYY = 0x5D;
+  static const int YWYZ = 0x9D;
+  static const int YWYW = 0xDD;
+  static const int YWZX = 0x2D;
+  static const int YWZY = 0x6D;
+  static const int YWZZ = 0xAD;
+  static const int YWZW = 0xED;
+  static const int YWWX = 0x3D;
+  static const int YWWY = 0x7D;
+  static const int YWWZ = 0xBD;
+  static const int YWWW = 0xFD;
+  static const int ZXXX = 0x2;
+  static const int ZXXY = 0x42;
+  static const int ZXXZ = 0x82;
+  static const int ZXXW = 0xC2;
+  static const int ZXYX = 0x12;
+  static const int ZXYY = 0x52;
+  static const int ZXYZ = 0x92;
+  static const int ZXYW = 0xD2;
+  static const int ZXZX = 0x22;
+  static const int ZXZY = 0x62;
+  static const int ZXZZ = 0xA2;
+  static const int ZXZW = 0xE2;
+  static const int ZXWX = 0x32;
+  static const int ZXWY = 0x72;
+  static const int ZXWZ = 0xB2;
+  static const int ZXWW = 0xF2;
+  static const int ZYXX = 0x6;
+  static const int ZYXY = 0x46;
+  static const int ZYXZ = 0x86;
+  static const int ZYXW = 0xC6;
+  static const int ZYYX = 0x16;
+  static const int ZYYY = 0x56;
+  static const int ZYYZ = 0x96;
+  static const int ZYYW = 0xD6;
+  static const int ZYZX = 0x26;
+  static const int ZYZY = 0x66;
+  static const int ZYZZ = 0xA6;
+  static const int ZYZW = 0xE6;
+  static const int ZYWX = 0x36;
+  static const int ZYWY = 0x76;
+  static const int ZYWZ = 0xB6;
+  static const int ZYWW = 0xF6;
+  static const int ZZXX = 0xA;
+  static const int ZZXY = 0x4A;
+  static const int ZZXZ = 0x8A;
+  static const int ZZXW = 0xCA;
+  static const int ZZYX = 0x1A;
+  static const int ZZYY = 0x5A;
+  static const int ZZYZ = 0x9A;
+  static const int ZZYW = 0xDA;
+  static const int ZZZX = 0x2A;
+  static const int ZZZY = 0x6A;
+  static const int ZZZZ = 0xAA;
+  static const int ZZZW = 0xEA;
+  static const int ZZWX = 0x3A;
+  static const int ZZWY = 0x7A;
+  static const int ZZWZ = 0xBA;
+  static const int ZZWW = 0xFA;
+  static const int ZWXX = 0xE;
+  static const int ZWXY = 0x4E;
+  static const int ZWXZ = 0x8E;
+  static const int ZWXW = 0xCE;
+  static const int ZWYX = 0x1E;
+  static const int ZWYY = 0x5E;
+  static const int ZWYZ = 0x9E;
+  static const int ZWYW = 0xDE;
+  static const int ZWZX = 0x2E;
+  static const int ZWZY = 0x6E;
+  static const int ZWZZ = 0xAE;
+  static const int ZWZW = 0xEE;
+  static const int ZWWX = 0x3E;
+  static const int ZWWY = 0x7E;
+  static const int ZWWZ = 0xBE;
+  static const int ZWWW = 0xFE;
+  static const int WXXX = 0x3;
+  static const int WXXY = 0x43;
+  static const int WXXZ = 0x83;
+  static const int WXXW = 0xC3;
+  static const int WXYX = 0x13;
+  static const int WXYY = 0x53;
+  static const int WXYZ = 0x93;
+  static const int WXYW = 0xD3;
+  static const int WXZX = 0x23;
+  static const int WXZY = 0x63;
+  static const int WXZZ = 0xA3;
+  static const int WXZW = 0xE3;
+  static const int WXWX = 0x33;
+  static const int WXWY = 0x73;
+  static const int WXWZ = 0xB3;
+  static const int WXWW = 0xF3;
+  static const int WYXX = 0x7;
+  static const int WYXY = 0x47;
+  static const int WYXZ = 0x87;
+  static const int WYXW = 0xC7;
+  static const int WYYX = 0x17;
+  static const int WYYY = 0x57;
+  static const int WYYZ = 0x97;
+  static const int WYYW = 0xD7;
+  static const int WYZX = 0x27;
+  static const int WYZY = 0x67;
+  static const int WYZZ = 0xA7;
+  static const int WYZW = 0xE7;
+  static const int WYWX = 0x37;
+  static const int WYWY = 0x77;
+  static const int WYWZ = 0xB7;
+  static const int WYWW = 0xF7;
+  static const int WZXX = 0xB;
+  static const int WZXY = 0x4B;
+  static const int WZXZ = 0x8B;
+  static const int WZXW = 0xCB;
+  static const int WZYX = 0x1B;
+  static const int WZYY = 0x5B;
+  static const int WZYZ = 0x9B;
+  static const int WZYW = 0xDB;
+  static const int WZZX = 0x2B;
+  static const int WZZY = 0x6B;
+  static const int WZZZ = 0xAB;
+  static const int WZZW = 0xEB;
+  static const int WZWX = 0x3B;
+  static const int WZWY = 0x7B;
+  static const int WZWZ = 0xBB;
+  static const int WZWW = 0xFB;
+  static const int WWXX = 0xF;
+  static const int WWXY = 0x4F;
+  static const int WWXZ = 0x8F;
+  static const int WWXW = 0xCF;
+  static const int WWYX = 0x1F;
+  static const int WWYY = 0x5F;
+  static const int WWYZ = 0x9F;
+  static const int WWYW = 0xDF;
+  static const int WWZX = 0x2F;
+  static const int WWZY = 0x6F;
+  static const int WWZZ = 0xAF;
+  static const int WWZW = 0xEF;
+  static const int WWWX = 0x3F;
+  static const int WWWY = 0x7F;
+  static const int WWWZ = 0xBF;
+  static const int WWWW = 0xFF;
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Uint32x4 shuffle(int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw new RangeError('mask $mask must be in the range [0..256)');
+    }
+    int _x = _storage[mask & 0x3];
+    int _y = _storage[(mask >> 2) & 0x3];
+    int _z = _storage[(mask >> 4) & 0x3];
+    int _w = _storage[(mask >> 6) & 0x3];
+    return new Uint32x4(_x, _y, _z, _w);
+  }
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Uint32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Uint32x4 shuffleMix(Uint32x4 other, int mask) {
+    if ((mask < 0) || (mask > 255)) {
+      throw new RangeError('mask $mask must be in the range [0..256)');
+    }
+    int _x = _storage[mask & 0x3];
+    int _y = _storage[(mask >> 2) & 0x3];
+    int _z = other._storage[(mask >> 4) & 0x3];
+    int _w = other._storage[(mask >> 6) & 0x3];
+    return new Uint32x4(_x, _y, _z, _w);
+  }
+
   /// Returns a new [Uint32x4] copied from [this] with a new x value.
   Uint32x4 withX(int x) {
     int _x = x;
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 398a360..d23d384 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -921,7 +921,7 @@
   /// Extract the sign bits from each lane return them in the first 4 bits.
   int get signMask;
 
-  /// Mask passed to [shuffle].
+  /// Mask passed to [shuffle] or [shuffleMix].
   static const int XXXX = 0x0;
   static const int XXXY = 0x40;
   static const int XXXZ = 0x80;
@@ -1182,25 +1182,10 @@
   /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
   Float32x4 shuffle(int mask);
 
-  /// Returns a new [Float32x4] with values in the X and Y lanes
-  /// replaced with the values in the Z and W lanes of [other].
-  Float32x4 withZWInXY(Float32x4 other);
-
-  /// Returns a new [Float32x4] with the X and Y lane values
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveXY(Float32x4 other);
-
-  /// Returns a new [Float32x4] with the Z and W lane values
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveZW(Float32x4 other);
-
-  /// Returns a new [Float32x4] with the X and Y lane value pairs
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveXYPairs(Float32x4 other);
-
-  /// Returns a new [Float32x4] with the Z and W lane value pairs
-  /// from [this] and [other] interleaved.
-  Float32x4 interleaveZWPairs(Float32x4 other);
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Float32x4 shuffleMix(Float32x4 other, int mask);
 
   /// Returns a new [Float32x4] copied from [this] with a new x value.
   Float32x4 withX(double x);
@@ -1261,6 +1246,272 @@
   /// Extract the top bit from each lane return them in the first 4 bits.
   int get signMask;
 
+  /// Mask passed to [shuffle] or [shuffleMix].
+  static const int XXXX = 0x0;
+  static const int XXXY = 0x40;
+  static const int XXXZ = 0x80;
+  static const int XXXW = 0xC0;
+  static const int XXYX = 0x10;
+  static const int XXYY = 0x50;
+  static const int XXYZ = 0x90;
+  static const int XXYW = 0xD0;
+  static const int XXZX = 0x20;
+  static const int XXZY = 0x60;
+  static const int XXZZ = 0xA0;
+  static const int XXZW = 0xE0;
+  static const int XXWX = 0x30;
+  static const int XXWY = 0x70;
+  static const int XXWZ = 0xB0;
+  static const int XXWW = 0xF0;
+  static const int XYXX = 0x4;
+  static const int XYXY = 0x44;
+  static const int XYXZ = 0x84;
+  static const int XYXW = 0xC4;
+  static const int XYYX = 0x14;
+  static const int XYYY = 0x54;
+  static const int XYYZ = 0x94;
+  static const int XYYW = 0xD4;
+  static const int XYZX = 0x24;
+  static const int XYZY = 0x64;
+  static const int XYZZ = 0xA4;
+  static const int XYZW = 0xE4;
+  static const int XYWX = 0x34;
+  static const int XYWY = 0x74;
+  static const int XYWZ = 0xB4;
+  static const int XYWW = 0xF4;
+  static const int XZXX = 0x8;
+  static const int XZXY = 0x48;
+  static const int XZXZ = 0x88;
+  static const int XZXW = 0xC8;
+  static const int XZYX = 0x18;
+  static const int XZYY = 0x58;
+  static const int XZYZ = 0x98;
+  static const int XZYW = 0xD8;
+  static const int XZZX = 0x28;
+  static const int XZZY = 0x68;
+  static const int XZZZ = 0xA8;
+  static const int XZZW = 0xE8;
+  static const int XZWX = 0x38;
+  static const int XZWY = 0x78;
+  static const int XZWZ = 0xB8;
+  static const int XZWW = 0xF8;
+  static const int XWXX = 0xC;
+  static const int XWXY = 0x4C;
+  static const int XWXZ = 0x8C;
+  static const int XWXW = 0xCC;
+  static const int XWYX = 0x1C;
+  static const int XWYY = 0x5C;
+  static const int XWYZ = 0x9C;
+  static const int XWYW = 0xDC;
+  static const int XWZX = 0x2C;
+  static const int XWZY = 0x6C;
+  static const int XWZZ = 0xAC;
+  static const int XWZW = 0xEC;
+  static const int XWWX = 0x3C;
+  static const int XWWY = 0x7C;
+  static const int XWWZ = 0xBC;
+  static const int XWWW = 0xFC;
+  static const int YXXX = 0x1;
+  static const int YXXY = 0x41;
+  static const int YXXZ = 0x81;
+  static const int YXXW = 0xC1;
+  static const int YXYX = 0x11;
+  static const int YXYY = 0x51;
+  static const int YXYZ = 0x91;
+  static const int YXYW = 0xD1;
+  static const int YXZX = 0x21;
+  static const int YXZY = 0x61;
+  static const int YXZZ = 0xA1;
+  static const int YXZW = 0xE1;
+  static const int YXWX = 0x31;
+  static const int YXWY = 0x71;
+  static const int YXWZ = 0xB1;
+  static const int YXWW = 0xF1;
+  static const int YYXX = 0x5;
+  static const int YYXY = 0x45;
+  static const int YYXZ = 0x85;
+  static const int YYXW = 0xC5;
+  static const int YYYX = 0x15;
+  static const int YYYY = 0x55;
+  static const int YYYZ = 0x95;
+  static const int YYYW = 0xD5;
+  static const int YYZX = 0x25;
+  static const int YYZY = 0x65;
+  static const int YYZZ = 0xA5;
+  static const int YYZW = 0xE5;
+  static const int YYWX = 0x35;
+  static const int YYWY = 0x75;
+  static const int YYWZ = 0xB5;
+  static const int YYWW = 0xF5;
+  static const int YZXX = 0x9;
+  static const int YZXY = 0x49;
+  static const int YZXZ = 0x89;
+  static const int YZXW = 0xC9;
+  static const int YZYX = 0x19;
+  static const int YZYY = 0x59;
+  static const int YZYZ = 0x99;
+  static const int YZYW = 0xD9;
+  static const int YZZX = 0x29;
+  static const int YZZY = 0x69;
+  static const int YZZZ = 0xA9;
+  static const int YZZW = 0xE9;
+  static const int YZWX = 0x39;
+  static const int YZWY = 0x79;
+  static const int YZWZ = 0xB9;
+  static const int YZWW = 0xF9;
+  static const int YWXX = 0xD;
+  static const int YWXY = 0x4D;
+  static const int YWXZ = 0x8D;
+  static const int YWXW = 0xCD;
+  static const int YWYX = 0x1D;
+  static const int YWYY = 0x5D;
+  static const int YWYZ = 0x9D;
+  static const int YWYW = 0xDD;
+  static const int YWZX = 0x2D;
+  static const int YWZY = 0x6D;
+  static const int YWZZ = 0xAD;
+  static const int YWZW = 0xED;
+  static const int YWWX = 0x3D;
+  static const int YWWY = 0x7D;
+  static const int YWWZ = 0xBD;
+  static const int YWWW = 0xFD;
+  static const int ZXXX = 0x2;
+  static const int ZXXY = 0x42;
+  static const int ZXXZ = 0x82;
+  static const int ZXXW = 0xC2;
+  static const int ZXYX = 0x12;
+  static const int ZXYY = 0x52;
+  static const int ZXYZ = 0x92;
+  static const int ZXYW = 0xD2;
+  static const int ZXZX = 0x22;
+  static const int ZXZY = 0x62;
+  static const int ZXZZ = 0xA2;
+  static const int ZXZW = 0xE2;
+  static const int ZXWX = 0x32;
+  static const int ZXWY = 0x72;
+  static const int ZXWZ = 0xB2;
+  static const int ZXWW = 0xF2;
+  static const int ZYXX = 0x6;
+  static const int ZYXY = 0x46;
+  static const int ZYXZ = 0x86;
+  static const int ZYXW = 0xC6;
+  static const int ZYYX = 0x16;
+  static const int ZYYY = 0x56;
+  static const int ZYYZ = 0x96;
+  static const int ZYYW = 0xD6;
+  static const int ZYZX = 0x26;
+  static const int ZYZY = 0x66;
+  static const int ZYZZ = 0xA6;
+  static const int ZYZW = 0xE6;
+  static const int ZYWX = 0x36;
+  static const int ZYWY = 0x76;
+  static const int ZYWZ = 0xB6;
+  static const int ZYWW = 0xF6;
+  static const int ZZXX = 0xA;
+  static const int ZZXY = 0x4A;
+  static const int ZZXZ = 0x8A;
+  static const int ZZXW = 0xCA;
+  static const int ZZYX = 0x1A;
+  static const int ZZYY = 0x5A;
+  static const int ZZYZ = 0x9A;
+  static const int ZZYW = 0xDA;
+  static const int ZZZX = 0x2A;
+  static const int ZZZY = 0x6A;
+  static const int ZZZZ = 0xAA;
+  static const int ZZZW = 0xEA;
+  static const int ZZWX = 0x3A;
+  static const int ZZWY = 0x7A;
+  static const int ZZWZ = 0xBA;
+  static const int ZZWW = 0xFA;
+  static const int ZWXX = 0xE;
+  static const int ZWXY = 0x4E;
+  static const int ZWXZ = 0x8E;
+  static const int ZWXW = 0xCE;
+  static const int ZWYX = 0x1E;
+  static const int ZWYY = 0x5E;
+  static const int ZWYZ = 0x9E;
+  static const int ZWYW = 0xDE;
+  static const int ZWZX = 0x2E;
+  static const int ZWZY = 0x6E;
+  static const int ZWZZ = 0xAE;
+  static const int ZWZW = 0xEE;
+  static const int ZWWX = 0x3E;
+  static const int ZWWY = 0x7E;
+  static const int ZWWZ = 0xBE;
+  static const int ZWWW = 0xFE;
+  static const int WXXX = 0x3;
+  static const int WXXY = 0x43;
+  static const int WXXZ = 0x83;
+  static const int WXXW = 0xC3;
+  static const int WXYX = 0x13;
+  static const int WXYY = 0x53;
+  static const int WXYZ = 0x93;
+  static const int WXYW = 0xD3;
+  static const int WXZX = 0x23;
+  static const int WXZY = 0x63;
+  static const int WXZZ = 0xA3;
+  static const int WXZW = 0xE3;
+  static const int WXWX = 0x33;
+  static const int WXWY = 0x73;
+  static const int WXWZ = 0xB3;
+  static const int WXWW = 0xF3;
+  static const int WYXX = 0x7;
+  static const int WYXY = 0x47;
+  static const int WYXZ = 0x87;
+  static const int WYXW = 0xC7;
+  static const int WYYX = 0x17;
+  static const int WYYY = 0x57;
+  static const int WYYZ = 0x97;
+  static const int WYYW = 0xD7;
+  static const int WYZX = 0x27;
+  static const int WYZY = 0x67;
+  static const int WYZZ = 0xA7;
+  static const int WYZW = 0xE7;
+  static const int WYWX = 0x37;
+  static const int WYWY = 0x77;
+  static const int WYWZ = 0xB7;
+  static const int WYWW = 0xF7;
+  static const int WZXX = 0xB;
+  static const int WZXY = 0x4B;
+  static const int WZXZ = 0x8B;
+  static const int WZXW = 0xCB;
+  static const int WZYX = 0x1B;
+  static const int WZYY = 0x5B;
+  static const int WZYZ = 0x9B;
+  static const int WZYW = 0xDB;
+  static const int WZZX = 0x2B;
+  static const int WZZY = 0x6B;
+  static const int WZZZ = 0xAB;
+  static const int WZZW = 0xEB;
+  static const int WZWX = 0x3B;
+  static const int WZWY = 0x7B;
+  static const int WZWZ = 0xBB;
+  static const int WZWW = 0xFB;
+  static const int WWXX = 0xF;
+  static const int WWXY = 0x4F;
+  static const int WWXZ = 0x8F;
+  static const int WWXW = 0xCF;
+  static const int WWYX = 0x1F;
+  static const int WWYY = 0x5F;
+  static const int WWYZ = 0x9F;
+  static const int WWYW = 0xDF;
+  static const int WWZX = 0x2F;
+  static const int WWZY = 0x6F;
+  static const int WWZZ = 0xAF;
+  static const int WWZW = 0xEF;
+  static const int WWWX = 0x3F;
+  static const int WWWY = 0x7F;
+  static const int WWWZ = 0xBF;
+  static const int WWWW = 0xFF;
+
+  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
+  Uint32x4 shuffle(int mask);
+
+  /// Shuffle the lane values in [this] and [other]. The returned
+  /// Uint32x4 will have XY lanes from [this] and ZW lanes from [other].
+  /// Uses the same [mask] as [shuffle].
+  Uint32x4 shuffleMix(Uint32x4 other, int mask);
+
   /// Returns a new [Uint32x4] copied from [this] with a new x value.
   Uint32x4 withX(int x);
   /// Returns a new [Uint32x4] copied from [this] with a new y value.
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 7d88a47f..da0374b 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -71,6 +71,13 @@
 # co19 issue #623: main() { {}; } is block and empty statement, not a map
 Language/13_Statements/02_Expression_Statements_A01_t13: Fail, OK
 
+# co19 issue #650: two argument shuffles have been refactored.
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
+
 # co19 issue #626: StreamTransformers have been refactored.
 LibTest/async/EventTransformStream/EventTransformStream_A01_t01: Fail
 LibTest/async/EventTransformStream/EventTransformStream_A01_t02: Fail
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 4df2aa6..6e93f45 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -88,9 +88,6 @@
 
 LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
 
-LibTest/async/Stream/handleError_A04_t02: Fail # co19-roll r641: Please triage this failure
-LibTest/async/Stream/listen_A05_t02: Fail # co19-roll r641: Please triage this failure
-LibTest/async/StreamSink/addError_A01_t01: Fail # co19-roll r641: Please triage this failure
 LibTest/async/StreamSink/addStream_A01_t02: Timeout, Fail, OK # Dart issue 14334 - test is also incorrect.
 LibTest/collection/ListBase/ListBase_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: Fail, Timeout # co19-roll r641: Please triage this failure
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 0091d34..e7f75af 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -67,6 +67,11 @@
 LibTest/math/exp_A01_t01: Fail # Issue co19 - 44
 LibTest/math/sin_A01_t01: Fail # Inherited from VM.
 LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
 
 
 [ $compiler == dart2dart && $system == windows ]
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 73161a3..1a5e702 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -53,6 +53,11 @@
 LibTest/typed_data/Uint32List/Uint32List_A02_t01: fail # co19-roll r576: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/Uint8ClampedList_A02_t01: fail # co19-roll r576: Please triage this failure
 LibTest/typed_data/Uint8List/Uint8List_A02_t01: fail # co19-roll r576: Please triage this failure
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
 
 [ $compiler == dart2js && $runtime != ie9 ]
 LibTest/typed_data/ByteData/ByteData_A02_t01: fail # co19-roll r576: Please triage this failure
@@ -445,7 +450,6 @@
 Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # co19-roll r546: Please triage this failure
 Language/15_Types/4_Interface_Types_A11_t01: crash # co19-roll r546: Please triage this failure
 Language/15_Types/4_Interface_Types_A11_t02: crash # co19-roll r546: Please triage this failure
-Language/15_Types/4_Interface_Types_A11_t04: fail # co19-roll r546: Please triage this failure
 Language/15_Types/4_Interface_Types_A12_t10: fail # co19-roll r546: Please triage this failure
 LibTest/core/DateTime/DateTime_A01_t03: fail # co19-roll r546: Please triage this failure
 LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
@@ -599,6 +603,7 @@
 Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
 Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
 Language/14_Libraries_and_Scripts/2_Exports_A05_t03: MissingCompileTimeError # co19-roll r623: Please triage this failure
+Language/15_Types/4_Interface_Types_A11_t04: fail # Issue 14654
 LibTest/core/Symbol/Symbol_A01_t02: CompileTimeError # co19-roll r607: Please triage this failure
 
 [ $compiler == dart2js ]
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 317c87b..6915f46 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -57,6 +57,11 @@
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/typed_data/Float32x4/clamp_A01_t01: Pass, Fail # co19 issue 636
+LibTest/typed_data/Float32x4/interleaveZWPairs_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveZW_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/withZWInXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXY_A01_t01: Fail # co19 issue 650
+LibTest/typed_data/Float32x4/interleaveXYPairs_A01_t01: Fail # co19 issue 650
 
 [ $compiler == none && $runtime == vm ]
 LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # Issue 13398
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index affcf0d..adb0673 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -133,7 +133,8 @@
       handler.diagnosticHandler,
       libraryRoot, libraryRoot,
       <String>['--analyze-only', '--analyze-all',
-               '--categories=Client,Server']);
+               '--categories=Client,Server'],
+      {});
   compiler.librariesToAnalyzeWhenRun = uriList;
   return compiler.run(null).then((_) {
     handler.checkResults();
diff --git a/tests/compiler/dart2js/bad_loop_test.dart b/tests/compiler/dart2js/bad_loop_test.dart
index ea1f03d..e8c2848 100644
--- a/tests/compiler/dart2js/bad_loop_test.dart
+++ b/tests/compiler/dart2js/bad_loop_test.dart
@@ -36,7 +36,8 @@
                                    diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   ['--analyze-only']);
+                                   ['--analyze-only'],
+                                   {});
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     Expect.isTrue(compiler.compilationFailed);
     Expect.equals(5, errorCount);
diff --git a/tests/compiler/dart2js/codegen_helper.dart b/tests/compiler/dart2js/codegen_helper.dart
index 445276e..1d1f455 100644
--- a/tests/compiler/dart2js/codegen_helper.dart
+++ b/tests/compiler/dart2js/codegen_helper.dart
@@ -21,7 +21,8 @@
                                    handler.diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   options);
+                                   options,
+                                   {});
   Uri uri = Uri.parse('memory:main.dart');
   return compiler.run(uri).then((success) {
     Expect.isTrue(success);
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 777c4fc..f753aad 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -26,7 +26,8 @@
                                    handler.diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   ['--analyze-only']);
+                                   ['--analyze-only'],
+                                   {});
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     var main = compiler.mainApp.find(dart2js.Compiler.MAIN);
     Expect.isNotNull(main, "Could not find 'main'");
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 475979a..5e93e2e29 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -29,7 +29,8 @@
                                    diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   ['--analyze-only']);
+                                   ['--analyze-only'],
+                                   {});
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     diagnostics.sort();
     var expected = [
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 5d3373b..414e5cd 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -97,7 +97,8 @@
                                    handler,
                                    libraryRoot,
                                    packageRoot,
-                                   options);
+                                   options,
+                                   {});
   if (cachedCompiler != null) {
     compiler.coreLibrary = cachedCompiler.libraries['dart:core'];
     compiler.types = cachedCompiler.types;
diff --git a/tests/compiler/dart2js/mirror_tree_shaking_test.dart b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
index 5104a48..5caab85 100644
--- a/tests/compiler/dart2js/mirror_tree_shaking_test.dart
+++ b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
@@ -41,7 +41,8 @@
                                    diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   []);
+                                   [],
+                                   {});
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     Expect.isFalse(compiler.compilationFailed);
     Expect.isFalse(compiler.enqueuer.resolution.hasEnqueuedEverything);
diff --git a/tests/compiler/dart2js/missing_file_test.dart b/tests/compiler/dart2js/missing_file_test.dart
index 0e53476..8ae236e 100644
--- a/tests/compiler/dart2js/missing_file_test.dart
+++ b/tests/compiler/dart2js/missing_file_test.dart
@@ -57,7 +57,8 @@
                                    diagnosticHandler,
                                    libraryRoot,
                                    null,
-                                   []);
+                                   [],
+                                   {});
 
   asyncTest(() => compiler.run(main).then((_) {
     Expect.equals(1, errors.length);
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 6ff118f..c05469c 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -57,7 +57,8 @@
                                    diagnosticHandler,
                                    libraryRoot,
                                    null,
-                                   []);
+                                   [],
+                                   {});
 
   asyncTest(() => compiler.run(main).then((_) {
     Expect.equals(1, errors.length);
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index b1aeb6a..a0d433e 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -114,8 +114,9 @@
 """);
   compiler.resolveStatement("Bar bar;");
   ClassElement classBar = compiler.mainApp.find("Bar");
-  Expect.equals('[ Foo, X<Bar>, X<Foo>, Object ]',
-                classBar.allSupertypes.toString());
+  Expect.equals(1, compiler.errors.length);
+  Expect.equals(0, compiler.warnings.length);
+  Expect.equals(MessageKind.MULTI_INHERITANCE, compiler.errors[0].message.kind);
 }
 
 testTypeVariables() {
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index 2d1a4d5..cd09732 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -8,39 +8,39 @@
 import "../../../sdk/lib/_internal/compiler/implementation/ssa/ssa.dart";
 import "../../../sdk/lib/_internal/compiler/implementation/types/types.dart";
 
-HType nullType;
-HType objectType;
-HType jsBoolean;
-HType jsNumber;
-HType jsInteger;
-HType jsDouble;
-HType jsBooleanOrNull;
-HType jsNumberOrNull;
-HType jsIntegerOrNull;
-HType jsDoubleOrNull;
-HType emptyType;
-HType dynamicType;
+TypeMask nullType;
+TypeMask objectType;
+TypeMask jsBoolean;
+TypeMask jsNumber;
+TypeMask jsInteger;
+TypeMask jsDouble;
+TypeMask jsBooleanOrNull;
+TypeMask jsNumberOrNull;
+TypeMask jsIntegerOrNull;
+TypeMask jsDoubleOrNull;
+TypeMask emptyType;
+TypeMask dynamicType;
 
 var patternClass;
-HType nonPrimitive1;
-HType nonPrimitive2;
-HType potentialArray;
-HType potentialString;
-HType jsInterceptor;
+TypeMask nonPrimitive1;
+TypeMask nonPrimitive2;
+TypeMask potentialArray;
+TypeMask potentialString;
+TypeMask jsInterceptor;
 
-HType jsIndexable;
-HType jsReadableArray;
-HType jsMutableArray;
-HType jsFixedArray;
-HType jsExtendableArray;
-HType jsString;
-HType jsStringOrNull;
-HType jsArrayOrNull;
-HType jsMutableArrayOrNull;
-HType jsFixedArrayOrNull;
-HType jsExtendableArrayOrNull;
-HType jsIndexableOrNull;
-HType jsInterceptorOrNull;
+TypeMask jsIndexable;
+TypeMask jsReadableArray;
+TypeMask jsMutableArray;
+TypeMask jsFixedArray;
+TypeMask jsExtendableArray;
+TypeMask jsString;
+TypeMask jsStringOrNull;
+TypeMask jsArrayOrNull;
+TypeMask jsMutableArrayOrNull;
+TypeMask jsFixedArrayOrNull;
+TypeMask jsExtendableArrayOrNull;
+TypeMask jsIndexableOrNull;
+TypeMask jsInterceptorOrNull;
 
 
 class Pair {
@@ -376,8 +376,8 @@
 
   check(nonPrimitive1, nullType, (type) => type is HBoundedType);
   check(nonPrimitive2, nullType, (type) => type is HBoundedType);
-  check(nullType, nonPrimitive1, (type) => type.canBeNull());
-  check(nullType, nonPrimitive2, (type) => type.canBeNull());
+  check(nullType, nonPrimitive1, (type) => type.isNullable);
+  check(nullType, nonPrimitive2, (type) => type.isNullable);
 
   ruleSet.validateCoverage();
 }
@@ -517,9 +517,10 @@
   rule(jsIndexable, jsExtendableArray, jsExtendableArray);
   rule(jsIndexable, nonPrimitive1, emptyType);
   rule(jsIndexable, nonPrimitive2, emptyType);
-  rule(jsIndexable, potentialArray, new HType.nonNullSubtype(
-      compiler.backend.jsArrayClass, compiler));
-  rule(jsIndexable, potentialString, jsString);
+  rule(jsIndexable, potentialArray, new TypeMask.nonNullSubtype(
+      compiler.backend.jsArrayClass));
+  rule(jsIndexable, potentialString, new TypeMask.nonNullSubtype(
+      compiler.backend.jsStringClass));
   rule(jsIndexable, jsBooleanOrNull, emptyType);
   rule(jsIndexable, jsNumberOrNull, emptyType);
   rule(jsIndexable, jsIntegerOrNull, emptyType);
@@ -667,8 +668,8 @@
 }
 
 void testRegressions(MockCompiler compiler) {
-  HType nonNullPotentialString = new HType.nonNullSubtype(
-      patternClass, compiler);
+  TypeMask nonNullPotentialString = new TypeMask.nonNullSubtype(
+      patternClass);
   Expect.equals(
       potentialString, jsStringOrNull.union(nonNullPotentialString, compiler));
 }
@@ -689,66 +690,64 @@
   // string types.
   patternClass = compiler.coreLibrary.find('Pattern');
 
-  nonPrimitive1 = new HType.nonNullSubtype(
-      compiler.mapClass, compiler);
-  nonPrimitive2 = new HType.nonNullSubtype(
-      compiler.functionClass, compiler);
-  potentialArray = new HType.subtype(
-      compiler.listClass, compiler);
-  potentialString = new HType.subtype(
-      patternClass, compiler);
-  jsInterceptor = new HType.nonNullSubclass(
-      compiler.backend.jsInterceptorClass, compiler);
-  jsArrayOrNull = new HType.subclass(
-      compiler.backend.jsArrayClass, compiler);
-  jsReadableArray = new HType.nonNullSubclass(
-      compiler.backend.jsArrayClass, compiler);
-  jsMutableArrayOrNull = new HType.subclass(
-      compiler.backend.jsMutableArrayClass, compiler);
-  jsMutableArray = new HType.nonNullSubclass(
-      compiler.backend.jsMutableArrayClass, compiler);
-  jsFixedArrayOrNull = new HType.exact(
-      compiler.backend.jsFixedArrayClass, compiler);
-  jsFixedArray = new HType.nonNullExact(
-      compiler.backend.jsFixedArrayClass, compiler);
-  jsExtendableArrayOrNull = new HType.exact(
-      compiler.backend.jsExtendableArrayClass, compiler);
-  jsExtendableArray = new HType.nonNullExact(
-      compiler.backend.jsExtendableArrayClass, compiler);
-  jsIndexableOrNull = new HType.subtype(
-      compiler.backend.jsIndexableClass, compiler);
-  jsIndexable = new HType.nonNullSubtype(
-      compiler.backend.jsIndexableClass, compiler);
-  jsInterceptorOrNull = new HType.subclass(
-      compiler.backend.jsInterceptorClass, compiler);
-  jsStringOrNull = new HType.exact(
-      compiler.backend.jsStringClass, compiler);
-  jsString = new HType.nonNullExact(
-      compiler.backend.jsStringClass, compiler);
-  jsBoolean = new HType.nonNullExact(
-      compiler.backend.jsBoolClass, compiler);
-  jsNumber = new HType.nonNullSubclass(
-      compiler.backend.jsNumberClass, compiler);
-  jsInteger = new HType.nonNullExact(
-      compiler.backend.jsIntClass, compiler);
-  jsDouble = new HType.nonNullExact(
-      compiler.backend.jsDoubleClass, compiler);
-  jsBooleanOrNull = new HType.exact(
-      compiler.backend.jsBoolClass, compiler);
-  jsNumberOrNull = new HType.subclass(
-      compiler.backend.jsNumberClass, compiler);
-  jsIntegerOrNull = new HType.exact(
-      compiler.backend.jsIntClass, compiler);
-  jsDoubleOrNull = new HType.exact(
-      compiler.backend.jsDoubleClass, compiler);
-  nullType = new HBoundedType(
-      const TypeMask.empty());
-  objectType = new HType.nonNullSubclass(
-      compiler.objectClass, compiler);
-  emptyType = new HBoundedType(
-      const TypeMask.nonNullEmpty());
-  dynamicType = new HType.subclass(
-      compiler.objectClass, compiler);
+  nonPrimitive1 = new TypeMask.nonNullSubtype(
+      compiler.mapClass);
+  nonPrimitive2 = new TypeMask.nonNullSubtype(
+      compiler.functionClass);
+  potentialArray = new TypeMask.subtype(
+      compiler.listClass);
+  potentialString = new TypeMask.subtype(
+      patternClass);
+  jsInterceptor = new TypeMask.nonNullSubclass(
+      compiler.backend.jsInterceptorClass);
+  jsArrayOrNull = new TypeMask.subclass(
+      compiler.backend.jsArrayClass);
+  jsReadableArray = new TypeMask.nonNullSubclass(
+      compiler.backend.jsArrayClass);
+  jsMutableArrayOrNull = new TypeMask.subclass(
+      compiler.backend.jsMutableArrayClass);
+  jsMutableArray = new TypeMask.nonNullSubclass(
+      compiler.backend.jsMutableArrayClass);
+  jsFixedArrayOrNull = new TypeMask.exact(
+      compiler.backend.jsFixedArrayClass);
+  jsFixedArray = new TypeMask.nonNullExact(
+      compiler.backend.jsFixedArrayClass);
+  jsExtendableArrayOrNull = new TypeMask.exact(
+      compiler.backend.jsExtendableArrayClass);
+  jsExtendableArray = new TypeMask.nonNullExact(
+      compiler.backend.jsExtendableArrayClass);
+  jsIndexableOrNull = new TypeMask.subtype(
+      compiler.backend.jsIndexableClass);
+  jsIndexable = new TypeMask.nonNullSubtype(
+      compiler.backend.jsIndexableClass);
+  jsInterceptorOrNull = new TypeMask.subclass(
+      compiler.backend.jsInterceptorClass);
+  jsStringOrNull = new TypeMask.exact(
+      compiler.backend.jsStringClass);
+  jsString = new TypeMask.nonNullExact(
+      compiler.backend.jsStringClass);
+  jsBoolean = new TypeMask.nonNullExact(
+      compiler.backend.jsBoolClass);
+  jsNumber = new TypeMask.nonNullSubclass(
+      compiler.backend.jsNumberClass);
+  jsInteger = new TypeMask.nonNullExact(
+      compiler.backend.jsIntClass);
+  jsDouble = new TypeMask.nonNullExact(
+      compiler.backend.jsDoubleClass);
+  jsBooleanOrNull = new TypeMask.exact(
+      compiler.backend.jsBoolClass);
+  jsNumberOrNull = new TypeMask.subclass(
+      compiler.backend.jsNumberClass);
+  jsIntegerOrNull = new TypeMask.exact(
+      compiler.backend.jsIntClass);
+  jsDoubleOrNull = new TypeMask.exact(
+      compiler.backend.jsDoubleClass);
+  nullType = const TypeMask.empty();
+  objectType = new TypeMask.nonNullSubclass(
+      compiler.objectClass);
+  emptyType = const TypeMask.nonNullEmpty();
+  dynamicType = new TypeMask.subclass(
+      compiler.objectClass);
 
   testUnion(compiler);
   testIntersection(compiler);
diff --git a/tests/compiler/dart2js/unneeded_part_js_test.dart b/tests/compiler/dart2js/unneeded_part_js_test.dart
index a4d1835..abbd674 100644
--- a/tests/compiler/dart2js/unneeded_part_js_test.dart
+++ b/tests/compiler/dart2js/unneeded_part_js_test.dart
@@ -40,7 +40,8 @@
                                    diagnosticHandler,
                                    libraryRoot,
                                    packageRoot,
-                                   []);
+                                   [],
+                                   {});
   asyncTest(() => compiler.run(Uri.parse('memory:main.dart')).then((_) {
     Expect.isFalse(compiler.compilationFailed);
   }));
diff --git a/tests/compiler/dart2js_extra/mirror_test.dart b/tests/compiler/dart2js_extra/mirror_test.dart
index dbc2b46..5c4e452 100644
--- a/tests/compiler/dart2js_extra/mirror_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_test.dart
@@ -5,9 +5,7 @@
 import "package:expect/expect.dart";
 import 'dart:mirrors';
 
-import 'async_helper.dart';
-
-void test(void onDone(bool success)) {
+void main() {
   var now = new DateTime.now();
   InstanceMirror mirror = reflect(now);
   print('now: ${now}');
@@ -18,15 +16,4 @@
   print('mirror.invoke("toUtc", []): $value');
   Expect.isTrue(value.hasReflectee);
   Expect.equals(now.toUtc(), value.reflectee);
-
-  mirror.invokeAsync(const Symbol("toUtc"), []).then((value) {
-    print('mirror.invokeAsync("toUtc", []): $value');
-    Expect.isTrue(value.hasReflectee);
-    Expect.equals(now.toUtc(), value.reflectee);
-    onDone(true);
-  });
-}
-
-void main() {
-  asyncTest(test);
 }
diff --git a/tests/corelib/bool_from_environment_default_value_test.dart b/tests/corelib/bool_from_environment_default_value_test.dart
index 82acf265..f412522 100644
--- a/tests/corelib/bool_from_environment_default_value_test.dart
+++ b/tests/corelib/bool_from_environment_default_value_test.dart
@@ -5,7 +5,7 @@
 import "package:expect/expect.dart";
 
 main() {
-  Expect.isNull(const bool.fromEnvironment('NOT_FOUND'));
+  Expect.isFalse(const bool.fromEnvironment('NOT_FOUND'));
   Expect.isTrue(const bool.fromEnvironment('NOT_FOUND', defaultValue: true));
   Expect.isFalse(const bool.fromEnvironment('NOT_FOUND', defaultValue: false));
   Expect.isNull(const bool.fromEnvironment('NOT_FOUND', defaultValue: null));
diff --git a/tests/corelib/bool_from_environment_test.dart b/tests/corelib/bool_from_environment_test.dart
index 66351e4..34e9ee1 100644
--- a/tests/corelib/bool_from_environment_test.dart
+++ b/tests/corelib/bool_from_environment_test.dart
@@ -1,11 +1,14 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// SharedOptions=-Da=true -Db=false
+// SharedOptions=-Da=true -Db=false -Dc=NOTBOOL -Dd=True
 
 import "package:expect/expect.dart";
 
 main() {
   Expect.isTrue(const bool.fromEnvironment('a'));
   Expect.isFalse(const bool.fromEnvironment('b'));
+  Expect.isTrue(const bool.fromEnvironment('c', defaultValue: true));
+  Expect.isFalse(const bool.fromEnvironment('c', defaultValue: false));
+  Expect.isFalse(const bool.fromEnvironment('d', defaultValue: false));
 }
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 8a46c88..90f4ff8 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -2,8 +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.
 
-# Skip these tests until XXX.fromEnvironment in dart2js lands.
-[ $compiler == dart2js || $compiler == dart2dart]
+[ $compiler == dart2dart]
 bool_from_environment2_test: Skip
 bool_from_environment_default_value_test: Skip
 bool_from_environment_test: Skip
diff --git a/tests/corelib/int_from_environment2_test.dart b/tests/corelib/int_from_environment2_test.dart
index 8b14526..2645337 100644
--- a/tests/corelib/int_from_environment2_test.dart
+++ b/tests/corelib/int_from_environment2_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// SharedOptions=-Da=x -Db=- -Dc=0xg
+// SharedOptions=-Da=x -Db=- -Dc=0xg -Dd=+ -Dd=
 
 import "package:expect/expect.dart";
 
@@ -9,4 +9,7 @@
   Expect.isNull(const int.fromEnvironment('a'));
   Expect.isNull(const int.fromEnvironment('b'));
   Expect.isNull(const int.fromEnvironment('c'));
+  Expect.isNull(const int.fromEnvironment('d'));
+  Expect.isNull(const int.fromEnvironment('e'));
 }
+
diff --git a/tests/corelib/int_from_environment_default_value_test.dart b/tests/corelib/int_from_environment_default_value_test.dart
index bb318d0..d97145a 100644
--- a/tests/corelib/int_from_environment_default_value_test.dart
+++ b/tests/corelib/int_from_environment_default_value_test.dart
@@ -6,5 +6,6 @@
 
 main() {
   Expect.isNull(const int.fromEnvironment('NOT_FOUND'));
-  Expect.equals(12345, const int.fromEnvironment('NOT_FOUND', defaultValue: 12345));
+  Expect.equals(12345, const int.fromEnvironment('NOT_FOUND',
+                                                 defaultValue: 12345));
 }
diff --git a/tests/corelib/int_from_environment_test.dart b/tests/corelib/int_from_environment_test.dart
index f842fdd..f6033a5 100644
--- a/tests/corelib/int_from_environment_test.dart
+++ b/tests/corelib/int_from_environment_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234
+// SharedOptions=-Da=1 -Db=-12 -Dc=0x123 -Dd=-0x1234 -De=+0x112296 -Df=99999999999999999999
 
 import "package:expect/expect.dart";
 
@@ -10,4 +10,6 @@
   Expect.equals(-12, const int.fromEnvironment('b'));
   Expect.equals(0x123, const int.fromEnvironment('c'));
   Expect.equals(-0x1234, const int.fromEnvironment('d'));
+  Expect.equals(0x112296, const int.fromEnvironment('e'));
+  Expect.equals(99999999999999999999, const int.fromEnvironment('f'));
 }
diff --git a/tests/html/custom/template_wrappers_test.dart b/tests/html/custom/template_wrappers_test.dart
index 8754f85..c52ad7b 100644
--- a/tests/html/custom/template_wrappers_test.dart
+++ b/tests/html/custom/template_wrappers_test.dart
@@ -32,7 +32,6 @@
 main() {
   useHtmlConfiguration();
 
-  var registeredTypes = false;
   setUp(loadPolyfills);
 
   test('element is upgraded once', () {
@@ -52,12 +51,31 @@
       expect(createdCount, 1);
     });
   });
+/*
+  test('old wrappers do not cause multiple upgrades', () {
+    createdCount = 0;
+    var d1 = document.querySelector('x-custom-two');
+    d1.attributes['foo'] = 'bar';
+    d1 = null;
+
+    document.register('x-custom-two', CustomElement);
+
+    expect(createdCount, 1);
+
+    forceGC();
+
+    return new Future.delayed(new Duration(milliseconds: 50)).then((_) {
+      var d = document.querySelector('x-custom-two');
+      expect(createdCount, 1);
+    });
+  });
+*/
 }
 
 
 void forceGC() {
   var N = 1000000;
-  var M = 1000;
+  var M = 100;
   for (var i = 0; i < M; ++i) {
     var l = new List(N);
   }
diff --git a/tests/html/custom/template_wrappers_test.html b/tests/html/custom/template_wrappers_test.html
index ea5b81d..2613bdc 100644
--- a/tests/html/custom/template_wrappers_test.html
+++ b/tests/html/custom/template_wrappers_test.html
@@ -16,6 +16,7 @@
   <template class='t1'>
     <x-custom></x-custom>
   </template>
+  <x-custom-two></x-custom-two>
   <script type="text/javascript"
       src="/packages/unittest/test_controller.js"></script>
   %TEST_SCRIPTS%
diff --git a/tests/isolate/illegal_msg_test.dart b/tests/isolate/illegal_msg_function_test.dart
similarity index 87%
rename from tests/isolate/illegal_msg_test.dart
rename to tests/isolate/illegal_msg_function_test.dart
index 422ae39..f967afd 100644
--- a/tests/isolate/illegal_msg_test.dart
+++ b/tests/isolate/illegal_msg_function_test.dart
@@ -2,9 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library illegal_msg_tests;
+library illegal_msg_function_test;
+
 import "package:expect/expect.dart";
-import 'dart:isolate';
+import "dart:isolate";
+import "dart:async" show Future;
 import "package:async_helper/async_helper.dart";
 
 funcFoo(x) => x + 2;
@@ -18,6 +20,8 @@
 }
 
 main() {
+  var function = funcFoo;
+
   ReceivePort port = new ReceivePort();
   Future spawn = Isolate.spawn(echo, port.sendPort);
   var caught_exception = false;
@@ -25,7 +29,7 @@
   asyncStart();
   stream.first.then((snd) {
     try {
-      snd.send(funcFoo);
+      snd.send(function);
     } catch (e) {
       caught_exception = true;
     }
diff --git a/tests/isolate/illegal_msg_test.dart b/tests/isolate/illegal_msg_mirror_test.dart
similarity index 75%
copy from tests/isolate/illegal_msg_test.dart
copy to tests/isolate/illegal_msg_mirror_test.dart
index 422ae39..eed2981 100644
--- a/tests/isolate/illegal_msg_test.dart
+++ b/tests/isolate/illegal_msg_mirror_test.dart
@@ -1,13 +1,18 @@
-// 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.
 
-library illegal_msg_tests;
-import "package:expect/expect.dart";
-import 'dart:isolate';
-import "package:async_helper/async_helper.dart";
+library illegal_msg_mirror_test;
 
-funcFoo(x) => x + 2;
+import "package:expect/expect.dart";
+import "dart:isolate";
+import "dart:async" show Future;
+import "package:async_helper/async_helper.dart";
+import "dart:mirrors";
+
+class Class {
+  method() {}
+}
 
 echo(sendPort) {
   var port = new ReceivePort();
@@ -18,6 +23,8 @@
 }
 
 main() {
+  var methodMirror = reflectClass(Class).declarations[#method];
+
   ReceivePort port = new ReceivePort();
   Future spawn = Isolate.spawn(echo, port.sendPort);
   var caught_exception = false;
@@ -25,7 +32,7 @@
   asyncStart();
   stream.first.then((snd) {
     try {
-      snd.send(funcFoo);
+      snd.send(methodMirror);
     } catch (e) {
       caught_exception = true;
     }
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 2fb39ff..fa6c738 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -62,7 +62,8 @@
 serialization_test: Pass # Issue 12628
 isolate_import_negative_test: Fail # Issue 12628
 isolate2_negative_test: Fail # Issue 12628
-illegal_msg_test: Pass # Issue 12628
+illegal_msg_function_test: Pass # Issue 12628
+illegal_msg_mirror_test: Pass # Issue 12628
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 isolate_stress_test: Pass, Slow # TODO(kasperl): Please triage.
@@ -102,7 +103,8 @@
 cross_isolate_message_test: Fail
 global_error_handler2_test: Fail
 global_error_handler_test: Fail
-illegal_msg_test: Fail
+illegal_msg_function_test: Fail
+illegal_msg_mirror_test: Fail
 isolate_complex_messages_test: Fail
 isolate_stress_test: Fail
 mandel_isolate_test: Fail
@@ -119,9 +121,7 @@
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 browser/typed_data_message_test: StaticWarning
-illegal_msg_test: StaticWarning
 isolate3_negative_test: CompileTimeError
-isolate/illegal_msg_test: StaticWarning
 isolate_import_negative_test: CompileTimeError
 isolate/mint_maker_test: StaticWarning
 isolate/unresolved_ports_test: StaticWarning
diff --git a/tests/language/cast2_test.dart b/tests/language/cast2_test.dart
index 397ac45..d67c89b 100644
--- a/tests/language/cast2_test.dart
+++ b/tests/language/cast2_test.dart
@@ -3,10 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program for constructors and initializers.
 
+import "package:expect/expect.dart";
+
 // Test 'expression as Type' casts.
 
 class C {
   final int foo = 42;
+
+  int val = 0;
+  void inc() { ++val; }
 }
 
 class D extends C {
@@ -14,10 +19,14 @@
 }
 
 main() {
-  Object oc = new C();
-  Object od = new D();
+  C oc = new C();
+  D od = new D();
 
   (oc as dynamic).bar;  /// 01: runtime error
+
+  // Casts should always evaluate the left-hand side, if only for its effects.
+  oc.inc() as dynamic;
+  Expect.equals(1, oc.val);
+  oc.inc() as Object;
+  Expect.equals(2, oc.val);
 }
-
-
diff --git a/tests/language/implicit_setter_test.dart b/tests/language/implicit_setter_test.dart
deleted file mode 100644
index ff940bf..0000000
--- a/tests/language/implicit_setter_test.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-
-// Test of final fields generating implicit setters that throw.
-
-String x = "toplevel";  // Should never be read in this test.
-
-class B {
-  var x = 37;
-}
-
-class C extends B {
-  final x = 42;
-
-  // Local access should work the same as direct access.
-  get cx => x;
-  void set cx(value) {
-    x = value;              /// 02: static type warning
-    erase(this).x = value;  // but crash even if the direct setting is omitted.
-  }
-
-  // Super access should work.
-  get bx => super.x;
-  void set bx(value) { super.x = value; }
-
-  noSuchMethod(i) => "noSuchMethod";  // Should never be called in this test.
-}
-
-// Class with only final field has setter in implicit interface.
-class A {
-  final int x = 42;
-}
-
-// Should get warning because the implicit interface contains the setter,
-// and this non-abstract class doesn't.
-class AI
-    implements A   /// 01: static type warning
-{
-  int get x => 37;
-}
-
-// Erases static type information. Used to avoid *static* warnings when
-// using a setter for a final field.
-erase(x) => x;
-
-void main() {
-  Expect.equals(42, new C().x);
-  Expect.throws(() { erase(new C()).x = 10; });
-  Expect.equals(42, new C().cx);
-  Expect.throws(() { erase(new C()).cx = 10; });
-  Expect.equals(37, new C().bx);
-  Expect.equals(10, (erase(new C())..bx = 10).bx);
-
-  Expect.equals(42, new A().x);
-  Expect.throws(() { erase(new A()).x = 10; });
-  Expect.equals(37, new AI().x);
-  Expect.throws(() { erase(new AI()).x = 10; });
-
-  Expect.equals("toplevel", x);  // Should not have changed.
-}
diff --git a/tests/language/language.status b/tests/language/language.status
index 79ab9b5..9c6fe8b 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -22,7 +22,6 @@
 lazy_static3_test: Fail # Issue 12593
 duplicate_export_negative_test: Fail # Issue 6134
 mixin_forwarding_constructor2_test: Fail # Issue 13641
-implicit_setter_test: Fail # Issue 13917
 
 [ $compiler == none && $runtime == vm ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
@@ -75,9 +74,8 @@
 
 [ $compiler == none && $runtime == dartium ]
 first_class_types_literals_test: Pass, Fail # Issue 13719: Please triage this failure.
-issue13474_test: Pass, Fail # Issue 13719: Please triage this failure.
-regress_13494_test: Pass, Fail # Issue 13719: Please triage this failure.
+issue13474_test: Pass, Fail # Issue 14651.
 
 [ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
 typed_message_test: Crash, Fail # Issue 13921, 14400
-
+vm/optimized_guarded_field_isolates_test: Fail # Issue 13921.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 96b17d3..bf10504 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -23,7 +23,6 @@
 
 built_in_identifier_test/none: Fail # Issue 13023
 
-
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
 #
@@ -161,10 +160,6 @@
 # test issue 14363, "if ((a is B))" has the same effect as "if (a is B)", so no static warning expected
 type_promotion_parameter_test/53: Fail
 
-# test issue 14406, setter for final field was removed from spec
-implicit_setter_test/01: fail
-implicit_setter_test/02: fail
-
 # test issue 14410, "typedef C = " is now really illegal syntax
 mixin_illegal_syntax_test/none: fail
 
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a8ebdfd..4a6e5a3 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -23,7 +23,6 @@
 
 built_in_identifier_test/none: Fail # Issue 13023
 
-
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
 #
@@ -174,10 +173,6 @@
 type_promotion_more_specific_test/10: Fail
 type_promotion_more_specific_test/11: Fail
 
-# test issue 14406, setter for final field was removed from spec
-implicit_setter_test/01: fail
-implicit_setter_test/02: fail
-
 # test issue 14410, "typedef C = " is now really illegal syntax
 mixin_illegal_syntax_test/none: fail
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 426c6c4..6ffdd63 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -23,7 +23,6 @@
 type_variable_conflict_test/04: Fail # Issue 13702
 type_variable_conflict_test/05: Fail # Issue 13702
 type_variable_conflict_test/06: Fail # Issue 13702
-implicit_setter_test: Fail # Issue 13919
 
 # VM specific tests that should not be run by dart2js.
 vm/*: Skip # Issue 12699
@@ -118,6 +117,7 @@
 not_enough_positional_arguments_test/02: CompileTimeError # Issue 12838
 not_enough_positional_arguments_test/05: CompileTimeError # Issue 12838
 metadata_test: CompileTimeError # Issue 5841
+metadata_syntax_test/05: MissingCompileTimeError # Issue 14548
 infinity_test: RuntimeError # Issue 4984
 positive_bit_operations_test: RuntimeError # Issue 12795
 mixin_mixin2_test: RuntimeError # Issue 13109.
@@ -136,7 +136,6 @@
 built_in_identifier_test/01: CompileTimeError # Issue 13022
 
 scope_variable_test/01: MissingCompileTimeError # Issue 13016
-static_final_field2_test/02: MissingCompileTimeError # Issue 13017
 
 numbers_test: RuntimeError, OK # Issue 1533
 canonical_const2_test: RuntimeError, OK # Issue 1533
@@ -227,6 +226,7 @@
 not_enough_positional_arguments_test/05: Fail # Issue 12839
 
 metadata_test: Fail # Issue 12762
+metadata_syntax_test/05: MissingCompileTimeError # Issue 14548
 const_var_test: Pass, Fail # Issue 12794
 map_literal3_test: Fail # Issue 12794
 external_test/13: Fail # Issue 12888
@@ -236,7 +236,6 @@
 map_literal1_test/01: Fail # Issue 12993
 method_override4_test: Fail # Issue 12810
 method_override5_test: Fail # Issue 12810
-static_final_field2_test/02: Fail # Issue 13017
 scope_variable_test/01: Fail # Issue 13016
 factory_redirection_test/01: Fail # Issue 12753
 factory_redirection_test/02: Crash # Issue 12753
diff --git a/tests/language/metadata_syntax_test.dart b/tests/language/metadata_syntax_test.dart
deleted file mode 100644
index dc3ff8c..0000000
--- a/tests/language/metadata_syntax_test.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-
-// Test that is is an error to use type arguments in metadata without
-// parens.
-
-@Bar()
-@List<String> /// 01: compile-time error
-class Bar {
-  @Bar()
-  @List<String> /// 02: compile-time error
-  const Bar();
-
-  @Bar()
-  @List<String> /// 03: compile-time error
-  final x = '';
-}
-
-main() {
-  Expect.equals('', new Bar().x);
-  Expect.equals('', const Bar().x);
-}
diff --git a/tests/language/range_analysis2_test.dart b/tests/language/range_analysis2_test.dart
new file mode 100644
index 0000000..a84ede69
--- /dev/null
+++ b/tests/language/range_analysis2_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to remove bounds checks on
+// boxed variables.
+
+import "package:expect/expect.dart";
+
+main() {
+  var a = 0;
+  var b = [1];
+  foo() => b[a--] + b[a];
+  Expect.throws(foo, (e) => e is RangeError);
+}
diff --git a/tests/language/static_final_field2_test.dart b/tests/language/static_final_field2_test.dart
index c80588a..2c550a3 100644
--- a/tests/language/static_final_field2_test.dart
+++ b/tests/language/static_final_field2_test.dart
@@ -12,10 +12,11 @@
   final n;
   static const a;  /// 02: compile-time error
   static const b = 3 + 5;
-  static const c;  /// 02: continued
 }
 
 main() {
   A.x = 2;  /// 01: static type warning, runtime error
   new B();
+  print(B.b);
+  print(B.a);  /// 02: continued
 }
diff --git a/tests/language/substring_test.dart b/tests/language/substring_test.dart
new file mode 100644
index 0000000..aee5777
--- /dev/null
+++ b/tests/language/substring_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart version of two-argument Ackermann-Peter function.
+
+import "package:expect/expect.dart";
+
+
+main() {
+  try {
+    print("abcdef".substring(1.5, 3.5));    /// 01: static type warning
+    Expect.fail("Should have thrown an exception");  /// 01: continued
+  } on TypeError catch (e) {
+    // OK.
+  } on ArgumentError catch (e) {
+    // OK.
+  }
+}
diff --git a/tests/language/type_check_test.dart b/tests/language/type_check_test.dart
new file mode 100644
index 0000000..0b10a72
--- /dev/null
+++ b/tests/language/type_check_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to remove the a B type check
+// after an A type check, because it thought any subtype of A had to be B.
+
+import "package:expect/expect.dart";
+
+class A {
+}
+
+class B extends A {
+}
+
+main() {
+  var a = [new A(), new B()];
+  var b = a[0];
+  b = b as A;
+  Expect.throws(() => b as B, (e) => e is CastError);
+}
diff --git a/tests/language/type_propagation3_test.dart b/tests/language/type_propagation3_test.dart
new file mode 100644
index 0000000..e17e95e
--- /dev/null
+++ b/tests/language/type_propagation3_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for dart2js that used to generate wrong code for
+// it. The bug happened in the SSA type propagation.
+
+class A {
+  next() => new B();
+  doIt() => null;
+  bool get isEmpty => false;
+  foo() => 42;
+  bar() => 54;
+}
+
+bool entered = false;
+
+class B extends A {
+  foo() => 54;
+  doIt() => new A();
+  bool get isEmpty => true;
+  bar() => entered = true;
+}
+
+// (1) At initialization phase of the type propagation, [a] would be
+//     marked as [exact A].
+// (2) Will make the loop phi [b] typed [null, exact A].
+// (3) Will create a [HTypeKnown] [exact A] for [b].
+// (4) Will create a [HTypeKnown] [exact A] for [b] and update users
+//     of [b] to use this [HTypeKnown] instead.
+// (5) [a] will be updated to [subclass A].
+// (6) Will change the [HTypeKnown] of [b] from [exact A] to [subclass A].
+// (7) Receiver is [subclass A] and it will refine it to
+//     [subclass A]. We used to wrongly assume there was
+//     no need to update the [HTypeKnown] created in (3).
+// (8) Consider that bar is called on an [exact A] (the [HTypeKnown]
+//     created in (3)) and remove the call because it does not have
+//     any side effects.
+
+main() {
+  var a = new A();
+  for (var i in [42]) {
+    a = a.next();
+  }
+
+  // (1, 5)
+
+  var b = a;
+  while (b.isEmpty) { // (4, 6)
+    b.foo(); // (3, 7)
+    b.bar(); // (8)
+    b = b.doIt(); // (2)
+  }
+
+  if (!entered) throw 'Test failed';
+}
diff --git a/tests/language/vm/optimized_guarded_field_isolates_test.dart b/tests/language/vm/optimized_guarded_field_isolates_test.dart
new file mode 100644
index 0000000..fc5e915
--- /dev/null
+++ b/tests/language/vm/optimized_guarded_field_isolates_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization_counter_threshold=100
+
+// Test field type tracking and field list-length tracking in the presence of
+// multiple isolates.
+
+import "dart:isolate";
+import "dart:async";
+import "package:expect/expect.dart";
+
+class A {
+  A(this.a);
+  var a;
+}
+
+class B extends A {
+  B(a, this.b) : super(a) { }
+
+  var b;
+}
+
+f1(SendPort send_port) {
+  send_port.send(new B("foo", "bar"));
+}
+
+test_b(B obj) => obj.a + obj.b;
+
+test_field_type() {
+  var receive_port = new ReceivePort();
+  Future<Isolate> isolate = Isolate.spawn(f1, receive_port.sendPort);
+  B b = new B(1, 2);
+  for (var i = 0; i < 200; i++) { test_b(b); }
+  Expect.equals(3, test_b(b));
+  Future<B> item = receive_port.first;
+  item.then((B value) {
+      Expect.equals("foobar", test_b(value));
+      receive_port.close();
+  });
+}
+
+class C {
+  C(this.list);
+  final List list;
+}
+
+f2(SendPort send_port) {
+  send_port.send(new C(new List(1)));
+}
+
+test_c(C obj) => obj.list[9999];
+
+test_list_length() {
+  var receive_port = new ReceivePort();
+  Future<Isolate> isolate = Isolate.spawn(f2, receive_port.sendPort);
+  C c = new C(new List(10000));
+  for (var i = 0; i < 200; i++) { test_c(c); }
+  Expect.equals(null, test_c(c));
+  Future<C> item = receive_port.first;
+  item.then((C value) {
+      Expect.throws(() => test_c(value), (e) => e is RangeError);
+      receive_port.close();
+  });
+}
+
+main() {
+  test_field_type();
+  test_list_length();
+}
diff --git a/tests/language/vm/optimized_guarded_field_test.dart b/tests/language/vm/optimized_guarded_field_test.dart
index 2ef5dcb..c6aea4d 100644
--- a/tests/language/vm/optimized_guarded_field_test.dart
+++ b/tests/language/vm/optimized_guarded_field_test.dart
@@ -17,6 +17,41 @@
 
 test(obj) => obj.foo == null ? "null" : "other";
 
+
+class C {
+  C(this.x, this.y);
+  final x;
+  final y;
+}
+
+test_deopt(a, b) {
+  var c = new C(a, b);
+  return c.x + c.y;
+}
+
+
+create_error (x) {
+  return x as int;
+}
+
+check_stacktrace(e) {
+  var s = e.stackTrace;
+  if (identical(s, null)) throw "FAIL";
+  // s should never be null.
+  return "OK";
+}
+
+test_stacktrace() {
+  try {
+    create_error("bar");
+  } catch (e) {
+    Expect.equals("OK", check_stacktrace(e));
+    for (var i=0; i<20; i++) { check_stacktrace(e); }
+    Expect.equals("OK", check_stacktrace(e));
+  }
+}
+
+
 main() {
   var a = new A();
   var b = new B();
@@ -32,4 +67,13 @@
   a.foo = 123;
   Expect.equals("other", test(a));
   Expect.equals("null", test(b));
+
+  // Test guarded fields with allocation sinking and deoptimization.
+  Expect.equals(43, test_deopt(42, 1));
+  for (var i = 0; i < 20; i++) { test_deopt(42, 1); }
+  Expect.equals(43, test_deopt(42, 1));
+  Expect.equals("aaabbb", test_deopt("aaa", "bbb"));
+
+  // Regression test for fields initialized in native code (Error._stackTrace).
+  test_stacktrace();
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index bba8036..8244ded 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -16,25 +16,21 @@
 mirrors/basic_types_in_dart_core_test: RuntimeError # Issue 14025
 mirrors/class_declarations_test/none: RuntimeError # Issue 13440
 mirrors/closures_test/none: RuntimeError # Issue 6490
-mirrors/closure_mirror_find_in_context_test: Fail # Issue 6490
 mirrors/constructor_kinds_test: RuntimeError # Issue 13799
 mirrors/equality_test/02: RuntimeError # Issue 12333
 mirrors/fake_function_with_call_test: RuntimeError # Issue 11612
 mirrors/fake_function_without_call_test: RuntimeError # Issue 11612
+mirrors/find_in_context_test: Fail # Issue 6490
+mirrors/find_in_context_private_test: Fail # Issue 6490
 mirrors/find_in_context_fake_function_test: Fail # Issue 6490
 mirrors/function_type_mirror_test: RuntimeError # Issue 12166
 mirrors/generics_test/01: RuntimeError # Issue 12087
-mirrors/generic_bounded_test/none: RuntimeError # Issue 12087
-mirrors/generic_bounded_test/01: RuntimeError # Issue 12087
-mirrors/generic_bounded_by_type_parameter_test/none: RuntimeError # Issue 12087
-mirrors/generic_bounded_by_type_parameter_test/01: RuntimeError # Issue 12087
-mirrors/generic_f_bounded_test/01: RuntimeError # Issue 12087
 mirrors/generic_f_bounded_mixin_application_test: RuntimeError # Issue 12087
 mirrors/generic_function_typedef_test: RuntimeError # Issue 12333
 mirrors/generic_interface_test: RuntimeError # Issue 12087
 mirrors/generic_mixin_test: RuntimeError # Issue 12333
 mirrors/generic_mixin_applications_test: RuntimeError # Issue 12333
-mirrors/generics_substitution_test: RuntimeError # Issue 12087
+mirrors/generics_substitution_test/01: RuntimeError # Issue 12087
 mirrors/hierarchy_invariants_test: RuntimeError # Issue 11863
 mirrors/immutable_collections_test: RuntimeError # Issue 14030
 mirrors/initializing_formals_test/01: RuntimeError # Issue 6490
@@ -53,6 +49,12 @@
 mirrors/library_declarations_test/none: RuntimeError # Issue 13439, Issue 13733
 mirrors/library_metadata2_test/01: CompileTimeError # Issue 13633
 mirrors/library_uri_io_test: Skip # Not intended for dart2js as it uses dart:io.
+mirrors/metadata_allowed_values_test/01: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/05: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/10: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/11: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/13: MissingCompileTimeError # Issue 14548
+mirrors/metadata_allowed_values_test/14: MissingCompileTimeError # Issue 14548
 mirrors/method_mirror_name_test: RuntimeError # Issue 6335
 mirrors/method_mirror_properties_test: RuntimeError # Issue 11861
 mirrors/method_mirror_returntype_test : RuntimeError # Issue 11928
@@ -70,6 +72,7 @@
 mirrors/redirecting_factory_test/02: RuntimeError # Issue 6490
 mirrors/reflected_type_test: RuntimeError # Issue 12607
 mirrors/static_members_test: CompileTimeError # Issue 14633, Issue 12164
+mirrors/set_field_with_final_inheritance_test: RuntimeError # Issue 13919
 mirrors/symbol_validation_test: RuntimeError # Issue 13597
 mirrors/toplevel_members_test: CompileTimeError # Issue 14633, Issue 12164
 mirrors/type_argument_is_type_variable_test: RuntimeError # Issue 12333
@@ -79,10 +82,6 @@
 mirrors/type_variable_owner_test/01: RuntimeError # Issue 12785
 mirrors/generic_type_mirror_test/01: RuntimeError # 6490
 
-[ $compiler == dart2js && $unchecked ]
-mirrors/generic_bounded_test/02: RuntimeError # Issue 12087
-mirrors/generic_bounded_by_type_parameter_test/02: RuntimeError # Issue 12087
-
 [ $runtime == safari ]
 mirrors/return_type_test: Pass, Timeout # Issue 12858
 
@@ -183,6 +182,9 @@
 mirrors/typedef_test/01: Fail, OK # Incorrect dart2js behavior.
 
 mirrors/generic_f_bounded_test/01: RuntimeError # Issue 14000
+mirrors/generic_superclass_test/01: RuntimeError # Issue 14000
+mirrors/generic_type_mirror_test/02: RuntimeError # Issue 14613
+
 mirrors/symbol_validation_test: RuntimeError # Issue 13596
 
 mirrors/static_members_test: RuntimeError # Issue 14632
@@ -194,10 +196,10 @@
 async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
 
 [ $compiler == none && ( $runtime == drt || $runtime == dartium ) ]
+async/schedule_microtask6_test: Fail # Issue 10910
 mirrors/immutable_collections_test: Fail # Issue 11857, Issue 14321
 mirrors/library_uri_io_test: Skip # Not intended for drt as it uses dart:io.
 mirrors/local_isolate_test: Skip # http://dartbug.com/12188
-async/schedule_microtask6_test: Fail # Issue 10910
 
 [ $compiler == none && $runtime == drt && $mode == debug ]
 mirrors/hierarchy_invariants_test: Pass, Slow # Issue 14449
@@ -209,7 +211,6 @@
 [ $arch == simmips || $arch == mips ]
 convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12025.
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow
-typed_data/uint32x4_list_test: Pass, Crash # Issue 14644
 
 [ $arch == simarm ]
 convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12644.
@@ -218,6 +219,9 @@
 [ $compiler == none && $runtime == dartium ]
 async/schedule_microtask5_test: Pass, Timeout # Issue 13719: Please triage this failure.
 async/timer_cancel2_test: Pass, Timeout # Issue 13719: Please triage this failure.
+mirrors/find_in_context_test: Fail # Issue 13719: Needs VM flag
+mirrors/find_in_context_private_test: Fail # Issue 13719: Needs VM flag
+mirrors/find_in_context_fake_function_test: Fail # Issue 13719: Needs VM flag
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 # Issue 13921: spawnFunction is not allowed on Dartium's DOM thread.
@@ -249,6 +253,7 @@
 mirrors/equality_test/02: StaticWarning # Issue 14524
 mirrors/generic_f_bounded_mixin_application_test: CompileTimeError # Issue 14116
 mirrors/invoke_named_test: StaticWarning # Issue 14522
+mirrors/metadata_allowed_values_test/none: CompileTimeError # Issue 14688
 mirrors/private_symbol_test: StaticWarning # Issue 14524
 mirrors/reflect_class_test: StaticWarning # Issue 14524
 mirrors/type_variable_owner_test: StaticWarning # Issue 14524
@@ -262,7 +267,7 @@
 mirrors/find_in_context_fake_function_test: StaticWarning, OK # Implements Function without defining call.
 mirrors/immutable_collections_test: StaticWarning, OK # Expect failure for any type of Iterable.
 mirrors/inference_and_no_such_method_test: StaticWarning, OK # Expect to trigger noSuchMethod.
-mirrors/library_metadata2_test/01: StaticWarning, OK # Compile-time or run-time
+mirrors/library_metadata2_test/01: CompileTimeError # Test issue 14682
 
 mirrors/basic_types_in_dart_core_test: StaticWarning, OK # API being removed.
 mirrors/constructor_kinds_test/01: StaticWarning, OK # API being removed.
@@ -273,6 +278,7 @@
 mirrors/fake_function_with_call_test: StaticWarning, OK # API being removed.
 mirrors/generic_function_typedef_test: StaticWarning, OK # API being removed.
 mirrors/generic_type_mirror_test/01: StaticWarning, OK # API being removed.
+mirrors/generic_type_mirror_test/02: StaticWarning, OK # API being removed.
 mirrors/generic_type_mirror_test/none: StaticWarning, OK # API being removed.
 mirrors/generics_substitution_test: StaticWarning, OK # API being removed.
 mirrors/inherit_field_test: StaticWarning, OK # API being removed.
@@ -282,8 +288,6 @@
 mirrors/initializing_formals_test/none: StaticWarning, OK # API being removed.
 mirrors/intercepted_class_test: StaticWarning, OK # API being removed.
 mirrors/intercepted_object_test: StaticWarning, OK # API being removed.
-mirrors/invoke_closurization_test: StaticWarning, OK # API being removed.
-mirrors/invoke_test: StaticWarning, OK # API being removed.
 mirrors/lazy_static_test: StaticWarning, OK # API being removed.
 mirrors/libraries_test: StaticWarning, OK # API being removed.
 mirrors/library_metadata_test: StaticWarning, OK # API being removed.
diff --git a/tests/lib/mirrors/find_in_context_fake_function_test.dart b/tests/lib/mirrors/find_in_context_fake_function_test.dart
index 5ccfaee..93aeeb8 100644
--- a/tests/lib/mirrors/find_in_context_fake_function_test.dart
+++ b/tests/lib/mirrors/find_in_context_fake_function_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=--support_find_in_context=true
+
 // Regression test: this used to crash the VM.
 
 library test.find_in_context_fake_function;
diff --git a/tests/lib/mirrors/find_in_context_private_test.dart b/tests/lib/mirrors/find_in_context_private_test.dart
new file mode 100644
index 0000000..dc35893
--- /dev/null
+++ b/tests/lib/mirrors/find_in_context_private_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--support_find_in_context=true
+
+library test.find_in_context_private;
+
+import "dart:mirrors";
+import "package:expect/expect.dart";
+
+var _globalVariable = "globalVariable";
+_globalFoo() => 17;
+
+class S {
+  static _staticFooInS() => "staticFooInS";
+  static var _staticInS = "staticInS";
+  var _instanceInS = "instanceInS";
+}
+
+class C extends S {
+  static _staticFooInC() => "staticFooInC";
+  static var _staticInC = "staticInC";
+  var _instanceInC = "instanceInC";
+
+  _method() {
+    var _local = "local";
+    nested() {
+      var _innerLocal = "innerLocal";
+      print(this._instanceInC);
+      print(_local);
+      print(_innerLocal);
+    }
+    return nested;
+  }
+
+}
+
+doFindInContext(cm, name, value) {
+  Expect.equals(value,
+                cm.findInContext(name).reflectee);
+}
+dontFindInContext(cm, name) {
+  Expect.isNull(cm.findInContext(name));
+}
+
+main() {
+  LibraryMirror wrongLibrary = reflectClass(List).owner;
+  p(name) => MirrorSystem.getSymbol(name, wrongLibrary);
+
+  C c = new C();
+
+  // In the context of C._method.nested.
+  ClosureMirror cm = reflect(c._method());
+
+  // N.B.: innerLocal is only defined with respective to an activation of the
+  // closure 'nested', not the closure itself.
+  dontFindInContext(cm, #_innerLocal);
+
+  doFindInContext(cm, #_local, "local");
+  doFindInContext(cm, #_method, c._method);
+  doFindInContext(cm, #_instanceInC, "instanceInC");
+  doFindInContext(cm, #_staticInC, "staticInC");
+  doFindInContext(cm, #_staticFooInC, C._staticFooInC);
+  dontFindInContext(cm, #_staticInS);
+  dontFindInContext(cm, #_staticFooInS);
+  doFindInContext(cm, #_globalFoo, _globalFoo);
+  doFindInContext(cm, #_globalVariable, "globalVariable");
+
+  dontFindInContext(cm, p('_local'));
+  dontFindInContext(cm, p('_innerLocal'));
+  dontFindInContext(cm, p('_method'));
+  dontFindInContext(cm, p('_instanceInC'));
+  dontFindInContext(cm, p('_staticInC'));
+  dontFindInContext(cm, p('_staticFooInC'));
+  dontFindInContext(cm, p('_staticInS'));
+  dontFindInContext(cm, p('_staticFooInS'));
+  dontFindInContext(cm, p('_globalFoo'));
+  dontFindInContext(cm, p('_globalVariable'));
+
+  // In the context of C._method.
+  cm = reflect(c._method);
+  dontFindInContext(cm, #_innerLocal);
+  dontFindInContext(cm, #_local);  // N.B.: See above.
+  doFindInContext(cm, #_method, c._method);
+  doFindInContext(cm, #_instanceInC, "instanceInC");
+  doFindInContext(cm, #_staticInC, "staticInC");
+  doFindInContext(cm, #_staticFooInC, C._staticFooInC);
+  dontFindInContext(cm, #_staticInS);
+  dontFindInContext(cm, #_staticFooInS);
+  doFindInContext(cm, #_globalFoo, _globalFoo);
+  doFindInContext(cm, #_globalVariable, "globalVariable");
+
+  dontFindInContext(cm, p('_local'));
+  dontFindInContext(cm, p('_innerLocal'));
+  dontFindInContext(cm, p('_method'));
+  dontFindInContext(cm, p('_instanceInC'));
+  dontFindInContext(cm, p('_staticInC'));
+  dontFindInContext(cm, p('_staticFooInC'));
+  dontFindInContext(cm, p('_staticInS'));
+  dontFindInContext(cm, p('_staticFooInS'));
+  dontFindInContext(cm, p('_globalFoo'));
+  dontFindInContext(cm, p('_globalVariable'));
+}
diff --git a/tests/lib/mirrors/closure_mirror_find_in_context_test.dart b/tests/lib/mirrors/find_in_context_test.dart
similarity index 94%
rename from tests/lib/mirrors/closure_mirror_find_in_context_test.dart
rename to tests/lib/mirrors/find_in_context_test.dart
index b26a140..348cd3a 100644
--- a/tests/lib/mirrors/closure_mirror_find_in_context_test.dart
+++ b/tests/lib/mirrors/find_in_context_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=--support_find_in_context=true
+
 import "dart:mirrors";
 
 import "stringify.dart";
@@ -69,12 +71,16 @@
   Expect.equals(null, result);
 
   result = cm.findInContext(#staticFooInS);
+  Expect.isFalse(result is InstanceMirror);
+  Expect.equals(null, result);
+
+  result = cm.findInContext(#S.staticFooInS);
   Expect.isTrue(result is ClosureMirror);
   expect("Instance(value = staticFooInS)", result.apply(const []));
 
   result = cm.findInContext(#C.staticFooInS);
-  Expect.isTrue(result is ClosureMirror);
-  expect("Instance(value = staticFooInS)", result.apply(const []));
+  Expect.isFalse(result is InstanceMirror);
+  Expect.equals(null, result);
 
   result = cm.findInContext(#C.staticInC);
   expect("Instance(value = staticInC)", result);
diff --git a/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
index c6f2b16..92426d5 100644
--- a/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
+++ b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart
@@ -11,11 +11,20 @@
 import 'generics_helper.dart';
 
 class Super<T, R extends T> {}
-
 class Fixed extends Super<num, int> {}
-class Generic<X, Y> extends Super<X, Y> {}  /// 02: static type warning
+class Generic<X, Y> extends Super<X, Y> {} /// 02: static type warning
 class Malbounded extends Super<num, String> {} /// 01: static type warning
 
+bool inCheckedMode() {
+  try {
+    var s = 'string';
+    int i = s;
+  } catch(e) {
+    return true;
+  }
+  return false;
+}
+
 main() {
   ClassMirror superDecl = reflectClass(Super);
   ClassMirror superOfNumAndInt = reflectClass(Fixed).superclass;
@@ -23,18 +32,28 @@
   ClassMirror superOfXAndY = genericDecl.superclass;  /// 02: continued
   ClassMirror genericOfNumAndDouble = reflect(new Generic<num, double>()).type;  /// 02: continued
   ClassMirror superOfNumAndDouble = genericOfNumAndDouble.superclass;  /// 02: continued
-  ClassMirror genericOfNumAndBool = reflect(new Generic<num, bool>()).type;  /// 02: static type warning, dynamic type error
-  ClassMirror superOfNumAndBool = genericOfNumAndBool.superclass;  /// 02: continued
   ClassMirror superOfNumAndString = reflectClass(Malbounded).superclass;  /// 01: continued
 
+  try {
+    ClassMirror genericOfNumAndBool = reflect(new Generic<num, bool>()).type;  /// 02: static type warning
+    ClassMirror superOfNumAndBool = genericOfNumAndBool.superclass;  /// 02: continued
+    Expect.isFalse(genericOfNumAndBool.isOriginalDeclaration);  /// 02: continued
+    Expect.isFalse(superOfNumAndBool.isOriginalDeclaration);  /// 02: continued
+    typeParameters(genericOfNumAndBool, [#X, #Y]);  /// 02: continued
+    typeParameters(superOfNumAndBool, [#T, #R]);  /// 02: continued
+    typeArguments(genericOfNumAndBool, [reflectClass(num), reflectClass(bool)]);  /// 02: continued
+    typeArguments(superOfNumAndBool, [reflectClass(num), reflectClass(bool)]);  /// 02: continued
+    Expect.isFalse(inCheckedMode()); /// 02: continued
+  } on TypeError catch(e) {
+    Expect.isTrue(inCheckedMode());
+  }
+
   Expect.isTrue(superDecl.isOriginalDeclaration);
   Expect.isFalse(superOfNumAndInt.isOriginalDeclaration);
   Expect.isTrue(genericDecl.isOriginalDeclaration);  /// 02: continued
   Expect.isFalse(superOfXAndY.isOriginalDeclaration);   /// 02: continued
   Expect.isFalse(genericOfNumAndDouble.isOriginalDeclaration);  /// 02: continued
   Expect.isFalse(superOfNumAndDouble.isOriginalDeclaration);  /// 02: continued
-  Expect.isFalse(genericOfNumAndBool.isOriginalDeclaration);  /// 02: continued
-  Expect.isFalse(superOfNumAndBool.isOriginalDeclaration);  /// 02: continued
   Expect.isFalse(superOfNumAndString.isOriginalDeclaration);  /// 01: continued
 
   TypeVariableMirror tFromSuper = superDecl.typeVariables[0];
@@ -53,8 +72,6 @@
   typeParameters(superOfXAndY, [#T, #R]);  /// 02: continued
   typeParameters(genericOfNumAndDouble, [#X, #Y]);  /// 02: continued
   typeParameters(superOfNumAndDouble, [#T, #R]);  /// 02: continued
-  typeParameters(genericOfNumAndBool, [#X, #Y]);  /// 02: continued
-  typeParameters(superOfNumAndBool, [#T, #R]);  /// 02: continued
   typeParameters(superOfNumAndString, [#T, #R]);  /// 01: continued
 
   typeArguments(superDecl, []);
@@ -63,7 +80,5 @@
   typeArguments(superOfXAndY, [xFromGeneric, yFromGeneric]);  /// 02: continued
   typeArguments(genericOfNumAndDouble, [reflectClass(num), reflectClass(double)]);  /// 02: continued
   typeArguments(superOfNumAndDouble, [reflectClass(num), reflectClass(double)]);  /// 02: continued
-  typeArguments(genericOfNumAndBool, [reflectClass(num), reflectClass(bool)]);  /// 02: continued
-  typeArguments(superOfNumAndBool, [reflectClass(num), reflectClass(bool)]);  /// 02: continued
   typeArguments(superOfNumAndString, [reflectClass(num), reflectClass(String)]);  /// 01: continued
 }
diff --git a/tests/lib/mirrors/generic_bounded_test.dart b/tests/lib/mirrors/generic_bounded_test.dart
index dec144a..3cfac14 100644
--- a/tests/lib/mirrors/generic_bounded_test.dart
+++ b/tests/lib/mirrors/generic_bounded_test.dart
@@ -16,6 +16,16 @@
 class Generic<R> extends Super<R> {}  /// 02: static type warning
 class Malbounded extends Super<String> {} /// 01: static type warning
 
+bool inCheckedMode() {
+  try {
+    var s = 'string';
+    int i = s;
+  } catch(e) {
+    return true;
+  }
+  return false;
+}
+
 main() {
   ClassMirror superDecl = reflectClass(Super);
   ClassMirror superOfInt = reflectClass(Fixed).superclass;
@@ -23,8 +33,21 @@
   ClassMirror superOfR = genericDecl.superclass;  /// 02: continued
   ClassMirror genericOfDouble = reflect(new Generic<double>()).type;  /// 02: continued
   ClassMirror superOfDouble = genericOfDouble.superclass;  /// 02: continued
-  ClassMirror genericOfBool = reflect(new Generic<bool>()).type;  /// 02: static type warning, dynamic type error
-  ClassMirror superOfBool = genericOfBool.superclass;  /// 02: continued
+
+  try {
+    ClassMirror genericOfBool = reflect(new Generic<bool>()).type;  /// 02: static type warning
+    ClassMirror superOfBool = genericOfBool.superclass;  /// 02: continued
+    Expect.isFalse(genericOfBool.isOriginalDeclaration);  /// 02: continued
+    Expect.isFalse(superOfBool.isOriginalDeclaration);  /// 02: continued
+    typeParameters(genericOfBool, [#R]);  /// 02: continued
+    typeParameters(superOfBool, [#T]);  /// 02: continued
+    typeArguments(genericOfBool, [reflectClass(bool)]);  /// 02: continued
+    typeArguments(superOfBool, [reflectClass(bool)]);  /// 02: continued
+    Expect.isFalse(inCheckedMode()); /// 02: continued
+  } on TypeError catch(e) {
+    Expect.isTrue(inCheckedMode());
+  }
+
   ClassMirror superOfString = reflectClass(Malbounded).superclass;  /// 01: continued
 
   Expect.isTrue(superDecl.isOriginalDeclaration);
@@ -33,8 +56,7 @@
   Expect.isFalse(superOfR.isOriginalDeclaration);  /// 02: continued
   Expect.isFalse(genericOfDouble.isOriginalDeclaration);  /// 02: continued
   Expect.isFalse(superOfDouble.isOriginalDeclaration);  /// 02: continued
-  Expect.isFalse(genericOfBool.isOriginalDeclaration);  /// 02: continued
-  Expect.isFalse(superOfBool.isOriginalDeclaration);  /// 02: continued
+
   Expect.isFalse(superOfString.isOriginalDeclaration);  /// 01: continued
 
   TypeVariableMirror tFromSuper = superDecl.typeVariables.single;
@@ -49,8 +71,6 @@
   typeParameters(superOfR, [#T]);  /// 02: continued
   typeParameters(genericOfDouble, [#R]);  /// 02: continued
   typeParameters(superOfDouble, [#T]);  /// 02: continued
-  typeParameters(genericOfBool, [#R]);  /// 02: continued
-  typeParameters(superOfBool, [#T]);  /// 02: continued
   typeParameters(superOfString, [#T]);  /// 01: continued
 
   typeArguments(superDecl, []);
@@ -59,7 +79,5 @@
   typeArguments(superOfR, [rFromGeneric]);  /// 02: continued
   typeArguments(genericOfDouble, [reflectClass(double)]);  /// 02: continued
   typeArguments(superOfDouble, [reflectClass(double)]);  /// 02: continued
-  typeArguments(genericOfBool, [reflectClass(bool)]);  /// 02: continued
-  typeArguments(superOfBool, [reflectClass(bool)]);  /// 02: continued
   typeArguments(superOfString, [reflectClass(String)]);  /// 01: continued
 }
diff --git a/tests/lib/mirrors/generic_f_bounded_test.dart b/tests/lib/mirrors/generic_f_bounded_test.dart
index 00e4fbb..bd36860 100644
--- a/tests/lib/mirrors/generic_f_bounded_test.dart
+++ b/tests/lib/mirrors/generic_f_bounded_test.dart
@@ -27,8 +27,8 @@
   Expect.isTrue(realDecl.isOriginalDeclaration);
   Expect.isTrue(sorterDecl.isOriginalDeclaration);
   Expect.isTrue(realSorterDecl.isOriginalDeclaration);
-  Expect.isFalse(magnitudeOfReal.isOriginalDeclaration); ///  01: ok
-  Expect.isFalse(sorterOfReal.isOriginalDeclaration); ///  01: ok
+  Expect.isFalse(magnitudeOfReal.isOriginalDeclaration);
+  Expect.isFalse(sorterOfReal.isOriginalDeclaration);
 
   TypeVariableMirror tFromMagnitude = magnitudeDecl.typeVariables.single;
   TypeVariableMirror rFromSorter = sorterDecl.typeVariables.single;
@@ -52,7 +52,7 @@
   typeArguments(realDecl, []);
   typeArguments(sorterDecl, []);
   typeArguments(realSorterDecl, []);
-  typeArguments(magnitudeOfReal, [realDecl]); ///  01: ok
+  typeArguments(magnitudeOfReal, [realDecl]); /// 01: ok
   typeArguments(sorterOfReal, [realDecl]); /// 01: ok
   typeArguments(magnitudeOfR, [rFromSorter]);
 }
diff --git a/tests/lib/mirrors/generic_superclass_test.dart b/tests/lib/mirrors/generic_superclass_test.dart
new file mode 100644
index 0000000..ebf4c8c
--- /dev/null
+++ b/tests/lib/mirrors/generic_superclass_test.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'dart:mirrors';
+
+
+class A<T> {}
+class B extends A<U>{}
+class C extends A<C> {}
+class D<T> extends A<T> {}
+class E<X,Y> extends G<H<Y>> {}
+class F<X> implements A<X> {}
+class FF<X,Y> implements G<H<Y>> {}
+class G<T> {}
+class H<T> {}
+class U {}
+class R {}
+
+void testOriginals() {
+  ClassMirror a = reflectClass(A);
+  ClassMirror b = reflectClass(B);
+  ClassMirror c = reflectClass(C);
+  ClassMirror d = reflectClass(D);
+  ClassMirror e = reflectClass(E);
+  ClassMirror f = reflectClass(F);
+  ClassMirror ff = reflectClass(FF);
+  ClassMirror superA = a.superclass;
+  ClassMirror superB = b.superclass;
+  ClassMirror superC = c.superclass;
+  ClassMirror superD = d.superclass;
+  ClassMirror superE = e.superclass;
+  ClassMirror superInterfaceF = f.superinterfaces[0];
+  ClassMirror superInterfaceFF = ff.superinterfaces[0];
+
+  TypeVariableMirror aT = a.typeVariables[0];
+  TypeVariableMirror dT = d.typeVariables[0];
+  TypeVariableMirror eX = e.typeVariables[0];
+  TypeVariableMirror eY = e.typeVariables[1];
+  TypeVariableMirror fX = f.typeVariables[0];
+  TypeVariableMirror feX = ff.typeVariables[0];
+  TypeVariableMirror feY = ff.typeVariables[1];
+
+  Expect.isTrue(superA.isOriginalDeclaration);
+  Expect.isFalse(superB.isOriginalDeclaration);
+  Expect.isFalse(superC.isOriginalDeclaration);
+  Expect.isFalse(superD.isOriginalDeclaration);
+  Expect.isFalse(superE.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceF.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceFF.isOriginalDeclaration);
+
+  Expect.equals(reflectClass(Object), superA);
+  Expect.equals(reflect(new A<U>()).type, superB);
+  Expect.equals(reflect(new A<C>()).type, superC); /// 01: ok
+  Expect.equals(reflect(new U()).type, superB.typeArguments[0]);
+  Expect.equals(reflect(new C()).type, superC.typeArguments[0]); /// 01: ok
+  Expect.equals(dT, superD.typeArguments[0]);
+  Expect.equals(eY, superE.typeArguments[0].typeArguments[0]);
+  Expect.equals(feY, superInterfaceFF.typeArguments[0].typeArguments[0]);
+  Expect.equals(fX, superInterfaceF.typeArguments[0]);
+}
+
+void testInstances() {
+  ClassMirror a = reflect(new A<U>()).type;
+  ClassMirror b = reflect(new B()).type;
+  ClassMirror c = reflect(new C()).type;
+  ClassMirror d = reflect(new D<U>()).type;
+  ClassMirror e = reflect(new E<U,R>()).type;
+  ClassMirror e0 = reflect(new E<U,H<R>>()).type;
+  ClassMirror ff = reflect(new FF<U,R>()).type;
+  ClassMirror f = reflect(new F<U>()).type;
+  ClassMirror u = reflect(new U()).type;
+  ClassMirror r = reflect(new R()).type;
+  ClassMirror hr = reflect(new H<R>()).type;
+
+  ClassMirror superA = a.superclass;
+  ClassMirror superB = b.superclass;
+  ClassMirror superC = c.superclass;
+  ClassMirror superD = d.superclass;
+  ClassMirror superE = e.superclass;
+  ClassMirror superE0 = e0.superclass;
+  ClassMirror superInterfaceF = f.superinterfaces[0];
+  ClassMirror superInterfaceFF = ff.superinterfaces[0];
+
+  Expect.isTrue(superA.isOriginalDeclaration);
+  Expect.isFalse(superB.isOriginalDeclaration);
+  Expect.isFalse(superC.isOriginalDeclaration);
+  Expect.isFalse(superD.isOriginalDeclaration);
+  Expect.isFalse(superE.isOriginalDeclaration);
+  Expect.isFalse(superE0.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceF.isOriginalDeclaration);
+  Expect.isFalse(superInterfaceFF.isOriginalDeclaration);
+
+  Expect.equals(reflectClass(Object), superA);
+  Expect.equals(reflect(new A<U>()).type, superB);
+  Expect.equals(reflect(new A<C>()).type, superC); /// 01: ok
+  Expect.equals(reflect(new A<U>()).type, superD);
+  Expect.equals(reflect(new G<H<R>>()).type, superE);
+  Expect.equals(reflect(new G<H<H<R>>>()).type, superE0);
+  Expect.equals(reflect(new G<H<R>>()).type, superInterfaceFF);
+  Expect.equals(u, superB.typeArguments[0]);
+  Expect.equals(reflect(new C()).type, superC.typeArguments[0]); /// 01: ok
+  Expect.equals(u, superD.typeArguments[0]);
+  Expect.equals(r, superE.typeArguments[0].typeArguments[0]);
+  Expect.equals(hr, superE0.typeArguments[0].typeArguments[0]);
+  Expect.equals(r, superInterfaceFF.typeArguments[0].typeArguments[0]);
+  Expect.equals(u, superInterfaceF.typeArguments[0]);
+}
+
+void testObject() {
+  ClassMirror object = reflectClass(Object);
+  Expect.equals(null, object.superclass);
+}
+
+main() {
+  testOriginals();
+  testInstances();
+  testObject();
+}
\ No newline at end of file
diff --git a/tests/lib/mirrors/generic_type_mirror_test.dart b/tests/lib/mirrors/generic_type_mirror_test.dart
index 6b25a39..6b38328 100644
--- a/tests/lib/mirrors/generic_type_mirror_test.dart
+++ b/tests/lib/mirrors/generic_type_mirror_test.dart
@@ -11,27 +11,25 @@
   set bar(V v) {}
   W m() {}
   V n() {}
+  H<V> p() {}
   o(W w) {}
 }
-
+class H<T> {}
 class Bar {}
 class Baz {}
 
-main() {
-  testInstance();
-  testOriginalDeclaration();
-}
-
 void testInstance() {
   ClassMirror foo = reflect((new Foo<Bar, Baz>())).type;
   ClassMirror bar = reflect(new Bar()).type;
   ClassMirror baz = reflect(new Baz()).type;
+  ClassMirror hOfBaz = reflect(new H<Baz>()).type;
   VariableMirror field = foo.variables.values.single;
   MethodMirror getter = foo.getters.values.single;
   MethodMirror setter = foo.setters.values.single;
   MethodMirror m = foo.methods[const Symbol('m')];
   MethodMirror n = foo.methods[const Symbol('n')];
   MethodMirror o = foo.methods[const Symbol('o')];
+  MethodMirror p = foo.methods[const Symbol('p')];
 
   Expect.equals(foo, field.owner);
   Expect.equals(foo, getter.owner);
@@ -39,12 +37,17 @@
   Expect.equals(foo, m.owner);
   Expect.equals(foo, n.owner);
   Expect.equals(foo, o.owner);
+  Expect.equals(foo, p.owner);
 
   Expect.equals(baz, field.type); /// 01: ok
   Expect.equals(baz, getter.returnType);
   Expect.equals(bar, m.returnType);
   Expect.equals(baz, n.returnType);
   Expect.equals(bar, o.parameters.single.type);
+  Expect.equals(hOfBaz, p.returnType);  /// 02: ok
+  Expect.equals(1, p.returnType.typeArguments.length);
+  Expect.equals(baz, p.returnType.typeArguments[0]); /// 02: ok
+
   Expect.equals(baz, setter.parameters.single.type);
 
 }
@@ -58,6 +61,7 @@
   MethodMirror m = foo.methods[const Symbol('m')];
   MethodMirror n = foo.methods[const Symbol('n')];
   MethodMirror o = foo.methods[const Symbol('o')];
+  MethodMirror p = foo.methods[const Symbol('p')];
   TypeVariableMirror w = foo.typeVariables[0];
   TypeVariableMirror v = foo.typeVariables[1];
 
@@ -67,12 +71,20 @@
   Expect.equals(foo, m.owner);
   Expect.equals(foo, n.owner);
   Expect.equals(foo, o.owner);
+  Expect.equals(foo, p.owner);
 
   Expect.equals(v, field.type); /// 01: ok
   Expect.equals(v, getter.returnType);
   Expect.equals(w, m.returnType);
   Expect.equals(v, n.returnType);
   Expect.equals(w, o.parameters.single.type);
-  Expect.equals(v, setter.parameters.single.type);
+  Expect.equals(1, p.returnType.typeArguments.length);
+  Expect.equals(v, p.returnType.typeArguments[0]);
 
+  Expect.equals(v, setter.parameters.single.type);
+}
+
+main() {
+  testInstance();
+  testOriginalDeclaration();
 }
\ No newline at end of file
diff --git a/tests/lib/mirrors/generics_substitution_test.dart b/tests/lib/mirrors/generics_substitution_test.dart
index 8b2f16f..1d0e924 100644
--- a/tests/lib/mirrors/generics_substitution_test.dart
+++ b/tests/lib/mirrors/generics_substitution_test.dart
@@ -32,21 +32,21 @@
   Symbol r(ClassMirror cm) => cm.variables[#r].type.simpleName;
   Symbol s(ClassMirror cm) => cm.methods[#s].parameters[0].type.simpleName;
   Symbol t(ClassMirror cm) => cm.methods[#t].returnType.simpleName;
-  
-  Expect.equals(#T, r(genericDecl.superclass));
+
+  Expect.equals(#T, r(genericDecl.superclass)); /// 01: ok
   Expect.equals(#int, s(genericDecl.superclass));
   Expect.equals(#T, t(genericDecl));
 
-  Expect.equals(#String, r(genericOfString.superclass));
+  Expect.equals(#String, r(genericOfString.superclass)); /// 01: ok
   Expect.equals(#int, s(genericOfString.superclass));
   Expect.equals(#String, t(genericOfString));
 
-  Expect.equals(#R, r(superGenericDecl));
+  Expect.equals(#R, r(superGenericDecl)); /// 01: ok
   Expect.equals(#S, s(superGenericDecl));
 
-  Expect.equals(#T, r(superOfTAndInt));
+  Expect.equals(#T, r(superOfTAndInt)); /// 01: ok
   Expect.equals(#int, s(superOfTAndInt));
 
-  Expect.equals(#String, r(superOfStringAndInt));
+  Expect.equals(#String, r(superOfStringAndInt)); /// 01: ok
   Expect.equals(#int, s(superOfStringAndInt));
 }
diff --git a/tests/lib/mirrors/invoke_closurization_test.dart b/tests/lib/mirrors/invoke_closurization_test.dart
index 28cdd56..1039161 100644
--- a/tests/lib/mirrors/invoke_closurization_test.dart
+++ b/tests/lib/mirrors/invoke_closurization_test.dart
@@ -35,33 +35,6 @@
   Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
 }
 
-testAsync() {
-  var future;
-
-  C c = new C();
-  InstanceMirror im = reflect(c);
-  future = im.getFieldAsync(#instanceMethod);
-  expectValueThen(future, (result) {
-    Expect.isTrue(result.reflectee is Function, "Should be closure");
-    Expect.equals("A+B+C", result.reflectee('A', 'B', 'C'));
-  });
-
-  ClassMirror cm = reflectClass(C);
-  future = cm.getFieldAsync(#staticFunction);
-  expectValueThen(future, (result) {
-    Expect.isTrue(result.reflectee is Function, "Should be closure");
-    Expect.equals("A-B-C", result.reflectee('A', 'B', 'C'));
-  });
-
-  LibraryMirror lm = cm.owner;
-  future = lm.getFieldAsync(#libraryFunction);
-  expectValueThen(future, (result) {
-    Expect.isTrue(result.reflectee is Function, "Should be closure");
-    Expect.equals("A:B:C", result.reflectee('A', 'B', 'C'));
-  });
-}
-
 main() {
   testSync();
-  testAsync();
 }
diff --git a/tests/lib/mirrors/invoke_named_test.dart b/tests/lib/mirrors/invoke_named_test.dart
index da0b54b..feee0ab 100644
--- a/tests/lib/mirrors/invoke_named_test.dart
+++ b/tests/lib/mirrors/invoke_named_test.dart
@@ -121,99 +121,6 @@
                 'Unmatched named argument');
 }
 
-testAsyncInvoke(ObjectMirror om) {
-  Future<InstanceMirror> future;
-
-  future = om.invokeAsync(const Symbol('a'), ['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-B-null', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('b') : 'Y'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-null', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('c') : 'Z', const Symbol('b') : 'Y'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('a'), []);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = om.invokeAsync(const Symbol('a'), ['X', 'Y']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = om.invokeAsync(const Symbol('a'), ['X'], {const Symbol('undef') : 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  future = om.invokeAsync(const Symbol('b'), []);
-  expectValueThen(future, (result) {
-    Expect.equals('A-null-null', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('b'), [], {const Symbol('a') : 'X'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-null-null', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('b'), [], {const Symbol('b') :'Y', const Symbol('c') :'Z', const Symbol('a') :'X'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('b'), ['X']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = om.invokeAsync(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-  future = om.invokeAsync(const Symbol('c'), ['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-null-C', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('c'), ['X', 'Y']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-C', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('c'), ['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('c'), []);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = om.invokeAsync(const Symbol('c'), ['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = om.invokeAsync(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  future = om.invokeAsync(const Symbol('d'), []);
-  expectValueThen(future, (result) {
-    Expect.equals('null-B-C', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('d'), ['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-B-C', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('d'), ['X', 'Y']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-C', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('d'), ['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('d'), ['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = om.invokeAsync(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-  future = om.invokeAsync(const Symbol('e'), ['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = om.invokeAsync(const Symbol('e'), ['X']);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = om.invokeAsync(const Symbol('e'), ['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = om.invokeAsync(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-}
-
 testSyncNewInstance() {
   ClassMirror cm = reflectClass(E);
   InstanceMirror result;
@@ -291,102 +198,6 @@
                 'Unmatched named argument');
 }
 
-testAsyncNewInstance() {
-  ClassMirror cm = reflectClass(E);
-  Future<InstanceMirror> future;
-
-  future = cm.newInstanceAsync(const Symbol(''), ['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-B-null', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('b') : 'Y'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-null', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('c') : 'Z', const Symbol('b') : 'Y'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol(''), []);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = cm.newInstanceAsync(const Symbol(''), ['X', 'Y']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.newInstanceAsync(const Symbol(''), ['X'], {const Symbol('undef') : 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  future = cm.newInstanceAsync(const Symbol('b'), []);
-  expectValueThen(future, (result) {
-    Expect.equals('A-null-null', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('b'), [], {const Symbol('a') : 'X'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-null-null', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('b'), [], {const Symbol('b') :'Y', const Symbol('c') :'Z', const Symbol('a') :'X'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('b'), ['X']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.newInstanceAsync(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  future = cm.newInstanceAsync(const Symbol('c'), ['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-null-C', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('c'), ['X', 'Y']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-C', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('c'), ['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('c'), []);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = cm.newInstanceAsync(const Symbol('c'), ['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.newInstanceAsync(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  future = cm.newInstanceAsync(const Symbol('d'), []);
-  expectValueThen(future, (result) {
-    Expect.equals('null-B-C', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('d'), ['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-B-C', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('d'), ['X', 'Y']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-C', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('d'), ['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('d'), ['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.newInstanceAsync(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  future = cm.newInstanceAsync(const Symbol('e'), ['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('e'), ['X']);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = cm.newInstanceAsync(const Symbol('e'), ['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.newInstanceAsync(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-}
-
 testSyncApply() {
   ClosureMirror cm;
   InstanceMirror result;
@@ -469,125 +280,18 @@
                 'Unmatched named argument');
 }
 
-testAsyncApply() {
-  ClosureMirror cm;
-  Future<InstanceMirror> future;
-
-  cm = reflect(a);
-  future = cm.applyAsync(['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-B-null', result.reflectee);
-  });
-  future = cm.applyAsync(['X'], {const Symbol('b') : 'Y'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-null', result.reflectee);
-  });
-  future = cm.applyAsync(['X'], {const Symbol('c') : 'Z', const Symbol('b') : 'Y'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = cm.applyAsync([]);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = cm.applyAsync(['X', 'Y']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.applyAsync(['X'], {const Symbol('undef') : 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  cm = reflect(b);
-  future = cm.applyAsync([]);
-  expectValueThen(future, (result) {
-    Expect.equals('A-null-null', result.reflectee);
-  });
-  future = cm.applyAsync([], {const Symbol('a') : 'X'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-null-null', result.reflectee);
-  });
-  future = cm.applyAsync([], {const Symbol('b') :'Y', const Symbol('c') :'Z', const Symbol('a') :'X'});
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = cm.applyAsync(['X']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  cm = reflect(c);
-  future = cm.applyAsync(['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-null-C', result.reflectee);
-  });
-  future = cm.applyAsync(['X', 'Y']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-C', result.reflectee);
-  });
-  future = cm.applyAsync(['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = cm.applyAsync([]);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = cm.applyAsync(['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  cm = reflect(d);
-  future = cm.applyAsync([]);
-  expectValueThen(future, (result) {
-    Expect.equals('null-B-C', result.reflectee);
-  });
-  future = cm.applyAsync(['X']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-B-C', result.reflectee);
-  });
-  future = cm.applyAsync(['X', 'Y']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-C', result.reflectee);
-  });
-  future = cm.applyAsync(['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = cm.applyAsync(['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-
-
-  cm = reflect(e);
-  future = cm.applyAsync(['X', 'Y', 'Z']);
-  expectValueThen(future, (result) {
-    Expect.equals('X-Y-Z', result.reflectee);
-  });
-  future = cm.applyAsync(['X']);
-  expectError(future, isNoSuchMethodError, 'Insufficient positional arguments');
-  future = cm.applyAsync(['X', 'Y', 'Z', 'W']);
-  expectError(future, isNoSuchMethodError, 'Extra positional arguments');
-  future = cm.applyAsync(['X'], {const Symbol('undef'): 'Y'});
-  expectError(future, isNoSuchMethodError, 'Unmatched named argument');
-}
-
 main() {
   isDart2js = true; /// 01: ok
 
   testSyncInvoke(reflect(new C())); // InstanceMirror
-  if (!isDart2js) testSyncInvoke(reflectClass(D)); // ClassMirror
-  LibraryMirror lib = reflectClass(D).owner;
-  if (!isDart2js) testSyncInvoke(lib); // LibraryMirror
-
-  testAsyncInvoke(reflect(new C())); // InstanceMirror
 
   if (isDart2js) return;
 
-  testAsyncInvoke(reflectClass(D)); // ClassMirror
-  testAsyncInvoke(lib); // LibraryMirror
+  testSyncInvoke(reflectClass(D)); // ClassMirror
+  LibraryMirror lib = reflectClass(D).owner;
+  testSyncInvoke(lib); // LibraryMirror
 
   testSyncNewInstance();
-  testAsyncNewInstance();
 
   testSyncApply();
-  testAsyncApply();
 }
diff --git a/tests/lib/mirrors/invoke_private_test.dart b/tests/lib/mirrors/invoke_private_test.dart
index 160d3ea..091ba31 100644
--- a/tests/lib/mirrors/invoke_private_test.dart
+++ b/tests/lib/mirrors/invoke_private_test.dart
@@ -2,12 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.invoke_test;
+library test.invoke_private_test;
 
 import 'dart:mirrors';
 
 import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
 
 class C {
   var _field;
diff --git a/tests/lib/mirrors/invoke_test.dart b/tests/lib/mirrors/invoke_test.dart
index 2d225d1..ec5056f 100644
--- a/tests/lib/mirrors/invoke_test.dart
+++ b/tests/lib/mirrors/invoke_test.dart
@@ -9,7 +9,6 @@
 import 'dart:async' show Future;
 
 import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
 
 class C {
   var field;
@@ -34,33 +33,6 @@
 set librarySetter(v) => libraryField = 'lset $v';
 libraryFunction(x,y) => '$x$y';
 
-Future expectValueThen(Future future, Function onValue) {
-  asyncStart();
-  wrappedOnValue(resultIn) {
-    var resultOut = onValue(resultIn);
-    asyncEnd();
-    return resultOut;
-  }
-  onError(e) {
-    Expect.fail("Value expected. ($e)");
-  }
-  return future.then(wrappedOnValue, onError: onError);
-}
-
-Future expectError(Future future, Function errorPredicate, String reason) {
-  asyncStart();
-  onValue(result) {
-    Expect.fail("Error expected ($reason)");
-  }
-  onError(e) {
-    asyncEnd();
-    if (!errorPredicate(e)) {
-      Expect.fail("Unexpected error ($reason)");
-    }
-  }
-  return future.then(onValue, onError: onError);
-}
-
 bool isNoSuchMethodError(e) {
   return e is NoSuchMethodError;
 }
@@ -181,177 +153,6 @@
                 'Not defined');
 }
 
-testAsync() {
-  var future;
-
-  // InstanceMirror invoke
-  C c = new C();
-  InstanceMirror im = reflect(c);
-  future = im.invokeAsync(const Symbol('method'), [2,4,8]);
-  expectValueThen(future, (result) {
-    Expect.equals('2+4+8', result.reflectee);
-  });
-  future = im.invokeAsync(const Symbol('method'), [im,im,im]);
-  expectValueThen(future, (result) {
-    Expect.equals('a C+a C+a C', result.reflectee);
-  });
-  future = im.invokeAsync(const Symbol('doesntExist'), [2,4,8]);
-  expectValueThen(future, (result) {
-    Expect.equals('DNU', result.reflectee);
-  });
-  future = im.invokeAsync(const Symbol('method'), [2, 4]);  // Wrong arity.
-  expectValueThen(future, (result) {
-    Expect.equals('DNU', result.reflectee);
-  });
-
-  // InstanceMirror invokeGetter
-  future = im.getFieldAsync(const Symbol('getter'));
-  expectValueThen(future, (result) {
-    Expect.equals('get default', result.reflectee);
-  });
-  future = im.getFieldAsync(const Symbol('field'));
-  expectValueThen(future, (result) {
-    Expect.equals('default', result.reflectee);
-  });
-  future = im.getFieldAsync(const Symbol('doesntExist'));
-  expectValueThen(future, (result) {
-    Expect.equals('DNU', result.reflectee);
-  });
-
-  // InstanceMirror invokeSetter
-  future = im.setFieldAsync(const Symbol('setter'), 'foo');
-  expectValueThen(future, (result) {
-    Expect.equals('foo', result.reflectee);
-    Expect.equals('set foo', c.field);
-    return im.setFieldAsync(const Symbol('field'), 'bar');
-  }).then((result) {
-    Expect.equals('bar', result.reflectee);
-    Expect.equals('bar', c.field);
-    return im.setFieldAsync(const Symbol('field'), im);
-  }).then((result) {
-    Expect.equals(im.reflectee, result.reflectee);
-    Expect.equals(c, c.field);
-  });
-  future = im.setFieldAsync(const Symbol('doesntExist'), 'bar');
-  expectValueThen(future, (result) {
-      Expect.equals('bar', result.reflectee);
-  });
-
-
-  // ClassMirror invoke
-  ClassMirror cm = reflectClass(C);
-  future = cm.invokeAsync(const Symbol('staticFunction'),[3,4]);
-  expectValueThen(future, (result) {
-    Expect.equals('(3,4)', result.reflectee);
-  });
-  future = cm.invokeAsync(const Symbol('staticFunction'),[im,im]);
-  expectValueThen(future, (result) {
-    Expect.equals('(a C,a C)', result.reflectee);
-  });
-  future = cm.invokeAsync(const Symbol('doesntExist'),[im,im]);
-  expectError(future, isNoSuchMethodError, 'Not defined');
-  future = cm.invokeAsync(const Symbol('staticFunction'),[3]);
-  expectError(future, isNoSuchMethodError, 'Wrong arity');
-
-  // ClassMirror invokeGetter
-  C.staticField = 'initial';  // Reset from synchronous test.
-  future = cm.getFieldAsync(const Symbol('staticGetter'));
-  expectValueThen(future, (result) {
-    Expect.equals('sget initial', result.reflectee);
-  });
-  future = cm.getFieldAsync(const Symbol('staticField'));
-  expectValueThen(future, (result) {
-    Expect.equals('initial', result.reflectee);
-  });
-  future = cm.getFieldAsync(const Symbol('doesntExist'));
-  expectError(future, isNoSuchMethodError, 'Not defined');
-
-  // ClassMirror invokeSetter
-  future = cm.setFieldAsync(const Symbol('staticSetter'), 'sfoo');
-  expectValueThen(future, (result) {
-    Expect.equals('sfoo', result.reflectee);
-    Expect.equals('sset sfoo', C.staticField);
-    return cm.setFieldAsync(const Symbol('staticField'), 'sbar');
-  }).then((result) {
-    Expect.equals('sbar', result.reflectee);
-    Expect.equals('sbar', C.staticField);
-    return cm.setFieldAsync(const Symbol('staticField'), im);
-  }).then((result) {
-    Expect.equals(im.reflectee, result.reflectee);
-    Expect.equals(c, C.staticField);
-  });
-  future = cm.setFieldAsync(const Symbol('doesntExist'), 'sbar');
-  expectError(future, isNoSuchMethodError, 'Not defined');
-
-  // ClassMirror invokeConstructor
-  future = cm.newInstanceAsync(const Symbol(''), []);
-  expectValueThen(future, (result) {
-    Expect.isTrue(result.reflectee is C);
-    Expect.equals('default', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('named'), ['my value']);
-  expectValueThen(future, (result) {
-    Expect.isTrue(result.reflectee is C);
-    Expect.equals('my value', result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('named'), [im]);
-  expectValueThen(future, (result) {
-    Expect.isTrue(result.reflectee is C);
-    Expect.equals(c, result.reflectee.field);
-  });
-  future = cm.newInstanceAsync(const Symbol('doesntExist'), ['my value']);
-  expectError(future, isNoSuchMethodError, 'Not defined');
-  future = cm.newInstanceAsync(const Symbol('named'), []);
-  expectError(future, isNoSuchMethodError, 'Wrong arity');
-
-
-  // LibraryMirror invoke
-  LibraryMirror lm = cm.owner;
-  future = lm.invokeAsync(const Symbol('libraryFunction'),[':',')']);
-  expectValueThen(future, (result) {
-    Expect.equals(':)', result.reflectee);
-  });
-  future = lm.invokeAsync(const Symbol('libraryFunction'),[im,im]);
-  expectValueThen(future, (result) {
-    Expect.equals('a Ca C', result.reflectee);
-  });
-  future = lm.invokeAsync(const Symbol('doesntExist'),[im,im]);
-  expectError(future, isNoSuchMethodError, 'Not defined');
-  future = lm.invokeAsync(const Symbol('libraryFunction'),[':']);
-  expectError(future, isNoSuchMethodError, 'Wrong arity');
-
-  // LibraryMirror invokeGetter
-  libraryField = 'a priori'; // Reset from synchronous test.
-  future = lm.getFieldAsync(const Symbol('libraryGetter'));
-  expectValueThen(future, (result) {
-    Expect.equals('lget a priori', result.reflectee);
-  });
-  future = lm.getFieldAsync(const Symbol('libraryField'));
-  expectValueThen(future, (result) {
-    Expect.equals('a priori', result.reflectee);
-  });
-  future = lm.getFieldAsync(const Symbol('doesntExist'));
-  expectError(future, isNoSuchMethodError, 'Not defined');
-
-  // LibraryMirror invokeSetter
-  future = lm.setFieldAsync(const Symbol('librarySetter'), 'lfoo');
-  expectValueThen(future, (result) {
-    Expect.equals('lfoo', result.reflectee);
-    Expect.equals('lset lfoo', libraryField);
-    return lm.setFieldAsync(const Symbol('libraryField'), 'lbar');
-  }).then((result) {
-    Expect.equals('lbar', result.reflectee);
-    Expect.equals('lbar', libraryField);
-    return lm.setFieldAsync(const Symbol('libraryField'), im);
-  }).then((result) {
-    Expect.equals(im.reflectee, result.reflectee);
-    Expect.equals(c, libraryField);
-  });
-  future = lm.setFieldAsync(const Symbol('doesntExist'), 'lbar');
-  expectError(future, isNoSuchMethodError, 'Not defined');
-}
-
 main() {
   testSync();
-  testAsync();
 }
diff --git a/tests/lib/mirrors/metadata_allowed_values_import.dart b/tests/lib/mirrors/metadata_allowed_values_import.dart
new file mode 100644
index 0000000..67df4e2
--- /dev/null
+++ b/tests/lib/mirrors/metadata_allowed_values_import.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Imported {
+  const Imported();
+  const Imported.named();
+  static const CONSTANT = 0;
+}
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
new file mode 100644
index 0000000..77e7374
--- /dev/null
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.metadata_with_type_literal;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+import 'metadata_allowed_values_import.dart';  // Unprefixed.
+import 'metadata_allowed_values_import.dart' as prefix;
+
+@A  /// 01: compile-time error
+class A {}
+
+@B.CONSTANT
+class B {
+  static const CONSTANT = 3;
+}
+
+@C(3)
+class C {
+  final field;
+  const C(this.field);
+}
+
+@D.named(4)
+class D {
+  final field;
+  const D.named(this.field);
+}
+
+@E.NOT_CONSTANT  /// 02: compile-time error
+class E {
+  static var NOT_CONSTANT = 3;
+}
+
+@F(6)  /// 03: compile-time error
+class F {
+  final field;
+  F(this.field);
+}
+
+@G.named(4)  /// 04: compile-time error
+class G {
+  final field;
+  G.named(this.field);
+}
+
+@H<int>()  /// 05: compile-time error
+class H<T> {
+  const H();
+}
+
+@I[0]  /// 06: compile-time error
+class I {}
+
+@this.toString  /// 07: compile-time error
+class J {}
+
+@super.toString  /// 08: compile-time error
+class K {}
+
+@L.func()  /// 09: compile-time error
+class L {
+  static func() => 6;
+}
+
+@Imported  /// 10: compile-time error
+class M {}
+
+@Imported()
+class N {}
+
+@Imported.named()
+class O {}
+
+@Imported.CONSTANT
+class P {}
+
+@prefix.Imported  /// 11: compile-time error
+class Q {}
+
+@prefix.Imported()
+class R {}
+
+@prefix.Imported.named()
+class S {}
+
+@prefix.Imported.CONSTANT
+class T {}
+
+@U..toString()  /// 12: compile-time error
+class U {}
+
+@V.tearOff  /// 13: compile-time error
+class V {
+  static tearOff() {}
+}
+
+topLevelTearOff() => 4;
+
+@topLevelTearOff  /// 14: compile-time error
+class W {}
+
+@TypeParameter  /// 15: compile-time error
+class X<TypeParameter> {}
+
+@TypeParameter.member  /// 16: compile-time error
+class Y<TypeParameter> {}
+
+@1  /// 17: compile-time error
+class Z {}
+
+@3.14  /// 18: compile-time error
+class AA {}
+
+@'string'  /// 19: compile-time error
+class BB {}
+
+@#symbol  /// 20: compile-time error
+class CC {}
+
+@['element']  /// 21: compile-time error
+class DD {}
+
+@{'key': 'value'}  /// 22: compile-time error
+class EE {}
+
+@true  /// 23: compile-time error
+class FF {}
+
+@false  /// 24: compile-time error
+class GG {}
+
+@null  /// 25: compile-time error
+class HH {}
+
+const a = const [1, 2, 3];
+@a
+class II {}
+
+@a[0]  /// 26: compile-time error
+class JJ {}
+
+checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
+  Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
+}
+
+main() {
+  reflectClass(A).metadata;
+  checkMetadata(reflectClass(B), [B.CONSTANT]);
+  checkMetadata(reflectClass(C), [const C(3)]);
+  checkMetadata(reflectClass(D), [const D.named(4)]);
+  reflectClass(E).metadata;
+  reflectClass(F).metadata;
+  reflectClass(G).metadata;
+  reflectClass(H).metadata;
+  reflectClass(I).metadata;
+  reflectClass(J).metadata;
+  reflectClass(K).metadata;
+  reflectClass(L).metadata;
+  reflectClass(M).metadata;
+  checkMetadata(reflectClass(N), [const Imported()]);
+  checkMetadata(reflectClass(O), [const Imported.named()]);
+  checkMetadata(reflectClass(P), [Imported.CONSTANT]);
+  reflectClass(Q).metadata;
+  checkMetadata(reflectClass(R), [const prefix.Imported()]);
+  checkMetadata(reflectClass(S), [const prefix.Imported.named()]);
+  checkMetadata(reflectClass(T), [prefix.Imported.CONSTANT]);
+  reflectClass(U).metadata;
+  reflectClass(V).metadata;
+  reflectClass(W).metadata;
+  reflectClass(X).metadata;
+  reflectClass(Y).metadata;
+  reflectClass(Z).metadata;
+  reflectClass(AA).metadata;
+  reflectClass(BB).metadata;
+  reflectClass(CC).metadata;
+  reflectClass(DD).metadata;
+  reflectClass(EE).metadata;
+  reflectClass(FF).metadata;
+  reflectClass(GG).metadata;
+  reflectClass(HH).metadata;
+  reflectClass(II).metadata;
+  reflectClass(JJ).metadata;
+}
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 69210a3..2cfde98 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -63,18 +63,6 @@
          throws);  // Wrong arity.
 }
 
-testInstanceFieldAccess(mirrors) {
-  var instance = new Class();
-  var instMirror = reflect(instance);
-
-  instMirror.setFieldAsync(#field, 44);
-  instMirror.getFieldAsync(#field).then(
-      expectAsync1((resultMirror) {
-        expect(resultMirror.reflectee, equals(44));
-        expect(instance.field, equals(44));
-      }));
-}
-
 /// In dart2js, lists, numbers, and other objects are treated special
 /// and their methods are invoked through a techique called interceptors.
 testIntercepted(mirrors) {
@@ -115,27 +103,6 @@
   expect(libMirror.getField(#topLevelField).reflectee,
          equals([91]));
   expect(topLevelField, equals([91]));
-
-  libMirror.setFieldAsync(#topLevelField, 42);
-  future = libMirror.getFieldAsync(#topLevelField);
-  future.then(expectAsync1((resultMirror) {
-    expect(resultMirror.reflectee, equals(42));
-    expect(topLevelField, equals(42));
-  }));
-
-  classMirror.setFieldAsync(#staticField, 43);
-  future = classMirror.getFieldAsync(#staticField);
-  future.then(expectAsync1((resultMirror) {
-    expect(resultMirror.reflectee, equals(43));
-    expect(Class.staticField, equals(43));
-  }));
-
-  instMirror.setFieldAsync(#field, 44);
-  future = instMirror.getFieldAsync(#field);
-  future.then(expectAsync1((resultMirror) {
-    expect(resultMirror.reflectee, equals(44));
-    expect(instance.field, equals(44));
-  }));
 }
 
 testClosureMirrors(mirrors) {
@@ -150,11 +117,6 @@
   expect(funcMirror.parameters.length, equals(3));
 
   expect(mirror.apply([7, 8, 9]).reflectee, equals(24));
-
-  var future = mirror.applyAsync([2, 4, 8]);
-  future.then(expectAsync1((resultMirror) {
-    expect(resultMirror.reflectee, equals(14));
-  }));
 }
 
 testInvokeConstructor(mirrors) {
@@ -189,21 +151,6 @@
                                            [10]);
   expect(instanceMirror.reflectee is Class, equals(true));
   expect(instanceMirror.reflectee.field, equals(30));
-
-
-  var future = classMirror.newInstanceAsync(const Symbol(''), []);
-  future.then(expectAsync1((resultMirror) {
-    var instance = resultMirror.reflectee;
-    expect(instance is Class, equals(true));
-    expect(instance.field, equals("default value"));
-  }));
-
-  future = classMirror.newInstanceAsync(#withInitialValue, [45]);
-  future.then(expectAsync1((resultMirror) {
-    var instance = resultMirror.reflectee;
-    expect(instance is Class, equals(true));
-    expect(instance.field, equals(45));
-  }));
 }
 
 testReflectClass(mirrors) {
@@ -265,7 +212,6 @@
 main() {
   var mirrors = currentMirrorSystem();
   test("Test reflective method invocation", () { testInvoke(mirrors); });
-  test("Test instance field access", () { testInstanceFieldAccess(mirrors); });
   test('Test intercepted objects', () { testIntercepted(mirrors); });
   test("Test field access", () { testFieldAccess(mirrors); });
   test("Test closure mirrors", () { testClosureMirrors(mirrors); });
diff --git a/tests/lib/mirrors/set_field_with_final_inheritance_test.dart b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart
new file mode 100644
index 0000000..6e1cd39
--- /dev/null
+++ b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.set_field_with_final_inheritance;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class S {
+  var sideEffect = 0;
+
+  var mutableWithInheritedMutable = 1;
+  final mutableWithInheritedFinal = 2;
+  set mutableWithInheritedSetter(x) => sideEffect = 3;
+
+  var finalWithInheritedMutable = 4;
+  final finalWithInheritedFinal = 5;
+  set finalWithInheritedSetter(x) => sideEffect = 6;
+
+  var setterWithInheritedMutable = 7;
+  final setterWithInheritedFinal = 8;
+  set setterWithInheritedSetter(x) => sideEffect = 9;
+}
+
+class C extends S {
+  var mutableWithInheritedMutable = 10;
+  var mutableWithInheritedFinal = 11;
+  var mutableWithInheritedSetter = 12;
+
+  final finalWithInheritedMutable = 13;
+  final finalWithInheritedFinal = 14;
+  final finalWithInheritedSetter = 15;
+
+  set setterWithInheritedMutable(x) => sideEffect = 16;
+  set setterWithInheritedFinal(x) => sideEffect = 17;
+  set setterWithInheritedSetter(x) => sideEffect = 18;
+
+  get superMutableWithInheritedMutable => super.mutableWithInheritedMutable;
+  get superMutableWithInheritedFinal => super.mutableWithInheritedFinal;
+
+  get superFinalWithInheritedMutable => super.finalWithInheritedMutable;
+  get superFinalWithInheritedFinal => super.finalWithInheritedFinal;
+
+  get superSetterWithInheritedMutable => super.setterWithInheritedMutable;
+  get superSetterWithInheritedFinal => super.setterWithInheritedFinal;
+}
+
+main() {
+  C c;
+  InstanceMirror im;
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(19, im.setField(#mutableWithInheritedMutable, 19).reflectee);
+  Expect.equals(19, c.mutableWithInheritedMutable);
+  Expect.equals(1, c.superMutableWithInheritedMutable);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(20, im.setField(#mutableWithInheritedFinal, 20).reflectee);
+  Expect.equals(20, c.mutableWithInheritedFinal);
+  Expect.equals(2, c.superMutableWithInheritedFinal);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(21, im.setField(#mutableWithInheritedSetter, 21).reflectee);
+  Expect.equals(21, c.mutableWithInheritedSetter);
+  Expect.equals(0, c.sideEffect);
+
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(22, im.setField(#finalWithInheritedMutable, 22).reflectee);
+  Expect.equals(13, c.finalWithInheritedMutable);
+  Expect.equals(22, c.superFinalWithInheritedMutable);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.throws(() => im.setField(#finalWithInheritedFinal, 23),
+                (e) => e is NoSuchMethodError);
+  Expect.equals(14, c.finalWithInheritedFinal);
+  Expect.equals(5, c.superFinalWithInheritedFinal);
+  Expect.equals(0, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(24, im.setField(#finalWithInheritedSetter, 24).reflectee);
+  Expect.equals(15, c.finalWithInheritedSetter);
+  Expect.equals(6, c.sideEffect);
+
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(25, im.setField(#setterWithInheritedMutable, 25).reflectee);
+  Expect.equals(7, c.setterWithInheritedMutable);
+  Expect.equals(7, c.superSetterWithInheritedMutable);
+  Expect.equals(16, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(26, im.setField(#setterWithInheritedFinal, 26).reflectee);
+  Expect.equals(8, c.setterWithInheritedFinal);
+  Expect.equals(8, c.superSetterWithInheritedFinal);
+  Expect.equals(17, c.sideEffect);
+
+  c = new C();
+  im = reflect(c);
+  Expect.equals(27, im.setField(#setterWithInheritedSetter, 27).reflectee);
+  Expect.equals(18, c.sideEffect);
+}
diff --git a/tests/lib/mirrors/set_field_with_final_test.dart b/tests/lib/mirrors/set_field_with_final_test.dart
new file mode 100644
index 0000000..63b07a5
--- /dev/null
+++ b/tests/lib/mirrors/set_field_with_final_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.set_field_with_final;
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class C {
+  final instanceField = 1;
+  get instanceGetter => 2;
+  static final staticFinal = 3;
+  static get staticGetter => 4;
+}
+
+final toplevelFinal = 5;
+get toplevelGetter => 6;
+
+main() {
+  InstanceMirror im = reflect(new C());
+  Expect.throws(() => im.setField(#instanceField, 7),
+                (e) => e is NoSuchMethodError);
+  Expect.throws(() => im.setField(#instanceGetter, 8),
+                (e) => e is NoSuchMethodError);
+
+  ClassMirror cm = im.type;
+  Expect.throws(() => cm.setField(#staticFinal, 9),
+                (e) => e is NoSuchMethodError);
+  Expect.throws(() => cm.setField(#staticGetter, 10),
+                (e) => e is NoSuchMethodError);
+
+  LibraryMirror lm = cm.owner;
+  Expect.throws(() => lm.setField(#toplevelFinal, 11),
+                (e) => e is NoSuchMethodError);
+  Expect.throws(() => lm.setField(#toplevelGetter, 12),
+                (e) => e is NoSuchMethodError);
+}
diff --git a/tests/lib/typed_data/float32x4_transpose_test.dart b/tests/lib/typed_data/float32x4_transpose_test.dart
index f408d74..ecb39fb 100644
--- a/tests/lib/typed_data/float32x4_transpose_test.dart
+++ b/tests/lib/typed_data/float32x4_transpose_test.dart
@@ -15,14 +15,16 @@
   var m1 = m[1];
   var m2 = m[2];
   var m3 = m[3];
-  var t0 = m0.interleaveXY(m1);
-  var t1 = m2.interleaveXY(m3);
-  var t2 = m0.interleaveZW(m1);
-  var t3 = m2.interleaveZW(m3);
-  m[0] = t0.interleaveXYPairs(t1);
-  m[1] = t0.interleaveZWPairs(t1);
-  m[2] = t2.interleaveXYPairs(t3);
-  m[3] = t2.interleaveZWPairs(t3);
+
+  var t0 = m0.shuffleMix(m1, Float32x4.XYXY);
+  var t1 = m2.shuffleMix(m3, Float32x4.XYXY);
+  m[0] = t0.shuffleMix(t1, Float32x4.XZXZ);
+  m[1] = t0.shuffleMix(t1, Float32x4.YWYW);
+
+  var t2 = m0.shuffleMix(m1, Float32x4.ZWZW);
+  var t3 = m2.shuffleMix(m3, Float32x4.ZWZW);
+  m[2] = t2.shuffleMix(t3, Float32x4.XZXZ);
+  m[3] = t2.shuffleMix(t3, Float32x4.YWYW);
 }
 
 void testTranspose(Float32x4List m, Float32x4List r) {
diff --git a/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart b/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
index 5186b60..9b47e9c 100644
--- a/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
+++ b/tests/lib/typed_data/float32x4_two_arg_shuffle_test.dart
@@ -12,7 +12,7 @@
 testWithZWInXY() {
   Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
-  Float32x4 c = a.withZWInXY(b);
+  Float32x4 c = b.shuffleMix(a, Float32x4.ZWZW);
   Expect.equals(7.0, c.x);
   Expect.equals(8.0, c.y);
   Expect.equals(3.0, c.z);
@@ -22,7 +22,7 @@
 testInterleaveXY() {
   Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
-  Float32x4 c = a.interleaveXY(b);
+  Float32x4 c = a.shuffleMix(b, Float32x4.XYXY).shuffle(Float32x4.XZYW);
   Expect.equals(1.0, c.x);
   Expect.equals(5.0, c.y);
   Expect.equals(2.0, c.z);
@@ -32,7 +32,7 @@
 testInterleaveZW() {
   Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
-  Float32x4 c = a.interleaveZW(b);
+  Float32x4 c = a.shuffleMix(b, Float32x4.ZWZW).shuffle(Float32x4.XZYW);
   Expect.equals(3.0, c.x);
   Expect.equals(7.0, c.y);
   Expect.equals(4.0, c.z);
@@ -42,7 +42,7 @@
 testInterleaveXYPairs() {
   Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
-  Float32x4 c = a.interleaveXYPairs(b);
+  Float32x4 c = a.shuffleMix(b, Float32x4.XYXY);
   Expect.equals(1.0, c.x);
   Expect.equals(2.0, c.y);
   Expect.equals(5.0, c.z);
@@ -52,7 +52,7 @@
 testInterleaveZWPairs() {
   Float32x4 a = new Float32x4(1.0, 2.0, 3.0, 4.0);
   Float32x4 b = new Float32x4(5.0, 6.0, 7.0, 8.0);
-  Float32x4 c = a.interleaveZWPairs(b);
+  Float32x4 c = a.shuffleMix(b, Float32x4.ZWZW);
   Expect.equals(3.0, c.x);
   Expect.equals(4.0, c.y);
   Expect.equals(7.0, c.z);
diff --git a/tests/lib/typed_data/uint32x4_shuffle_test.dart b/tests/lib/typed_data/uint32x4_shuffle_test.dart
new file mode 100644
index 0000000..f3335a8
--- /dev/null
+++ b/tests/lib/typed_data/uint32x4_shuffle_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10
+
+// Library tag to be able to run in html test framework.
+library uint32x4_shuffle_test;
+
+import "package:expect/expect.dart";
+import 'dart:typed_data';
+
+void testShuffle() {
+  var m = new Uint32x4(1, 2, 3, 4);
+  var c;
+  c = m.shuffle(Uint32x4.WZYX);
+  Expect.equals(4, c.x);
+  Expect.equals(3, c.y);
+  Expect.equals(2, c.z);
+  Expect.equals(1, c.w);
+}
+
+void testShuffleNonConstant(mask) {
+  var m = new Uint32x4(1, 2, 3, 4);
+  var c;
+  c = m.shuffle(mask);
+  if (mask == 1) {
+    Expect.equals(2, c.x);
+    Expect.equals(1, c.y);
+    Expect.equals(1, c.z);
+    Expect.equals(1, c.w);
+  } else {
+    Expect.equals(Uint32x4.YYYY + 1, mask);
+    Expect.equals(3, c.x);
+    Expect.equals(2, c.y);
+    Expect.equals(2, c.z);
+    Expect.equals(2, c.w);
+  }
+}
+
+void testShuffleMix() {
+  var m = new Uint32x4(1, 2, 3, 4);
+  var n = new Uint32x4(5, 6, 7, 8);
+  var c = m.shuffleMix(n, Uint32x4.XYXY);
+  Expect.equals(1, c.x);
+  Expect.equals(2, c.y);
+  Expect.equals(5, c.z);
+  Expect.equals(6, c.w);
+}
+
+main() {
+  var xxxx = Uint32x4.XXXX + 1;
+  var yyyy = Uint32x4.YYYY + 1;
+  for (int i = 0; i < 20; i++) {
+    testShuffle();
+    testShuffleNonConstant(xxxx);
+    testShuffleNonConstant(yyyy);
+    testShuffleMix();
+  }
+}
\ No newline at end of file
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index d764b39..7bf4ccf 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -9,6 +9,8 @@
 
 package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
 
+issue14236_test: Pass, Fail, Crash # Issue 14516.
+
 [ $runtime == vm ]
 package/package_isolate_test: Fail # Issue 12474
 
diff --git a/tools/VERSION b/tools/VERSION
index 8b57d3e..b4cf83b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 8
-BUILD 9
+BUILD 10
 PATCH 0
diff --git a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
index 524b928..a19ba4d 100644
--- a/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
+++ b/tools/dom/templates/html/impl/impl_XMLHttpRequest.darttemplate
@@ -4,36 +4,57 @@
 
 part of $LIBRARYNAME;
 
-/**
- * A utility for retrieving data from a URL.
- *
- * HttpRequest can be used to obtain data from http, ftp, and file
- * protocols.
- *
- * For example, suppose we're developing these API docs, and we
- * wish to retrieve the HTML of the top-level page and print it out.
- * The easiest way to do that would be:
- *
- *     HttpRequest.getString('http://api.dartlang.org').then((response) {
- *       print(response);
- *     });
- *
- * **Important**: With the default behavior of this class, your
- * code making the request should be served from the same origin (domain name,
- * port, and application layer protocol) as the URL you are trying to access
- * with HttpRequest. However, there are ways to
- * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#note-on-jsonp).
- *
- * See also:
- *
- * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
- * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
- * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
+ /**
+  * A client-side XHR request for getting data from a URL,
+  * formally known as XMLHttpRequest.
+  *
+  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
+  * and is useful for AJAX-style page updates.
+  *
+  * The simplest way to get the contents of a text file, such as a
+  * JSON-formatted file, is with [getString].
+  * For example, the following code gets the contents of a JSON file
+  * and prints its length:
+  *
+  *     var path = 'myData.json';
+  *     HttpRequest.getString(path)
+  *         .then((String fileContents) {
+  *           print(fileContents.length);
+  *         })
+  *         .catchError((Error error) {
+  *           print(error.toString());
+  *         });
+  *
+  * ## Fetching data from other servers
+  *
+  * For security reasons, browsers impose restrictions on requests
+  * made by embedded apps.
+  * With the default behavior of this class,
+  * the code making the request must be served from the same origin
+  * (domain name, port, and application layer protocol)
+  * as the requested resource.
+  * In the example above, the myData.json file must be co-located with the
+  * app that uses it.
+  * You might be able to
+  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
+  * by using CORS headers or JSONP.
+  *
+  * ## Other resources
+  *
+  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
+  * a tutorial from _A Game of Darts_,
+  * shows two different ways to use HttpRequest to get a JSON file.
+  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
+  * another tutorial from _A Game of Darts_,
+  * shows using HttpRequest with a custom server.
+  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
+  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
+  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
  */
 $(ANNOTATIONS)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
 
   /**
-   * Creates a URL get request for the specified [url].
+   * Creates a GET request for the specified [url].
    *
    * The server response must be a `text/` mime type for this request to
    * succeed.
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 477a617..19d5bbb 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1175,6 +1175,7 @@
     }
     args.add('--out=$outputFile');
     args.add(inputFile);
+    args.addAll(optionsFromFile['sharedOptions']);
     if (executable.endsWith('.dart')) {
       // Run the compiler script via the Dart VM.
       args.insert(0, executable);