Version 0.6.9.0 .

svn merge -r 25219:25244 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@25249 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 5d0b391..415102a 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -368,7 +368,7 @@
   var typedefs = {};
   var errors = {};
   
-  mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
+  mirrorMap.forEach((String mirrorName, ClassMirror mirror) {    
     if (includePrivate || !mirror.isPrivate) {
       var superclass = (mirror.superclass != null) ?
           mirror.superclass.qualifiedName : '';
@@ -377,7 +377,7 @@
       var clazz = new Class(mirrorName, superclass, _getComment(mirror), 
           interfaces.toList(), _getVariables(mirror.variables, includePrivate),
           _getMethods(mirror.methods, includePrivate),
-          _getAnnotations(mirror), mirror.qualifiedName);
+          _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName);
       _currentClass = mirror;
       
       if (isError(mirror.qualifiedName)) {
@@ -417,6 +417,15 @@
 }
 
 /**
+ * Returns a map of [Generic] objects constructed from the class mirror. 
+ */
+Map<String, Generic> _getGenerics(ClassMirror mirror) {
+  return new Map.fromIterable(mirror.typeVariables, 
+      key: (e) => e.toString(), 
+      value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
+}
+
+/**
  * Writes text to a file in the 'docs' directory.
  */
 void _writeToFile(String text, String filename) {
@@ -515,6 +524,9 @@
   /// Methods in the class.
   Map<String, Map<String, Method>> methods;
   
+  /// Generic infomation about the class. 
+  Map<String, Generic> generics;
+  
   String name;
   String superclass;
 
@@ -522,7 +534,7 @@
   List<String> annotations;
   
   Class(this.name, this.superclass, this.comment, this.interfaces, 
-      this.variables, this.methods, this.annotations, 
+      this.variables, this.methods, this.annotations, this.generics,
       String qualifiedName) : super(qualifiedName) {}
 
   /// Generates a map describing the [Class] object.
@@ -535,6 +547,7 @@
     classMap['variables'] = recurseMap(variables);
     classMap['methods'] = recurseMap(methods);
     classMap['annotations'] = new List.from(annotations);
+    classMap['generics'] = recurseMap(generics);
     return classMap;
   }
 }
@@ -637,3 +650,20 @@
     return parameterMap;
   }
 }
+
+/**
+ * A class containing properties of a Generic. 
+ */
+class Generic {
+  String name;
+  String type;
+  
+  Generic(this.name, this.type);
+  
+  Map toMap() {
+    return {
+      'name': name,
+      'type': type
+    };
+  }
+}
\ No newline at end of file
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 3ced5d0..fc0522a 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -324,7 +324,7 @@
 
 
 bool FileHandle::IsClosed() {
-  return IsClosing();
+  return IsClosing() && !HasPendingRead() && !HasPendingWrite();
 }
 
 
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index a3cc62b..c24ba4d 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -426,6 +426,8 @@
   }
 
   _NativeSocket accept() {
+    // Don't issue accept if we're closing.
+    if (isClosing || isClosed) return null;
     var socket = new _NativeSocket.normal();
     if (nativeAccept(socket) != true) return null;
     socket.localPort = localPort;
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 450aa2d..e967378 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -733,6 +733,9 @@
 
   var _owner;
   DeclarationMirror get owner {
+    if (_owner == null) {
+      _owner = _LocalClassMirrorImpl._library(_reflectee);
+    }
     if (_owner is! Mirror) {
       _owner = _owner.resolve(mirrors);
     }
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 81894fe..542eee4 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -229,31 +229,16 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(Float32x4_getXXXX, 1) {
+DEFINE_NATIVE_ENTRY(Float32x4_shuffle, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  float value = self.x();
-  return Float32x4::New(value, value, value, value);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_getYYYY, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  float value = self.y();
-  return Float32x4::New(value, value, value, value);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_getZZZZ, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  float value = self.z();
-  return Float32x4::New(value, value, value, value);
-}
-
-
-DEFINE_NATIVE_ENTRY(Float32x4_getWWWW, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Float32x4, self, arguments->NativeArgAt(0));
-  float value = self.w();
-  return Float32x4::New(value, value, value, value);
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(1));
+  int64_t m = mask.AsInt64Value();
+  float data[4] = { self.x(), self.y(), self.z(), self.w() };
+  float _x = data[m & 0x3];
+  float _y = data[(m >> 2) & 0x3];
+  float _z = data[(m >> 4) & 0x3];
+  float _w = data[(m >> 6) & 0x3];
+  return Float32x4::New(_x, _y, _z, _w);
 }
 
 
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index f2fde0d..15a8deb 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -2006,10 +2006,263 @@
   double get y native "Float32x4_getY";
   double get z native "Float32x4_getZ";
   double get w native "Float32x4_getW";
-  Float32x4 get xxxx native "Float32x4_getXXXX";
-  Float32x4 get yyyy native "Float32x4_getYYYY";
-  Float32x4 get zzzz native "Float32x4_getZZZZ";
-  Float32x4 get wwww native "Float32x4_getWWWW";
+  Float32x4 get xxxx => _shuffle(0x0);
+  Float32x4 get xxxy => _shuffle(0x40);
+  Float32x4 get xxxz => _shuffle(0x80);
+  Float32x4 get xxxw => _shuffle(0xC0);
+  Float32x4 get xxyx => _shuffle(0x10);
+  Float32x4 get xxyy => _shuffle(0x50);
+  Float32x4 get xxyz => _shuffle(0x90);
+  Float32x4 get xxyw => _shuffle(0xD0);
+  Float32x4 get xxzx => _shuffle(0x20);
+  Float32x4 get xxzy => _shuffle(0x60);
+  Float32x4 get xxzz => _shuffle(0xA0);
+  Float32x4 get xxzw => _shuffle(0xE0);
+  Float32x4 get xxwx => _shuffle(0x30);
+  Float32x4 get xxwy => _shuffle(0x70);
+  Float32x4 get xxwz => _shuffle(0xB0);
+  Float32x4 get xxww => _shuffle(0xF0);
+  Float32x4 get xyxx => _shuffle(0x4);
+  Float32x4 get xyxy => _shuffle(0x44);
+  Float32x4 get xyxz => _shuffle(0x84);
+  Float32x4 get xyxw => _shuffle(0xC4);
+  Float32x4 get xyyx => _shuffle(0x14);
+  Float32x4 get xyyy => _shuffle(0x54);
+  Float32x4 get xyyz => _shuffle(0x94);
+  Float32x4 get xyyw => _shuffle(0xD4);
+  Float32x4 get xyzx => _shuffle(0x24);
+  Float32x4 get xyzy => _shuffle(0x64);
+  Float32x4 get xyzz => _shuffle(0xA4);
+  Float32x4 get xyzw => _shuffle(0xE4);
+  Float32x4 get xywx => _shuffle(0x34);
+  Float32x4 get xywy => _shuffle(0x74);
+  Float32x4 get xywz => _shuffle(0xB4);
+  Float32x4 get xyww => _shuffle(0xF4);
+  Float32x4 get xzxx => _shuffle(0x8);
+  Float32x4 get xzxy => _shuffle(0x48);
+  Float32x4 get xzxz => _shuffle(0x88);
+  Float32x4 get xzxw => _shuffle(0xC8);
+  Float32x4 get xzyx => _shuffle(0x18);
+  Float32x4 get xzyy => _shuffle(0x58);
+  Float32x4 get xzyz => _shuffle(0x98);
+  Float32x4 get xzyw => _shuffle(0xD8);
+  Float32x4 get xzzx => _shuffle(0x28);
+  Float32x4 get xzzy => _shuffle(0x68);
+  Float32x4 get xzzz => _shuffle(0xA8);
+  Float32x4 get xzzw => _shuffle(0xE8);
+  Float32x4 get xzwx => _shuffle(0x38);
+  Float32x4 get xzwy => _shuffle(0x78);
+  Float32x4 get xzwz => _shuffle(0xB8);
+  Float32x4 get xzww => _shuffle(0xF8);
+  Float32x4 get xwxx => _shuffle(0xC);
+  Float32x4 get xwxy => _shuffle(0x4C);
+  Float32x4 get xwxz => _shuffle(0x8C);
+  Float32x4 get xwxw => _shuffle(0xCC);
+  Float32x4 get xwyx => _shuffle(0x1C);
+  Float32x4 get xwyy => _shuffle(0x5C);
+  Float32x4 get xwyz => _shuffle(0x9C);
+  Float32x4 get xwyw => _shuffle(0xDC);
+  Float32x4 get xwzx => _shuffle(0x2C);
+  Float32x4 get xwzy => _shuffle(0x6C);
+  Float32x4 get xwzz => _shuffle(0xAC);
+  Float32x4 get xwzw => _shuffle(0xEC);
+  Float32x4 get xwwx => _shuffle(0x3C);
+  Float32x4 get xwwy => _shuffle(0x7C);
+  Float32x4 get xwwz => _shuffle(0xBC);
+  Float32x4 get xwww => _shuffle(0xFC);
+  Float32x4 get yxxx => _shuffle(0x1);
+  Float32x4 get yxxy => _shuffle(0x41);
+  Float32x4 get yxxz => _shuffle(0x81);
+  Float32x4 get yxxw => _shuffle(0xC1);
+  Float32x4 get yxyx => _shuffle(0x11);
+  Float32x4 get yxyy => _shuffle(0x51);
+  Float32x4 get yxyz => _shuffle(0x91);
+  Float32x4 get yxyw => _shuffle(0xD1);
+  Float32x4 get yxzx => _shuffle(0x21);
+  Float32x4 get yxzy => _shuffle(0x61);
+  Float32x4 get yxzz => _shuffle(0xA1);
+  Float32x4 get yxzw => _shuffle(0xE1);
+  Float32x4 get yxwx => _shuffle(0x31);
+  Float32x4 get yxwy => _shuffle(0x71);
+  Float32x4 get yxwz => _shuffle(0xB1);
+  Float32x4 get yxww => _shuffle(0xF1);
+  Float32x4 get yyxx => _shuffle(0x5);
+  Float32x4 get yyxy => _shuffle(0x45);
+  Float32x4 get yyxz => _shuffle(0x85);
+  Float32x4 get yyxw => _shuffle(0xC5);
+  Float32x4 get yyyx => _shuffle(0x15);
+  Float32x4 get yyyy => _shuffle(0x55);
+  Float32x4 get yyyz => _shuffle(0x95);
+  Float32x4 get yyyw => _shuffle(0xD5);
+  Float32x4 get yyzx => _shuffle(0x25);
+  Float32x4 get yyzy => _shuffle(0x65);
+  Float32x4 get yyzz => _shuffle(0xA5);
+  Float32x4 get yyzw => _shuffle(0xE5);
+  Float32x4 get yywx => _shuffle(0x35);
+  Float32x4 get yywy => _shuffle(0x75);
+  Float32x4 get yywz => _shuffle(0xB5);
+  Float32x4 get yyww => _shuffle(0xF5);
+  Float32x4 get yzxx => _shuffle(0x9);
+  Float32x4 get yzxy => _shuffle(0x49);
+  Float32x4 get yzxz => _shuffle(0x89);
+  Float32x4 get yzxw => _shuffle(0xC9);
+  Float32x4 get yzyx => _shuffle(0x19);
+  Float32x4 get yzyy => _shuffle(0x59);
+  Float32x4 get yzyz => _shuffle(0x99);
+  Float32x4 get yzyw => _shuffle(0xD9);
+  Float32x4 get yzzx => _shuffle(0x29);
+  Float32x4 get yzzy => _shuffle(0x69);
+  Float32x4 get yzzz => _shuffle(0xA9);
+  Float32x4 get yzzw => _shuffle(0xE9);
+  Float32x4 get yzwx => _shuffle(0x39);
+  Float32x4 get yzwy => _shuffle(0x79);
+  Float32x4 get yzwz => _shuffle(0xB9);
+  Float32x4 get yzww => _shuffle(0xF9);
+  Float32x4 get ywxx => _shuffle(0xD);
+  Float32x4 get ywxy => _shuffle(0x4D);
+  Float32x4 get ywxz => _shuffle(0x8D);
+  Float32x4 get ywxw => _shuffle(0xCD);
+  Float32x4 get ywyx => _shuffle(0x1D);
+  Float32x4 get ywyy => _shuffle(0x5D);
+  Float32x4 get ywyz => _shuffle(0x9D);
+  Float32x4 get ywyw => _shuffle(0xDD);
+  Float32x4 get ywzx => _shuffle(0x2D);
+  Float32x4 get ywzy => _shuffle(0x6D);
+  Float32x4 get ywzz => _shuffle(0xAD);
+  Float32x4 get ywzw => _shuffle(0xED);
+  Float32x4 get ywwx => _shuffle(0x3D);
+  Float32x4 get ywwy => _shuffle(0x7D);
+  Float32x4 get ywwz => _shuffle(0xBD);
+  Float32x4 get ywww => _shuffle(0xFD);
+  Float32x4 get zxxx => _shuffle(0x2);
+  Float32x4 get zxxy => _shuffle(0x42);
+  Float32x4 get zxxz => _shuffle(0x82);
+  Float32x4 get zxxw => _shuffle(0xC2);
+  Float32x4 get zxyx => _shuffle(0x12);
+  Float32x4 get zxyy => _shuffle(0x52);
+  Float32x4 get zxyz => _shuffle(0x92);
+  Float32x4 get zxyw => _shuffle(0xD2);
+  Float32x4 get zxzx => _shuffle(0x22);
+  Float32x4 get zxzy => _shuffle(0x62);
+  Float32x4 get zxzz => _shuffle(0xA2);
+  Float32x4 get zxzw => _shuffle(0xE2);
+  Float32x4 get zxwx => _shuffle(0x32);
+  Float32x4 get zxwy => _shuffle(0x72);
+  Float32x4 get zxwz => _shuffle(0xB2);
+  Float32x4 get zxww => _shuffle(0xF2);
+  Float32x4 get zyxx => _shuffle(0x6);
+  Float32x4 get zyxy => _shuffle(0x46);
+  Float32x4 get zyxz => _shuffle(0x86);
+  Float32x4 get zyxw => _shuffle(0xC6);
+  Float32x4 get zyyx => _shuffle(0x16);
+  Float32x4 get zyyy => _shuffle(0x56);
+  Float32x4 get zyyz => _shuffle(0x96);
+  Float32x4 get zyyw => _shuffle(0xD6);
+  Float32x4 get zyzx => _shuffle(0x26);
+  Float32x4 get zyzy => _shuffle(0x66);
+  Float32x4 get zyzz => _shuffle(0xA6);
+  Float32x4 get zyzw => _shuffle(0xE6);
+  Float32x4 get zywx => _shuffle(0x36);
+  Float32x4 get zywy => _shuffle(0x76);
+  Float32x4 get zywz => _shuffle(0xB6);
+  Float32x4 get zyww => _shuffle(0xF6);
+  Float32x4 get zzxx => _shuffle(0xA);
+  Float32x4 get zzxy => _shuffle(0x4A);
+  Float32x4 get zzxz => _shuffle(0x8A);
+  Float32x4 get zzxw => _shuffle(0xCA);
+  Float32x4 get zzyx => _shuffle(0x1A);
+  Float32x4 get zzyy => _shuffle(0x5A);
+  Float32x4 get zzyz => _shuffle(0x9A);
+  Float32x4 get zzyw => _shuffle(0xDA);
+  Float32x4 get zzzx => _shuffle(0x2A);
+  Float32x4 get zzzy => _shuffle(0x6A);
+  Float32x4 get zzzz => _shuffle(0xAA);
+  Float32x4 get zzzw => _shuffle(0xEA);
+  Float32x4 get zzwx => _shuffle(0x3A);
+  Float32x4 get zzwy => _shuffle(0x7A);
+  Float32x4 get zzwz => _shuffle(0xBA);
+  Float32x4 get zzww => _shuffle(0xFA);
+  Float32x4 get zwxx => _shuffle(0xE);
+  Float32x4 get zwxy => _shuffle(0x4E);
+  Float32x4 get zwxz => _shuffle(0x8E);
+  Float32x4 get zwxw => _shuffle(0xCE);
+  Float32x4 get zwyx => _shuffle(0x1E);
+  Float32x4 get zwyy => _shuffle(0x5E);
+  Float32x4 get zwyz => _shuffle(0x9E);
+  Float32x4 get zwyw => _shuffle(0xDE);
+  Float32x4 get zwzx => _shuffle(0x2E);
+  Float32x4 get zwzy => _shuffle(0x6E);
+  Float32x4 get zwzz => _shuffle(0xAE);
+  Float32x4 get zwzw => _shuffle(0xEE);
+  Float32x4 get zwwx => _shuffle(0x3E);
+  Float32x4 get zwwy => _shuffle(0x7E);
+  Float32x4 get zwwz => _shuffle(0xBE);
+  Float32x4 get zwww => _shuffle(0xFE);
+  Float32x4 get wxxx => _shuffle(0x3);
+  Float32x4 get wxxy => _shuffle(0x43);
+  Float32x4 get wxxz => _shuffle(0x83);
+  Float32x4 get wxxw => _shuffle(0xC3);
+  Float32x4 get wxyx => _shuffle(0x13);
+  Float32x4 get wxyy => _shuffle(0x53);
+  Float32x4 get wxyz => _shuffle(0x93);
+  Float32x4 get wxyw => _shuffle(0xD3);
+  Float32x4 get wxzx => _shuffle(0x23);
+  Float32x4 get wxzy => _shuffle(0x63);
+  Float32x4 get wxzz => _shuffle(0xA3);
+  Float32x4 get wxzw => _shuffle(0xE3);
+  Float32x4 get wxwx => _shuffle(0x33);
+  Float32x4 get wxwy => _shuffle(0x73);
+  Float32x4 get wxwz => _shuffle(0xB3);
+  Float32x4 get wxww => _shuffle(0xF3);
+  Float32x4 get wyxx => _shuffle(0x7);
+  Float32x4 get wyxy => _shuffle(0x47);
+  Float32x4 get wyxz => _shuffle(0x87);
+  Float32x4 get wyxw => _shuffle(0xC7);
+  Float32x4 get wyyx => _shuffle(0x17);
+  Float32x4 get wyyy => _shuffle(0x57);
+  Float32x4 get wyyz => _shuffle(0x97);
+  Float32x4 get wyyw => _shuffle(0xD7);
+  Float32x4 get wyzx => _shuffle(0x27);
+  Float32x4 get wyzy => _shuffle(0x67);
+  Float32x4 get wyzz => _shuffle(0xA7);
+  Float32x4 get wyzw => _shuffle(0xE7);
+  Float32x4 get wywx => _shuffle(0x37);
+  Float32x4 get wywy => _shuffle(0x77);
+  Float32x4 get wywz => _shuffle(0xB7);
+  Float32x4 get wyww => _shuffle(0xF7);
+  Float32x4 get wzxx => _shuffle(0xB);
+  Float32x4 get wzxy => _shuffle(0x4B);
+  Float32x4 get wzxz => _shuffle(0x8B);
+  Float32x4 get wzxw => _shuffle(0xCB);
+  Float32x4 get wzyx => _shuffle(0x1B);
+  Float32x4 get wzyy => _shuffle(0x5B);
+  Float32x4 get wzyz => _shuffle(0x9B);
+  Float32x4 get wzyw => _shuffle(0xDB);
+  Float32x4 get wzzx => _shuffle(0x2B);
+  Float32x4 get wzzy => _shuffle(0x6B);
+  Float32x4 get wzzz => _shuffle(0xAB);
+  Float32x4 get wzzw => _shuffle(0xEB);
+  Float32x4 get wzwx => _shuffle(0x3B);
+  Float32x4 get wzwy => _shuffle(0x7B);
+  Float32x4 get wzwz => _shuffle(0xBB);
+  Float32x4 get wzww => _shuffle(0xFB);
+  Float32x4 get wwxx => _shuffle(0xF);
+  Float32x4 get wwxy => _shuffle(0x4F);
+  Float32x4 get wwxz => _shuffle(0x8F);
+  Float32x4 get wwxw => _shuffle(0xCF);
+  Float32x4 get wwyx => _shuffle(0x1F);
+  Float32x4 get wwyy => _shuffle(0x5F);
+  Float32x4 get wwyz => _shuffle(0x9F);
+  Float32x4 get wwyw => _shuffle(0xDF);
+  Float32x4 get wwzx => _shuffle(0x2F);
+  Float32x4 get wwzy => _shuffle(0x6F);
+  Float32x4 get wwzz => _shuffle(0xAF);
+  Float32x4 get wwzw => _shuffle(0xEF);
+  Float32x4 get wwwx => _shuffle(0x3F);
+  Float32x4 get wwwy => _shuffle(0x7F);
+  Float32x4 get wwwz => _shuffle(0xBF);
+  Float32x4 get wwww => _shuffle(0xFF);
+  Float32x4 _shuffle(int mask) native "Float32x4_shuffle";
   Float32x4 withX(double x) native "Float32x4_setX";
   Float32x4 withY(double y) native "Float32x4_setY";
   Float32x4 withZ(double z) native "Float32x4_setZ";
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 5bf8ad1..ef83acb 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -195,10 +195,7 @@
   V(Float32x4_getY, 1)                                                         \
   V(Float32x4_getZ, 1)                                                         \
   V(Float32x4_getW, 1)                                                         \
-  V(Float32x4_getXXXX, 1)                                                      \
-  V(Float32x4_getYYYY, 1)                                                      \
-  V(Float32x4_getZZZZ, 1)                                                      \
-  V(Float32x4_getWWWW, 1)                                                      \
+  V(Float32x4_shuffle, 2)                                                      \
   V(Float32x4_setX, 2)                                                         \
   V(Float32x4_setY, 2)                                                         \
   V(Float32x4_setZ, 2)                                                         \
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 7294784..f439def 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1024,6 +1024,42 @@
 }
 
 
+// Handles a static call in unoptimized code that has two argument types not
+// seen before. Compile the target if necessary and update the ICData.
+// Arg0: argument 0.
+// Arg1: argument 1.
+// Arg2: IC data object.
+DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) {
+  ASSERT(arguments.ArgCount() ==
+      kStaticCallMissHandlerTwoArgsRuntimeEntry.argument_count());
+  const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0));
+  const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1));
+  const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2));
+  // IC data for static call is prepopulated with the statically known target.
+  ASSERT(ic_data.NumberOfChecks() > 0);
+  const Function& target = Function::Handle(ic_data.GetTargetAt(0));
+  if (!target.HasCode()) {
+    const Error& error = Error::Handle(Compiler::CompileFunction(target));
+    if (!error.IsNull()) {
+      Exceptions::PropagateError(error);
+    }
+  }
+  ASSERT(!target.IsNull() && target.HasCode());
+  GrowableArray<intptr_t> cids(2);
+  cids.Add(arg0.GetClassId());
+  cids.Add(arg1.GetClassId());
+  ic_data.AddCheck(cids, target);
+  if (FLAG_trace_ic) {
+    DartFrameIterator iterator;
+    StackFrame* caller_frame = iterator.NextFrame();
+    ASSERT(caller_frame != NULL);
+    OS::PrintErr("StaticCallMissHandler at %#"Px" target %s (%"Pd", %"Pd")\n",
+        caller_frame->pc(), target.ToCString(), cids[0], cids[1]);
+  }
+  arguments.SetReturn(target);
+}
+
+
 // Handle a miss of a megamorphic cache.
 //   Arg0: Receiver.
 //   Arg1: ICData object.
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 2461594..6ec0c13 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -35,6 +35,7 @@
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs);
+DECLARE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs);
 DECLARE_RUNTIME_ENTRY(InstanceFunctionLookup);
 DECLARE_RUNTIME_ENTRY(Instanceof);
 DECLARE_RUNTIME_ENTRY(InstantiateType);
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index d68c938..9cccd56 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -91,7 +91,7 @@
 #if defined(DEBUG)
     ICData& test_ic_data = ICData::Handle();
     test_ic_data ^= ic_data();
-    ASSERT(test_ic_data.num_args_tested() == 0);
+    ASSERT(test_ic_data.num_args_tested() >= 0);
 #endif  // DEBUG
   }
 
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index ec9e56f..ae307d57 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -82,7 +82,7 @@
 #if defined(DEBUG)
     ICData& test_ic_data = ICData::Handle();
     test_ic_data ^= ic_data();
-    ASSERT(test_ic_data.num_args_tested() == 0);
+    ASSERT(test_ic_data.num_args_tested() >= 0);
 #endif  // DEBUG
   }
 
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 1a65c51..9b6d509 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -190,6 +190,7 @@
 const Register PP = R10;  // Caches object pool pointer in generated code.
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
+const Register ICREG = R5;  // IC data register.
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index c679e12..acc1898 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -65,6 +65,7 @@
 const Register PP = kNoRegister;  // No object pool pointer.
 const Register SPREG = ESP;  // Stack pointer register.
 const Register FPREG = EBP;  // Frame pointer register.
+const Register ICREG = ECX;  // IC data register.
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index bb16ccd..006280b 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -174,6 +174,7 @@
 const Register PP = S7;  // Caches object pool pointer in generated code.
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
+const Register ICREG = S5;  // IC data register.
 
 // The code that generates a comparison can be far away from the code that
 // generates the branch that uses the result of that comparison. In this case,
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 8cc827c..3fa9526 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -89,6 +89,7 @@
 const Register PP = kNoRegister;  // No object pool pointer.
 const Register SPREG = RSP;  // Stack pointer register.
 const Register FPREG = RBP;  // Frame pointer register.
+const Register ICREG = RBX;  // IC data register.
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 554ae8a..449c928 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -630,6 +630,48 @@
 }
 
 
+void FlowGraphCompiler::EmitUnoptimizedStaticCall(
+    const Function& target_function,
+    const Array& arguments_descriptor,
+    intptr_t argument_count,
+    intptr_t deopt_id,
+    intptr_t token_pos,
+    LocationSummary* locs) {
+  // TODO(srdjan): Improve performance of function recognition.
+  MethodRecognizer::Kind recognized_kind =
+      MethodRecognizer::RecognizeKind(target_function);
+  int num_args_checked = 0;
+  if ((recognized_kind == MethodRecognizer::kMathMin) ||
+      (recognized_kind == MethodRecognizer::kMathMax)) {
+    num_args_checked = 2;
+  }
+  const ICData& ic_data = ICData::ZoneHandle(
+      ICData::New(parsed_function().function(),  // Caller function.
+                  String::Handle(target_function.name()),
+                  arguments_descriptor,
+                  deopt_id,
+                  num_args_checked));  // No arguments checked.
+  ic_data.AddTarget(target_function);
+  uword label_address = 0;
+  if (ic_data.num_args_tested() == 0) {
+    label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
+  } else if (ic_data.num_args_tested() == 2) {
+    label_address = StubCode::TwoArgsUnoptimizedStaticCallEntryPoint();
+  } else {
+    UNIMPLEMENTED();
+  }
+  ExternalLabel target_label("StaticCallICStub", label_address);
+  assembler()->LoadObject(ICREG, ic_data);
+  GenerateDartCall(deopt_id,
+                   token_pos,
+                   &target_label,
+                   PcDescriptors::kUnoptStaticCall,
+                   locs);
+  assembler()->Drop(argument_count);
+}
+
+
+
 void FlowGraphCompiler::GenerateNumberTypeCheck(Register kClassIdReg,
                                                 const AbstractType& type,
                                                 Label* is_instance_lbl,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 01b166f..0aeec79 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1406,30 +1406,6 @@
 }
 
 
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
-    const Function& target_function,
-    const Array& arguments_descriptor,
-    intptr_t argument_count,
-    intptr_t deopt_id,
-    intptr_t token_pos,
-    LocationSummary* locs) {
-  const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(parsed_function().function(),  // Caller function.
-                  String::Handle(target_function.name()),
-                  arguments_descriptor,
-                  deopt_id,
-                  0));  // No arguments checked.
-  ic_data.AddTarget(target_function);
-  __ LoadObject(R5, ic_data);
-  GenerateDartCall(deopt_id,
-                   token_pos,
-                   &StubCode::UnoptimizedStaticCallLabel(),
-                   PcDescriptors::kUnoptStaticCall,
-                   locs);
-  __ Drop(argument_count);
-}
-
-
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 6683c36..6db56ad 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1409,30 +1409,6 @@
 }
 
 
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
-    const Function& target_function,
-    const Array& arguments_descriptor,
-    intptr_t argument_count,
-    intptr_t deopt_id,
-    intptr_t token_pos,
-    LocationSummary* locs) {
-  const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(parsed_function().function(),  // Caller function.
-                  String::Handle(target_function.name()),
-                  arguments_descriptor,
-                  deopt_id,
-                  0));  // No arguments checked.
-  ic_data.AddTarget(target_function);
-  __ LoadObject(ECX, ic_data);
-  GenerateDartCall(deopt_id,
-                   token_pos,
-                   &StubCode::UnoptimizedStaticCallLabel(),
-                   PcDescriptors::kUnoptStaticCall,
-                   locs);
-  __ Drop(argument_count);
-}
-
-
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 2a5f44f..adbd850 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1462,30 +1462,6 @@
 }
 
 
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
-    const Function& target_function,
-    const Array& arguments_descriptor,
-    intptr_t argument_count,
-    intptr_t deopt_id,
-    intptr_t token_pos,
-    LocationSummary* locs) {
-  const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(parsed_function().function(),  // Caller function.
-                  String::Handle(target_function.name()),
-                  arguments_descriptor,
-                  deopt_id,
-                  0));  // No arguments checked.
-  ic_data.AddTarget(target_function);
-  __ LoadObject(S5, ic_data);
-  GenerateDartCall(deopt_id,
-                   token_pos,
-                   &StubCode::UnoptimizedStaticCallLabel(),
-                   PcDescriptors::kUnoptStaticCall,
-                   locs);
-  __ Drop(argument_count);
-}
-
-
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 22e25a9..c165e50 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1404,30 +1404,6 @@
 }
 
 
-void FlowGraphCompiler::EmitUnoptimizedStaticCall(
-    const Function& target_function,
-    const Array& arguments_descriptor,
-    intptr_t argument_count,
-    intptr_t deopt_id,
-    intptr_t token_pos,
-    LocationSummary* locs) {
-  const ICData& ic_data = ICData::ZoneHandle(
-      ICData::New(parsed_function().function(),  // Caller function.
-                  String::Handle(target_function.name()),
-                  arguments_descriptor,
-                  deopt_id,
-                  0));  // No arguments checked.
-  ic_data.AddTarget(target_function);
-  __ LoadObject(RBX, ic_data);
-  GenerateDartCall(deopt_id,
-                   token_pos,
-                   &StubCode::UnoptimizedStaticCallLabel(),
-                   PcDescriptors::kUnoptStaticCall,
-                   locs);
-  __ Drop(argument_count);
-}
-
-
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check,
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index e3a1f82..566290b 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1468,9 +1468,23 @@
                 call->deopt_id(),
                 call->env(),
                 call);
+  intptr_t mask = 0;
+  if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+    ASSERT(call->ArgumentCount() == 2);
+    // Extract shuffle mask.
+    Definition* mask_definition = call->ArgumentAt(1);
+    ASSERT(mask_definition->IsConstant());
+    ConstantInstr* constant_instruction = mask_definition->AsConstant();
+    const Object& constant_mask = constant_instruction->value();
+    ASSERT(constant_mask.IsSmi());
+    mask = Smi::Cast(constant_mask).Value();
+    ASSERT(mask >= 0);
+    ASSERT(mask <= 255);
+  }
   Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
       getter,
       new Value(call->ArgumentAt(0)),
+      mask,
       call->deopt_id());
   ReplaceCall(call, instr);
   return true;
@@ -1561,10 +1575,6 @@
       }
       InlineStringIsEmptyGetter(call);
       return true;
-    case MethodRecognizer::kFloat32x4ShuffleXXXX:
-    case MethodRecognizer::kFloat32x4ShuffleYYYY:
-    case MethodRecognizer::kFloat32x4ShuffleZZZZ:
-    case MethodRecognizer::kFloat32x4ShuffleWWWW:
     case MethodRecognizer::kFloat32x4ShuffleX:
     case MethodRecognizer::kFloat32x4ShuffleY:
     case MethodRecognizer::kFloat32x4ShuffleZ:
@@ -2035,6 +2045,9 @@
       ReplaceCall(call, cast);
       return true;
     }
+    case MethodRecognizer::kFloat32x4Shuffle: {
+      return InlineFloat32x4Getter(call, recognized_kind);
+    }
     default:
       return false;
   }
@@ -2485,7 +2498,7 @@
       MethodRecognizer::RecognizeKind(call->function());
   if (recognized_kind == MethodRecognizer::kMathSqrt) {
     MathSqrtInstr* sqrt =
-        new MathSqrtInstr(new Value(call->ArgumentAt(0)), call);
+        new MathSqrtInstr(new Value(call->ArgumentAt(0)), call->deopt_id());
     ReplaceCall(call, sqrt);
   } else if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
     Float32x4ZeroInstr* zero = new Float32x4ZeroInstr(call->deopt_id());
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index bc01952..47e0967 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -36,6 +36,7 @@
 // (class-name, function-name, recognized enum, fingerprint).
 // See intrinsifier for fingerprint computation.
 #define RECOGNIZED_LIST(V)                                                     \
+  V(::, identical, ObjectIdentical, 1018911876)                                \
   V(Object, Object., ObjectConstructor, 2030609793)                            \
   V(Object, get:_cid, ObjectCid, 732498573)                                    \
   V(_ObjectArray, get:length, ObjectArrayLength, 405297088)                    \
@@ -77,13 +78,12 @@
   V(_Double, pow, DoublePow, 102305574)                                        \
   V(_Double, _modulo, DoubleMod, 663439671)                                    \
   V(::, sqrt, MathSqrt, 1662640002)                                            \
+  V(::, min, MathMin, 269896129)                                               \
+  V(::, max, MathMax, 1286442186)                                              \
   V(Float32x4, Float32x4., Float32x4Constructor, 1492157358)                   \
   V(Float32x4, Float32x4.zero, Float32x4Zero, 444339161)                       \
   V(Float32x4, Float32x4.splat, Float32x4Splat, 1843231403)                    \
-  V(_Float32x4, get:xxxx, Float32x4ShuffleXXXX, 42621627)                      \
-  V(_Float32x4, get:yyyy, Float32x4ShuffleYYYY, 42621627)                      \
-  V(_Float32x4, get:zzzz, Float32x4ShuffleZZZZ, 42621627)                      \
-  V(_Float32x4, get:wwww, Float32x4ShuffleWWWW, 42621627)                      \
+  V(_Float32x4, _shuffle, Float32x4Shuffle, 1618450134)                        \
   V(_Float32x4, get:x, Float32x4ShuffleX, 211144022)                           \
   V(_Float32x4, get:y, Float32x4ShuffleY, 211144022)                           \
   V(_Float32x4, get:z, Float32x4ShuffleZ, 211144022)                           \
@@ -4593,9 +4593,9 @@
 
 class MathSqrtInstr : public TemplateDefinition<1> {
  public:
-  MathSqrtInstr(Value* value, StaticCallInstr* instance_call) {
+  MathSqrtInstr(Value* value, intptr_t deopt_id) {
     SetInputAt(0, value);
-    deopt_id_ = instance_call->deopt_id();
+    deopt_id_ = deopt_id;
   }
 
   Value* value() const { return inputs_[0]; }
@@ -4748,8 +4748,9 @@
 class Float32x4ShuffleInstr : public TemplateDefinition<1> {
  public:
   Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
+                        intptr_t mask,
                         intptr_t deopt_id)
-      : op_kind_(op_kind) {
+      : op_kind_(op_kind), mask_(mask) {
     SetInputAt(0, value);
     deopt_id_ = deopt_id;
   }
@@ -4758,6 +4759,8 @@
 
   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; }
@@ -4790,13 +4793,15 @@
   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();
+    return op_kind() == other->AsFloat32x4Shuffle()->op_kind() &&
+           mask() == other->AsFloat32x4Shuffle()->mask();
   }
 
   virtual bool MayThrow() const { return false; }
 
  private:
   const MethodRecognizer::Kind op_kind_;
+  const intptr_t mask_;
 
   DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr);
 };
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 8d95969..f6790b7 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2965,18 +2965,6 @@
   // For these cases the vdup instruction requires fewer
   // instructions. For arbitrary shuffles, vtbl will be needed.
   switch (op_kind()) {
-    case MethodRecognizer::kFloat32x4ShuffleXXXX:
-      __ vdup(kWord, result, dvalue0, 0);
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleYYYY:
-      __ vdup(kWord, result, dvalue0, 1);
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleZZZZ:
-      __ vdup(kWord, result, dvalue1, 0);
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleWWWW:
-      __ vdup(kWord, result, dvalue1, 1);
-      break;
     case MethodRecognizer::kFloat32x4ShuffleX:
       __ vdup(kWord, result, dvalue0, 0);
       __ vcvtds(dresult0, sresult0);
@@ -2993,6 +2981,20 @@
       __ vdup(kWord, result, dvalue1, 1);
       __ vcvtds(dresult0, sresult0);
       break;
+    case MethodRecognizer::kFloat32x4Shuffle:
+      if (mask_ == 0x00) {
+        __ vdup(kWord, result, dvalue0, 0);
+      } else if (mask_ == 0x55) {
+        __ vdup(kWord, result, dvalue0, 1);
+      } else if (mask_ == 0xAA) {
+        __ vdup(kWord, result, dvalue1, 0);
+      } else  if (mask_ == 0xFF) {
+        __ vdup(kWord, result, dvalue1, 1);
+      } else {
+        // TODO(zra): Implement other shuffles.
+        UNIMPLEMENTED();
+      }
+      break;
     default: UNREACHABLE();
   }
 }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 0f4e24b..00a833e 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -3006,18 +3006,6 @@
   ASSERT(locs()->out().fpu_reg() == value);
 
   switch (op_kind()) {
-    case MethodRecognizer::kFloat32x4ShuffleXXXX:
-      __ shufps(value, value, Immediate(0x00));
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleYYYY:
-      __ shufps(value, value, Immediate(0x55));
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleZZZZ:
-      __ shufps(value, value, Immediate(0xAA));
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleWWWW:
-      __ shufps(value, value, Immediate(0xFF));
-      break;
     case MethodRecognizer::kFloat32x4ShuffleX:
       __ shufps(value, value, Immediate(0x00));
       __ cvtss2sd(value, value);
@@ -3034,7 +3022,9 @@
       __ shufps(value, value, Immediate(0xFF));
       __ cvtss2sd(value, value);
       break;
-
+    case MethodRecognizer::kFloat32x4Shuffle:
+      __ shufps(value, value, Immediate(mask_));
+      break;
     default: UNREACHABLE();
   }
 }
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index a320b95..d0b0245 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -3047,18 +3047,6 @@
   ASSERT(locs()->out().fpu_reg() == value);
 
   switch (op_kind()) {
-    case MethodRecognizer::kFloat32x4ShuffleXXXX:
-      __ shufps(value, value, Immediate(0x00));
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleYYYY:
-      __ shufps(value, value, Immediate(0x55));
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleZZZZ:
-      __ shufps(value, value, Immediate(0xAA));
-      break;
-    case MethodRecognizer::kFloat32x4ShuffleWWWW:
-      __ shufps(value, value, Immediate(0xFF));
-      break;
     case MethodRecognizer::kFloat32x4ShuffleX:
       __ shufps(value, value, Immediate(0x00));
       __ cvtss2sd(value, value);
@@ -3075,6 +3063,9 @@
       __ shufps(value, value, Immediate(0xFF));
       __ cvtss2sd(value, value);
       break;
+    case MethodRecognizer::kFloat32x4Shuffle:
+      __ shufps(value, value, Immediate(mask_));
+      break;
     default: UNREACHABLE();
   }
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a16190e..bc4c338 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -8779,12 +8779,14 @@
 
 
 const char* ICData::ToCString() const {
-  const char* kFormat = "ICData target:'%s' num-checks: %"Pd"";
+  const char* kFormat = "ICData target:'%s' num-args: %"Pd" num-checks: %"Pd"";
   const String& name = String::Handle(target_name());
-  const intptr_t num = NumberOfChecks();
-  intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(), num) + 1;
+  const intptr_t num_args = num_args_tested();
+  const intptr_t num_checks = NumberOfChecks();
+  intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(),
+      num_args, num_checks) + 1;
   char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
-  OS::SNPrint(chars, len, kFormat, name.ToCString(), num);
+  OS::SNPrint(chars, len, kFormat, name.ToCString(), num_args, num_checks);
   return chars;
 }
 
@@ -8876,7 +8878,16 @@
 
 // Used for unoptimized static calls when no class-ids are checked.
 void ICData::AddTarget(const Function& target) const {
-  ASSERT(num_args_tested() == 0);
+  if (num_args_tested() > 0) {
+    // Create a fake cid entry, so that we can store the target.
+    GrowableArray<intptr_t> class_ids(num_args_tested());
+    for (intptr_t i = 0; i < num_args_tested(); i++) {
+      class_ids.Add(kObjectCid);
+    }
+    AddCheck(class_ids, target);
+    return;
+  }
+  ASSERT(num_args_tested() >= 0);
   // Can add only once.
   const intptr_t old_num = NumberOfChecks();
   ASSERT(old_num == 0);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 60c57bc..5538c8d 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2798,7 +2798,14 @@
                                   *(qual_ident->ident),
                                   NULL)) {
       LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle();
-      lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
+      if (current_class().mixin() == Type::null()) {
+        lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
+      } else {
+        // TODO(hausner): Should we resolve the prefix via the library scope
+        // rather than via the class?
+        Class& cls = Class::Handle(parsed_function()->function().origin());
+        lib_prefix = cls.LookupLibraryPrefix(*(qual_ident->ident));
+      }
       if (!lib_prefix.IsNull()) {
         // We have a library prefix qualified identifier, unless the prefix is
         // shadowed by a type parameter in scope.
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 185ca37..9d7a08e 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -62,7 +62,8 @@
   V(ThreeArgsOptimizedCheckInlineCache)                                        \
   V(ClosureCallInlineCache)                                                    \
   V(MegamorphicCall)                                                           \
-  V(UnoptimizedStaticCall)                                                     \
+  V(ZeroArgsUnoptimizedStaticCall)                                             \
+  V(TwoArgsUnoptimizedStaticCall)                                              \
   V(OptimizeFunction)                                                          \
   V(BreakpointDynamic)                                                         \
   V(EqualityWithNullArg)                                                       \
@@ -193,8 +194,10 @@
                                              const Class& cls);
   static void GenerateAllocationStubForClosure(Assembler* assembler,
                                                const Function& func);
-  static void GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
-                                                intptr_t num_args);
+  static void GenerateNArgsCheckInlineCacheStub(
+      Assembler* assembler,
+      intptr_t num_args,
+      const RuntimeEntry& handle_ic_miss);
   static void GenerateUsageCounterIncrement(Assembler* assembler,
                                             Register temp_reg);
   static void GenerateOptimizedUsageCounterIncrement(Assembler* assembler);
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index c7c1787..db932ba 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1362,8 +1362,10 @@
 // - Check if 'num_args' (including receiver) match any IC data group.
 // - Match found -> jump to target.
 // - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
-                                                 intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1470,16 +1472,7 @@
   }
   // Pass IC data object.
   __ Push(R5);
-
-  if (num_args == 1) {
-    __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
-  } else if (num_args == 2) {
-    __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
-  } else if (num_args == 3) {
-    __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
-  } else {
-    UNIMPLEMENTED();
-  }
+  __ CallRuntime(handle_ic_miss);
   // Remove the call arguments pushed earlier, including the IC data object.
   __ Drop(num_args + 1);
   // Pop returned code object into R0 (null if not found).
@@ -1540,57 +1533,65 @@
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // R5: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
 #if defined(DEBUG)
   { Label ok;
@@ -1664,6 +1665,13 @@
 }
 
 
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ Unimplemented("BreakpointRuntime stub");
 }
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index ef24ad8..926816e 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1417,8 +1417,10 @@
 // - Check if 'num_args' (including receiver) match any IC data group.
 // - Match found -> jump to target.
 // - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
-                                                 intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1446,6 +1448,7 @@
   __ LeaveFrame();
   __ Bind(&not_stepping);
 
+  // ECX: IC data object (preserved).
   // Load arguments descriptor into EDX.
   __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
   // Loop that checks if there is an IC data match.
@@ -1519,15 +1522,7 @@
     __ pushl(EBX);
   }
   __ pushl(ECX);  // Pass IC data object.
-  if (num_args == 1) {
-    __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
-  } else if (num_args == 2) {
-    __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
-  } else if (num_args == 3) {
-    __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
-  } else {
-    UNIMPLEMENTED();
-  }
+  __ CallRuntime(handle_ic_miss);
   // Remove the call arguments pushed earlier, including the IC data object.
   for (intptr_t i = 0; i < num_args + 1; i++) {
     __ popl(EAX);
@@ -1590,19 +1585,22 @@
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
@@ -1620,44 +1618,50 @@
 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
 // Do not count as no type feedback is collected.
 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 // Megamorphic call is currently implemented as IC call but through a stub
 // that does not check/count function invocations.
 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // ECX: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
+
 #if defined(DEBUG)
   { Label ok;
-    // Check that the IC data array has NumberOfArgumentsChecked() == 0.
+    // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
     // 'num_args_tested' is stored as an untagged int.
     __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
     __ cmpl(EBX, Immediate(0));
@@ -1666,7 +1670,6 @@
     __ Bind(&ok);
   }
 #endif  // DEBUG
-
   // Check single stepping.
   Label not_stepping;
   __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
@@ -1725,6 +1728,13 @@
 }
 
 
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
 // EDX, EXC: May contain arguments to runtime stub.
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ EnterStubFrame();
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 0881c59..5644aa4 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1542,8 +1542,10 @@
 // - Check if 'num_args' (including receiver) match any IC data group.
 // - Match found -> jump to target.
 // - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
-                                                 intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss) {
   __ TraceSimMsg("NArgsCheckInlineCacheStub");
   ASSERT(num_args > 0);
 #if defined(DEBUG)
@@ -1668,16 +1670,7 @@
   }
   // Pass IC data object.
   __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize));
-
-  if (num_args == 1) {
-    __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
-  } else if (num_args == 2) {
-    __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
-  } else if (num_args == 3) {
-    __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
-  } else {
-    UNIMPLEMENTED();
-  }
+  __ CallRuntime(handle_ic_miss);
   __ TraceSimMsg("NArgsCheckInlineCacheStub return");
   // Pop returned code object into T3 (null if not found).
   // Restore arguments descriptor array and IC data array.
@@ -1749,57 +1742,65 @@
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // S5: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   __ TraceSimMsg("UnoptimizedStaticCallStub");
 #if defined(DEBUG)
@@ -1882,6 +1883,13 @@
 }
 
 
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, T0);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
   __ Unimplemented("BreakpointRuntime stub");
 }
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index e222c70..e74e83f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1401,8 +1401,10 @@
 // - Check if 'num_args' (including receiver) match any IC data group.
 // - Match found -> jump to target.
 // - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
-                                                 intptr_t num_args) {
+void StubCode::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1500,15 +1502,7 @@
     __ pushq(RCX);
   }
   __ pushq(RBX);  // Pass IC data object.
-  if (num_args == 1) {
-    __ CallRuntime(kInlineCacheMissHandlerOneArgRuntimeEntry);
-  } else if (num_args == 2) {
-    __ CallRuntime(kInlineCacheMissHandlerTwoArgsRuntimeEntry);
-  } else if (num_args == 3) {
-    __ CallRuntime(kInlineCacheMissHandlerThreeArgsRuntimeEntry);
-  } else {
-    UNIMPLEMENTED();
-  }
+  __ CallRuntime(handle_ic_miss);
   // Remove the call arguments pushed earlier, including the IC data object.
   for (intptr_t i = 0; i < num_args + 1; i++) {
     __ popq(RAX);
@@ -1570,19 +1564,22 @@
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 // Use inline cache data array to invoke the target or continue in inline
@@ -1599,41 +1596,46 @@
 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry);
 }
 
 
 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub(
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 3, kInlineCacheMissHandlerThreeArgsRuntimeEntry);
 }
 
 
 // Do not count as no type feedback is collected.
 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 // Megamorphic call is currently implemented as IC call but through a stub
 // that does not check/count function invocations.
 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  GenerateNArgsCheckInlineCacheStub(assembler, 1);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry);
 }
 
 
 // Intermediary stub between a static call and its target. ICData contains
 // the target function and the call count.
 // RBX: ICData
-void StubCode::GenerateUnoptimizedStaticCallStub(Assembler* assembler) {
+void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
 #if defined(DEBUG)
   { Label ok;
@@ -1706,6 +1708,13 @@
 }
 
 
+void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry);
+}
+
+
 //  RBX, R10: May contain arguments to runtime stub.
 //  TOS(0): return address (Dart code).
 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
diff --git a/sdk/lib/_internal/pub/lib/src/source/hosted.dart b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
index aec150c..a4b7160 100644
--- a/sdk/lib/_internal/pub/lib/src/source/hosted.dart
+++ b/sdk/lib/_internal/pub/lib/src/source/hosted.dart
@@ -167,7 +167,7 @@
 
     if (error is io.SocketException) {
       fail('Got socket error trying to find package "$package" at $url.\n'
-          '${error.osError}');
+          '$error');
     }
 
     // Otherwise re-throw the original exception.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 2870931..13696d9 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -3519,12 +3519,17 @@
   }
 
   /** Gets the value of "box-sizing" */
-  String get boxSizing =>
-    getPropertyValue('box-sizing');
+  String get boxSizing => Device.isFirefox ? 
+      getPropertyValue('${Device.cssPrefix}box-sizing') : 
+      getPropertyValue('box-sizing');
 
   /** Sets the value of "box-sizing" */
   void set boxSizing(String value) {
-    setProperty('box-sizing', value, '');
+    if (Device.isFirefox) {
+      setProperty('${Device.cssPrefix}box-sizing', value, '');
+    } else {
+      setProperty('box-sizing', value, '');
+    }
   }
 
   /** Gets the value of "caption-side" */
@@ -7919,7 +7924,8 @@
 
 /**
  * An immutable list containing HTML elements. This list contains some
- * additional methods for ease of CSS manipulation on a group of elements.
+ * additional methods when compared to regular lists for ease of CSS 
+ * manipulation on a group of elements.
  */
 abstract class ElementList<T extends Element> extends ListBase<T> {
   /**
@@ -7936,6 +7942,63 @@
 
   /** Replace the classes with `value` for every element in this list. */
   set classes(Iterable<String> value);
+
+  /** 
+   * Access dimensions and position of the Elements in this list.
+   * 
+   * Setting the height or width properties will set the height or width
+   * property for all elements in the list. This returns a rectangle with the 
+   * dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Getting the height or width returns the height or width of the
+   * first Element in this list. 
+   *
+   * Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   */
+  @Experimental()
+  CssRect get contentEdge;
+  
+  /**
+   * Access dimensions and position of the first Element's content + padding box
+   * in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `innerHeight` value for an element. This
+   * is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   */
+  @Experimental()
+  CssRect get paddingEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border box in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  @Experimental()
+  CssRect get borderEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border + margin box in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  @Experimental()
+  CssRect get marginEdge;
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -7944,8 +8007,12 @@
 // contains Node objects that are not Elements.
 class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
   final List<Node> _nodeList;
+  // The subset of _nodeList that are Elements.
+  List<Element> _elementList;
 
-  _FrozenElementList._wrap(this._nodeList);
+  _FrozenElementList._wrap(this._nodeList) {
+    _elementList = _nodeList.where((e) => e is Element).toList();
+  }
 
   int get length => _nodeList.length;
 
@@ -7969,12 +8036,19 @@
 
   Element get single => _nodeList.single;
 
-  CssClassSet get classes => new _MultiElementCssClassSet(
-      _nodeList.where((e) => e is Element));
+  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
 
   void set classes(Iterable<String> value) {
-    _nodeList.where((e) => e is Element).forEach((e) => e.classes = value);
+    _elementList.forEach((e) => e.classes = value);
   }
+
+  CssRect get contentEdge => new _ContentCssListRect(_elementList);
+  
+  CssRect get paddingEdge => _elementList.first.paddingEdge;
+
+  CssRect get borderEdge => _elementList.first.borderEdge;
+
+  CssRect get marginEdge => _elementList.first.marginEdge;
 }
 
 /**
@@ -8676,6 +8750,79 @@
     TemplateElement.decorate(this);
   }
 
+  /**
+   * Access this element's content position.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get contentEdge => new _ContentCssRect(this);
+  
+  /**
+   * Access the dimensions and position of this element's content + padding box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element. 
+   * This is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get paddingEdge => new _PaddingCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that 
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get borderEdge => new _BorderCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border + margin box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   * 
+   * _Important_ _note_: use of this method will perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get marginEdge => new _MarginCssRect(this);
   // To suppress missing implicit constructor warnings.
   factory Element._() { throw new UnsupportedError("Not supported"); }
 
@@ -12186,7 +12333,7 @@
    * The data received as a reponse from the request.
    *
    * The data could be in the
-   * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
    * [String]). `null` indicates request failure.
    */
   @DomName('XMLHttpRequest.response')
@@ -26703,6 +26850,348 @@
     _element.className = s.join(' ');
   }
 }
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+
+  _ContentCssRect(element) : super(element);
+
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+  num get width => _element.offsetWidth +
+      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   */
+  void set height(newHeight) {
+    if (newHeight is Dimension) {
+      if (newHeight.value < 0) newHeight = new Dimension.px(0);
+      _element.style.height = newHeight.toString();
+    } else {
+      if (newHeight < 0) newHeight = 0;
+      _element.style.height = '${newHeight}px';
+    }
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  void set width(newWidth) {
+    if (newWidth is Dimension) {
+      if (newWidth.value < 0) newWidth = new Dimension.px(0);
+      _element.style.width = newWidth.toString();
+    } else {
+      if (newWidth < 0) newWidth = 0;
+      _element.style.width = '${newWidth}px';
+    }
+  }
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _CONTENT);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+  List<Element> _elementList;
+
+  _ContentCssListRect(elementList) : super(elementList.first) {
+    _elementList = elementList;
+  }
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * Values of newHeight that are less than zero are converted to effectively
+   * setting the height to 0. This is equivalent to the `height`
+   * function in jQuery and the calculated `height` CSS value, converted to a
+   * num in pixels.
+   */
+  void set height(newHeight) {
+    _elementList.forEach((e) => e.contentEdge.height = newHeight);
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  void set width(newWidth) {
+    _elementList.forEach((e) => e.contentEdge.width = newWidth);
+  }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+  _PaddingCssRect(element) : super(element);
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+  num get width => _element.offsetWidth +
+      _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _PADDING);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+  _BorderCssRect(element) : super(element);
+  num get height => _element.offsetHeight;
+  num get width => _element.offsetWidth;
+
+  num get left => _element.getBoundingClientRect().left;
+  num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+  _MarginCssRect(element) : super(element);
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+  num get width =>
+      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _MARGIN);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rect] class, this class's values are
+ * mutable, so one can change the height of an element programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect extends RectBase implements Rect {
+  Element _element;
+
+  CssRect(this._element);
+
+  num get left;
+
+  num get top;
+
+  /**
+   * The height of this rectangle.
+   *
+   * This is equivalent to the `height` function in jQuery and the calculated
+   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `height` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get height;
+
+  /**
+   * The width of this rectangle.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `width` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get width;
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   *
+   * Note that only the content height can actually be set via this method.
+   */
+  void set height(newHeight) {
+    throw new UnsupportedError("Can only set height for content rect.");
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   *
+   * Note that only the content width can be set via this method.
+   */
+  void set width(newWidth) {
+    throw new UnsupportedError("Can only set width for content rect.");
+  }
+
+  /**
+   * Return a value that is used to modify the initial height or width
+   * measurement of an element. Depending on the value (ideally an enum) passed
+   * to augmentingMeasurement, we may need to add or subtract margin, padding,
+   * or border values, depending on the measurement we're trying to obtain.
+   */
+  num _addOrSubtractToBoxModel(List<String> dimensions,
+      String augmentingMeasurement) {
+    // getComputedStyle always returns pixel values (hence, computed), so we're
+    // always dealing with pixels in this method.
+    var styles = _element.getComputedStyle();
+
+    var val = 0;
+
+    for (String measurement in dimensions) {
+      // The border-box and default box model both exclude margin in the regular
+      // height/width calculation, so add it if we want it for this measurement.
+      if (augmentingMeasurement == _MARGIN) {
+        val += new Dimension.css(styles.getPropertyValue(
+            '$augmentingMeasurement-$measurement')).value;
+      }
+
+      // The border-box includes padding and border, so remove it if we want
+      // just the content itself.
+      if (augmentingMeasurement == _CONTENT) {
+      	val -= new Dimension.css(
+            styles.getPropertyValue('${_PADDING}-$measurement')).value;
+      }
+
+      // At this point, we don't wan't to augment with border or margin,
+      // so remove border.
+      if (augmentingMeasurement != _MARGIN) {
+	      val -= new Dimension.css(styles.getPropertyValue(
+            'border-${measurement}-width')).value;
+      }
+    }
+    return val;
+  }
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+@Experimental()
+class Dimension {
+  num _value;
+  String _unit;
+
+  /** Set this CSS Dimension to a percentage `value`. */
+  Dimension.percent(this._value) : _unit = '%';
+
+  /** Set this CSS Dimension to a pixel `value`. */
+  Dimension.px(this._value) : _unit = 'px';
+
+  /** Set this CSS Dimension to a pica `value`. */
+  Dimension.pc(this._value) : _unit = 'pc';
+
+  /** Set this CSS Dimension to a point `value`. */
+  Dimension.pt(this._value) : _unit = 'pt';
+
+  /** Set this CSS Dimension to an inch `value`. */
+  Dimension.inch(this._value) : _unit = 'in';
+
+  /** Set this CSS Dimension to a centimeter `value`. */
+  Dimension.cm(this._value) : _unit = 'cm';
+
+  /** Set this CSS Dimension to a millimeter `value`. */
+  Dimension.mm(this._value) : _unit = 'mm';
+
+  /**
+   * Set this CSS Dimension to the specified number of ems.
+   *
+   * 1em is equal to the current font size. (So 2ems is equal to double the font
+   * size). This is useful for producing website layouts that scale nicely with
+   * the user's desired font size.
+   */
+  Dimension.em(this._value) : _unit = 'em';
+
+  /**
+   * Set this CSS Dimension to the specified number of x-heights.
+   *
+   * One ex is equal to the the x-height of a font's baseline to its mean line,
+   * generally the height of the letter "x" in the font, which is usually about
+   * half the font-size.
+   */
+  Dimension.ex(this._value) : _unit = 'ex';
+
+  /**
+   * Construct a Dimension object from the valid, simple CSS string `cssValue`
+   * that represents a distance measurement.
+   *
+   * This constructor is intended as a convenience method for working with
+   * simplistic CSS length measurements. Non-numeric values such as `auto` or
+   * `inherit` or invalid CSS will cause this constructor to throw a
+   * FormatError.
+   */
+  Dimension.css(String cssValue) {
+    if (cssValue == '') cssValue = '0px';
+    if (cssValue.endsWith('%')) {
+      _unit = '%';
+    } else {
+      _unit = cssValue.substring(cssValue.length - 2);
+    }
+    if (cssValue.contains('.')) {
+      _value = double.parse(cssValue.substring(0,
+          cssValue.length - _unit.length));
+    } else {
+      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+    }
+  }
+
+  /** Print out the CSS String representation of this value. */
+  String toString() {
+    return '${_value}${_unit}';
+  }
+
+  /** Return a unitless, numerical value of this CSS value. */
+  num get value => this._value;
+}
 // 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.
@@ -28220,44 +28709,24 @@
 
 
 /**
- * A class for representing two-dimensional rectangles.
+ * A base class for representing two-dimensional rectangles. This will hopefully
+ * be moved merged with the dart:math Rect.
  */
-class Rect {
-  final num left;
-  final num top;
-  final num width;
-  final num height;
+// TODO(efortuna): Merge with Math rect after finalizing with Florian.
+abstract class RectBase {
+  //  Not used, but keeps the VM from complaining about Rect having a const
+  // constructor and this one not.
+  const RectBase();
 
-  const Rect(this.left, this.top, this.width, this.height);
-
-  factory Rect.fromPoints(Point a, Point b) {
-    var left;
-    var width;
-    if (a.x < b.x) {
-      left = a.x;
-      width = b.x - left;
-    } else {
-      left = b.x;
-      width = a.x - left;
-    }
-    var top;
-    var height;
-    if (a.y < b.y) {
-      top = a.y;
-      height = b.y - top;
-    } else {
-      top = b.y;
-      height = a.y - top;
-    }
-
-    return new Rect(left, top, width, height);
-  }
+  num get left;
+  num get top;
+  num get width;
+  num get height;
 
   num get right => left + width;
   num get bottom => top + height;
 
   // NOTE! All code below should be common with Rect.
-  // TODO: implement with mixins when available.
 
   String toString() {
     return '($left, $top, $width, $height)';
@@ -28351,6 +28820,46 @@
   Point get bottomRight => new Point(this.left + this.width,
       this.top + this.height);
 }
+
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ *
+ * This class is distinctive from RectBase in that it enforces that its
+ * properties are immutable.
+ */
+class Rect extends RectBase {
+  final num left;
+  final num top;
+  final num width;
+  final num height;
+
+  const Rect(this.left, this.top, this.width, this.height): super();
+
+  factory Rect.fromPoints(Point a, Point b) {
+    var left;
+    var width;
+    if (a.x < b.x) {
+      left = a.x;
+      width = b.x - left;
+    } else {
+      left = b.x;
+      width = a.x - left;
+    }
+    var top;
+    var height;
+    if (a.y < b.y) {
+      top = a.y;
+      height = b.y - top;
+    } else {
+      top = b.y;
+      height = a.y - top;
+    }
+
+    return new Rect(left, top, width, height);
+  }
+}
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 4a510d0..04268cd 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -3995,12 +3995,17 @@
   }
 
   /** Gets the value of "box-sizing" */
-  String get boxSizing =>
-    getPropertyValue('box-sizing');
+  String get boxSizing => Device.isFirefox ? 
+      getPropertyValue('${Device.cssPrefix}box-sizing') : 
+      getPropertyValue('box-sizing');
 
   /** Sets the value of "box-sizing" */
   void set boxSizing(String value) {
-    setProperty('box-sizing', value, '');
+    if (Device.isFirefox) {
+      setProperty('${Device.cssPrefix}box-sizing', value, '');
+    } else {
+      setProperty('box-sizing', value, '');
+    }
   }
 
   /** Gets the value of "caption-side" */
@@ -8382,7 +8387,8 @@
 
 /**
  * An immutable list containing HTML elements. This list contains some
- * additional methods for ease of CSS manipulation on a group of elements.
+ * additional methods when compared to regular lists for ease of CSS 
+ * manipulation on a group of elements.
  */
 abstract class ElementList<T extends Element> extends ListBase<T> {
   /**
@@ -8399,6 +8405,63 @@
 
   /** Replace the classes with `value` for every element in this list. */
   set classes(Iterable<String> value);
+
+  /** 
+   * Access dimensions and position of the Elements in this list.
+   * 
+   * Setting the height or width properties will set the height or width
+   * property for all elements in the list. This returns a rectangle with the 
+   * dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Getting the height or width returns the height or width of the
+   * first Element in this list. 
+   *
+   * Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   */
+  @Experimental()
+  CssRect get contentEdge;
+  
+  /**
+   * Access dimensions and position of the first Element's content + padding box
+   * in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `innerHeight` value for an element. This
+   * is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   */
+  @Experimental()
+  CssRect get paddingEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border box in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  @Experimental()
+  CssRect get borderEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border + margin box in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  @Experimental()
+  CssRect get marginEdge;
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -8407,8 +8470,12 @@
 // contains Node objects that are not Elements.
 class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
   final List<Node> _nodeList;
+  // The subset of _nodeList that are Elements.
+  List<Element> _elementList;
 
-  _FrozenElementList._wrap(this._nodeList);
+  _FrozenElementList._wrap(this._nodeList) {
+    _elementList = _nodeList.where((e) => e is Element).toList();
+  }
 
   int get length => _nodeList.length;
 
@@ -8432,12 +8499,19 @@
 
   Element get single => _nodeList.single;
 
-  CssClassSet get classes => new _MultiElementCssClassSet(
-      _nodeList.where((e) => e is Element));
+  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
 
   void set classes(Iterable<String> value) {
-    _nodeList.where((e) => e is Element).forEach((e) => e.classes = value);
+    _elementList.forEach((e) => e.classes = value);
   }
+
+  CssRect get contentEdge => new _ContentCssListRect(_elementList);
+  
+  CssRect get paddingEdge => _elementList.first.paddingEdge;
+
+  CssRect get borderEdge => _elementList.first.borderEdge;
+
+  CssRect get marginEdge => _elementList.first.marginEdge;
 }
 
 /**
@@ -8990,6 +9064,79 @@
     TemplateElement.decorate(this);
   }
 
+  /**
+   * Access this element's content position.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get contentEdge => new _ContentCssRect(this);
+  
+  /**
+   * Access the dimensions and position of this element's content + padding box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element. 
+   * This is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get paddingEdge => new _PaddingCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that 
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get borderEdge => new _BorderCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border + margin box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   * 
+   * _Important_ _note_: use of this method will perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get marginEdge => new _MarginCssRect(this);
   // To suppress missing implicit constructor warnings.
   factory Element._() { throw new UnsupportedError("Not supported"); }
 
@@ -12590,7 +12737,7 @@
    * The data received as a reponse from the request.
    *
    * The data could be in the
-   * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a
+   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a
    * [String]). `null` indicates request failure.
    */
   @DomName('XMLHttpRequest.response')
@@ -28313,6 +28460,348 @@
     _element.className = s.join(' ');
   }
 }
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+/**
+ * A rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+
+  _ContentCssRect(element) : super(element);
+
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+  num get width => _element.offsetWidth +
+      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   */
+  void set height(newHeight) {
+    if (newHeight is Dimension) {
+      if (newHeight.value < 0) newHeight = new Dimension.px(0);
+      _element.style.height = newHeight.toString();
+    } else {
+      if (newHeight < 0) newHeight = 0;
+      _element.style.height = '${newHeight}px';
+    }
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  void set width(newWidth) {
+    if (newWidth is Dimension) {
+      if (newWidth.value < 0) newWidth = new Dimension.px(0);
+      _element.style.width = newWidth.toString();
+    } else {
+      if (newWidth < 0) newWidth = 0;
+      _element.style.width = '${newWidth}px';
+    }
+  }
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _CONTENT);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+  List<Element> _elementList;
+
+  _ContentCssListRect(elementList) : super(elementList.first) {
+    _elementList = elementList;
+  }
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * Values of newHeight that are less than zero are converted to effectively
+   * setting the height to 0. This is equivalent to the `height`
+   * function in jQuery and the calculated `height` CSS value, converted to a
+   * num in pixels.
+   */
+  void set height(newHeight) {
+    _elementList.forEach((e) => e.contentEdge.height = newHeight);
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  void set width(newWidth) {
+    _elementList.forEach((e) => e.contentEdge.width = newWidth);
+  }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+  _PaddingCssRect(element) : super(element);
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+  num get width => _element.offsetWidth +
+      _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _PADDING);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+  _BorderCssRect(element) : super(element);
+  num get height => _element.offsetHeight;
+  num get width => _element.offsetWidth;
+
+  num get left => _element.getBoundingClientRect().left;
+  num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+  _MarginCssRect(element) : super(element);
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+  num get width =>
+      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _MARGIN);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rect] class, this class's values are
+ * mutable, so one can change the height of an element programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect extends RectBase implements Rect {
+  Element _element;
+
+  CssRect(this._element);
+
+  num get left;
+
+  num get top;
+
+  /**
+   * The height of this rectangle.
+   *
+   * This is equivalent to the `height` function in jQuery and the calculated
+   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `height` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get height;
+
+  /**
+   * The width of this rectangle.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `width` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get width;
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   *
+   * Note that only the content height can actually be set via this method.
+   */
+  void set height(newHeight) {
+    throw new UnsupportedError("Can only set height for content rect.");
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   *
+   * Note that only the content width can be set via this method.
+   */
+  void set width(newWidth) {
+    throw new UnsupportedError("Can only set width for content rect.");
+  }
+
+  /**
+   * Return a value that is used to modify the initial height or width
+   * measurement of an element. Depending on the value (ideally an enum) passed
+   * to augmentingMeasurement, we may need to add or subtract margin, padding,
+   * or border values, depending on the measurement we're trying to obtain.
+   */
+  num _addOrSubtractToBoxModel(List<String> dimensions,
+      String augmentingMeasurement) {
+    // getComputedStyle always returns pixel values (hence, computed), so we're
+    // always dealing with pixels in this method.
+    var styles = _element.getComputedStyle();
+
+    var val = 0;
+
+    for (String measurement in dimensions) {
+      // The border-box and default box model both exclude margin in the regular
+      // height/width calculation, so add it if we want it for this measurement.
+      if (augmentingMeasurement == _MARGIN) {
+        val += new Dimension.css(styles.getPropertyValue(
+            '$augmentingMeasurement-$measurement')).value;
+      }
+
+      // The border-box includes padding and border, so remove it if we want
+      // just the content itself.
+      if (augmentingMeasurement == _CONTENT) {
+      	val -= new Dimension.css(
+            styles.getPropertyValue('${_PADDING}-$measurement')).value;
+      }
+
+      // At this point, we don't wan't to augment with border or margin,
+      // so remove border.
+      if (augmentingMeasurement != _MARGIN) {
+	      val -= new Dimension.css(styles.getPropertyValue(
+            'border-${measurement}-width')).value;
+      }
+    }
+    return val;
+  }
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+@Experimental()
+class Dimension {
+  num _value;
+  String _unit;
+
+  /** Set this CSS Dimension to a percentage `value`. */
+  Dimension.percent(this._value) : _unit = '%';
+
+  /** Set this CSS Dimension to a pixel `value`. */
+  Dimension.px(this._value) : _unit = 'px';
+
+  /** Set this CSS Dimension to a pica `value`. */
+  Dimension.pc(this._value) : _unit = 'pc';
+
+  /** Set this CSS Dimension to a point `value`. */
+  Dimension.pt(this._value) : _unit = 'pt';
+
+  /** Set this CSS Dimension to an inch `value`. */
+  Dimension.inch(this._value) : _unit = 'in';
+
+  /** Set this CSS Dimension to a centimeter `value`. */
+  Dimension.cm(this._value) : _unit = 'cm';
+
+  /** Set this CSS Dimension to a millimeter `value`. */
+  Dimension.mm(this._value) : _unit = 'mm';
+
+  /**
+   * Set this CSS Dimension to the specified number of ems.
+   *
+   * 1em is equal to the current font size. (So 2ems is equal to double the font
+   * size). This is useful for producing website layouts that scale nicely with
+   * the user's desired font size.
+   */
+  Dimension.em(this._value) : _unit = 'em';
+
+  /**
+   * Set this CSS Dimension to the specified number of x-heights.
+   *
+   * One ex is equal to the the x-height of a font's baseline to its mean line,
+   * generally the height of the letter "x" in the font, which is usually about
+   * half the font-size.
+   */
+  Dimension.ex(this._value) : _unit = 'ex';
+
+  /**
+   * Construct a Dimension object from the valid, simple CSS string `cssValue`
+   * that represents a distance measurement.
+   *
+   * This constructor is intended as a convenience method for working with
+   * simplistic CSS length measurements. Non-numeric values such as `auto` or
+   * `inherit` or invalid CSS will cause this constructor to throw a
+   * FormatError.
+   */
+  Dimension.css(String cssValue) {
+    if (cssValue == '') cssValue = '0px';
+    if (cssValue.endsWith('%')) {
+      _unit = '%';
+    } else {
+      _unit = cssValue.substring(cssValue.length - 2);
+    }
+    if (cssValue.contains('.')) {
+      _value = double.parse(cssValue.substring(0,
+          cssValue.length - _unit.length));
+    } else {
+      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+    }
+  }
+
+  /** Print out the CSS String representation of this value. */
+  String toString() {
+    return '${_value}${_unit}';
+  }
+
+  /** Return a unitless, numerical value of this CSS value. */
+  num get value => this._value;
+}
 // 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.
@@ -29830,44 +30319,24 @@
 
 
 /**
- * A class for representing two-dimensional rectangles.
+ * A base class for representing two-dimensional rectangles. This will hopefully
+ * be moved merged with the dart:math Rect.
  */
-class Rect {
-  final num left;
-  final num top;
-  final num width;
-  final num height;
+// TODO(efortuna): Merge with Math rect after finalizing with Florian.
+abstract class RectBase {
+  //  Not used, but keeps the VM from complaining about Rect having a const
+  // constructor and this one not.
+  const RectBase();
 
-  const Rect(this.left, this.top, this.width, this.height);
-
-  factory Rect.fromPoints(Point a, Point b) {
-    var left;
-    var width;
-    if (a.x < b.x) {
-      left = a.x;
-      width = b.x - left;
-    } else {
-      left = b.x;
-      width = a.x - left;
-    }
-    var top;
-    var height;
-    if (a.y < b.y) {
-      top = a.y;
-      height = b.y - top;
-    } else {
-      top = b.y;
-      height = a.y - top;
-    }
-
-    return new Rect(left, top, width, height);
-  }
+  num get left;
+  num get top;
+  num get width;
+  num get height;
 
   num get right => left + width;
   num get bottom => top + height;
 
   // NOTE! All code below should be common with Rect.
-  // TODO: implement with mixins when available.
 
   String toString() {
     return '($left, $top, $width, $height)';
@@ -29961,6 +30430,46 @@
   Point get bottomRight => new Point(this.left + this.width,
       this.top + this.height);
 }
+
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ *
+ * This class is distinctive from RectBase in that it enforces that its
+ * properties are immutable.
+ */
+class Rect extends RectBase {
+  final num left;
+  final num top;
+  final num width;
+  final num height;
+
+  const Rect(this.left, this.top, this.width, this.height): super();
+
+  factory Rect.fromPoints(Point a, Point b) {
+    var left;
+    var width;
+    if (a.x < b.x) {
+      left = a.x;
+      width = b.x - left;
+    } else {
+      left = b.x;
+      width = a.x - left;
+    }
+    var top;
+    var height;
+    if (a.y < b.y) {
+      top = a.y;
+      height = b.y - top;
+    } else {
+      top = b.y;
+      height = a.y - top;
+    }
+
+    return new Rect(left, top, width, height);
+  }
+}
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index 043a61e..756b34a 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -870,15 +870,518 @@
   /// Extracted w value.
   double get w;
 
-  /// Returns a new [Float32x4] with [this]' x value in all four lanes.
+  /// Returns a new [Float32x4] with lane values reordered.
   Float32x4 get xxxx;
-  /// Returns a new [Float32x4] with [this]' y value in all four lanes.
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xxww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xywx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xywy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xywz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xyww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xzww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get xwww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yxww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyyx;
+  /// Returns a new [Float32x4] with lane values reordered.
   Float32x4 get yyyy;
-  /// Returns a new [Float32x4] with [this]' z value in all four lanes.
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yywx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yywy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yywz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yyww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get yzww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get ywww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zxww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zywx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zywy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zywz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zyww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzzy;
+  /// Returns a new [Float32x4] with lane values reordered.
   Float32x4 get zzzz;
-  /// Returns a new [Float32x4] with [this]' w value in all four lanes.
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zzww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get zwww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wxww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wywx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wywy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wywz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wyww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzwz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wzww;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwxx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwxy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwxz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwxw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwyx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwyy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwyz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwyw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwzx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwzy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwzz;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwzw;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwwx;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwwy;
+  /// Returns a new [Float32x4] with lane values reordered.
+  Float32x4 get wwwz;
+  /// Returns a new [Float32x4] with lane values reordered.
   Float32x4 get wwww;
-  // TODO(johnmccutchan): Add all 256 possible combinations.
 
   /// Returns a new [Float32x4] copied from [this] with a new x value.
   Float32x4 withX(double x);
diff --git a/tests/async_helper.dart b/tests/async_helper.dart
index 34d471e..c1b8273 100644
--- a/tests/async_helper.dart
+++ b/tests/async_helper.dart
@@ -18,8 +18,14 @@
 
 library async_helper;
 
+// TODO(kustermann): This is problematic because we rely on a working
+// 'dart:isolate' (i.e. it is in particular problematic with dart2js).
+// It would be nice if we could use a different mechanism for different
+// runtimes.
+import 'dart:isolate';
 
 bool _initialized = false;
+ReceivePort _port = null;
 int _asyncLevel = 0;
 
 Exception _buildException(String msg) {
@@ -34,6 +40,7 @@
   if (!_initialized) {
     print('unittest-suite-wait-for-done');
     _initialized = true;
+    _port = new ReceivePort();
   }
   _asyncLevel++;
 }
@@ -49,6 +56,8 @@
   }
   _asyncLevel--;
   if (_asyncLevel == 0) {
+    _port.close();
+    _port = null;
     print('unittest-suite-done');
   }
 }
diff --git a/tests/html/element_dimensions_test.dart b/tests/html/element_dimensions_test.dart
new file mode 100644
index 0000000..413d302
--- /dev/null
+++ b/tests/html/element_dimensions_test.dart
@@ -0,0 +1,263 @@
+// 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 element_dimensions_test;
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlConfiguration();
+
+  var isElement = predicate((x) => x is Element, 'is an Element');
+  var isCanvasElement =
+      predicate((x) => x is CanvasElement, 'is a CanvasElement');
+  var isDivElement = predicate((x) => x is DivElement, 'is a isDivElement');
+
+  var div = new DivElement();
+  div.id = 'test';
+  document.body.nodes.add(div);
+
+  void initDiv() {
+    var style = div.style;
+    style..padding = '4px'
+         ..border = '0px solid #fff'
+         ..margin = '6px'
+         ..height = '10px'
+         ..width = '11px'
+         ..boxSizing = 'content-box'
+         ..overflow = 'visible';
+  }
+
+  div.nodes.addAll([
+      new DivElement(),
+      new CanvasElement(),
+      new DivElement(),
+      new Text('Hello'),
+      new DivElement(),
+      new Text('World'),
+      new CanvasElement()]);
+
+  group('dimensions', () {
+    setUp(initDiv);
+
+    test('contentEdge.height', () {
+      var all1 = queryAll('#test');
+
+      expect(all1.contentEdge.height, 10);
+      expect(all1[0].getComputedStyle().getPropertyValue('height'), '10px');
+
+      all1.contentEdge.height = new Dimension.px(600);
+      all1.contentEdge.height = 600;
+      expect(all1.contentEdge.height, 600);
+      expect(all1[0].getComputedStyle().getPropertyValue('height'), '600px');
+      all1[0].style.visibility = 'hidden';
+      expect(all1.contentEdge.height, 600);
+      all1[0].style.visibility = 'visible';
+
+      // If user passes in a negative number, set height to 0.
+      all1.contentEdge.height = new Dimension.px(-1);
+      expect(all1.contentEdge.height, 0);
+
+      // Adding padding or border shouldn't affect the height for
+      // non-box-sizing.
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.height, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.height, 0);
+    });
+
+    test('contentEdge.height with border-box', () {
+      var all1 = queryAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.contentEdge.height, 2);
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.height, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.height, 0);
+    });
+
+    test('contentEdge.width', () {
+      var all1 = queryAll('#test');
+      expect(all1.contentEdge.width, 11);
+      expect(all1[0].getComputedStyle().getPropertyValue('width'), '11px');
+
+      all1.contentEdge.width = new Dimension.px(600);
+      expect(all1.contentEdge.width, 600);
+      expect(all1[0].getComputedStyle().getPropertyValue('width'), '600px');
+      all1[0].style.visibility = 'hidden';
+      expect(all1.contentEdge.width, 600);
+      all1[0].style.visibility = 'visible';
+
+      // If user passes in a negative number, set width to 0.
+      all1.contentEdge.width = new Dimension.px(-1);
+      expect(all1.contentEdge.width, 0);
+
+      // Adding padding or border shouldn't affect the width.
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.width, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.width, 0);
+    });
+
+    test('contentEdge.width with border-box', () {
+      var all1 = queryAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.contentEdge.width, 3);
+      div.style.padding = '20pc';
+      expect(all1.contentEdge.width, 0);
+      div.style.border = '2px solid #fff';
+      expect(all1.contentEdge.width, 0);
+
+    });
+
+    test('paddingEdge.height', () {
+      var all1 = queryAll('#test');
+      expect(all1.paddingEdge.height, 18);
+      all1[0].style.visibility = 'hidden';
+      expect(all1.paddingEdge.height, 18);
+      all1[0].style.visibility = 'visible';
+
+      // Adding border shouldn't affect the paddingEdge.height.
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.height, 18);
+      // Adding padding should affect the paddingEdge.height.
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.height, 650);
+    });
+
+    test('paddingEdge.height with border-box', () {
+      var all1 = queryAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.paddingEdge.height, 10);
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.height, 640);
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.height, 640);
+    });
+
+    test('paddingEdge.width', () {
+      var all1 = queryAll('#test');
+      expect(all1.paddingEdge.width, 19);
+      all1[0].style.visibility = 'hidden';
+      expect(all1.paddingEdge.width, 19);
+      all1[0].style.visibility = 'visible';
+
+      // Adding border shouldn't affect the width.
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.width, 19);
+
+      // Adding padding should affect the paddingEdge.width.
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.width, 651);
+    });
+
+    test('paddingEdge.width with border-box', () {
+      var all1 = queryAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.paddingEdge.width, 11);
+      div.style.padding = '20pc';
+      expect(all1.paddingEdge.width, 640);
+      div.style.border = '2px solid #fff';
+      expect(all1.paddingEdge.width, 640);
+    });
+
+    test('borderEdge.height and marginEdge.height', () {
+      var all1 = queryAll('#test');
+      expect(div.borderEdge.height, 18);
+      expect(div.marginEdge.height, 30);
+      expect(all1.borderEdge.height, 18);
+      expect(all1.marginEdge.height, 30);
+      all1[0].style.visibility = 'hidden';
+      expect(all1.borderEdge.height, 18);
+      all1[0].style.visibility = 'visible';
+
+      // Adding border should affect the borderEdge.height.
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.height, 22);
+      // Adding padding should affect the borderEdge.height.
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.height, 654);
+      expect(all1.marginEdge.height, 666);
+    });
+
+
+    test('borderEdge.height and marginEdge.height with border-box', () {
+      var all1 = queryAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.borderEdge.height, 10);
+      expect(all1.marginEdge.height, 22);
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.height, 640);
+      expect(all1.marginEdge.height, 652);
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.height, 644);
+      expect(all1.marginEdge.height, 656);
+    });
+
+    test('borderEdge.width and marginEdge.width', () {
+      var all1 = queryAll('#test');
+      expect(all1.borderEdge.width, 19);
+      expect(all1.marginEdge.width, 31);
+
+      // Adding border should affect the width.
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.width, 23);
+
+      // Adding padding should affect the borderEdge.width.
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.width, 655);
+      expect(all1.marginEdge.width, 667);
+    });
+
+    test('borderEdge.width and marginEdge.width with border-box', () {
+      var all1 = queryAll('#test');
+      div.style.boxSizing = 'border-box';
+      expect(all1.borderEdge.width, 11);
+      expect(all1.marginEdge.width, 23);
+      div.style.padding = '20pc';
+      expect(all1.borderEdge.width, 640);
+      expect(all1.marginEdge.width, 652);
+      div.style.border = '2px solid #fff';
+      expect(all1.borderEdge.width, 644);
+      expect(all1.marginEdge.width, 656);
+    });
+
+    test('left and top', () {
+      div.style.border = '1px solid #fff';
+      div.style.margin = '6px 7px';
+      div.style.padding = '4px 5px';
+      var all1 = queryAll('#test');
+
+      expect(all1.borderEdge.left, all1[0].getBoundingClientRect().left);
+      expect(all1.borderEdge.top, all1[0].getBoundingClientRect().top);
+
+      expect(all1.contentEdge.left,
+          all1[0].getBoundingClientRect().left + 1 + 5);
+      expect(all1.contentEdge.top, all1[0].getBoundingClientRect().top + 1 + 4);
+
+      expect(all1.marginEdge.left, all1[0].getBoundingClientRect().left - 7);
+      expect(all1.marginEdge.top, all1[0].getBoundingClientRect().top - 6);
+
+      expect(all1.paddingEdge.left, all1[0].getBoundingClientRect().left + 1);
+      expect(all1.paddingEdge.top, all1[0].getBoundingClientRect().top + 1);
+    });
+
+    test('setHeight ElementList', () {
+      div.style.border = '1px solid #fff';
+      div.style.margin = '6px 7px';
+      div.style.padding = '4px 5px';
+      var all1 = queryAll('div');
+      all1.contentEdge.height = new Dimension.px(200);
+      all1.contentEdge.height = 200;
+      for (Element elem in all1) {
+        expect(elem.contentEdge.height, 200);
+      }
+      all1.contentEdge.height = new Dimension.px(10);
+      for (Element elem in all1) {
+        expect(elem.contentEdge.height, 10);
+      }
+    });
+  });
+}
diff --git a/tests/language/library1.dart b/tests/language/library1.dart
index 849a188..96cdd1b 100644
--- a/tests/language/library1.dart
+++ b/tests/language/library1.dart
@@ -6,3 +6,13 @@
 library library1.dart;
 
 var foo;
+
+bar() => "library1.dart bar()";
+
+baz() => "library1.dart baz()";
+
+var bay;
+
+typedef int bax(int a, int b);
+
+class baw {}
diff --git a/tests/language/library1_negative_test.dart b/tests/language/library1_negative_test.dart
deleted file mode 100644
index aa5f869..0000000
--- a/tests/language/library1_negative_test.dart
+++ /dev/null
@@ -1,16 +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.
-
-// This test should fail to load because we are importing two libraries
-// which define the same top level name foo, and we are referring to the name.
-
-library Library1NegativeTest.dart;
-import "package:expect/expect.dart";
-import "library1.dart";  // Defines top level variable 'foo'
-import "library2.dart";  // Defines top level variable 'foo'
-
-
-main() {
-  Expect.equals(0, foo); // Reference ambiguous name 'foo'
-}
diff --git a/tests/language/library2.dart b/tests/language/library2.dart
index 1632878..275bf26 100644
--- a/tests/language/library2.dart
+++ b/tests/language/library2.dart
@@ -7,3 +7,13 @@
 
 var foo;
 var foo1 = 0;
+
+bar() => "library2.dart bar()";
+
+var baz;
+
+bay() => "library2.dart bay()";
+
+typedef double bax(int a, int b);
+
+var baw;
\ No newline at end of file
diff --git a/tests/language/library_ambiguous_test.dart b/tests/language/library_ambiguous_test.dart
new file mode 100644
index 0000000..4a16f92
--- /dev/null
+++ b/tests/language/library_ambiguous_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test should fail to load because we are importing two libraries
+// which define the same top level name foo, and we are referring to the name.
+
+library Library1NegativeTest.dart;
+import "library1.dart";  // Defines top level variable 'foo'
+import "library2.dart";  // Defines top level variable 'foo'
+
+class X
+extends baw   /// 05: compile-time error
+{}
+
+main() {
+  print(foo);  /// 00: compile-time error
+  print(bar());  /// 01: compile-time error
+  print(baz());  /// 02: compile-time error
+  print(bay());  /// 03: compile-time error
+  print(main is bax);  /// 04: compile-time error
+  var x = new X();  /// 05: continued
+  print("No error expected if ambiguous definitions are not used.");
+}
diff --git a/tests/language/mixin_prefix_lib.dart b/tests/language/mixin_prefix_lib.dart
new file mode 100644
index 0000000..9c1295f
--- /dev/null
+++ b/tests/language/mixin_prefix_lib.dart
@@ -0,0 +1,11 @@
+// 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 mixin_prefix_lib;
+
+import 'dart:json' as json;
+
+class MixinClass {
+  String bar() => json.stringify({'a':1});
+}
diff --git a/tests/language/mixin_prefix_test.dart b/tests/language/mixin_prefix_test.dart
new file mode 100644
index 0000000..eea64ce
--- /dev/null
+++ b/tests/language/mixin_prefix_test.dart
@@ -0,0 +1,17 @@
+// 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 issue 11891.
+
+import "package:expect/expect.dart";
+import "mixin_prefix_lib.dart";
+
+class A extends Object with MixinClass {
+  String baz() => bar();
+}
+
+void main() {
+  var a = new A();
+  Expect.equals('{"a":1}', a.baz());
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 9b5952c..81eb98d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -17,6 +17,7 @@
 typed_data/float32x4_list_test: Fail, OK
 typed_data/float32x4_unbox_phi_test: Fail, OK
 typed_data/float32x4_unbox_regress_test: Fail, OK
+typed_data/float32x4_shuffle_test: Fail, OK
 
 [ $compiler == dart2js && ($runtime == d8 || $runtime == ie9) ]
 typed_data/byte_data_test: Fail, OK # d8/ie9 doesn't support DataView
@@ -64,6 +65,7 @@
 typed_data/float32x4_list_test: Fail           # Issue 10961
 typed_data/float32x4_unbox_phi_test: Fail      # Issue 10961
 typed_data/float32x4_unbox_regress_test: Fail  # Issue 10961
+typed_data/float32x4_shuffle_test: Fail        # Issue 10961
 
 [ $runtime == ff ]
 # FF setTimeout can fire early: https://bugzilla.mozilla.org/show_bug.cgi?id=291386
@@ -109,6 +111,7 @@
 
 [ $arch == arm || $arch == simarm ]
 typed_data/float32x4_test: Crash # Unimplemented
+typed_data/float32x4_shuffle_test: Crash # Unimplemented
 
 [ $arch == mips ]
 *: Skip
@@ -118,3 +121,4 @@
 typed_data/float32x4_unbox_phi_test: Crash # Unimplemented
 typed_data/float32x4_list_test: Crash # Unimplemented
 typed_data/float32x4_test: Crash # Unimplemented
+typed_data/float32x4_shuffle_test: Crash # Unimplemented
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index 1b9a999..bf108ce 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -254,6 +254,11 @@
     expect(typedefMirror.simpleName, equals(const Symbol('Typedef')));
     expect(typedefMirror.qualifiedName,
            equals(const Symbol('MirrorsTest.Typedef')));
+
+    var typedefMirrorDeNovo = reflectClass(Typedef);
+    expect(typedefMirrorDeNovo.simpleName, equals(const Symbol('Typedef')));
+    expect(typedefMirrorDeNovo.qualifiedName,
+           equals(const Symbol('MirrorsTest.Typedef')));
   }
 
   expect(methodMirror.simpleName, equals(const Symbol('testNames')));
diff --git a/tests/lib/typed_data/float32x4_shuffle_test.dart b/tests/lib/typed_data/float32x4_shuffle_test.dart
new file mode 100644
index 0000000..5492259
--- /dev/null
+++ b/tests/lib/typed_data/float32x4_shuffle_test.dart
@@ -0,0 +1,1319 @@
+// 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 tag to be able to run in html test framework.
+library float32x4_shuffle_test;
+
+import "package:expect/expect.dart";
+import 'dart:typed_data';
+
+void testShuffle0() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.xxxx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xxxy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xxxz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xxxw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xxyx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xxyy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xxyz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xxyw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xxzx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xxzy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xxzz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xxzw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xxwx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xxwy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xxwz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xxww;
+  Expect.equals(1.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xyxx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xyxy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xyxz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xyxw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xyyx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xyyy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xyyz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xyyw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xyzx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xyzy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xyzz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xyzw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xywx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xywy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xywz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xyww;
+  Expect.equals(1.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xzxx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xzxy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xzxz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xzxw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xzyx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xzyy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xzyz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xzyw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xzzx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xzzy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xzzz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xzzw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xzwx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xzwy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xzwz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xzww;
+  Expect.equals(1.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xwxx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xwxy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xwxz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xwxw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xwyx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xwyy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xwyz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xwyw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xwzx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xwzy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xwzz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xwzw;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.xwwx;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.xwwy;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.xwwz;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.xwww;
+  Expect.equals(1.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle1() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.yxxx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yxxy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yxxz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yxxw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yxyx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yxyy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yxyz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yxyw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yxzx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yxzy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yxzz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yxzw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yxwx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yxwy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yxwz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yxww;
+  Expect.equals(2.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yyxx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yyxy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yyxz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yyxw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yyyx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yyyy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yyyz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yyyw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yyzx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yyzy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yyzz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yyzw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yywx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yywy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yywz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yyww;
+  Expect.equals(2.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yzxx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yzxy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yzxz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yzxw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yzyx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yzyy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yzyz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yzyw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yzzx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yzzy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yzzz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yzzw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.yzwx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.yzwy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.yzwz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.yzww;
+  Expect.equals(2.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.ywxx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.ywxy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.ywxz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.ywxw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.ywyx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.ywyy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.ywyz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.ywyw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.ywzx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.ywzy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.ywzz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.ywzw;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.ywwx;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.ywwy;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.ywwz;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.ywww;
+  Expect.equals(2.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle2() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.zxxx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zxxy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zxxz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zxxw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zxyx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zxyy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zxyz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zxyw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zxzx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zxzy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zxzz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zxzw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zxwx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zxwy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zxwz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zxww;
+  Expect.equals(3.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zyxx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zyxy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zyxz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zyxw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zyyx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zyyy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zyyz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zyyw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zyzx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zyzy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zyzz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zyzw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zywx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zywy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zywz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zyww;
+  Expect.equals(3.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zzxx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zzxy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zzxz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zzxw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zzyx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zzyy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zzyz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zzyw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zzzx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zzzy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zzzz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zzzw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zzwx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zzwy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zzwz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zzww;
+  Expect.equals(3.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zwxx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zwxy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zwxz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zwxw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zwyx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zwyy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zwyz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zwyw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zwzx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zwzy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zwzz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zwzw;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.zwwx;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.zwwy;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.zwwz;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.zwww;
+  Expect.equals(3.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+void testShuffle3() {
+  var m = new Float32x4(1.0, 2.0, 3.0, 4.0);
+  var c;
+  c = m.wxxx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wxxy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wxxz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wxxw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wxyx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wxyy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wxyz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wxyw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wxzx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wxzy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wxzz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wxzw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wxwx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wxwy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wxwz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wxww;
+  Expect.equals(4.0, c.x);
+  Expect.equals(1.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wyxx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wyxy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wyxz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wyxw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wyyx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wyyy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wyyz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wyyw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wyzx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wyzy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wyzz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wyzw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wywx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wywy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wywz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wyww;
+  Expect.equals(4.0, c.x);
+  Expect.equals(2.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wzxx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wzxy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wzxz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wzxw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wzyx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wzyy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wzyz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wzyw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wzzx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wzzy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wzzz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wzzw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wzwx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wzwy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wzwz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wzww;
+  Expect.equals(4.0, c.x);
+  Expect.equals(3.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wwxx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wwxy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wwxz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wwxw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(1.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wwyx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wwyy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wwyz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wwyw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(2.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wwzx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wwzy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wwzz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wwzw;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(3.0, c.z);
+  Expect.equals(4.0, c.w);
+  c = m.wwwx;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(1.0, c.w);
+  c = m.wwwy;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(2.0, c.w);
+  c = m.wwwz;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(3.0, c.w);
+  c = m.wwww;
+  Expect.equals(4.0, c.x);
+  Expect.equals(4.0, c.y);
+  Expect.equals(4.0, c.z);
+  Expect.equals(4.0, c.w);
+}
+
+
+main() {
+  for (int i = 0; i < 4000; i++) {
+    testShuffle0();
+    testShuffle1();
+    testShuffle2();
+    testShuffle3();
+  }
+}
diff --git a/tests/lib/typed_data/float32x4_test.dart b/tests/lib/typed_data/float32x4_test.dart
index 4d2c15e..35ee655 100644
--- a/tests/lib/typed_data/float32x4_test.dart
+++ b/tests/lib/typed_data/float32x4_test.dart
@@ -149,6 +149,26 @@
   Expect.equals(4.0, wwww.y);
   Expect.equals(4.0, wwww.z);
   Expect.equals(4.0, wwww.w);
+  var wzyx = m.wzyx;
+  Expect.equals(4.0, wzyx.x);
+  Expect.equals(3.0, wzyx.y);
+  Expect.equals(2.0, wzyx.z);
+  Expect.equals(1.0, wzyx.w);
+  var wwzz = m.wwzz;
+  Expect.equals(4.0, wwzz.x);
+  Expect.equals(4.0, wwzz.y);
+  Expect.equals(3.0, wwzz.z);
+  Expect.equals(3.0, wwzz.w);
+  var xxyy = m.xxyy;
+  Expect.equals(1.0, xxyy.x);
+  Expect.equals(1.0, xxyy.y);
+  Expect.equals(2.0, xxyy.z);
+  Expect.equals(2.0, xxyy.w);
+  var yyww = m.yyww;
+  Expect.equals(2.0, yyww.x);
+  Expect.equals(2.0, yyww.y);
+  Expect.equals(4.0, yyww.z);
+  Expect.equals(4.0, yyww.w);
 }
 
 testMin() {
diff --git a/tools/VERSION b/tools/VERSION
index de9958b..0655e7f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 6
-BUILD 8
+BUILD 9
 PATCH 0
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index b2fd1ba..7ce71fb 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -527,7 +527,7 @@
           "   * The data received as a reponse from the request.",
           "   *",
           "   * The data could be in the",
-          "   * form of a [String], [ArrayBuffer], [Document], [Blob], or json (also a",
+          "   * form of a [String], [ByteBuffer], [Document], [Blob], or json (also a",
           "   * [String]). `null` indicates request failure.",
           "   */"
         ],
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index f4a5c85..54844a6 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -40,10 +40,10 @@
 def analyze():
   ''' Runs the dart analyzer. '''
   return call([
-    os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart_analyzer'),
+    os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dartanalyzer'),
     os.path.join('tests', 'html', 'element_test.dart'),
-    '--dart-sdk', 'sdk',
-    '--show-sdk-warnings',
+    '--dart-sdk=sdk',
+    '--show-package-warnings',
   ])
 
 def build():
diff --git a/tools/dom/src/CssRectangle.dart b/tools/dom/src/CssRectangle.dart
new file mode 100644
index 0000000..6808927
--- /dev/null
+++ b/tools/dom/src/CssRectangle.dart
@@ -0,0 +1,261 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of html;
+
+/**
+ * A rectangle representing all the content of the element in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssRect extends CssRect {
+
+  _ContentCssRect(element) : super(element);
+
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _CONTENT);
+
+  num get width => _element.offsetWidth +
+      _addOrSubtractToBoxModel(_WIDTH, _CONTENT);
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   */
+  void set height(newHeight) {
+    if (newHeight is Dimension) {
+      if (newHeight.value < 0) newHeight = new Dimension.px(0);
+      _element.style.height = newHeight.toString();
+    } else {
+      if (newHeight < 0) newHeight = 0;
+      _element.style.height = '${newHeight}px';
+    }
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  void set width(newWidth) {
+    if (newWidth is Dimension) {
+      if (newWidth.value < 0) newWidth = new Dimension.px(0);
+      _element.style.width = newWidth.toString();
+    } else {
+      if (newWidth < 0) newWidth = 0;
+      _element.style.width = '${newWidth}px';
+    }
+  }
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _CONTENT);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _CONTENT);
+}
+
+/**
+ * A list of element content rectangles in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _ContentCssListRect extends _ContentCssRect {
+  List<Element> _elementList;
+
+  _ContentCssListRect(elementList) : super(elementList.first) {
+    _elementList = elementList;
+  }
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * Values of newHeight that are less than zero are converted to effectively
+   * setting the height to 0. This is equivalent to the `height`
+   * function in jQuery and the calculated `height` CSS value, converted to a
+   * num in pixels.
+   */
+  void set height(newHeight) {
+    _elementList.forEach((e) => e.contentEdge.height = newHeight);
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   */
+  void set width(newWidth) {
+    _elementList.forEach((e) => e.contentEdge.width = newWidth);
+  }
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _PaddingCssRect extends CssRect {
+  _PaddingCssRect(element) : super(element);
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _PADDING);
+  num get width => _element.offsetWidth +
+      _addOrSubtractToBoxModel(_WIDTH, _PADDING);
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _PADDING);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _PADDING);
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _BorderCssRect extends CssRect {
+  _BorderCssRect(element) : super(element);
+  num get height => _element.offsetHeight;
+  num get width => _element.offsetWidth;
+
+  num get left => _element.getBoundingClientRect().left;
+  num get top => _element.getBoundingClientRect().top;
+}
+
+/**
+ * A rectangle representing the dimensions of the space occupied by the
+ * element's content + padding + border + margin in the
+ * [box model](http://www.w3.org/TR/CSS2/box.html).
+ */
+class _MarginCssRect extends CssRect {
+  _MarginCssRect(element) : super(element);
+  num get height => _element.offsetHeight +
+      _addOrSubtractToBoxModel(_HEIGHT, _MARGIN);
+  num get width =>
+      _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN);
+
+  num get left => _element.getBoundingClientRect().left -
+      _addOrSubtractToBoxModel(['left'], _MARGIN);
+  num get top => _element.getBoundingClientRect().top -
+      _addOrSubtractToBoxModel(['top'], _MARGIN);
+}
+
+/**
+ * A class for representing CSS dimensions.
+ *
+ * In contrast to the more general purpose [Rect] class, this class's values are
+ * mutable, so one can change the height of an element programmatically.
+ *
+ * _Important_ _note_: use of these methods will perform CSS calculations that
+ * can trigger a browser reflow. Therefore, use of these properties _during_ an
+ * animation frame is discouraged. See also:
+ * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+ */
+abstract class CssRect extends RectBase implements Rect {
+  Element _element;
+
+  CssRect(this._element);
+
+  num get left;
+
+  num get top;
+
+  /**
+   * The height of this rectangle.
+   *
+   * This is equivalent to the `height` function in jQuery and the calculated
+   * `height` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `height` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get height;
+
+  /**
+   * The width of this rectangle.
+   *
+   * This is equivalent to the `width` function in jQuery and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels. Unlike
+   * [getBoundingClientRect], `width` will return the same numerical width if
+   * the element is hidden or not.
+   */
+  num get width;
+
+  /**
+   * Set the height to `newHeight`.
+   *
+   * newHeight can be either a [num] representing the height in pixels or a
+   * [Dimension] object. Values of newHeight that are less than zero are
+   * converted to effectively setting the height to 0. This is equivalent to the
+   * `height` function in jQuery and the calculated `height` CSS value,
+   * converted to a num in pixels.
+   *
+   * Note that only the content height can actually be set via this method.
+   */
+  void set height(newHeight) {
+    throw new UnsupportedError("Can only set height for content rect.");
+  }
+
+  /**
+   * Set the current computed width in pixels of this element.
+   *
+   * newWidth can be either a [num] representing the width in pixels or a
+   * [Dimension] object. This is equivalent to the `width` function in jQuery
+   * and the calculated
+   * `width` CSS value, converted to a dimensionless num in pixels.
+   *
+   * Note that only the content width can be set via this method.
+   */
+  void set width(newWidth) {
+    throw new UnsupportedError("Can only set width for content rect.");
+  }
+
+  /**
+   * Return a value that is used to modify the initial height or width
+   * measurement of an element. Depending on the value (ideally an enum) passed
+   * to augmentingMeasurement, we may need to add or subtract margin, padding,
+   * or border values, depending on the measurement we're trying to obtain.
+   */
+  num _addOrSubtractToBoxModel(List<String> dimensions,
+      String augmentingMeasurement) {
+    // getComputedStyle always returns pixel values (hence, computed), so we're
+    // always dealing with pixels in this method.
+    var styles = _element.getComputedStyle();
+
+    var val = 0;
+
+    for (String measurement in dimensions) {
+      // The border-box and default box model both exclude margin in the regular
+      // height/width calculation, so add it if we want it for this measurement.
+      if (augmentingMeasurement == _MARGIN) {
+        val += new Dimension.css(styles.getPropertyValue(
+            '$augmentingMeasurement-$measurement')).value;
+      }
+
+      // The border-box includes padding and border, so remove it if we want
+      // just the content itself.
+      if (augmentingMeasurement == _CONTENT) {
+      	val -= new Dimension.css(
+            styles.getPropertyValue('${_PADDING}-$measurement')).value;
+      }
+
+      // At this point, we don't wan't to augment with border or margin,
+      // so remove border.
+      if (augmentingMeasurement != _MARGIN) {
+	      val -= new Dimension.css(styles.getPropertyValue(
+            'border-${measurement}-width')).value;
+      }
+    }
+    return val;
+  }
+}
+
+final _HEIGHT = ['top', 'bottom'];
+final _WIDTH = ['right', 'left'];
+final _CONTENT = 'content';
+final _PADDING = 'padding';
+final _MARGIN = 'margin';
diff --git a/tools/dom/src/Dimension.dart b/tools/dom/src/Dimension.dart
new file mode 100644
index 0000000..96014c3
--- /dev/null
+++ b/tools/dom/src/Dimension.dart
@@ -0,0 +1,83 @@
+part of html;
+
+/**
+ * Class representing a
+ * [length measurement](https://developer.mozilla.org/en-US/docs/Web/CSS/length)
+ * in CSS.
+ */
+@Experimental()
+class Dimension {
+  num _value;
+  String _unit;
+
+  /** Set this CSS Dimension to a percentage `value`. */
+  Dimension.percent(this._value) : _unit = '%';
+
+  /** Set this CSS Dimension to a pixel `value`. */
+  Dimension.px(this._value) : _unit = 'px';
+
+  /** Set this CSS Dimension to a pica `value`. */
+  Dimension.pc(this._value) : _unit = 'pc';
+
+  /** Set this CSS Dimension to a point `value`. */
+  Dimension.pt(this._value) : _unit = 'pt';
+
+  /** Set this CSS Dimension to an inch `value`. */
+  Dimension.inch(this._value) : _unit = 'in';
+
+  /** Set this CSS Dimension to a centimeter `value`. */
+  Dimension.cm(this._value) : _unit = 'cm';
+
+  /** Set this CSS Dimension to a millimeter `value`. */
+  Dimension.mm(this._value) : _unit = 'mm';
+
+  /**
+   * Set this CSS Dimension to the specified number of ems.
+   *
+   * 1em is equal to the current font size. (So 2ems is equal to double the font
+   * size). This is useful for producing website layouts that scale nicely with
+   * the user's desired font size.
+   */
+  Dimension.em(this._value) : _unit = 'em';
+
+  /**
+   * Set this CSS Dimension to the specified number of x-heights.
+   *
+   * One ex is equal to the the x-height of a font's baseline to its mean line,
+   * generally the height of the letter "x" in the font, which is usually about
+   * half the font-size.
+   */
+  Dimension.ex(this._value) : _unit = 'ex';
+
+  /**
+   * Construct a Dimension object from the valid, simple CSS string `cssValue`
+   * that represents a distance measurement.
+   *
+   * This constructor is intended as a convenience method for working with
+   * simplistic CSS length measurements. Non-numeric values such as `auto` or
+   * `inherit` or invalid CSS will cause this constructor to throw a
+   * FormatError.
+   */
+  Dimension.css(String cssValue) {
+    if (cssValue == '') cssValue = '0px';
+    if (cssValue.endsWith('%')) {
+      _unit = '%';
+    } else {
+      _unit = cssValue.substring(cssValue.length - 2);
+    }
+    if (cssValue.contains('.')) {
+      _value = double.parse(cssValue.substring(0,
+          cssValue.length - _unit.length));
+    } else {
+      _value = int.parse(cssValue.substring(0, cssValue.length - _unit.length));
+    }
+  }
+
+  /** Print out the CSS String representation of this value. */
+  String toString() {
+    return '${_value}${_unit}';
+  }
+
+  /** Return a unitless, numerical value of this CSS value. */
+  num get value => this._value;
+}
diff --git a/tools/dom/src/Rectangle.dart b/tools/dom/src/Rectangle.dart
index e6a80b2..294fa85 100644
--- a/tools/dom/src/Rectangle.dart
+++ b/tools/dom/src/Rectangle.dart
@@ -5,44 +5,24 @@
 part of html;
 
 /**
- * A class for representing two-dimensional rectangles.
+ * A base class for representing two-dimensional rectangles. This will hopefully
+ * be moved merged with the dart:math Rect.
  */
-class Rect {
-  final num left;
-  final num top;
-  final num width;
-  final num height;
+// TODO(efortuna): Merge with Math rect after finalizing with Florian.
+abstract class RectBase {
+  //  Not used, but keeps the VM from complaining about Rect having a const
+  // constructor and this one not.
+  const RectBase();
 
-  const Rect(this.left, this.top, this.width, this.height);
-
-  factory Rect.fromPoints(Point a, Point b) {
-    var left;
-    var width;
-    if (a.x < b.x) {
-      left = a.x;
-      width = b.x - left;
-    } else {
-      left = b.x;
-      width = a.x - left;
-    }
-    var top;
-    var height;
-    if (a.y < b.y) {
-      top = a.y;
-      height = b.y - top;
-    } else {
-      top = b.y;
-      height = a.y - top;
-    }
-
-    return new Rect(left, top, width, height);
-  }
+  num get left;
+  num get top;
+  num get width;
+  num get height;
 
   num get right => left + width;
   num get bottom => top + height;
 
   // NOTE! All code below should be common with Rect.
-  // TODO: implement with mixins when available.
 
   String toString() {
     return '($left, $top, $width, $height)';
@@ -136,3 +116,43 @@
   Point get bottomRight => new Point(this.left + this.width,
       this.top + this.height);
 }
+
+
+
+/**
+ * A class for representing two-dimensional rectangles.
+ *
+ * This class is distinctive from RectBase in that it enforces that its
+ * properties are immutable.
+ */
+class Rect extends RectBase {
+  final num left;
+  final num top;
+  final num width;
+  final num height;
+
+  const Rect(this.left, this.top, this.width, this.height): super();
+
+  factory Rect.fromPoints(Point a, Point b) {
+    var left;
+    var width;
+    if (a.x < b.x) {
+      left = a.x;
+      width = b.x - left;
+    } else {
+      left = b.x;
+      width = a.x - left;
+    }
+    var top;
+    var height;
+    if (a.y < b.y) {
+      top = a.y;
+      height = b.y - top;
+    } else {
+      top = b.y;
+      height = a.y - top;
+    }
+
+    return new Rect(left, top, width, height);
+  }
+}
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 4a94db8..bfe368c 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -38,6 +38,8 @@
 part '$AUXILIARY_DIR/CanvasImageSource.dart';
 part '$AUXILIARY_DIR/CrossFrameTypes.dart';
 part '$AUXILIARY_DIR/CssClassSet.dart';
+part '$AUXILIARY_DIR/CssRectangle.dart';
+part '$AUXILIARY_DIR/Dimension.dart';
 part '$AUXILIARY_DIR/EventListener.dart';
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
 part '$AUXILIARY_DIR/ImmutableListMixin.dart';
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index f8973eb..dd64ae7 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -34,6 +34,8 @@
 part '$AUXILIARY_DIR/CanvasImageSource.dart';
 part '$AUXILIARY_DIR/CrossFrameTypes.dart';
 part '$AUXILIARY_DIR/CssClassSet.dart';
+part '$AUXILIARY_DIR/CssRectangle.dart';
+part '$AUXILIARY_DIR/Dimension.dart';
 part '$AUXILIARY_DIR/EventListener.dart';
 part '$AUXILIARY_DIR/EventStreamProvider.dart';
 part '$AUXILIARY_DIR/ImmutableListMixin.dart';
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index cddb5da..984f10d 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -918,12 +918,17 @@
   }
 
   /** Gets the value of "box-sizing" */
-  String get boxSizing =>
-    getPropertyValue('box-sizing');
+  String get boxSizing => Device.isFirefox ? 
+      getPropertyValue('${Device.cssPrefix}box-sizing') : 
+      getPropertyValue('box-sizing');
 
   /** Sets the value of "box-sizing" */
   void set boxSizing(String value) {
-    setProperty('box-sizing', value, '');
+    if (Device.isFirefox) {
+      setProperty('${Device.cssPrefix}box-sizing', value, '');
+    } else {
+      setProperty('box-sizing', value, '');
+    }
   }
 
   /** Gets the value of "caption-side" */
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 305d5f2..abe094c 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -157,7 +157,8 @@
 
 /**
  * An immutable list containing HTML elements. This list contains some
- * additional methods for ease of CSS manipulation on a group of elements.
+ * additional methods when compared to regular lists for ease of CSS 
+ * manipulation on a group of elements.
  */
 abstract class ElementList<T extends Element> extends ListBase<T> {
   /**
@@ -174,6 +175,63 @@
 
   /** Replace the classes with `value` for every element in this list. */
   set classes(Iterable<String> value);
+
+  /** 
+   * Access dimensions and position of the Elements in this list.
+   * 
+   * Setting the height or width properties will set the height or width
+   * property for all elements in the list. This returns a rectangle with the 
+   * dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Getting the height or width returns the height or width of the
+   * first Element in this list. 
+   *
+   * Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   */
+  @Experimental()
+  CssRect get contentEdge;
+  
+  /**
+   * Access dimensions and position of the first Element's content + padding box
+   * in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `innerHeight` value for an element. This
+   * is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   */
+  @Experimental()
+  CssRect get paddingEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border box in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  @Experimental()
+  CssRect get borderEdge;
+
+  /**
+   * Access dimensions and position of the first Element's content + padding +
+   * border + margin box in this list.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's `outerHeight` value for an element.
+   */
+  @Experimental()
+  CssRect get marginEdge;
 }
 
 // TODO(jacobr): this is an inefficient implementation but it is hard to see
@@ -182,8 +240,12 @@
 // contains Node objects that are not Elements.
 class _FrozenElementList<T extends Element> extends ListBase<T> implements ElementList {
   final List<Node> _nodeList;
+  // The subset of _nodeList that are Elements.
+  List<Element> _elementList;
 
-  _FrozenElementList._wrap(this._nodeList);
+  _FrozenElementList._wrap(this._nodeList) {
+    _elementList = _nodeList.where((e) => e is Element).toList();
+  }
 
   int get length => _nodeList.length;
 
@@ -207,12 +269,19 @@
 
   Element get single => _nodeList.single;
 
-  CssClassSet get classes => new _MultiElementCssClassSet(
-      _nodeList.where((e) => e is Element));
+  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
 
   void set classes(Iterable<String> value) {
-    _nodeList.where((e) => e is Element).forEach((e) => e.classes = value);
+    _elementList.forEach((e) => e.classes = value);
   }
+
+  CssRect get contentEdge => new _ContentCssListRect(_elementList);
+  
+  CssRect get paddingEdge => _elementList.first.paddingEdge;
+
+  CssRect get borderEdge => _elementList.first.borderEdge;
+
+  CssRect get marginEdge => _elementList.first.marginEdge;
 }
 
 /**
@@ -924,6 +993,79 @@
     TemplateElement.decorate(this);
   }
 
+  /**
+   * Access this element's content position.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get contentEdge => new _ContentCssRect(this);
+  
+  /**
+   * Access the dimensions and position of this element's content + padding box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [innerHeight](http://api.jquery.com/innerHeight/) value for an element. 
+   * This is also a rectangle equalling the dimensions of clientHeight and
+   * clientWidth.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get paddingEdge => new _PaddingCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   * 
+   * _Important_ _note_: use of this method _will_ perform CSS calculations that 
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get borderEdge => new _BorderCssRect(this);
+
+  /**
+   * Access the dimensions and position of this element's content + padding +
+   * border + margin box.
+   * 
+   * This returns a rectangle with the dimenions actually available for content
+   * in this element, in pixels, regardless of this element's box-sizing 
+   * property. Unlike [getBoundingClientRect], the dimensions of this rectangle
+   * will return the same numerical height if the element is hidden or not. This
+   * can be used to retrieve jQuery's
+   * [outerHeight](http://api.jquery.com/outerHeight/) value for an element.
+   * 
+   * _Important_ _note_: use of this method will perform CSS calculations that
+   * can trigger a browser reflow. Therefore, use of this property _during_ an 
+   * animation frame is discouraged. See also: 
+   * [Browser Reflow](https://developers.google.com/speed/articles/reflow)
+   */
+  @Experimental()
+  CssRect get marginEdge => new _MarginCssRect(this);
 $!MEMBERS
 }