Version 0.7.5.0

svn merge -r 27585:27697 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@27701 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer_experimental/bin/formatter.dart b/pkg/analyzer_experimental/bin/formatter.dart
index 52b8fd7..504646c 100755
--- a/pkg/analyzer_experimental/bin/formatter.dart
+++ b/pkg/analyzer_experimental/bin/formatter.dart
@@ -116,7 +116,7 @@
 
 /// Format the given [src] as a compilation unit.
 String _formatCU(src, {options: const FormatterOptions()}) =>
-    new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src);
+    new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src).source;
 
 /// Log the given [msg].
 _log(String msg) {
diff --git a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
index 180e9de..04f0e2b 100644
--- a/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer_experimental/lib/src/services/formatter_impl.dart
@@ -78,11 +78,37 @@
 
   /// Format the specified portion (from [offset] with [length]) of the given
   /// [source] string, optionally providing an [indentationLevel].
-  String format(CodeKind kind, String source, {int offset, int end,
-    int indentationLevel: 0});
+  FormattedSource format(CodeKind kind, String source, {int offset, int end,
+    int indentationLevel: 0, Selection selection: null});
 
 }
 
+/// Source selection state information.
+class Selection {
+  
+  /// The offset of the source selection.
+  final int offset;
+  
+  /// The length of the selection.
+  final int length;
+  
+  Selection(this.offset, this.length);
+}
+
+/// Formatted source.
+class FormattedSource {
+  
+  /// Selection state or null if unspecified.
+  final Selection selection;
+  
+  /// Formatted source string.
+  final String source;
+  
+  /// Create a formatted [source] result, with optional [selection] information.
+  FormattedSource(this.source, [this.selection = null]);
+}
+
+
 class CodeFormatterImpl implements CodeFormatter, AnalysisErrorListener {
 
   final FormatterOptions options;
@@ -93,8 +119,8 @@
 
   CodeFormatterImpl(this.options);
 
-  String format(CodeKind kind, String source, {int offset, int end,
-      int indentationLevel: 0}) {
+  FormattedSource format(CodeKind kind, String source, {int offset, int end,
+      int indentationLevel: 0, Selection selection: null}) {
 
     var startToken = tokenize(source);
     checkForErrors();
@@ -109,7 +135,7 @@
     
     checkTokenStreams(startToken, tokenize(formattedSource));
 
-    return formattedSource;
+    return new FormattedSource(formattedSource);
   }
 
   checkTokenStreams(Token t1, Token t2) =>
diff --git a/pkg/analyzer_experimental/test/services/formatter_test.dart b/pkg/analyzer_experimental/test/services/formatter_test.dart
index 37147f7..5503234 100644
--- a/pkg/analyzer_experimental/test/services/formatter_test.dart
+++ b/pkg/analyzer_experimental/test/services/formatter_test.dart
@@ -767,7 +767,8 @@
     test('initialIndent', () {
       var formatter = new CodeFormatter(
           new FormatterOptions(initialIndentationLevel: 2));
-      var formattedSource = formatter.format(CodeKind.STATEMENT, 'var x;');
+      var formattedSource = 
+          formatter.format(CodeKind.STATEMENT, 'var x;').source;
       expect(formattedSource, startsWith('    '));
     });
 
@@ -955,10 +956,10 @@
 }
 
 String formatCU(src, {options: const FormatterOptions()}) =>
-    new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src);
+    new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src).source;
 
 String formatStatement(src, {options: const FormatterOptions()}) =>
-    new CodeFormatter(options).format(CodeKind.STATEMENT, src);
+    new CodeFormatter(options).format(CodeKind.STATEMENT, src).source;
 
 Token tokenize(String str) => new StringScanner(null, str, null).tokenize();
 
diff --git a/pkg/crypto/lib/crypto.dart b/pkg/crypto/lib/crypto.dart
index ee11c25..5125912 100644
--- a/pkg/crypto/lib/crypto.dart
+++ b/pkg/crypto/lib/crypto.dart
@@ -35,7 +35,7 @@
   /**
    * Add a list of bytes to the hash computation.
    */
-  add(List<int> data);
+  void add(List<int> data);
 
   /**
    * Finish the hash computation and extract the message digest as
diff --git a/pkg/crypto/lib/src/hash_utils.dart b/pkg/crypto/lib/src/hash_utils.dart
index 713dbb9..84df9d0 100644
--- a/pkg/crypto/lib/src/hash_utils.dart
+++ b/pkg/crypto/lib/src/hash_utils.dart
@@ -22,16 +22,17 @@
 // Base class encapsulating common behavior for cryptographic hash
 // functions.
 abstract class _HashBase implements Hash {
-  _HashBase(int this._chunkSizeInWords,
-            int this._digestSizeInWords,
+  _HashBase(int chunkSizeInWords,
+            int digestSizeInWords,
             bool this._bigEndianWords)
-      : _pendingData = [] {
-    _currentChunk = new List(_chunkSizeInWords);
-    _h = new List(_digestSizeInWords);
-  }
+      : _pendingData = [],
+        _currentChunk = new List(chunkSizeInWords),
+        _h = new List(digestSizeInWords),
+        _chunkSizeInWords = chunkSizeInWords,
+        _digestSizeInWords = digestSizeInWords;
 
   // Update the hasher with more data.
-  add(List<int> data) {
+  void add(List<int> data) {
     if (_digestCalled) {
       throw new StateError(
           'Hash update method called after digest was retrieved');
@@ -58,18 +59,15 @@
     return _chunkSizeInWords * _BYTES_PER_WORD;
   }
 
-  // Create a fresh instance of this Hash.
-  newInstance();
-
   // One round of the hash computation.
-  _updateHash(List<int> m);
+  void _updateHash(List<int> m);
 
   // Helper methods.
-  _add32(x, y) => (x + y) & _MASK_32;
-  _roundUp(val, n) => (val + n - 1) & -n;
+  int _add32(x, y) => (x + y) & _MASK_32;
+  int _roundUp(val, n) => (val + n - 1) & -n;
 
   // Compute the final result as a list of bytes from the hash words.
-  _resultAsBytes() {
+  List<int> _resultAsBytes() {
     var result = [];
     for (var i = 0; i < _h.length; i++) {
       result.addAll(_wordToBytes(_h[i]));
@@ -78,7 +76,7 @@
   }
 
   // Converts a list of bytes to a chunk of 32-bit words.
-  _bytesToChunk(List<int> data, int dataIndex) {
+  void _bytesToChunk(List<int> data, int dataIndex) {
     assert((data.length - dataIndex) >= (_chunkSizeInWords * _BYTES_PER_WORD));
 
     for (var wordIndex = 0; wordIndex < _chunkSizeInWords; wordIndex++) {
@@ -96,7 +94,7 @@
   }
 
   // Convert a 32-bit word to four bytes.
-  _wordToBytes(int word) {
+  List<int> _wordToBytes(int word) {
     List<int> bytes = new List(_BYTES_PER_WORD);
     bytes[0] = (word >> (_bigEndianWords ? 24 : 0)) & _MASK_8;
     bytes[1] = (word >> (_bigEndianWords ? 16 : 8)) & _MASK_8;
@@ -107,7 +105,7 @@
 
   // Iterate through data updating the hash computation for each
   // chunk.
-  _iterate() {
+  void _iterate() {
     var len = _pendingData.length;
     var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
     if (len >= chunkSizeInBytes) {
@@ -122,7 +120,7 @@
 
   // Finalize the data. Add a 1 bit to the end of the message. Expand with
   // 0 bits and add the length of the message.
-  _finalizeData() {
+  void _finalizeData() {
     _pendingData.add(0x80);
     var contentsLength = _lengthInBytes + 9;
     var chunkSizeInBytes = _chunkSizeInWords * _BYTES_PER_WORD;
@@ -148,7 +146,7 @@
   final bool _bigEndianWords;
   int _lengthInBytes = 0;
   List<int> _pendingData;
-  List<int> _currentChunk;
-  List<int> _h;
+  final List<int> _currentChunk;
+  final List<int> _h;
   bool _digestCalled = false;
 }
diff --git a/pkg/crypto/lib/src/hmac.dart b/pkg/crypto/lib/src/hmac.dart
index 59c1771..ba6cc11 100644
--- a/pkg/crypto/lib/src/hmac.dart
+++ b/pkg/crypto/lib/src/hmac.dart
@@ -22,7 +22,7 @@
   /**
    * Add a list of bytes to the message.
    */
-  add(List<int> data) {
+  void add(List<int> data) {
     if (_isClosed) throw new StateError("HMAC is closed");
     _message.addAll(data);
   }
@@ -110,5 +110,5 @@
   // HMAC internal state.
   Hash _hash;
   List<int> _key;
-  List<int> _message;
+  final List<int> _message;
 }
diff --git a/pkg/crypto/lib/src/sha256.dart b/pkg/crypto/lib/src/sha256.dart
index f1c20e3..b429b8f 100644
--- a/pkg/crypto/lib/src/sha256.dart
+++ b/pkg/crypto/lib/src/sha256.dart
@@ -103,5 +103,5 @@
     _h[7] = _add32(h, _h[7]);
   }
 
-  List<int> _w;
+  final List<int> _w;
 }
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index f5a0810..64ca2b6 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -14,12 +14,7 @@
   // integers, storing the 22 low, 22 middle, and 20 high bits of the
   // 64-bit value.  _l (low) and _m (middle) are in the range
   // [0, 2^22 - 1] and _h (high) is in the range [0, 2^20 - 1].
-  int _l, _m, _h;
-
-  // Note: instances of [Int64] are immutable outside of this library,
-  // therefore we may return a reference to an existing instance.
-  // We take care to perform mutation only on internally-generated
-  // instances before they are exposed to external code.
+  final int _l, _m, _h;
 
   // Note: several functions require _BITS == 22 -- do not change this value.
   static const int _BITS = 22;
@@ -30,67 +25,38 @@
   static const int _SIGN_BIT = 19; // _BITS2 - 1
   static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT
 
-  // Cached constants
-  static Int64 _MAX_VALUE;
-  static Int64 _MIN_VALUE;
-  static Int64 _ZERO;
-  static Int64 _ONE;
-  static Int64 _TWO;
-
-  // The remainder of the last divide operation.
-  static Int64 _remainder;
-
   /**
    * The maximum positive value attainable by an [Int64], namely
    * 9,223,372,036,854,775,807.
    */
-  static Int64 get MAX_VALUE {
-    if (_MAX_VALUE == null) {
-      _MAX_VALUE = new Int64._bits(_MASK, _MASK, _MASK2 >> 1);
-    }
-    return _MAX_VALUE;
-  }
+  static const Int64 MAX_VALUE = const Int64._bits(_MASK, _MASK, _MASK2 >> 1);
 
   /**
    * The minimum positive value attainable by an [Int64], namely
    * -9,223,372,036,854,775,808.
    */
-  static Int64 get MIN_VALUE {
-    if (_MIN_VALUE == null) {
-      _MIN_VALUE = new Int64._bits(0, 0, _SIGN_BIT_MASK);
-    }
-    return _MIN_VALUE;
-  }
+  static const Int64 MIN_VALUE = const Int64._bits(0, 0, _SIGN_BIT_MASK);
 
   /**
    * An [Int64] constant equal to 0.
    */
-  static Int64 get ZERO {
-    if (_ZERO == null) {
-      _ZERO = new Int64();
-    }
-    return _ZERO;
-  }
+  static const Int64 ZERO = const Int64._bits(0, 0, 0);
 
   /**
    * An [Int64] constant equal to 1.
    */
-  static Int64 get ONE {
-    if (_ONE == null) {
-      _ONE = new Int64._bits(1, 0, 0);
-    }
-    return _ONE;
-  }
+  static const Int64 ONE = const Int64._bits(1, 0, 0);
 
   /**
    * An [Int64] constant equal to 2.
    */
-  static Int64 get TWO {
-    if (_TWO == null) {
-      _TWO = new Int64._bits(2, 0, 0);
-    }
-    return _TWO;
-  }
+  static const Int64 TWO = const Int64._bits(2, 0, 0);
+
+  /**
+   * Constructs an [Int64] with a given bitwise representation.  No validation
+   * is performed.
+   */
+  const Int64._bits(int this._l, int this._m, int this._h);
 
   /**
    * Parses a [String] in a given [radix] between 2 and 36 and returns an
@@ -122,26 +88,18 @@
       // multiply and add within 30 bit temporary values.
       d0 = d0 * radix + digit;
       int carry = d0 >> _BITS;
-      d0 &= _MASK;
+      d0 = _MASK & d0;
 
       d1 = d1 * radix + carry;
       carry = d1 >> _BITS;
-      d1 &= _MASK;
+      d1 = _MASK & d1;;
 
       d2 = d2 * radix + carry;
-      d2 &= _MASK2;
+      d2 = _MASK2 & d2;
     }
 
-    if (negative) {
-      d0 = 0 - d0;
-      int borrow = (d0 >> _BITS) & 1;
-      d0 &= _MASK;
-      d1 = 0 - d1 - borrow;
-      borrow = (d1 >> _BITS) & 1;
-      d1 &= _MASK;
-      d2 = 0 - d2 - borrow;
-      d2 &= _MASK2;
-    }
+    if (negative) return _negate(d0, d1, d2);
+
     return new Int64._bits(d0, d1, d2);
   }
 
@@ -167,30 +125,32 @@
   /**
    * Constructs an [Int64] with a given [int] value.
    */
-  Int64.fromInt(int value) {
+  factory Int64.fromInt(int value) {
+    int v0 = 0, v1 = 0, v2 = 0;
     bool negative = false;
     if (value < 0) {
       negative = true;
       value = -value - 1;
     }
     if (_haveBigInts) {
-      _l = value & _MASK;
-      _m = (value >> _BITS) & _MASK;
-      _h = (value >> _BITS01) & _MASK2;
+      v0 = _MASK & value;
+      v1 = _MASK & (value >> _BITS);
+      v2 = _MASK2 & (value >> _BITS01);
     } else {
       // Avoid using bitwise operations that coerce their input to 32 bits.
-      _h = value ~/ 17592186044416; // 2^44
-      value -= _h * 17592186044416;
-      _m = value ~/ 4194304; // 2^22
-      value -= _m * 4194304;
-      _l = value;
+      v2 = value ~/ 17592186044416; // 2^44
+      value -= v2 * 17592186044416;
+      v1 = value ~/ 4194304; // 2^22
+      value -= v1 * 4194304;
+      v0 = value;
     }
 
     if (negative) {
-      _l = ~_l & _MASK;
-      _m = ~_m & _MASK;
-      _h = ~_h & _MASK2;
+      v0 = _MASK & ~v0;
+      v1 = _MASK & ~v1;
+      v2 = _MASK2 & ~v2;
     }
+    return new Int64._bits(v0, v1, v2);
   }
 
   factory Int64.fromBytes(List<int> bytes) {
@@ -248,7 +208,7 @@
 
   // Returns the [Int64] representation of the specified value. Throws
   // [ArgumentError] for non-integer arguments.
-  Int64 _promote(val) {
+  static Int64 _promote(val) {
     if (val is Int64) {
       return val;
     } else if (val is int) {
@@ -262,31 +222,17 @@
   Int64 operator +(other) {
     Int64 o = _promote(other);
     int sum0 = _l + o._l;
-    int sum1 = _m + o._m + _shiftRight(sum0, _BITS);
-    int sum2 = _h + o._h + _shiftRight(sum1, _BITS);
-
-    Int64 result = new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK2);
-    return result;
+    int sum1 = _m + o._m + (sum0 >> _BITS);
+    int sum2 = _h + o._h + (sum1 >> _BITS);
+    return Int64._masked(sum0, sum1, sum2);
   }
 
   Int64 operator -(other) {
     Int64 o = _promote(other);
-    int sum0 = _l - o._l;
-    int sum1 = _m - o._m + _shiftRight(sum0, _BITS);
-    int sum2 = _h - o._h + _shiftRight(sum1, _BITS);
-
-    Int64 result = new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK2);
-    return result;
+    return _sub(_l, _m, _h, o._l, o._m, o._h);
   }
 
-  Int64 operator -() {
-    // Like 0 - this.
-    int sum0 = -_l;
-    int sum1 = -_m + _shiftRight(sum0, _BITS);
-    int sum2 = -_h + _shiftRight(sum1, _BITS);
-
-    return new Int64._bits(sum0 & _MASK, sum1 & _MASK, sum2 & _MASK2);
-  }
+  Int64 operator -() => _negate(_l, _m, _h);
 
   Int64 operator *(other) {
     Int64 o = _promote(other);
@@ -372,29 +318,11 @@
     return new Int64._bits(c0, c1, c2);
   }
 
-  Int64 operator %(other) {
-    if (other.isZero) {
-      throw new IntegerDivisionByZeroException();
-    }
-    if (this.isZero) {
-      return ZERO;
-    }
-    Int64 o = _promote(other).abs();
-    _divMod(this, o, true);
-    return _remainder < 0 ? (_remainder + o) : _remainder;
-  }
+  Int64 operator %(other) => _divide(this, other, _RETURN_MOD);
 
-  Int64 operator ~/(other) => _divMod(this, _promote(other), false);
+  Int64 operator ~/(other) => _divide(this, other, _RETURN_DIV);
 
-  // Int64 remainder(other) => this - (this ~/ other) * other;
-  Int64 remainder(other) {
-    if (other.isZero) {
-      throw new IntegerDivisionByZeroException();
-    }
-    Int64 o = _promote(other).abs();
-    _divMod(this, o, true);
-    return _remainder;
-  }
+  Int64 remainder(other) => _divide(this, other, _RETURN_REM);
 
   Int64 operator &(other) {
     Int64 o = _promote(other);
@@ -421,8 +349,7 @@
   }
 
   Int64 operator ~() {
-    var result = new Int64._bits((~_l) & _MASK, (~_m) & _MASK, (~_h) & _MASK2);
-    return result;
+    return Int64._masked(~_l, ~_m, ~_h);
   }
 
   Int64 operator <<(int n) {
@@ -446,7 +373,7 @@
       res2 = _l << (n - _BITS01);
     }
 
-    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK2);
+    return Int64._masked(res0, res1, res2);
   }
 
   Int64 operator >>(int n) {
@@ -460,8 +387,10 @@
     // Sign extend h(a).
     int a2 = _h;
     bool negative = (a2 & _SIGN_BIT_MASK) != 0;
-    if (negative) {
-      a2 += 0x3 << _BITS2; // add extra one bits on the left
+    if (negative && _MASK > _MASK2) {
+      // Add extra one bits on the left so the sign gets shifted into the wider
+      // lower words.
+      a2 += (_MASK - _MASK2);
     }
 
     if (n < _BITS) {
@@ -487,7 +416,7 @@
       }
     }
 
-    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK2);
+    return Int64._masked(res0, res1, res2);
   }
 
   Int64 shiftRightUnsigned(int n) {
@@ -497,7 +426,7 @@
     n &= 63;
 
     int res0, res1, res2;
-    int a2 = _h & _MASK2; // Ensure a2 is positive.
+    int a2 = _MASK2 & _h; // Ensure a2 is positive.
     if (n < _BITS) {
       res2 = a2 >> n;
       res1 = (_m >> n) | (a2 << (_BITS - n));
@@ -512,7 +441,7 @@
       res0 = a2 >> (n - _BITS01);
     }
 
-    return new Int64._bits(res0 & _MASK, res1 & _MASK, res2 & _MASK2);
+    return Int64._masked(res0, res1, res2);
   }
 
   /**
@@ -524,6 +453,10 @@
     if (other is Int64) {
       o = other;
     } else if (other is int) {
+      if (_h == 0 && _m == 0) return _l == other;
+      // Since we know one of [_h] or [_m] is non-zero, if [other] fits in the
+      // low word then it can't be numerically equal.
+      if ((_MASK & other) == other) return false;
       o = new Int64.fromInt(other);
     } else if (other is Int32) {
       o = other.toInt64();
@@ -578,7 +511,7 @@
   bool get isEven => (_l & 0x1) == 0;
   bool get isMaxValue => (_h == _MASK2 >> 1) && _m == _MASK && _l == _MASK;
   bool get isMinValue => _h == _SIGN_BIT_MASK && _m == 0 && _l == 0;
-  bool get isNegative => (_h >> (_BITS2 - 1)) != 0;
+  bool get isNegative => (_h & _SIGN_BIT_MASK) != 0;
   bool get isOdd => (_l & 0x1) == 1;
   bool get isZero => _h == 0 && _m == 0 && _l == 0;
 
@@ -586,13 +519,15 @@
    * Returns a hash code based on all the bits of this [Int64].
    */
   int get hashCode {
+    // TODO(sra): Should we ensure that hashCode values match corresponding int?
+    // i.e. should `new Int64.fromInt(x).hashCode == x.hashCode`?
     int bottom = ((_m & 0x3ff) << _BITS) | _l;
     int top = (_h << 12) | ((_m >> 10) & 0xfff);
     return bottom ^ top;
   }
 
   Int64 abs() {
-    return this < 0 ? -this : this;
+    return this.isNegative ? -this : this;
   }
 
   /**
@@ -689,10 +624,8 @@
 
   // TODO(rice) - Make this faster by avoiding arithmetic.
   String toHexString() {
-    Int64 x = new Int64._copy(this);
-    if (isZero) {
-      return "0";
-    }
+    if (isZero) return "0";
+    Int64 x = this;
     String hexStr = "";
     Int64 digit_f = new Int64.fromInt(0xf);
     while (!x.isZero) {
@@ -854,19 +787,20 @@
     return "Int64[_l=$_l, _m=$_m, _h=$_h]";
   }
 
-  /**
-   * Constructs an [Int64] with a given bitwise representation.  No validation
-   * is performed.
-   */
-  Int64._bits(int this._l, int this._m, int this._h);
 
-  /**
-   * Constructs an [Int64] with the same value as an existing [Int64].
-   */
-  Int64._copy(Int64 other)
-      : _l = other._l,
-        _m = other._m,
-        _h = other._h;
+  static Int64 _masked(int a0, int a1, int a2) =>
+      new Int64._bits(_MASK & a0, _MASK & a1, _MASK2 & a2);
+
+  static Int64 _sub(int a0, int a1, int a2, int b0, int b1, int b2) {
+    int diff0 = a0 - b0;
+    int diff1 = a1 - b1 - ((diff0 >> _BITS) & 1);
+    int diff2 = a2 - b2 - ((diff1 >> _BITS) & 1);
+    return _masked(diff0, diff1, diff2);
+  }
+
+  static Int64 _negate(int b0, int b1, int b2) {
+    return _sub(0, 0, 0, b0, b1, b2);
+  }
 
   // Determine whether the platform supports ints greater than 2^53
   // without loss of precision.
@@ -888,40 +822,6 @@
 
   String _hexDigit(int digit) => "0123456789ABCDEF"[digit];
 
-  // Implementation of '~/' and '%'.
-
-  // Note: mutates [this].
-  void _negate() {
-    int neg0 = (~_l + 1) & _MASK;
-    int neg1 = (~_m + (neg0 == 0 ? 1 : 0)) & _MASK;
-    int neg2 = (~_h + ((neg0 == 0 && neg1 == 0) ? 1 : 0)) & _MASK2;
-
-    _l = neg0;
-    _m = neg1;
-    _h = neg2;
-  }
-
-  // Note: mutates [this].
-  void _setBit(int bit) {
-    if (bit < _BITS) {
-      _l |= 0x1 << bit;
-    } else if (bit < _BITS01) {
-      _m |= 0x1 << (bit - _BITS);
-    } else {
-      _h |= 0x1 << (bit - _BITS01);
-    }
-  }
-
-  // Note: mutates [this].
-  void _toShru1() {
-    int a2 = _h;
-    int a1 = _m;
-    int a0 = _l;
-
-    _h = a2 >> 1;
-    _m = (a1 >> 1) | ((a2 & 0x1) << (_BITS - 1));
-    _l = (a0 >> 1) | ((a1 & 0x1) << (_BITS - 1));
-  }
 
   // Work around dart2js bugs with negative arguments to '>>' operator.
   static int _shiftRight(int x, int n) {
@@ -936,267 +836,157 @@
     }
   }
 
-  /**
-   * Attempt to subtract b from a if a >= b:
-   *
-   * if (a >= b) {
-   *   a -= b;
-   *   return true;
-   * } else {
-   *   return false;
-   * }
-   */
-  // Note: mutates [a].
-  static bool _trialSubtract(Int64 a, Int64 b) {
-    // Early exit.
-    int sum2 = a._h - b._h;
-    if (sum2 < 0) {
-      return false;
-    }
 
-    int sum0 = a._l - b._l;
-    int sum1 = a._m - b._m + _shiftRight(sum0, _BITS);
-    sum2 += _shiftRight(sum1, _BITS);
+  // Implementation of '~/', '%' and 'remainder'.
 
-    if (sum2 < 0) {
-      return false;
-    }
-
-    a._l = sum0 & _MASK;
-    a._m = sum1 & _MASK;
-    a._h = sum2 & _MASK2;
-
-    return true;
-  }
-
-  // Note: mutates [a] via _trialSubtract.
-  static Int64 _divModHelper(Int64 a, Int64 b,
-      bool negative, bool aIsNegative, bool aIsMinValue,
-      bool computeRemainder) {
-    // Align the leading one bits of a and b by shifting b left.
-    int shift = b.numberOfLeadingZeros() - a.numberOfLeadingZeros();
-    Int64 bshift = b << shift;
-
-    // Quotient must be a new instance since we mutate it.
-    Int64 quotient = new Int64();
-    while (shift >= 0) {
-      bool gte = _trialSubtract(a, bshift);
-      if (gte) {
-        quotient._setBit(shift);
-        if (a.isZero) {
-          break;
-        }
-      }
-
-      bshift._toShru1();
-      shift--;
-    }
-
-    if (negative) {
-      quotient._negate();
-    }
-
-    if (computeRemainder) {
-      if (aIsNegative) {
-        _remainder = -a;
-        if (aIsMinValue) {
-          _remainder = _remainder - ONE;
-        }
-      } else {
-        _remainder = a;
-      }
-    }
-
-    return quotient;
-  }
-
-  Int64 _divModByMinValue(bool computeRemainder) {
-    // MIN_VALUE / MIN_VALUE == 1, remainder = 0
-    // (x != MIN_VALUE) / MIN_VALUE == 0, remainder == x
-    if (isMinValue) {
-      if (computeRemainder) {
-        _remainder = ZERO;
-      }
-      return ONE;
-    }
-    if (computeRemainder) {
-      _remainder = this;
-    }
-    return ZERO;
-  }
-
-  /**
-   * this &= ((1L << bits) - 1)
-   */
-  // Note: mutates [this].
-  Int64 _maskRight(int bits) {
-    int b0, b1, b2;
-    if (bits <= _BITS) {
-      b0 = _l & ((1 << bits) - 1);
-      b1 = b2 = 0;
-    } else if (bits <= _BITS01) {
-      b0 = _l;
-      b1 = _m & ((1 << (bits - _BITS)) - 1);
-      b2 = 0;
-    } else {
-      b0 = _l;
-      b1 = _m;
-      b2 = _h & ((1 << (bits - _BITS01)) - 1);
-    }
-
-    _l = b0;
-    _m = b1;
-    _h = b2;
-  }
-
-  static Int64 _divModByShift(Int64 a, int bpower, bool negative, bool aIsCopy,
-      bool aIsNegative, bool computeRemainder) {
-    Int64 c = a >> bpower;
-    if (negative) {
-      c._negate();
-    }
-
-    if (computeRemainder) {
-      if (!aIsCopy) {
-        a = new Int64._copy(a);
-      }
-      a._maskRight(bpower);
-      if (aIsNegative) {
-        a._negate();
-      }
-      _remainder = a;
-    }
-    return c;
-  }
-
-  /**
-   * Return the exact log base 2 of this, or -1 if this is not a power of two.
-   */
-  int _powerOfTwo() {
-    // Power of two or 0.
-    int l = _l;
-    if ((l & (l - 1)) != 0) {
-      return -1;
-    }
-    int m = _m;
-    if ((m & (m - 1)) != 0) {
-      return -1;
-    }
-    int h = _h;
-    if ((h & (h - 1)) != 0) {
-      return -1;
-    }
-    if (h == 0 && m == 0 && l == 0) {
-      return -1;
-    }
-    if (h == 0 && m == 0 && l != 0) {
-      return Int32._numberOfTrailingZeros(l);
-    }
-    if (h == 0 && m != 0 && l == 0) {
-      return Int32._numberOfTrailingZeros(m) + _BITS;
-    }
-    if (h != 0 && m == 0 && l == 0) {
-      return Int32._numberOfTrailingZeros(h) + _BITS01;
-    }
-
-    return -1;
-  }
-
-  static Int64 _divMod(Int64 a, Int64 b, bool computeRemainder) {
+  static Int64 _divide(Int64 a, other, int what) {
+    Int64 b = _promote(other);
     if (b.isZero) {
       throw new IntegerDivisionByZeroException();
     }
-    if (a.isZero) {
-      if (computeRemainder) {
-        _remainder = ZERO;
+    if (a.isZero) return ZERO;
+
+    bool aNeg = a.isNegative;
+    bool bNeg = b.isNegative;
+    a = a.abs();
+    b = b.abs();
+
+    int a0 = a._l;
+    int a1 = a._m;
+    int a2 = a._h;
+
+    int b0 = b._l;
+    int b1 = b._m;
+    int b2 = b._h;
+    return _divideHelper(a0, a1, a2, aNeg, b0, b1, b2, bNeg, what);
+  }
+
+  static const _RETURN_DIV = 1;
+  static const _RETURN_REM = 2;
+  static const _RETURN_MOD = 3;
+
+  static _divideHelper(
+      // up to 64 bits unsigned in a2/a1/a0 and b2/b1/b0
+      int a0, int a1, int a2, bool aNeg,  // input A.
+      int b0, int b1, int b2, bool bNeg,  // input B.
+      int what) {
+    int q0 = 0, q1 = 0, q2 = 0;  // result Q.
+    int r0 = 0, r1 = 0, r2 = 0;  // result R.
+
+    if (b2 == 0 && b1 == 0 && b0 < (1 << (30 - _BITS))) {
+      // Small divisor can be handled by single-digit division within Smi range.
+      //
+      // Handling small divisors here helps the estimate version below by
+      // handling cases where the estimate is off by more than a small amount.
+
+      q2 = a2 ~/ b0;
+      int carry = a2 - q2 * b0;
+      int d1 = a1 + (carry << _BITS);
+      q1 = d1 ~/ b0;
+      carry = d1 - q1 * b0;
+      int d0 = a0 + (carry << _BITS);
+      q0 = d0 ~/ b0;
+      r0 = d0 - q0 * b0;
+    } else {
+      // Approximate Q = A ~/ B and R = A - Q * B using doubles.
+
+      // The floating point approximation is very close to the correct value
+      // when floor(A/B) fits in fewer that 53 bits.
+
+      // We use double arithmetic for intermediate values.  Double arithmetic on
+      // non-negative values is exact under the following conditions:
+      //
+      //   - The values are integer values that fit in 53 bits.
+      //   - Dividing by powers of two (adjusts exponent only).
+      //   - Floor (zeroes bits with fractional weight).
+
+      const double K2 = 17592186044416.0; // 2^44
+      const double K1 = 4194304.0; // 2^22
+
+      // Approximate double values for [a] and [b].
+      double ad = a0 + K1 * a1 + K2 * a2;
+      double bd = b0 + K1 * b1 + K2 * b2;
+      // Approximate quotient.
+      double qd = (ad / bd).floorToDouble();
+
+      // Extract components of [qd] using double arithmetic.
+      double q2d = (qd / K2).floorToDouble();
+      qd = qd - K2 * q2d;
+      double q1d = (qd / K1).floorToDouble();
+      double q0d = qd - K1 * q1d;
+      q2 = q2d.toInt();
+      q1 = q1d.toInt();
+      q0 = q0d.toInt();
+
+      assert(q0 + K1 * q1 + K2 * q2 == (ad / bd).floorToDouble());
+      assert(q2 == 0 || b2 == 0);  // Q and B can't both be big since Q*B <= A.
+
+      // P = Q * B, using doubles to hold intermediates.
+      // We don't need all partial sums since Q*B <= A.
+      double p0d = q0d * b0;
+      double p0carry = (p0d / K1).floorToDouble();
+      p0d = p0d - p0carry * K1;
+      double p1d = q1d * b0 + q0d * b1 + p0carry;
+      double p1carry = (p1d / K1).floorToDouble();
+      p1d = p1d - p1carry * K1;
+      double p2d = q2d * b0 + q1d * b1 + q0d * b2 + p1carry;
+      assert(p2d <= _MASK2);  // No partial sum overflow.
+
+      // R = A - P
+      int diff0 = a0 - p0d.toInt();
+      int diff1 = a1 - p1d.toInt() - ((diff0 >> _BITS) & 1);
+      int diff2 = a2 - p2d.toInt() - ((diff1 >> _BITS) & 1);
+      r0 = _MASK & diff0;
+      r1 = _MASK & diff1;
+      r2 = _MASK2 & diff2;
+
+      // while (R < 0 || R >= B)
+      //  adjust R towards [0, B)
+      while (
+          r2 >= _SIGN_BIT_MASK ||
+          r2 > b2 ||
+          (r2 == b2 && (r1 > b1 || (r1 == b1 && r0 >= b0)))) {
+        // Direction multiplier for adjustment.
+        int m = (r2 & _SIGN_BIT_MASK) == 0 ? 1 : -1;
+        // R = R - B  or  R = R + B
+        int d0 = r0 - m * b0;
+        int d1 = r1 - m * (b1 + ((d0 >> _BITS) & 1));
+        int d2 = r2 - m * (b2 + ((d1 >> _BITS) & 1));
+        r0 = _MASK & d0;
+        r1 = _MASK & d1;
+        r2 = _MASK2 & d2;
+
+        // Q = Q + 1  or  Q = Q - 1
+        d0 = q0 + m;
+        d1 = q1 + m * ((d0 >> _BITS) & 1);
+        d2 = q2 + m * ((d1 >> _BITS) & 1);
+        q0 = _MASK & d0;
+        q1 = _MASK & d1;
+        q2 = _MASK2 & d2;
       }
-      return ZERO;
     }
-    // MIN_VALUE / MIN_VALUE = 1, anything other a / MIN_VALUE is 0.
-    if (b.isMinValue) {
-      return a._divModByMinValue(computeRemainder);
-    }
-    // Normalize b to abs(b), keeping track of the parity in 'negative'.
-    // We can do this because we have already ensured that b != MIN_VALUE.
-    bool negative = false;
-    if (b.isNegative) {
-      b = -b;
-      negative = !negative;
-    }
-    // If b == 2^n, bpower will be n, otherwise it will be -1.
-    int bpower = b._powerOfTwo();
 
-    // True if the original value of a is negative.
-    bool aIsNegative = false;
-    // True if the original value of a is Int64.MIN_VALUE.
-    bool aIsMinValue = false;
+    // 0 <= R < B
+    assert(Int64.ZERO <= new Int64._bits(r0, r1, r2));
+    assert(r2 < b2 ||  // Handles case where B = -(MIN_VALUE)
+        new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2));
 
-    /*
-     * Normalize a to a positive value, keeping track of the sign change in
-     * 'negative' (which tracks the sign of both a and b and is used to
-     * determine the sign of the quotient) and 'aIsNegative' (which is used to
-     * determine the sign of the remainder).
-     *
-     * For all values of a except MIN_VALUE, we can just negate a and modify
-     * negative and aIsNegative appropriately. When a == MIN_VALUE, negation is
-     * not possible without overflowing 64 bits, so instead of computing
-     * abs(MIN_VALUE) / abs(b) we compute (abs(MIN_VALUE) - 1) / abs(b). The
-     * only circumstance under which these quotients differ is when b is a power
-     * of two, which will divide abs(MIN_VALUE) == 2^64 exactly. In this case,
-     * we can get the proper result by shifting MIN_VALUE in unsigned fashion.
-     *
-     * We make a single copy of a before the first operation that needs to
-     * modify its value.
-     */
-    bool aIsCopy = false;
-    if (a.isMinValue) {
-      aIsMinValue = true;
-      aIsNegative = true;
-      // If b is not a power of two, treat -a as MAX_VALUE (instead of the
-      // actual value (MAX_VALUE + 1)).
-      if (bpower == -1) {
-        a = new Int64._copy(MAX_VALUE);
-        aIsCopy = true;
-        negative = !negative;
+    assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM);
+    if (what == _RETURN_DIV) {
+      if (aNeg != bNeg) return _negate(q0, q1, q2);
+      return new Int64._bits(q0, q1, q2);
+    }
+
+    if (!aNeg) return new Int64._bits(r0, r1, r2);
+
+    if (what == _RETURN_MOD) {
+      if (r0 == 0 && r1 == 0 && r2 == 0) {
+        return ZERO;
       } else {
-        // Signed shift of MIN_VALUE produces the right answer.
-        Int64 c = a >> bpower;
-        if (negative) {
-          c._negate();
-        }
-        if (computeRemainder) {
-          _remainder = ZERO;
-        }
-        return c;
+        return _sub(b0, b1, b2, r0, r1, r2);
       }
-    } else if (a.isNegative) {
-      aIsNegative = true;
-      a = -a;
-      aIsCopy = true;
-      negative = !negative;
+    } else {
+      return _negate(r0, r1, r2);
     }
-
-    // Now both a and b are non-negative.
-    // If b is a power of two, just shift.
-    if (bpower != -1) {
-      return _divModByShift(a, bpower, negative, aIsCopy, aIsNegative,
-        computeRemainder);
-    }
-
-    // If a < b, the quotient is 0 and the remainder is a.
-    if (a < b) {
-      if (computeRemainder) {
-        if (aIsNegative) {
-          _remainder = -a;
-        } else {
-          _remainder = aIsCopy ? a : new Int64._copy(a);
-        }
-      }
-      return ZERO;
-    }
-
-    // Generate the quotient using bit-at-a-time long division.
-    return _divModHelper(aIsCopy ? a : new Int64._copy(a), b, negative,
-        aIsNegative, aIsMinValue, computeRemainder);
   }
 }
diff --git a/pkg/fixnum/test/int_64_test.dart b/pkg/fixnum/test/int_64_test.dart
index d781984..84323ee 100644
--- a/pkg/fixnum/test/int_64_test.dart
+++ b/pkg/fixnum/test/int_64_test.dart
@@ -45,8 +45,8 @@
           new Int64.fromInt(-3333));
       expect(new Int64.fromInt(-1111) * new Int64.fromInt(-3),
           new Int64.fromInt(3333));
-      expect(new Int64.fromInt(100) * new Int64.fromInt(0),
-          new Int64.fromInt(0));
+      expect(new Int64.fromInt(100) * Int64.ZERO,
+          Int64.ZERO);
 
       expect(new Int64.fromInts(0x12345678, 0x12345678) *
           new Int64.fromInts(0x1234, 0x12345678),
@@ -68,7 +68,7 @@
       expect((new Int64.fromInt(123456789) * new Int64.fromInt(987654321)),
           new Int64.fromInts(0x1b13114, 0xfbff5385));
 
-      expect(Int64.MIN_VALUE * new Int64.fromInt(2), new Int64.fromInt(0));
+      expect(Int64.MIN_VALUE * new Int64.fromInt(2), Int64.ZERO);
       expect(Int64.MIN_VALUE * new Int64.fromInt(1), Int64.MIN_VALUE);
       expect(Int64.MIN_VALUE * new Int64.fromInt(-1), Int64.MIN_VALUE);
     });
@@ -133,7 +133,7 @@
       expect(new Int64.fromInt(-1000) ~/ new Int64.fromInt(-3),
           new Int64.fromInt(333));
       expect(new Int64.fromInt(3) ~/ new Int64.fromInt(1000),
-          new Int64.fromInt(0));
+          Int64.ZERO);
       expect(new Int64.fromInts( 0x12345678, 0x12345678) ~/
           new Int64.fromInts(0x0, 0x123),
           new Int64.fromInts(0x1003d0, 0xe84f5ae8));
@@ -152,7 +152,7 @@
           new Int32.fromInt(432461));
       expect(new Int64.fromInt(829893893) ~/ 1919,
           new Int32.fromInt(432461));
-      expect(() => new Int64.fromInt(1) ~/ new Int64.fromInt(0),
+      expect(() => new Int64.fromInt(1) ~/ Int64.ZERO,
           throwsA(new isInstanceOf<IntegerDivisionByZeroException>()));
       expect(Int64.MIN_VALUE ~/ new Int64.fromInt(2),
           new Int64.fromInts(0xc0000000, 0x00000000));
@@ -164,11 +164,11 @@
 
     test("%", () {
       // Define % as Euclidean mod, with positive result for all arguments
-      expect(Int64.ZERO % new Int64.fromInt(1000), new Int64.fromInt(0));
-      expect(Int64.MIN_VALUE % Int64.MIN_VALUE, new Int64.fromInt(0));
+      expect(Int64.ZERO % new Int64.fromInt(1000), Int64.ZERO);
+      expect(Int64.MIN_VALUE % Int64.MIN_VALUE, Int64.ZERO);
       expect(new Int64.fromInt(1000) % Int64.MIN_VALUE,
           new Int64.fromInt(1000));
-      expect(Int64.MIN_VALUE % new Int64.fromInt(8192), new Int64.fromInt(0));
+      expect(Int64.MIN_VALUE % new Int64.fromInt(8192), Int64.ZERO);
       expect(Int64.MIN_VALUE % new Int64.fromInt(8193),
           new Int64.fromInt(6145));
       expect(new Int64.fromInt(-1000) % new Int64.fromInt(8192),
@@ -223,7 +223,7 @@
       expect(new Int64.fromInt(10) < new Int32.fromInt(10), false);
       expect(new Int64.fromInt(10) < new Int32.fromInt(9), false);
       expect(new Int64.fromInt(-10) < new Int64.fromInt(-11), false);
-      expect(Int64.MIN_VALUE < new Int64.fromInt(0), true);
+      expect(Int64.MIN_VALUE < Int64.ZERO, true);
       expect(largeNeg < largePos, true);
       expect(largePos < largePosPlusOne, true);
       expect(largePos < largePos, false);
@@ -303,7 +303,7 @@
       expect(largePos > largePosPlusOne, false);
       expect(largePos > largePos, false);
       expect(largePosPlusOne > largePos, true);
-      expect(new Int64.fromInt(0) > Int64.MIN_VALUE, true);
+      expect(Int64.ZERO > Int64.MIN_VALUE, true);
       expect(Int64.MIN_VALUE > Int64.MAX_VALUE, false);
       expect(Int64.MAX_VALUE > Int64.MIN_VALUE, true);
       expect(() => new Int64.fromInt(17) > null, throwsArgumentError);
diff --git a/pkg/pkg.status b/pkg/pkg.status
index f5a12e1..57a28b4 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -65,9 +65,6 @@
 polymer/test/events_test: Fail # Issue 12865, 13197
 polymer/test/event_path_test: Fail # Issue 12865, 13197
 
-[ $runtime == safari || $runtime == ie9 ]
-polymer_expressions/test/syntax_test: Fail # Issue 13361
-
 [ $runtime == ff ]
 polymer/test/event_path_test: Fail # Issue 12865, 13197
 
@@ -126,6 +123,10 @@
 crypto/test/sha1_test: Slow, Pass
 polymer/example/component: Fail # Issue 13198
 
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+docgen/test/single_library_test: Fail # TODO(kasperl): Please triage.
+intl/test/date_time_format_http_request_test: Fail # TODO(kasperl): Please triage.
+
 [ $browser ]
 analyzer_experimental/test/error_test: Fail, OK # Uses dart:io.
 analyzer_experimental/test/generated/element_test: Fail, OK # Uses dart:io.
@@ -230,6 +231,3 @@
 # Issue http://dartbug.com/12930
 [ $runtime == vm ]
 intl/test/message_extraction/message_extraction_test: Pass, Fail # Issue 12930
-
-[ $compiler == none && $runtime == drt && $arch == ia32 ]
-custom_element/test/custom_element_test: Fail, Pass # http://dartbug.com/12964
diff --git a/pkg/polymer_expressions/example/example.dart b/pkg/polymer_expressions/example/example.dart
index f3ad658..5266311 100644
--- a/pkg/polymer_expressions/example/example.dart
+++ b/pkg/polymer_expressions/example/example.dart
@@ -4,13 +4,18 @@
 
 import 'dart:html';
 
-import 'package:polymer_expressions/polymer_expressions.dart';
+import 'package:logging/logging.dart';
 import 'package:mdv/mdv.dart' as mdv;
+import 'package:polymer_expressions/polymer_expressions.dart';
 
 import 'person.dart';
 
 main() {
   mdv.initialize();
+  new Logger('polymer_expressions').onRecord.listen((LogRecord r) {
+    print("${r.loggerName} ${r.level} ${r.message}");
+  });
+
   var john = new Person('John', 'Messerly', ['A', 'B', 'C']);
   var justin = new Person('Justin', 'Fagnani', ['D', 'E', 'F']);
   var globals = {
diff --git a/pkg/polymer_expressions/lib/eval.dart b/pkg/polymer_expressions/lib/eval.dart
index b76b3b8..c191bd9 100644
--- a/pkg/polymer_expressions/lib/eval.dart
+++ b/pkg/polymer_expressions/lib/eval.dart
@@ -47,16 +47,33 @@
 /**
  * Evaluation [expr] in the context of [scope].
  */
-Object eval(Expression expr, Scope scope) => observe(expr, scope)._value;
+Object eval(Expression expr, Scope scope) {
+  var observer = observe(expr, scope);
+  new Updater(scope).visit(observer);
+  return observer._value;
+}
 
-
+/**
+ * Returns an [ExpressionObserver] that evaluates [expr] in the context of
+ * scope] and listens for any changes on [Observable] values that are
+ * returned from sub-expressions. When a value changes the expression is
+ * reevaluated and the new result is sent to the [onUpdate] stream of the
+ * [ExpressionObsserver].
+ */
 ExpressionObserver observe(Expression expr, Scope scope) {
   var observer = new ObserverBuilder(scope).visit(expr);
-  new Updater(scope).visit(observer);
   return observer;
 }
 
 /**
+ * Causes [expr] to be reevaluated a returns it's value.
+ */
+Object update(ExpressionObserver expr, Scope scope) {
+  new Updater(scope).visit(expr);
+  return expr.currentValue;
+}
+
+/**
  * Assign [value] to the variable or field referenced by [expr] in the context
  * of [scope].
  *
@@ -166,7 +183,7 @@
     if (parent != null) {
       return _convert(parent[name]);
     } else {
-      throw new EvalException("variable not found: $name in $hashCode");
+      throw new EvalException("variable '$name' not found");
     }
   }
 
@@ -205,8 +222,6 @@
     }
     return false;
   }
-
-  String toString() => 'Scope($hashCode $parent)';
 }
 
 Object _convert(v) {
diff --git a/pkg/polymer_expressions/lib/polymer_expressions.dart b/pkg/polymer_expressions/lib/polymer_expressions.dart
index d74daca..e7148ad 100644
--- a/pkg/polymer_expressions/lib/polymer_expressions.dart
+++ b/pkg/polymer_expressions/lib/polymer_expressions.dart
@@ -16,7 +16,7 @@
  * [Polymer.dart](http://www.dartlang.org/polymer-dart/)
  * homepage for example code, project status, and
  * information about how to get started using Polymer.dart in your apps.
- * 
+ *
  * ## Other resources
  *
  * The
@@ -31,11 +31,14 @@
 import 'dart:html';
 
 import 'package:observe/observe.dart';
+import 'package:logging/logging.dart';
 
 import 'eval.dart';
 import 'expression.dart';
 import 'parser.dart';
 
+final Logger _logger = new Logger('polymer_expressions');
+
 // TODO(justin): Investigate XSS protection
 Object _classAttributeConverter(v) =>
     (v is Map) ? v.keys.where((k) => v[k] == true).join(' ') :
@@ -86,12 +89,18 @@
   final _converter;
   var _value;
 
-
   _Binding(Expression expr, Scope scope, [this._converter])
       : _expr = observe(expr, scope),
         _scope = scope {
-    _expr.onUpdate.listen(_setValue);
-    _setValue(_expr.currentValue);
+    _expr.onUpdate.listen(_setValue).onError((e) {
+      _logger.warning("Error evaluating expression '$_expr': ${e.message}");
+    });
+    try {
+      update(_expr, _scope);
+      _setValue(_expr.currentValue);
+    } on EvalException catch (e) {
+      _logger.warning("Error evaluating expression '$_expr': ${e.message}");
+    }
   }
 
   _setValue(v) {
diff --git a/pkg/polymer_expressions/test/eval_test.dart b/pkg/polymer_expressions/test/eval_test.dart
index 96fcd2d..0ed7456 100644
--- a/pkg/polymer_expressions/test/eval_test.dart
+++ b/pkg/polymer_expressions/test/eval_test.dart
@@ -371,8 +371,9 @@
     mutate(),
     dynamic afterMatcher}) {
 
-  var observer = observe(new Parser(s).parse(),
-      new Scope(model: model, variables: variables));
+  var scope = new Scope(model: model, variables: variables);
+  var observer = observe(new Parser(s).parse(), scope);
+  update(observer, scope);
   expect(observer.currentValue, beforeMatcher);
   var passed = false;
   var future = observer.onUpdate.first.then((value) {
diff --git a/pkg/polymer_expressions/test/syntax_test.dart b/pkg/polymer_expressions/test/syntax_test.dart
index 82c3e60..dfc6689 100644
--- a/pkg/polymer_expressions/test/syntax_test.dart
+++ b/pkg/polymer_expressions/test/syntax_test.dart
@@ -5,11 +5,12 @@
 import 'dart:async';
 import 'dart:html';
 
-import 'package:polymer_expressions/polymer_expressions.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_enhanced_config.dart';
-import 'package:observe/observe.dart';
 import 'package:mdv/mdv.dart' as mdv;
+import 'package:logging/logging.dart';
+import 'package:observe/observe.dart';
+import 'package:polymer_expressions/polymer_expressions.dart';
+import 'package:unittest/html_enhanced_config.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   mdv.initialize();
@@ -23,7 +24,7 @@
     });
 
     tearDown(() {
-      testDiv.remove();
+      testDiv.firstChild.remove();
       testDiv = null;
     });
 
@@ -54,14 +55,30 @@
             <template repeat="{{ item in items }}">
               {{ item }}
             </template>
-          </template>'''));      
-      query('#test')
-          ..bindingDelegate = new PolymerExpressions(globals: {'items': null})
-          ..model = null;
+          </template>'''));
+      query('#test').bindingDelegate =
+          new PolymerExpressions(globals: {'items': null});
       // the template should be the only node
       expect(testDiv.nodes.length, 1);
       expect(testDiv.nodes[0].id, 'test');
     });
+
+    test('should silently handle bad variable names', () {
+      var logger = new Logger('polymer_expressions');
+      var logFuture = logger.onRecord.toList();
+      testDiv.nodes.add(new Element.html('''
+          <template id="test" bind>{{ foo }}</template>'''));
+      query('#test').bindingDelegate = new PolymerExpressions();
+      return new Future(() {
+        logger.clearListeners();
+        return logFuture.then((records) {
+          expect(records.length, 1);
+          expect(records.first.message,
+              contains('Error evaluating expression'));
+          expect(records.first.message, contains('foo'));
+        });
+      });
+    });
   });
 }
 
diff --git a/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart b/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart
index c71b7e8..7e6d3fc 100644
--- a/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart
+++ b/pkg/unmodifiable_collection/test/unmodifiable_collection_test.dart
@@ -225,52 +225,52 @@
   });
 
   test("$name - skip", () {
-    expect(wrapped.skip(0), equals(original.skip(0)));
-    expect(wrapped.skip(1), equals(original.skip(1)));
-    expect(wrapped.skip(5), equals(original.skip(5)));
+    expect(wrapped.skip(0), orderedEquals(original.skip(0)));
+    expect(wrapped.skip(1), orderedEquals(original.skip(1)));
+    expect(wrapped.skip(5), orderedEquals(original.skip(5)));
   });
 
   test("$name - skipWhile", () {
     expect(wrapped.skipWhile((x) => true),
-           equals(original.skipWhile((x) => true)));
+           orderedEquals(original.skipWhile((x) => true)));
     expect(wrapped.skipWhile((x) => false),
-           equals(original.skipWhile((x) => false)));
+           orderedEquals(original.skipWhile((x) => false)));
     expect(wrapped.skipWhile((x) => x != 42),
-           equals(original.skipWhile((x) => x != 42)));
+           orderedEquals(original.skipWhile((x) => x != 42)));
   });
 
   test("$name - take", () {
-    expect(wrapped.take(0), equals(original.take(0)));
-    expect(wrapped.take(1), equals(original.take(1)));
-    expect(wrapped.take(5), equals(original.take(5)));
+    expect(wrapped.take(0), orderedEquals(original.take(0)));
+    expect(wrapped.take(1), orderedEquals(original.take(1)));
+    expect(wrapped.take(5), orderedEquals(original.take(5)));
   });
 
   test("$name - takeWhile", () {
     expect(wrapped.takeWhile((x) => true),
-           equals(original.takeWhile((x) => true)));
+           orderedEquals(original.takeWhile((x) => true)));
     expect(wrapped.takeWhile((x) => false),
-           equals(original.takeWhile((x) => false)));
+           orderedEquals(original.takeWhile((x) => false)));
     expect(wrapped.takeWhile((x) => x != 42),
-           equals(original.takeWhile((x) => x != 42)));
+           orderedEquals(original.takeWhile((x) => x != 42)));
   });
 
   test("$name - toList", () {
-    expect(wrapped.toList(), equals(original.toList()));
+    expect(wrapped.toList(), orderedEquals(original.toList()));
     expect(wrapped.toList(growable: false),
-           equals(original.toList(growable: false)));
+           orderedEquals(original.toList(growable: false)));
   });
 
   test("$name - toSet", () {
-    expect(wrapped.toSet(), equals(original.toSet()));
+    expect(wrapped.toSet(), unorderedEquals(original.toSet()));
   });
 
   test("$name - where", () {
     expect(wrapped.where((x) => true),
-           equals(original.where((x) => true)));
+           orderedEquals(original.where((x) => true)));
     expect(wrapped.where((x) => false),
-           equals(original.where((x) => false)));
+           orderedEquals(original.where((x) => false)));
     expect(wrapped.where((x) => x != 42),
-           equals(original.where((x) => x != 42)));
+           orderedEquals(original.where((x) => x != 42)));
   });
 }
 
@@ -372,7 +372,7 @@
     List sortCopy = new List.from(original);
     sortCopy.sort();
     wrapped.sort();
-    expect(original, equals(sortCopy));
+    expect(original, orderedEquals(sortCopy));
     original.setAll(0, copy);
   });
 
@@ -475,20 +475,20 @@
 
   test("$name - intersection", () {
     expect(wrapped.intersection(new Set()), isEmpty);
-    expect(wrapped.intersection(copy), equals(original));
+    expect(wrapped.intersection(copy), unorderedEquals(original));
     expect(wrapped.intersection(new Set.from([42])),
             new Set.from(original.contains(42) ? [42] : []));
   });
 
   test("$name - union", () {
-    expect(wrapped.union(new Set()), equals(original));
-    expect(wrapped.union(copy), equals(original));
+    expect(wrapped.union(new Set()), unorderedEquals(original));
+    expect(wrapped.union(copy), unorderedEquals(original));
     expect(wrapped.union(new Set.from([42])),
            equals(original.union(new Set.from([42]))));
   });
 
   test("$name - difference", () {
-    expect(wrapped.difference(new Set()), equals(original));
+    expect(wrapped.difference(new Set()), unorderedEquals(original));
     expect(wrapped.difference(copy), isEmpty);
     expect(wrapped.difference(new Set.from([42])),
            equals(original.difference(new Set.from([42]))));
@@ -496,13 +496,13 @@
 }
 
 void testNoChangeSet(Set original, Set wrapped, String name) {
-  Set copy = new Set.from(original);
+  List originalElements = original.toList();
 
   testThrows(name, thunk) {
     test(name, () {
       expect(thunk, throwsUnsupportedError);
       // No modifications happened.
-      expect(original, equals(copy));
+      expect(original.toList(), equals(originalElements));
     });
   }
 
@@ -584,11 +584,11 @@
   });
 
   test("$name keys", () {
-    expect(wrapped.keys, equals(original.keys));
+    expect(wrapped.keys, orderedEquals(original.keys));
   });
 
   test("$name values", () {
-    expect(wrapped.values, equals(original.values));
+    expect(wrapped.values, orderedEquals(original.values));
   });
 }
 
diff --git a/runtime/bin/builtin_impl_sources.gypi b/runtime/bin/builtin_impl_sources.gypi
index 9d9d8ac..d62c091 100644
--- a/runtime/bin/builtin_impl_sources.gypi
+++ b/runtime/bin/builtin_impl_sources.gypi
@@ -61,5 +61,6 @@
     'utils_linux.cc',
     'utils_macos.cc',
     'utils_win.cc',
+    'utils_win.h',
   ],
 }
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 89698c0..e6f705b 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -54,7 +54,7 @@
   V(File_DeleteLink, 1)                                                        \
   V(File_Rename, 2)                                                            \
   V(File_RenameLink, 2)                                                        \
-  V(File_FullPath, 1)                                                          \
+  V(File_ResolveSymbolicLinks, 1)                                              \
   V(File_OpenStdio, 1)                                                         \
   V(File_GetStdioHandleType, 1)                                                \
   V(File_GetType, 2)                                                           \
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 35ea5fc..0ae6aad 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -508,7 +508,7 @@
 }
 
 
-void FUNCTION_NAME(File_FullPath)(Dart_NativeArguments args) {
+void FUNCTION_NAME(File_ResolveSymbolicLinks)(Dart_NativeArguments args) {
   const char* str =
       DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
   char* path = File::GetCanonicalPath(str);
@@ -711,7 +711,7 @@
 }
 
 
-static CObject* FileFullPathRequest(const CObjectArray& request) {
+static CObject* FileResolveSymbolicLinksRequest(const CObjectArray& request) {
   if (request.Length() == 2 && request[1]->IsString()) {
     CObjectString filename(request[1]);
     char* result = File::GetCanonicalPath(filename.CString());
@@ -1191,8 +1191,8 @@
         case File::kRenameRequest:
           response = FileRenameRequest(request);
           break;
-        case File::kFullPathRequest:
-          response = FileFullPathRequest(request);
+        case File::kResolveSymbolicLinksRequest:
+          response = FileResolveSymbolicLinksRequest(request);
           break;
         case File::kCloseRequest:
           response = FileCloseRequest(request);
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 3908154..a6eccce 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -67,7 +67,7 @@
     kDeleteRequest = 2,
     kRenameRequest = 3,
     kOpenRequest = 4,
-    kFullPathRequest = 5,
+    kResolveSymbolicLinksRequest = 5,
     kCloseRequest = 6,
     kPositionRequest = 7,
     kSetPositionRequest = 8,
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index 7732c2c..ea121f2 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -22,7 +22,6 @@
   /* patch */ static _lastModified(String path) native "File_LastModified";
   /* patch */ static _open(String path, int mode) native "File_Open";
   /* patch */ static int _openStdio(int fd) native "File_OpenStdio";
-  /* patch */ static _fullPath(String path) native "File_FullPath";
 }
 
 patch class _RandomAccessFile {
diff --git a/runtime/bin/file_system_entity_patch.dart b/runtime/bin/file_system_entity_patch.dart
index 2c2b324..e6b3fdc 100644
--- a/runtime/bin/file_system_entity_patch.dart
+++ b/runtime/bin/file_system_entity_patch.dart
@@ -12,4 +12,6 @@
       native "File_GetType";
   /* patch */ static _identical(String path1, String path2)
       native "File_AreIdentical";
+  /* patch */ static _resolveSymbolicLinks(String path)
+      native "File_ResolveSymbolicLinks";
 }
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 08417ea..e7cedb4 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -471,20 +471,50 @@
 char* File::GetCanonicalPath(const char* pathname) {
   struct _stat st;
   const wchar_t* system_name = StringUtils::Utf8ToWide(pathname);
-  int stat_status = _wstat(system_name, &st);
-  if (stat_status != 0) {
-    SetLastError(ERROR_FILE_NOT_FOUND);
+  HANDLE file_handle = CreateFileW(
+        system_name,
+        0,
+        FILE_SHARE_READ,
+        NULL,
+        OPEN_EXISTING,
+        FILE_FLAG_BACKUP_SEMANTICS,
+        NULL);
+  if (file_handle == INVALID_HANDLE_VALUE) {
     free(const_cast<wchar_t*>(system_name));
     return NULL;
   }
-  int required_size = GetFullPathNameW(system_name, 0, NULL, NULL);
+  wchar_t dummy_buffer[1];
+  int required_size = GetFinalPathNameByHandle(file_handle,
+                                               dummy_buffer,
+                                               0,
+                                               VOLUME_NAME_DOS);
+  if (required_size == 0) {
+    free(const_cast<wchar_t*>(system_name));
+    DWORD error = GetLastError();
+    CloseHandle(file_handle);
+    SetLastError(error);
+    return NULL;
+  }
   wchar_t* path =
       static_cast<wchar_t*>(malloc(required_size * sizeof(wchar_t)));
-  int written = GetFullPathNameW(system_name, required_size, path, NULL);
+  int result_size = GetFinalPathNameByHandle(file_handle,
+                                             path,
+                                             required_size,
+                                             VOLUME_NAME_DOS);
+  ASSERT(result_size <= required_size - 1);
+  // Remove leading \\?\ if possible, unless input used it.
+  char* result;
+  if (result_size < MAX_PATH - 1 + 4 &&
+      result_size > 4 &&
+      wcsncmp(path, L"\\\\?\\", 4) == 0 &&
+      wcsncmp(system_name, L"\\\\?\\", 4) != 0) {
+    result = StringUtils::WideToUtf8(path + 4);
+  } else {
+    result = StringUtils::WideToUtf8(path);
+  }
   free(const_cast<wchar_t*>(system_name));
-  ASSERT(written <= (required_size - 1));
-  char* result = StringUtils::WideToUtf8(path);
   free(path);
+  CloseHandle(file_handle);
   return result;
 }
 
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index d3efd4c..c83afab 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -13,6 +13,7 @@
 #include "bin/log.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
+#include "bin/utils_win.h"
 
 
 namespace dart {
@@ -305,21 +306,7 @@
   int error_code = GetLastError();
   static const int kMaxMessageLength = 256;
   wchar_t message[kMaxMessageLength];
-  DWORD message_size =
-      FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
-                     NULL,
-                     error_code,
-                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                     message,
-                     kMaxMessageLength,
-                     NULL);
-  if (message_size == 0) {
-    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-      Log::PrintErr("FormatMessage failed %d\n", GetLastError());
-    }
-    _snwprintf(message, kMaxMessageLength, L"OS Error %d", error_code);
-  }
-  message[kMaxMessageLength - 1] = '\0';
+  FormatMessageIntoBuffer(error_code, message, kMaxMessageLength);
   *os_error_message = StringUtils::WideToUtf8(message);
   return error_code;
 }
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index b926dd7..dab7355 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -9,15 +9,14 @@
 #include <time.h>  // NOLINT
 
 #include "bin/utils.h"
+#include "bin/utils_win.h"
 #include "bin/log.h"
 
 
 namespace dart {
 namespace bin {
 
-static void FormatMessageIntoBuffer(DWORD code,
-                                    wchar_t* buffer,
-                                    int buffer_length) {
+void FormatMessageIntoBuffer(DWORD code, wchar_t* buffer, int buffer_length) {
   DWORD message_size =
       FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                      NULL,
@@ -28,11 +27,14 @@
                      NULL);
   if (message_size == 0) {
     if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-      Log::PrintErr("FormatMessage failed %d\n", GetLastError());
+      Log::PrintErr("FormatMessage failed for error code %d (error %d)\n",
+                    code,
+                    GetLastError());
     }
     _snwprintf(buffer, buffer_length, L"OS Error %d", code);
   }
-  buffer[buffer_length - 1] = '\0';
+  // Ensure string termination.
+  buffer[buffer_length - 1] = 0;
 }
 
 
diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h
new file mode 100644
index 0000000..a044760
--- /dev/null
+++ b/runtime/bin/utils_win.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef BIN_UTILS_WIN_H_
+#define BIN_UTILS_WIN_H_
+
+#include "platform/globals.h"
+
+namespace dart {
+namespace bin {
+
+void FormatMessageIntoBuffer(DWORD code, wchar_t* buffer, int buffer_length);
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // BIN_UTILS_WIN_H_
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index 3716cca..61cf8d6 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -430,7 +430,7 @@
 class _HashMapKeyIterable<K> extends _HashMapIterable<K> {
   _HashMapKeyIterable(HashMap map) : super(map);
   Iterator<K> get iterator => new _HashMapKeyIterator<K>(_map);
-  bool contains(K key) => _map.containsKey(key);
+  bool contains(Object key) => _map.containsKey(key);
   void forEach(void action(K key)) {
     _map.forEach((K key, _) {
       action(key);
@@ -441,7 +441,7 @@
 class _HashMapValueIterable<V> extends _HashMapIterable<V> {
   _HashMapValueIterable(HashMap map) : super(map);
   Iterator<V> get iterator => new _HashMapValueIterator<V>(_map);
-  bool contains(V value) => _map.containsValue(value);
+  bool contains(Object value) => _map.containsValue(value);
   void forEach(void action(V value)) {
     _map.forEach((_, V value) {
       action(value);
@@ -504,86 +504,291 @@
 }
 
 patch class HashSet<E> {
-  static const int _INITIAL_CAPACITY = 8;
-  final _HashTable<E> _table;
-
-  /* patch */ HashSet() : _table = new _HashTable(_INITIAL_CAPACITY) {
-    _table._container = this;
-  }
-
-  factory HashSet.from(Iterable<E> iterable) {
-    return new HashSet<E>()..addAll(iterable);
-  }
-
-  // Iterable.
-  /* patch */ Iterator<E> get iterator => new _HashTableKeyIterator<E>(_table);
-
-  /* patch */ int get length => _table._elementCount;
-
-  /* patch */ bool get isEmpty => _table._elementCount == 0;
-
-  /* patch */ bool get isNotEmpty => !isEmpty;
-
-  /* patch */ bool contains(Object object) => _table._get(object) >= 0;
-
-  // Collection.
-  /* patch */ void add(E element) {
-    _table._put(element);
-    _table._checkCapacity();
-  }
-
-  /* patch */ void addAll(Iterable<E> objects) {
-    for (E object in objects) {
-      _table._put(object);
-      _table._checkCapacity();
-    }
-  }
-
-  /* patch */ bool remove(Object object) {
-    int offset = _table._remove(object);
-    _table._checkCapacity();
-    return offset >= 0;
-  }
-
-  /* patch */ void removeAll(Iterable<Object> objectsToRemove) {
-    for (Object object in objectsToRemove) {
-      _table._remove(object);
-      _table._checkCapacity();
-    }
-  }
-
-  void _filterWhere(bool test(E element), bool removeMatching) {
-    int entrySize = _table._entrySize;
-    int length = _table._table.length;
-    for (int offset =  0; offset < length; offset += entrySize) {
-      Object entry = _table._table[offset];
-      if (!_table._isFree(entry)) {
-        E key = identical(entry, _NULL) ? null : entry;
-        int modificationCount = _table._modificationCount;
-        bool shouldRemove = (removeMatching == test(key));
-        _table._checkModification(modificationCount);
-        if (shouldRemove) {
-          _table._deleteEntry(offset);
+  /* patch */ factory HashSet({ bool equals(E e1, E e2),
+                                int hashCode(E e),
+                                bool isValidKey(potentialKey) }) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _HashSet<E>();
         }
+        if (identical(identical, equals)) {
+          return new _IdentityHashSet<E>();
+        }
+        _hashCode = _defaultHashCode;
+      } else if (equals == null) {
+        _equals = _defaultEquals;
       }
+      isValidKey = new _TypeTest<E>().test;
+    } else {
+      if (hashCode == null) hashCode = _defaultHashCode;
+      if (equals == null) equals = _defaultEquals;
     }
-    _table._checkCapacity();
-  }
-
-  /* patch */ void removeWhere(bool test(E element)) {
-    _filterWhere(test, true);
-  }
-
-  /* patch */ void retainWhere(bool test(E element)) {
-    _filterWhere(test, false);
-  }
-
-  /* patch */ void clear() {
-    _table._clear();
+    return new _CustomHashSet<E>(equals, hashCode, isValidKey);
   }
 }
 
+class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
+  static const int _INITIAL_CAPACITY = 8;
+
+  List<_HashSetEntry> _buckets = new List(_INITIAL_CAPACITY);
+  int _elementCount = 0;
+  int _modificationCount = 0;
+
+  bool _equals(e1, e2) => e1 == e2;
+  int _hashCode(e) => e.hashCode;
+
+  // Iterable.
+
+  Iterator<E> get iterator => new _HashSetIterator<E>(this);
+
+  int get length => _elementCount;
+
+  bool get isEmpty => _elementCount == 0;
+
+  bool get isNotEmpty => _elementCount != 0;
+
+  bool contains(Object object) {
+    int index = _hashCode(object) & (_buckets.length - 1);
+    HashSetEntry entry = _buckets[index];
+    while (entry != null) {
+      if (_equals(entry.key, object)) return true;
+      entry = entry.next;
+    }
+    return false;
+  }
+
+  // Set.
+
+  void add(E element) {
+    int hashCode = _hashCode(element);
+    int index = hashCode & (_buckets.length - 1);
+    HashSetEntry entry = _buckets[index];
+    while (entry != null) {
+      if (_equals(entry.key, element)) return;
+      entry = entry.next;
+    }
+    _addEntry(element, hashCode, index);
+  }
+
+  void addAll(Iterable<E> objects) {
+    int ctr = 0;
+    for (E object in objects) {
+      ctr++;
+      add(object);
+    }
+  }
+
+  bool _remove(Object object, int hashCode) {
+    int index = hashCode & (_buckets.length - 1);
+    _HashSetEntry entry = _buckets[index];
+    _HashSetEntry previous = null;
+    while (entry != null) {
+      if (_equals(entry.key, object)) {
+        _HashSetEntry next = entry.remove();
+        if (previous == null) {
+          _buckets[index] = next;
+        } else {
+          previous.next = next;
+        }
+        _elementCount--;
+        _modificationCount =
+            (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+        return true;
+      }
+      previous = entry;
+      entry = entry.next;
+    }
+    return false;
+  }
+
+  bool remove(Object object) => _remove(object, _hashCode(object));
+
+  void removeAll(Iterable<Object> objectsToRemove) {
+    for (Object object in objectsToRemove) {
+      _remove(object, _hashCode(object));
+    }
+  }
+
+  void retainAll(Iterable<Object> objectsToRetain) {
+    super._retainAll(objectsToRetain, (o) => o is E);
+  }
+
+  void _filterWhere(bool test(E element), bool removeMatching) {
+    int length = _buckets.length;
+    for (int index =  0; index < length; index++) {
+      HashSetEntry entry = _buckets[index];
+      HashSetEntry previous = null;
+      while (entry != null) {
+        int modificationCount = _modificationCount;
+        bool testResult = test(entry.key);
+        if (modificationCount != _modificationCount) {
+          throw new ConcurrentModificationError(this);
+        }
+        if (testResult == removeMatching) {
+          HashSetEntry next = entry.remove();
+          if (previous == null) {
+            _buckets[index] = next;
+          } else {
+            previous.next = next;
+          }
+          _elementCount--;
+          _modificationCount =
+              (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+          entry = next;
+        } else {
+          previous = entry;
+          entry = entry.next;
+        }
+      }
+    }
+  }
+
+  void removeWhere(bool test(E element)) {
+    _filterWhere(test, true);
+  }
+
+  void retainWhere(bool test(E element)) {
+    _filterWhere(test, false);
+  }
+
+  void clear() {
+    _elementCount = 0;
+    _buckets = new List(_INITIAL_CAPACITY);
+    _modificationCount++;
+  }
+
+  void _addEntry(E key, int hashCode, int index) {
+    _buckets[index] = new _HashSetEntry(key, hashCode, _buckets[index]);
+    int newElements = _elementCount + 1;
+    _elementCount = newElements;
+    int length = _buckets.length;
+    // If we end up with more than 75% non-empty entries, we
+    // resize the backing store.
+    if ((newElements << 2) > ((length << 1) + length)) _resize();
+    _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+  }
+
+  void _resize() {
+    int oldLength = _buckets.length;
+    int newLength = oldLength << 1;
+    List oldBuckets = _buckets;
+    List newBuckets = new List(newLength);
+    for (int i = 0; i < oldLength; i++) {
+      _HashSetEntry entry = oldBuckets[i];
+      while (entry != null) {
+        _HashSetEntry next = entry.next;
+        int newIndex = entry.hashCode & (newLength - 1);
+        entry.next = newBuckets[newIndex];
+        newBuckets[newIndex] = entry;
+        entry = next;
+      }
+    }
+    _buckets = newBuckets;
+  }
+
+  HashSet<E> _newSet() => new _HashSet<E>();
+}
+
+class _IdentityHashSet<E> extends _HashSet<E> {
+  bool _equals(e1, e2) => identical(e1, e2);
+  HashSet<E> _newSet() => new _IdentityHashSet<E>();
+}
+
+class _CustomHashSet<E> extends _HashSet<E> {
+  final _Equality<E> _equality;
+  final _Hasher<E> _hasher;
+  final _Predicate _validKey;
+  _CustomHashSet(this._equality, this._hasher, this._validKey);
+
+  bool remove(Object element) {
+    if (!_validKey(element)) return false;
+    return super.remove(element);
+  }
+
+  bool contains(Object element) {
+    if (!_validKey(element)) return false;
+    return super.contains(element);
+  }
+
+  bool containsAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (!_validKey(element) || !this.contains(element)) return false;
+    }
+    return true;
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (_validKey(element)) {
+        super._remove(element, _hasher(element));
+      }
+    }
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    super._retainAll(elements, _validKey);
+  }
+
+  bool _equals(e1, e2) => _equality(e1, e2);
+  int _hashCode(e) => _hasher(e);
+
+  HashSet<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey);
+}
+
+class _HashSetEntry {
+  final key;
+  final int hashCode;
+  _HashSetEntry next;
+  _HashSetEntry(this.key, this.hashCode, this.next);
+
+  _HashSetEntry remove() {
+    _HashSetEntry result = next;
+    next = null;
+    return result;
+  }
+}
+
+class _HashSetIterator<E> implements Iterator<E> {
+  final _HashSet _set;
+  final int _modificationCount;
+  int _index = 0;
+  _HashSetEntry _next = null;
+  E _current = null;
+
+  _HashSetIterator(_HashSet hashSet)
+      : _set = hashSet, _modificationCount = hashSet._modificationCount;
+
+  bool moveNext() {
+    if (_modificationCount != _set._modificationCount) {
+      throw new ConcurrentModificationError(_set);
+    }
+    if (_next != null) {
+      _current = _next.key;
+      _next = _next.next;
+      return true;
+    }
+    List<_HashSetEntry> buckets = _set._buckets;
+    while (_index < buckets.length) {
+      _next = buckets[_index];
+      _index = _index + 1;
+      if (_next != null) {
+        _current = _next.key;
+        _next = _next.next;
+        return true;
+      }
+    }
+    _current = null;
+    return false;
+  }
+
+  E get current => _current;
+}
+
 class _LinkedHashMapEntry extends _HashMapEntry {
+  /// Double-linked list of entries of a linked hash map.
+  /// The _LinkedHashMap itself is the head of the list, so the type is "var".
+  /// Both are initialized to `this` when initialized.
   var _nextEntry;
   var _previousEntry;
   _LinkedHashMapEntry(key, value, int hashCode, _LinkedHashMapEntry next,
@@ -598,7 +803,7 @@
   LinkedHashMap<K, dynamic> _map;
   _LinkedHashMapKeyIterable(this._map);
   Iterator<K> get iterator => new _LinkedHashMapKeyIterator<K>(_map);
-  bool contains(K key) => _map.containsKey(key);
+  bool contains(Object key) => _map.containsKey(key);
   bool get isEmpty => _map.isEmpty;
   bool get isNotEmpty => _map.isNotEmpty;
   int get length => _map.length;
@@ -608,7 +813,7 @@
   LinkedHashMap<dynamic, V> _map;
   _LinkedHashMapValueIterable(this._map);
   Iterator<K> get iterator => new _LinkedHashMapValueIterator<V>(_map);
-  bool contains(V value) => _map.containsValue(value);
+  bool contains(Object value) => _map.containsValue(value);
   bool get isEmpty => _map.isEmpty;
   bool get isNotEmpty => _map.isNotEmpty;
   int get length => _map.length;
@@ -659,6 +864,11 @@
  * A hash-based map that iterates keys and values in key insertion order.
  */
 patch class LinkedHashMap<K, V> {
+  /// Holds a double-linked list of entries in insertion order.
+  /// The fields have the same name as the ones in [_LinkedHashMapEntry],
+  /// and this map is itself used as the head entry of the list.
+  /// Set to `this` when initialized, representing the empty list (containing
+  /// only the head entry itself).
   var _nextEntry;
   var _previousEntry;
 
@@ -738,6 +948,7 @@
     buckets[index] = entry;
     int newElements = _elementCount + 1;
     _elementCount = newElements;
+
     // If we end up with more than 75% non-empty entries, we
     // resize the backing store.
     if ((newElements << 2) > ((length << 1) + length)) _resize();
@@ -788,703 +999,213 @@
 }
 
 
-patch class LinkedHashSet<E> extends _HashSetBase<E> {
-  static const int _INITIAL_CAPACITY = 8;
-  _LinkedHashTable<E> _table;
+patch class LinkedHashSet<E> {
+  /* patch */ factory LinkedHashSet({ bool equals(E e1, E e2),
+                                      int hashCode(E e),
+                                      bool isValidKey(potentialKey) }) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _LinkedHashSet<E>();
+        }
+        if (identical(identical, equals)) {
+          return new _LinkedIdentityHashSet<E>();
+        }
+        _hashCode = _defaultHashCode;
+      } else if (equals == null) {
+        _equals = _defaultEquals;
+      }
+      isValidKey = new _TypeTest<E>().test;
+    } else {
+      if (hashCode == null) hashCode = _defaultHashCode;
+      if (equals == null) equals = _defaultEquals;
+    }
+    return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
+  }
+}
 
-  /* patch */ LinkedHashSet() {
-    _table = new _LinkedHashTable(_INITIAL_CAPACITY);
-    _table._container = this;
+class _LinkedHashSetEntry extends _HashSetEntry {
+  /// Links this element into a double-linked list of elements of a hash set.
+  /// The hash set object itself is used as the head entry of the list, so
+  /// the field is typed as "var".
+  /// Both links are initialized to `this` when the object is created.
+  var _nextEntry;
+  var _previousEntry;
+  _LinkedHashSetEntry(var key, int hashCode, _LinkedHashSetEntry next,
+                      this._previousEntry, this._nextEntry)
+      : super(key, hashCode, next) {
+    _previousEntry._nextEntry = _nextEntry._previousEntry = this;
+  }
+
+  _LinkedHashSetEntry remove() {
+    _previousEntry._nextEntry = _nextEntry;
+    _nextEntry._previousEntry = _previousEntry;
+    _nextEntry = _previousEntry = this;
+    return super.remove();
+  }
+}
+
+class _LinkedHashSet<E> extends _HashSet<E>
+                        implements LinkedHashSet<E> {
+  /// Holds a double linked list of the element entries of the set in
+  /// insertion order.
+  /// The fields have the same names as the ones in [_LinkedHashSetEntry],
+  /// allowing this object to be used as the head entry of the list.
+  /// The fields are initialized to `this` when created, representing the
+  /// empty list that only contains the head entry.
+  var _nextEntry;
+  var _previousEntry;
+
+  _LinkedHashSet() {
+    _nextEntry = _previousEntry = this;
   }
 
   // Iterable.
-  /* patch */ Iterator<E> get iterator {
-    return new _LinkedHashTableKeyIterator<E>(_table);
-  }
 
-  /* patch */ int get length => _table._elementCount;
-
-  /* patch */ bool get isEmpty => _table._elementCount == 0;
-
-  /* patch */ bool get isNotEmpty => !isEmpty;
-
-  /* patch */ bool contains(Object object) => _table._get(object) >= 0;
-
-  /* patch */ void forEach(void action(E element)) {
-    int offset = _table._next(_LinkedHashTable._HEAD_OFFSET);
-    int modificationCount = _table._modificationCount;
-    while (offset != _LinkedHashTable._HEAD_OFFSET) {
-      E key = _table._key(offset);
-      action(key);
-      _table._checkModification(modificationCount);
-      offset = _table._next(offset);
-    }
-  }
-
-  /* patch */ E get first {
-    int firstOffset = _table._next(_LinkedHashTable._HEAD_OFFSET);
-    if (firstOffset == _LinkedHashTable._HEAD_OFFSET) {
-      throw new StateError("No elements");
-    }
-    return _table._key(firstOffset);
-  }
-
-  /* patch */ E get last {
-    int lastOffset = _table._prev(_LinkedHashTable._HEAD_OFFSET);
-    if (lastOffset == _LinkedHashTable._HEAD_OFFSET) {
-      throw new StateError("No elements");
-    }
-    return _table._key(lastOffset);
-  }
-
-  // Collection.
-  void _filterWhere(bool test(E element), bool removeMatching) {
-    int entrySize = _table._entrySize;
-    int length = _table._table.length;
-    int offset = _table._next(_LinkedHashTable._HEAD_OFFSET);
-    while (offset != _LinkedHashTable._HEAD_OFFSET) {
-      E key = _table._key(offset);
-      int nextOffset = _table._next(offset);
-      int modificationCount = _table._modificationCount;
-      bool shouldRemove = (removeMatching == test(key));
-      _table._checkModification(modificationCount);
-      if (shouldRemove) {
-        _table._deleteEntry(offset);
-      }
-      offset = nextOffset;
-    }
-    _table._checkCapacity();
-  }
-
-  /* patch */ void add(E element) {
-    _table._put(element);
-    _table._checkCapacity();
-  }
-
-  /* patch */ void addAll(Iterable<E> objects) {
-    for (E object in objects) {
-      _table._put(object);
-      _table._checkCapacity();
-    }
-  }
-
-  /* patch */ bool remove(Object object) {
-    int offset = _table._remove(object);
-    if (offset >= 0) {
-      _table._checkCapacity();
-      return true;
-    }
-    return false;
-  }
-
-  /* patch */ void removeAll(Iterable objectsToRemove) {
-    for (Object object in objectsToRemove) {
-      if (_table._remove(object) >= 0) {
-        _table._checkCapacity();
-      }
-    }
-  }
-
-  /* patch */ void removeWhere(bool test(E element)) {
-    _filterWhere(test, true);
-  }
-
-  /* patch */ void retainWhere(bool test(E element)) {
-    _filterWhere(test, false);
-  }
-
-  /* patch */ void clear() {
-    _table._clear();
-  }
-}
-
-class _DeadEntry {
-  const _DeadEntry();
-}
-
-class _NullKey {
-  const _NullKey();
-  int get hashCode => null.hashCode;
-}
-
-const _TOMBSTONE = const _DeadEntry();
-const _NULL = const _NullKey();
-
-class _HashTable<K> {
-  /**
-   * Table of entries with [_entrySize] slots per entry.
-   *
-   * Capacity in entries must be factor of two.
-   */
-  List _table;
-  /** Current capacity. Always equal to [:_table.length ~/ _entrySize:]. */
-  int _capacity;
-  /** Count of occupied entries, including deleted ones. */
-  int _entryCount = 0;
-  /** Count of deleted entries. */
-  int _deletedCount = 0;
-  /** Counter incremented when table is modified. */
-  int _modificationCount = 0;
-  /** If set, used as the source object for [ConcurrentModificationError]s. */
-  Object _container;
-
-  _HashTable(int initialCapacity) : _capacity = initialCapacity {
-    _table = _createTable(initialCapacity);
-  }
-
-  /** Reads key from table. Converts _NULL marker to null. */
-  Object _key(offset) {
-    assert(!_isFree(_table[offset]));
-    Object key = _table[offset];
-    if (!identical(key, _NULL)) return key;
-    return null;
-  }
-
-  /** Writes key to table. Converts null to _NULL marker. */
-  void _setKey(int offset, Object key) {
-    if (key == null) key = _NULL;
-    _table[offset] = key;
-  }
-
-  int get _elementCount => _entryCount - _deletedCount;
-
-  /** Size of each entry. */
-  int get _entrySize => 1;
-
-  void _checkModification(int expectedModificationCount) {
-    if (_modificationCount != expectedModificationCount) {
-      throw new ConcurrentModificationError(_container);
-    }
-  }
-
-  void _recordModification() {
-    // Value cycles after 2^30 modifications. If you keep hold of an
-    // iterator for that long, you might miss a modification detection,
-    // and iteration can go sour. Don't do that.
-    _modificationCount = (_modificationCount + 1) & (0x3FFFFFFF);
-  }
-
-  /**
-   * Create an empty table.
-   */
-  List _createTable(int capacity) {
-    List table = new List(capacity * _entrySize);
-    return table;
-  }
-
-  /** First table probe. */
-  int _firstProbe(int hashCode, int capacity) {
-    return hashCode & (capacity - 1);
-  }
-
-  /** Following table probes. */
-  int _nextProbe(int previousIndex, int probeCount, int capacity) {
-    // When capacity is a power of 2, this probing algorithm (the triangular
-    // number sequence modulo capacity) is guaranteed to hit all indices exactly
-    // once before repeating.
-    return (previousIndex + probeCount) & (capacity - 1);
-  }
-
-  /** Whether an object is a free-marker (either tombstone or free). */
-  bool _isFree(Object marker) =>
-      marker == null || identical(marker, _TOMBSTONE);
-
-  /**
-   * Look up the offset for an object in the table.
-   *
-   * Finds the offset of the object in the table, if it is there,
-   * or the first free offset for its hashCode.
-   */
-  int _probeForAdd(int hashCode, Object object) {
-    int entrySize = _entrySize;
-    int index = _firstProbe(hashCode, _capacity);
-    int firstTombstone = -1;
-    int probeCount = 0;
-    while (true) {
-      int offset = index * entrySize;
-      Object entry = _table[offset];
-      if (identical(entry, _TOMBSTONE)) {
-        if (firstTombstone < 0) firstTombstone = offset;
-      } else if (entry == null) {
-        if (firstTombstone < 0) return offset;
-        return firstTombstone;
-      } else if (identical(_NULL, entry) ? _equals(null, object)
-                                         : _equals(entry, object)) {
-        return offset;
-      }
-      // The _nextProbe is designed so that it hits
-      // every index eventually.
-      index = _nextProbe(index, ++probeCount, _capacity);
-    }
-  }
-
-  /**
-   * Look up the offset for an object in the table.
-   *
-   * If the object is in the table, its offset is returned.
-   *
-   * If the object is not in the table, Otherwise a negative value is returned.
-   */
-  int _probeForLookup(int hashCode, Object object) {
-    int entrySize = _entrySize;
-    int index = _firstProbe(hashCode, _capacity);
-    int probeCount = 0;
-    while (true) {
-      int offset = index * entrySize;
-      Object entry = _table[offset];
-      if (entry == null) {
-        return -1;
-      } else if (!identical(_TOMBSTONE, entry)) {
-        if (identical(_NULL, entry) ? _equals(null, object)
-                                    : _equals(entry, object)) {
-          return offset;
-        }
-      }
-      // The _nextProbe is designed so that it hits
-      // every index eventually.
-      index = _nextProbe(index, ++probeCount, _capacity);
-    }
-  }
-
-  // Override the following two to change equality/hashCode computations
-
-  /**
-   * Compare two object for equality.
-   *
-   * The first object is the one already in the table,
-   * and the second is the one being searched for.
-   */
-  bool _equals(Object element, Object other) {
-    return element == other;
-  }
-
-  /**
-   * Compute hash-code for an object.
-   */
-  int _hashCodeOf(Object object) => object.hashCode;
-
-  /**
-   * Ensure that the table isn't too full for its own good.
-   *
-   * Call this after adding an element.
-   */
-  int _checkCapacity() {
-    // Compute everything in multiples of entrySize to avoid division.
-    int freeCount = _capacity - _entryCount;
-    if (freeCount * 4 < _capacity ||
-        freeCount < _deletedCount) {
-      // Less than 25% free or more deleted entries than free entries.
-      _grow(_entryCount - _deletedCount);
-    }
-  }
-
-  void _grow(int contentCount) {
-    int capacity = _capacity;
-    // Don't grow to less than twice the needed capacity.
-    int minCapacity = contentCount * 2;
-    while (capacity < minCapacity) {
-      capacity *= 2;
-    }
-    // Reset to another table and add all existing elements.
-    List oldTable = _table;
-    _table = _createTable(capacity);
-    _capacity = capacity;
-    _entryCount = 0;
-    _deletedCount = 0;
-    _addAllEntries(oldTable);
-    _recordModification();
-  }
-
-  /**
-   * Copies all non-free entries from the old table to the new empty table.
-   */
-  void _addAllEntries(List oldTable) {
-    for (int i = 0; i < oldTable.length; i += _entrySize) {
-      Object object = oldTable[i];
-      if (!_isFree(object)) {
-        int toOffset = _put(object);
-        _copyEntry(oldTable, i, toOffset);
-      }
-    }
-  }
-
-  /**
-   * Copies everything but the key element from one entry to another.
-   *
-   * Called while growing the base array.
-   *
-   * Override this if any non-key fields need copying.
-   */
-  void _copyEntry(List fromTable, int fromOffset, int toOffset) {}
-
-  // The following three methods are for simple get/set/remove operations.
-  // They only affect the key of an entry. The remaining fields must be
-  // filled by the caller.
-
-  /**
-   * Returns the offset of a key in [_table], or negative if it's not there.
-   */
-  int _get(Object key) {
-    return _probeForLookup(_hashCodeOf(key), key);
-  }
-
-  /**
-   * Puts the key into the table and returns its offset into [_table].
-   *
-   * If [_entrySize] is greater than 1, the caller should fill the
-   * remaining fields.
-   *
-   * Remember to call [_checkCapacity] after using this method.
-   */
-  int _put(K key) {
-    int offset = _probeForAdd(_hashCodeOf(key), key);
-    Object oldEntry = _table[offset];
-    if (oldEntry == null) {
-      _entryCount++;
-    } else if (identical(oldEntry, _TOMBSTONE)) {
-      _deletedCount--;
-    } else {
-      return offset;
-    }
-    _setKey(offset, key);
-    _recordModification();
-    return offset;
-  }
-
-  /**
-   * Removes a key from the table and returns its offset into [_table].
-   *
-   * Returns null if the key was not in the table.
-   * If [_entrySize] is greater than 1, the caller should clean up the
-   * remaining fields.
-   */
-  int _remove(Object key) {
-    int offset = _probeForLookup(_hashCodeOf(key), key);
-    if (offset >= 0) {
-      _deleteEntry(offset);
-    }
-    return offset;
-  }
-
-  /** Clears the table completely, leaving it empty. */
-  void _clear() {
-    if (_elementCount == 0) return;
-    for (int i = 0; i < _table.length; i++) {
-      _table[i] = null;
-    }
-    _entryCount = _deletedCount = 0;
-    _recordModification();
-  }
-
-  /** Clears an entry in the table. */
-  void _deleteEntry(int offset) {
-    assert(!_isFree(_table[offset]));
-    _setKey(offset, _TOMBSTONE);
-    _deletedCount++;
-    _recordModification();
-  }
-}
-
-/**
- * Generic iterable based on a [_HashTable].
- */
-abstract class _HashTableIterable<E> extends IterableBase<E> {
-  final _HashTable _hashTable;
-  _HashTableIterable(this._hashTable);
-
-  Iterator<E> get iterator;
-
-  /**
-   * Return the iterated value for a given entry.
-   */
-  E _valueAt(int offset, Object key);
-
-  int get length => _hashTable._elementCount;
-
-  bool get isEmpty => _hashTable._elementCount == 0;
+  Iterator<E> get iterator => new _LinkedHashSetIterator<E>(this);
 
   void forEach(void action(E element)) {
-    int entrySize = _hashTable._entrySize;
-    List table = _hashTable._table;
-    int modificationCount = _hashTable._modificationCount;
-    for (int offset = 0; offset < table.length; offset += entrySize) {
-      Object entry = table[offset];
-      if (!_hashTable._isFree(entry)) {
-        E value = _valueAt(offset, entry);
-        action(value);
+    var cursor = _nextEntry;
+    int modificationCount = _modificationCount;
+    while (!identical(cursor, this)) {
+      _LinkedHashSetEntry entry = cursor;
+      action(entry.key);
+      if (_modificationCount != modificationCount) {
+        throw new ConcurrentModificationError(this);
       }
-      _hashTable._checkModification(modificationCount);
+      cursor = entry._nextEntry;
     }
   }
-}
 
-abstract class _HashTableIterator<E> implements Iterator<E> {
-  final _HashTable _hashTable;
-  final int _modificationCount;
-  /** Location right after last found element. */
-  int _offset = 0;
-  E _current = null;
+  E get first {
+    if (identical(_nextEntry, this)) {
+      throw new StateError("No elements");
+    }
+    _LinkedHashSetEntry entry = _nextEntry;
+    return entry.key;
+  }
 
-  _HashTableIterator(_HashTable hashTable)
-      : _hashTable = hashTable,
-        _modificationCount = hashTable._modificationCount;
+  E get last {
+    if (identical(_previousEntry, this)) {
+      throw new StateError("No elements");
+    }
+    _LinkedHashSetEntry entry = _previousEntry;
+    return entry.key;
+  }
 
-  bool moveNext() {
-    _hashTable._checkModification(_modificationCount);
+  // Set.
 
-    List table = _hashTable._table;
-    int entrySize = _hashTable._entrySize;
-
-    while (_offset < table.length) {
-      int currentOffset = _offset;
-      Object entry = table[currentOffset];
-      _offset = currentOffset + entrySize;
-      if (!_hashTable._isFree(entry)) {
-        _current = _valueAt(currentOffset, entry);
-        return true;
+  void _filterWhere(bool test(E element), bool removeMatching) {
+    var cursor = _nextEntry;
+    while (!identical(cursor, this)) {
+      _LinkedHashSetEntry entry = cursor;
+      int modificationCount = _modificationCount;
+      bool testResult = test(entry.key);
+      if (modificationCount != _modificationCount) {
+        throw new ConcurrentModificationError(this);
+      }
+      cursor = entry._nextEntry;
+      if (testResult == removeMatching) {
+        _remove(entry.key, entry.hashCode);
       }
     }
-    _current = null;
-    return false;
   }
 
-  E get current => _current;
+  void _addEntry(E key, int hashCode, int index) {
+    _buckets[index] =
+        new _LinkedHashSetEntry(key, hashCode, _buckets[index],
+                                _previousEntry, this);
+    int newElements = _elementCount + 1;
+    _elementCount = newElements;
+    int length = _buckets.length;
+    // If we end up with more than 75% non-empty entries, we
+    // resize the backing store.
+    if ((newElements << 2) > ((length << 1) + length)) _resize();
+    _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
+  }
 
-  E _valueAt(int offset, Object key);
+  void clear() {
+    _nextEntry = _previousEntry = this;
+    super.clear();
+  }
+
+  HashSet<E> _newSet() => new _LinkedHashSet<E>();
 }
 
-class _HashTableKeyIterable<K> extends _HashTableIterable<K> {
-  _HashTableKeyIterable(_HashTable<K> hashTable) : super(hashTable);
-
-  Iterator<K> get iterator => new _HashTableKeyIterator<K>(_hashTable);
-
-  K _valueAt(int offset, Object key) {
-    if (identical(key, _NULL)) return null;
-    return key;
-  }
-
-  bool contains(Object value) => _hashTable._get(value) >= 0;
+class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
+  bool _equals(e1, e2) => identical(e1, e2);
+  HashSet<E> _newSet() => new _LinkedIdentityHashSet<E>();
 }
 
-class _HashTableKeyIterator<K> extends _HashTableIterator<K> {
-  _HashTableKeyIterator(_HashTable hashTable) : super(hashTable);
+class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
+  final _Equality<E> _equality;
+  final _Hasher<E> _hasher;
+  final _Predicate _validKey;
 
-  K _valueAt(int offset, Object key) {
-    if (identical(key, _NULL)) return null;
-    return key;
-  }
-}
+  _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(object))
+      : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
 
-class _HashTableValueIterable<V> extends _HashTableIterable<V> {
-  final int _entryIndex;
+  bool _equals(e1, e2) => _equality(e1, e2);
 
-  _HashTableValueIterable(_HashTable hashTable, this._entryIndex)
-      : super(hashTable);
+  int _hashCode(e) => _hasher(e);
 
-  Iterator<V> get iterator {
-    return new _HashTableValueIterator<V>(_hashTable, _entryIndex);
+  bool contains(Object o) {
+    if (!_validKey(o)) return false;
+    return super.contains(o);
   }
 
-  V _valueAt(int offset, Object key) => _hashTable._table[offset + _entryIndex];
-}
-
-class _HashTableValueIterator<V> extends _HashTableIterator<V> {
-  final int _entryIndex;
-
-  _HashTableValueIterator(_HashTable hashTable, this._entryIndex)
-      : super(hashTable);
-
-  V _valueAt(int offset, Object key) => _hashTable._table[offset + _entryIndex];
-}
-
-class _HashMapTable<K, V> extends _HashTable<K> {
-  static const int _INITIAL_CAPACITY = 8;
-  static const int _VALUE_INDEX = 1;
-
-  _HashMapTable() : super(_INITIAL_CAPACITY);
-
-  int get _entrySize => 2;
-
-  V _value(int offset) => _table[offset + _VALUE_INDEX];
-  void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; }
-
-  _copyEntry(List fromTable, int fromOffset, int toOffset) {
-    _table[toOffset + _VALUE_INDEX] = fromTable[fromOffset + _VALUE_INDEX];
-  }
-}
-
-/** Unique marker object for the head of a linked list of entries. */
-class _LinkedHashTableHeadMarker {
-  const _LinkedHashTableHeadMarker();
-}
-
-const _LinkedHashTableHeadMarker _HEAD_MARKER =
-    const _LinkedHashTableHeadMarker();
-
-class _LinkedHashTable<K> extends _HashTable<K> {
-  static const _NEXT_INDEX = 1;
-  static const _PREV_INDEX = 2;
-  static const _HEAD_OFFSET = 0;
-
-  _LinkedHashTable(int initialCapacity) : super(initialCapacity);
-
-  int get _entrySize => 3;
-
-  List _createTable(int capacity) {
-    List result = new List(capacity * _entrySize);
-    result[_HEAD_OFFSET] = _HEAD_MARKER;
-    result[_HEAD_OFFSET + _NEXT_INDEX] = _HEAD_OFFSET;
-    result[_HEAD_OFFSET + _PREV_INDEX] = _HEAD_OFFSET;
-    return result;
+  bool remove(Object o) {
+    if (!_validKey(o)) return false;
+    return super.remove(o);
   }
 
-  int _next(int offset) => _table[offset + _NEXT_INDEX];
-  void _setNext(int offset, int to) { _table[offset + _NEXT_INDEX] = to; }
-
-  int _prev(int offset) => _table[offset + _PREV_INDEX];
-  void _setPrev(int offset, int to) { _table[offset + _PREV_INDEX] = to; }
-
-  void _linkLast(int offset) {
-    // Add entry at offset at end of double-linked list.
-    int last = _prev(_HEAD_OFFSET);
-    _setNext(offset, _HEAD_OFFSET);
-    _setPrev(offset, last);
-    _setNext(last, offset);
-    _setPrev(_HEAD_OFFSET, offset);
-  }
-
-  void _unlink(int offset) {
-    assert(offset != _HEAD_OFFSET);
-    int next = _next(offset);
-    int prev = _prev(offset);
-    _setNext(offset, null);
-    _setPrev(offset, null);
-    _setNext(prev, next);
-    _setPrev(next, prev);
-  }
-
-  /**
-   * Copies all non-free entries from the old table to the new empty table.
-   */
-  void _addAllEntries(List oldTable) {
-    int offset = oldTable[_HEAD_OFFSET + _NEXT_INDEX];
-    while (offset != _HEAD_OFFSET) {
-      Object object = oldTable[offset];
-      int nextOffset = oldTable[offset + _NEXT_INDEX];
-      int toOffset = _put(object);
-      _copyEntry(oldTable, offset, toOffset);
-      offset = nextOffset;
+  bool containsAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (!_validKey(element) || !this.contains(element)) return false;
     }
-  }
-
-  void _clear() {
-    if (_elementCount == 0) return;
-    _setNext(_HEAD_OFFSET, _HEAD_OFFSET);
-    _setPrev(_HEAD_OFFSET, _HEAD_OFFSET);
-    for (int i = _entrySize; i < _table.length; i++) {
-      _table[i] = null;
-    }
-    _entryCount = _deletedCount = 0;
-    _recordModification();
-  }
-
-  int _put(K key) {
-    int offset = _probeForAdd(_hashCodeOf(key), key);
-    Object oldEntry = _table[offset];
-    if (identical(oldEntry, _TOMBSTONE)) {
-      _deletedCount--;
-    } else if (oldEntry == null) {
-      _entryCount++;
-    } else {
-      return offset;
-    }
-    _recordModification();
-    _setKey(offset, key);
-    _linkLast(offset);
-    return offset;
-  }
-
-  void _deleteEntry(int offset) {
-    _unlink(offset);
-    _setKey(offset, _TOMBSTONE);
-    _deletedCount++;
-    _recordModification();
-  }
-}
-
-class _LinkedHashTableKeyIterable<K> extends IterableBase<K> {
-  final _LinkedHashTable<K> _table;
-  _LinkedHashTableKeyIterable(this._table);
-  Iterator<K> get iterator => new _LinkedHashTableKeyIterator<K>(_table);
-
-  bool contains(Object value) => _table._get(value) >= 0;
-
-  int get length => _table._elementCount;
-}
-
-class _LinkedHashTableKeyIterator<K> extends _LinkedHashTableIterator<K> {
-  _LinkedHashTableKeyIterator(_LinkedHashTable<K> hashTable): super(hashTable);
-
-  K _getCurrent(int offset) => _hashTable._key(offset);
-}
-
-class _LinkedHashTableValueIterable<V> extends IterableBase<V> {
-  final _LinkedHashTable _hashTable;
-  final int _valueIndex;
-  _LinkedHashTableValueIterable(this._hashTable, this._valueIndex);
-  Iterator<V> get iterator =>
-      new _LinkedHashTableValueIterator<V>(_hashTable, _valueIndex);
-  int get length => _hashTable._elementCount;
-}
-
-class _LinkedHashTableValueIterator<V> extends _LinkedHashTableIterator<V> {
-  final int _valueIndex;
-
-  _LinkedHashTableValueIterator(_LinkedHashTable hashTable, this._valueIndex)
-      : super(hashTable);
-
-  V _getCurrent(int offset) => _hashTable._table[offset + _valueIndex];
-}
-
-abstract class _LinkedHashTableIterator<T> implements Iterator<T> {
-  final _LinkedHashTable _hashTable;
-  final int _modificationCount;
-  int _offset;
-  T _current;
-
-  _LinkedHashTableIterator(_LinkedHashTable table)
-      : _hashTable = table,
-        _modificationCount = table._modificationCount,
-        _offset = table._next(_LinkedHashTable._HEAD_OFFSET);
-
-  bool moveNext() {
-    _hashTable._checkModification(_modificationCount);
-    if (_offset == _LinkedHashTable._HEAD_OFFSET) {
-      _current = null;
-      return false;
-    }
-    _current = _getCurrent(_offset);
-    _offset = _hashTable._next(_offset);
     return true;
   }
 
-  T _getCurrent(int offset);
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (_validKey(element)) {
+        super._remove(element, _hasher(element));
+      }
+    }
+  }
 
-  T get current => _current;
+  void retainAll(Iterable<Object> elements) {
+    super._retainAll(elements, _validKey);
+  }
+
+  HashSet<E> _newSet() =>
+      new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey);
 }
 
-class _LinkedHashMapTable<K, V> extends _LinkedHashTable<K> {
-  static const int _INITIAL_CAPACITY = 8;
-  static const int _VALUE_INDEX = 3;
+class _LinkedHashSetIterator<E> implements Iterator<E> {
+  final _LinkedHashSet _set;
+  final int _modificationCount;
+  var _next;
+  E _current;
 
-  int get _entrySize => 4;
+  _LinkedHashSetIterator(_LinkedHashSet hashSet)
+      : _set = hashSet,
+        _modificationCount = hashSet._modificationCount,
+        _next = hashSet._nextEntry;
 
-  _LinkedHashMapTable() : super(_INITIAL_CAPACITY);
-
-  V _value(int offset) => _table[offset + _VALUE_INDEX];
-  void _setValue(int offset, V value) { _table[offset + _VALUE_INDEX] = value; }
-
-  _copyEntry(List oldTable, int fromOffset, int toOffset) {
-    _table[toOffset + _VALUE_INDEX] = oldTable[fromOffset + _VALUE_INDEX];
+  bool moveNext() {
+    if (_modificationCount != _set._modificationCount) {
+      throw new ConcurrentModificationError(_set);
+    }
+    if (identical(_set, _next)) {
+      _current = null;
+      return false;
+    }
+    _LinkedHashSetEntry entry = _next;
+    _current = entry.key;
+    _next = entry._nextEntry;
+    return true;
   }
+
+  E get current => _current;
 }
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 0487b58..0708da3 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -192,7 +192,7 @@
 
   InstanceMirror getField(Symbol memberName) {
     return reflect(this._invokeGetter(_reflectee,
-                                      _n(memberName))); 
+                                      _n(memberName)));
   }
 
   InstanceMirror setField(Symbol memberName, Object value) {
@@ -216,7 +216,7 @@
    try {
       var result = this._invokeGetter(_reflectee,
                                       _n(memberName));
-      return new Future.value(reflect(result)); 
+      return new Future.value(reflect(result));
     } catch(e) {
       return new Future.error(e);
     }
@@ -229,7 +229,7 @@
         unwrappedValue = value;
       } else if(value is InstanceMirror) {
         unwrappedValue = value._reflectee;
-      } else { 
+      } else {
         throw "setter argument ($value) must be"
               "a simple value or InstanceMirror";
       }
@@ -237,7 +237,7 @@
       this._invokeSetter(_reflectee,
                          _n(memberName),
                          unwrappedValue);
-      return new Future.value(reflect(unwrappedValue)); 
+      return new Future.value(reflect(unwrappedValue));
     } catch(e) {
       return new Future.error(e);
     }
@@ -285,7 +285,7 @@
       // system to access a private field in a different library.  For
       // some reason, that works.  On the other hand, calling a
       // private method does not work.
-      
+
       _LocalInstanceMirrorImpl mirror =
           reflect(invocation);
       _invokeOnClosure = reflectClass(invocation.runtimeType)
@@ -375,7 +375,7 @@
     // replaced with
     //   return this.invoke(#call, positionalArguments, namedArguments);
     // and the native ClosureMirror_apply can be removed.
-    
+
     int numPositionalArguments = positionalArguments.length + 1;  // Receiver.
     int numNamedArguments = namedArguments != null ? namedArguments.length : 0;
     int numArguments = numPositionalArguments + numNamedArguments;
@@ -515,11 +515,11 @@
       klass = klass.superclass;
     }
     return _s(
-      _n(klass.qualifiedName) 
+      _n(klass.qualifiedName)
       + ' with '
       + mixins.reversed.map((m)=>_n(m.qualifiedName)).join(', '));
   }
- 
+
   var _mixin;
   ClassMirror get mixin {
     if (_mixin == null) {
@@ -594,34 +594,33 @@
       var stringName = _n(simpleName);
       constructorsList.forEach((c) => c._patchConstructorName(stringName));
       _constructors = _makeMemberMap(constructorsList);
-    } 
-    return _constructors;  
+    }
+    return _constructors;
   }
 
-  Map<Symbol, TypeVariableMirror> _typeVariables = null;
-  Map<Symbol, TypeVariableMirror> get typeVariables {
+  List<TypeVariableMirror> _typeVariables = null;
+  List<TypeVariableMirror> get typeVariables {
     if (_typeVariables == null) {
       List params = _ClassMirror_type_variables(_reflectee);
-      _typeVariables = new LinkedHashMap<Symbol, TypeVariableMirror>();
+      _typeVariables = new List<TypeVariableMirror>();
       var mirror;
       for (var i = 0; i < params.length; i += 2) {
         mirror = new _LocalTypeVariableMirrorImpl(
             params[i + 1], params[i], this);
-        _typeVariables[mirror.simpleName] = mirror;
+        _typeVariables.add(mirror);
       }
     }
     return _typeVariables;
   }
 
-  Map<Symbol, TypeMirror> _typeArguments = null;
-  Map<Symbol, TypeMirror> get typeArguments {
+  List<TypeMirror> _typeArguments = null;
+  List<TypeMirror> get typeArguments {
     if(_typeArguments == null) {
       if(_isGenericDeclaration) {
-        _typeArguments = new LinkedHashMap<Symbol, TypeMirror>();
+        _typeArguments = new List<TypeMirror>();
       } else {
         _typeArguments =
-            new LinkedHashMap<Symbol, TypeMirror>.fromIterables(
-                typeVariables.keys, _computeTypeArguments(_reflectedType));
+            new List<TypeMirror>.from(_computeTypeArguments(_reflectedType));
       }
     }
     return _typeArguments;
@@ -705,7 +704,7 @@
 
   _computeMembers(reflectee)
       native "ClassMirror_members";
-  
+
   _computeConstructors(reflectee)
       native "ClassMirror_constructors";
 
@@ -807,7 +806,7 @@
 
   bool operator ==(other) {
     return this.runtimeType == other.runtimeType &&
-           this._reflectee == other._reflectee; 
+           this._reflectee == other._reflectee;
   }
 
   int get hashCode => simpleName.hashCode;
@@ -988,7 +987,7 @@
 
   bool operator ==(other) {
     return this.runtimeType == other.runtimeType &&
-           this._reflectee == other._reflectee; 
+           this._reflectee == other._reflectee;
   }
 
   int get hashCode => simpleName.hashCode;
@@ -1294,7 +1293,7 @@
 
   // Creates a new local mirror for some Object.
   static InstanceMirror reflect(Object reflectee) {
-    return reflectee is Function 
+    return reflectee is Function
         ? new _LocalClosureMirrorImpl(reflectee)
         : new _LocalInstanceMirrorImpl(reflectee);
   }
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index b7c7a69..a59a6fd 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -2,6 +2,7 @@
 
 #include "vm/bigint_operations.h"
 
+#include "platform/assert.h"
 #include "platform/utils.h"
 
 #include "vm/double_internals.h"
@@ -106,7 +107,9 @@
     return result.raw();
   }
 
-  intptr_t str_length = strlen(str);
+  // No overflow check needed since overflowing str_length implies that we take
+  // the branch to FromDecimalCString() which contains a check itself.
+  const intptr_t str_length = strlen(str);
   if ((str_length > 2) &&
       (str[0] == '0') &&
       ((str[1] == 'x') || (str[1] == 'X'))) {
@@ -121,7 +124,11 @@
 
 intptr_t BigintOperations::ComputeChunkLength(const char* hex_string) {
   ASSERT(kDigitBitSize % 4 == 0);
-  intptr_t hex_length = strlen(hex_string);
+  const intptr_t hex_length = strlen(hex_string);
+  if (hex_length < 0) {
+    FATAL("Fatal error in BigintOperations::ComputeChunkLength: "
+          "string too long");
+  }
   // Round up.
   intptr_t bigint_length = ((hex_length - 1) / kHexCharsPerDigit) + 1;
   return bigint_length;
@@ -158,7 +165,11 @@
   const Chunk kTenMultiplier = 100000000;
   ASSERT(kDigitBitSize >= 27);
 
-  intptr_t str_length = strlen(str);
+  const intptr_t str_length = strlen(str);
+  if (str_length < 0) {
+    FATAL("Fatal error in BigintOperations::FromDecimalCString: "
+          "string too long");
+  }
   intptr_t str_pos = 0;
 
   // Read first digit separately. This avoids a multiplication and addition.
@@ -247,11 +258,21 @@
 
   ASSERT(kDigitBitSize % 4 == 0);
 
-  intptr_t chunk_length = length;
+  // Conservative maximum chunk length.
+  const intptr_t kMaxChunkLen =
+      (kIntptrMax - 2 /* 0x */
+                  - 1 /* trailing '\0' */
+                  - 1 /* leading '-' */) / kHexCharsPerDigit;
+  const intptr_t chunk_length = length;
+  // Conservative check assuming leading bigint-digit also takes up
+  // kHexCharsPerDigit.
+  if (chunk_length > kMaxChunkLen) {
+    FATAL("Fatal error in BigintOperations::ToHexCString: string too long");
+  }
   Chunk* chunk_data = reinterpret_cast<Chunk*>(data);
   if (length == 0) {
     const char* zero = "0x0";
-    const int kLength = strlen(zero);
+    const intptr_t kLength = strlen(zero);
     char* result = reinterpret_cast<char*>(allocator(kLength + 1));
     ASSERT(result != NULL);
     memmove(result, zero, kLength);
@@ -330,7 +351,7 @@
   const intptr_t kMaxAllowedDigitLength =
       (kIntptrMax - 10) / kLog2Dividend / kDigitBitSize * kLog2Divisor;
 
-  intptr_t length = bigint.Length();
+  const intptr_t length = bigint.Length();
   Isolate* isolate = Isolate::Current();
   if (length >= kMaxAllowedDigitLength) {
     // Use the preallocated out of memory exception to avoid calling
@@ -365,25 +386,18 @@
   ASSERT(pow(10.0, kChunkDigits) == kChunkDivisor);
   ASSERT(static_cast<Chunk>(kChunkDivisor) < kDigitMaxValue);
   ASSERT(Smi::IsValid(kChunkDivisor));
-  const Bigint& divisor = Bigint::Handle(NewFromInt64(kChunkDivisor));
+  const Chunk divisor = static_cast<Chunk>(kChunkDivisor);
 
   // Rest contains the remaining bigint that needs to be printed.
-  Bigint& rest = Bigint::Handle(bigint.raw());
-  Bigint& quotient = Bigint::Handle();
-  Bigint& remainder = Bigint::Handle();
+  const Bigint& rest = Bigint::Handle(Copy(bigint));
   while (!rest.IsZero()) {
-    HANDLESCOPE(isolate);
-    DivideRemainder(rest, divisor, &quotient, &remainder);
-    ASSERT(remainder.Length() <= 1);
-    intptr_t part = (remainder.Length() == 1)
-        ? static_cast<intptr_t>(remainder.GetChunkAt(0))
-        : 0;
+    Chunk remainder = InplaceUnsignedDivideRemainderDigit(rest, divisor);
+    intptr_t part = static_cast<intptr_t>(remainder);
     for (int i = 0; i < kChunkDigits; i++) {
       result[result_pos++] = '0' + (part % 10);
       part /= 10;
     }
     ASSERT(part == 0);
-    rest = quotient.raw();
   }
   // Move the resulting position back until we don't have any zeroes anymore.
   // This is done so that we can remove all leading zeroes.
@@ -1341,7 +1355,10 @@
   // given string has it's lsd at the last position.
   // The hex_i index, pointing into the string, starts therefore at the end,
   // whereas the bigint-index (i) starts at 0.
-  intptr_t hex_length = strlen(hex_string);
+  const intptr_t hex_length = strlen(hex_string);
+  if (hex_length < 0) {
+    FATAL("Fatal error in BigintOperations::FromHexCString: string too long");
+  }
   intptr_t hex_i = hex_length - 1;
   for (intptr_t i = 0; i < bigint_length; i++) {
     Chunk digit = 0;
@@ -1572,6 +1589,22 @@
     return;
   }
 
+  intptr_t b_length = b.Length();
+
+  if (b_length == 1) {
+    const Bigint& dividend_quotient = Bigint::Handle(Copy(a));
+    Chunk remainder_digit =
+        BigintOperations::InplaceUnsignedDivideRemainderDigit(
+            dividend_quotient, b.GetChunkAt(0));
+    dividend_quotient.SetSign(a.IsNegative() != b.IsNegative());
+    *quotient = dividend_quotient.raw();
+    *remainder = Bigint::Allocate(1);
+    remainder->SetChunkAt(0, remainder_digit);
+    remainder->SetSign(a.IsNegative());
+    Clamp(*remainder);
+    return;
+  }
+
   // High level description:
   // The algorithm is basically the algorithm that is taught in school:
   // Let a the dividend and b the divisor. We are looking for
@@ -1590,7 +1623,6 @@
   //
   // Instead of working in base 10 we work in base kDigitBitSize.
 
-  intptr_t b_length = b.Length();
   int normalization_shift =
       kDigitBitSize - CountBits(b.GetChunkAt(b_length - 1));
   Bigint& dividend = Bigint::Handle(ShiftLeft(a, normalization_shift));
@@ -1724,6 +1756,24 @@
 }
 
 
+BigintOperations::Chunk BigintOperations::InplaceUnsignedDivideRemainderDigit(
+    const Bigint& dividend_quotient, Chunk divisor_digit) {
+  Chunk remainder = 0;
+  for (intptr_t i = dividend_quotient.Length() - 1; i >= 0; i--) {
+    DoubleChunk dividend_digit =
+        (static_cast<DoubleChunk>(remainder) << kDigitBitSize) +
+        dividend_quotient.GetChunkAt(i);
+    Chunk quotient_digit = static_cast<Chunk>(dividend_digit / divisor_digit);
+    remainder = static_cast<Chunk>(
+        dividend_digit -
+        static_cast<DoubleChunk>(quotient_digit) * divisor_digit);
+    dividend_quotient.SetChunkAt(i, quotient_digit);
+  }
+  Clamp(dividend_quotient);
+  return remainder;
+}
+
+
 void BigintOperations::Clamp(const Bigint& bigint) {
   intptr_t length = bigint.Length();
   while (length > 0 && (bigint.GetChunkAt(length - 1) == 0)) {
diff --git a/runtime/vm/bigint_operations.h b/runtime/vm/bigint_operations.h
index b38bc41..54c2416 100644
--- a/runtime/vm/bigint_operations.h
+++ b/runtime/vm/bigint_operations.h
@@ -140,6 +140,8 @@
   }
   static void DivideRemainder(const Bigint& a, const Bigint& b,
                               Bigint* quotient, Bigint* remainder);
+  static Chunk InplaceUnsignedDivideRemainderDigit(
+      const Bigint& dividend_quotient, Chunk divisor_digit);
 
   // Removes leading zero-chunks by adjusting the bigint's length.
   static void Clamp(const Bigint& bigint);
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 2cf1ac1..e85053a 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -95,4 +95,20 @@
   }
 }
 
+
+void ClassTable::PrintToJSONStream(JSONStream* stream) {
+  Class& cls = Class::Handle();
+  JSONObject jsobj(stream);
+  jsobj.AddProperty("type", "ClassList");
+  {
+    JSONArray members(&jsobj, "members");
+    for (intptr_t i = 1; i < top_; i++) {
+      if (HasValidClassAt(i)) {
+        cls = At(i);
+        members.AddValue(cls);
+      }
+    }
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 8fe8159..6ea4dfa 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -13,6 +13,7 @@
 class Class;
 class ObjectPointerVisitor;
 class RawClass;
+class JSONStream;
 
 class ClassTable {
  public:
@@ -41,6 +42,8 @@
 
   void Print();
 
+  void PrintToJSONStream(JSONStream* stream);
+
   static intptr_t table_offset() {
     return OFFSET_OF(ClassTable, table_);
   }
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 1f2d1c2..2527c3b 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -270,7 +270,9 @@
     LongJump bailout_jump;
     isolate->set_long_jump_base(&bailout_jump);
     if (setjmp(*bailout_jump.Set()) == 0) {
+      FlowGraphBuilder* builder = NULL;
       FlowGraph* flow_graph = NULL;
+      GrowableArray<const Field*> guarded_fields;
       // TimerScope needs an isolate to be properly terminated in case of a
       // LongJump.
       {
@@ -290,11 +292,12 @@
         }
 
         // Build the flow graph.
-        FlowGraphBuilder builder(parsed_function,
-                                 ic_data_array,
-                                 NULL,  // NULL = not inlining.
-                                 osr_id);
-        flow_graph = builder.BuildGraph();
+        builder = new FlowGraphBuilder(parsed_function,
+                                       ic_data_array,
+                                       NULL,  // NULL = not inlining.
+                                       &guarded_fields,
+                                       osr_id);
+        flow_graph = builder->BuildGraph();
       }
 
       if (FLAG_print_flow_graph ||
@@ -326,13 +329,12 @@
       // Collect all instance fields that are loaded in the graph and
       // have non-generic type feedback attached to them that can
       // potentially affect optimizations.
-      GrowableArray<const Field*> guarded_fields(10);
       if (optimized) {
         TimerScope timer(FLAG_compiler_stats,
                          &CompilerStats::graphoptimizer_timer,
                          isolate);
 
-        FlowGraphOptimizer optimizer(flow_graph, &guarded_fields);
+        FlowGraphOptimizer optimizer(flow_graph);
         optimizer.ApplyICData();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
@@ -358,7 +360,7 @@
           optimizer.ApplyClassIds();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-          FlowGraphInliner inliner(flow_graph, &guarded_fields);
+          FlowGraphInliner inliner(flow_graph);
           inliner.Inline();
           // Use lists are maintained and validated by the inliner.
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index c3bc011..a88df07 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -230,6 +230,11 @@
   // Different objects.
   EXPECT_VALID(Dart_ObjectEquals(five, seven, &equal));
   EXPECT(!equal);
+
+  // Case where identity is not equality.
+  Dart_Handle nan = Dart_NewDouble(NAN);
+  EXPECT_VALID(Dart_ObjectEquals(nan, nan, &equal));
+  EXPECT(!equal);
 }
 
 
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 54fbb01..adca206 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -1018,7 +1018,7 @@
 }
 
 
-RawDeoptInfo* DeoptInfoBuilder::CreateDeoptInfo() {
+RawDeoptInfo* DeoptInfoBuilder::CreateDeoptInfo(const Array& deopt_table) {
   // TODO(vegorov): enable compression of deoptimization info containing object
   // materialization instructions.
   const bool disable_compression =
@@ -1054,14 +1054,17 @@
     node = new TrieNode(instr, current_info_number_);
     node->AddChild(child);
   }
-  suffix->AddChild(node);
 
   if (suffix_length > 1) {
+    suffix->AddChild(node);
     DeoptInstr* instr =
         new DeoptSuffixInstr(suffix->info_number(), suffix_length);
     deopt_info.SetAt(length - 1, instr->kind(), instr->from_index());
+  } else {
+    trie_root_->AddChild(node);
   }
 
+  ASSERT(deopt_info.VerifyDecompression(instructions_, deopt_table));
   instructions_.Clear();
   materializations_.Clear();
   frame_start_ = -1;
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index a7c8ab9..564b744 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -202,7 +202,7 @@
   // Returns the index of the next stack slot. Used for verification.
   intptr_t EmitMaterializationArguments(intptr_t to_index);
 
-  RawDeoptInfo* CreateDeoptInfo();
+  RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table);
 
   // Mark the actual start of the frame description after all materialization
   // instructions were emitted. Used for verification purposes.
diff --git a/runtime/vm/disassembler_ia32.cc b/runtime/vm/disassembler_ia32.cc
index 9272794..69e5ed0 100644
--- a/runtime/vm/disassembler_ia32.cc
+++ b/runtime/vm/disassembler_ia32.cc
@@ -240,6 +240,7 @@
     case 0xA5: return "shld";
     case 0xAD: return "shrd";
     case 0xAB: return "bts";
+    case 0xBD: return "bsr";
     case 0xB1: return "cmpxchg";
     case 0x50: return "movmskps";
     case 0x51: return "sqrtps";
@@ -1301,7 +1302,7 @@
         } else if ((f0byte & 0xF0) == 0x80) {
           data += JumpConditional(data, branch_hint);
         } else if (f0byte == 0xBE || f0byte == 0xBF || f0byte == 0xB6 ||
-                   f0byte == 0xB7 || f0byte == 0xAF) {
+                   f0byte == 0xB7 || f0byte == 0xAF || f0byte == 0xBD) {
           data += 2;
           data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data);
         } else if (f0byte == 0x57) {
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index e7f4293..e0a71b0 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -24,6 +24,7 @@
   : parent_(),
     current_ssa_temp_index_(0),
     max_block_id_(max_block_id),
+    builder_(builder),
     parsed_function_(*builder.parsed_function()),
     num_copied_params_(builder.num_copied_params()),
     num_non_copied_params_(builder.num_non_copied_params()),
@@ -97,6 +98,20 @@
 }
 
 
+Instruction* FlowGraph::AppendTo(Instruction* prev,
+                                 Instruction* instr,
+                                 Environment* env,
+                                 Definition::UseKind use_kind) {
+  if (use_kind == Definition::kValue) {
+    ASSERT(instr->IsDefinition());
+    instr->AsDefinition()->set_ssa_temp_index(alloc_ssa_temp_index());
+  }
+  ASSERT(instr->env() == NULL);
+  if (env != NULL) env->DeepCopyTo(instr);
+  return prev->AppendInstruction(instr);
+}
+
+
 void FlowGraph::DiscoverBlocks() {
   // Initialize state.
   preorder_.Clear();
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 34112c6..7b4be08be 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -48,6 +48,10 @@
             GraphEntryInstr* graph_entry,
             intptr_t max_block_id);
 
+  const FlowGraphBuilder& builder() const {
+    return builder_;
+  }
+
   // Function properties.
   const ParsedFunction& parsed_function() const {
     return parsed_function_;
@@ -124,6 +128,10 @@
                    Instruction* instr,
                    Environment* env,
                    Definition::UseKind use_kind);
+  Instruction* AppendTo(Instruction* prev,
+                        Instruction* instr,
+                        Environment* env,
+                        Definition::UseKind use_kind);
 
   // Operations on the flow graph.
   void ComputeSSA(intptr_t next_virtual_register_number,
@@ -242,6 +250,7 @@
   intptr_t max_block_id_;
 
   // Flow graph fields.
+  const FlowGraphBuilder& builder_;
   const ParsedFunction& parsed_function_;
   const intptr_t num_copied_params_;
   const intptr_t num_non_copied_params_;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 78efd46..42a4ffa 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -45,6 +45,7 @@
 FlowGraphBuilder::FlowGraphBuilder(ParsedFunction* parsed_function,
                                    const Array& ic_data_array,
                                    InlineExitCollector* exit_collector,
+                                   GrowableArray<const Field*>* guarded_fields,
                                    intptr_t osr_id)
   : parsed_function_(parsed_function),
     ic_data_array_(ic_data_array),
@@ -55,6 +56,7 @@
         : 0),
     num_stack_locals_(parsed_function->num_stack_locals()),
     exit_collector_(exit_collector),
+    guarded_fields_(guarded_fields),
     last_used_block_id_(0),  // 0 is used for the graph entry.
     context_level_(0),
     try_index_(CatchClauseNode::kInvalidTryIndex),
@@ -70,6 +72,20 @@
 }
 
 
+void FlowGraphBuilder::AddToGuardedFields(const Field& field) const {
+  if ((field.guarded_cid() == kDynamicCid) ||
+      (field.guarded_cid() == kIllegalCid)) {
+    return;
+  }
+  for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
+    if ((*guarded_fields_)[j]->raw() == field.raw()) {
+      return;
+    }
+  }
+  guarded_fields_->Add(&field);
+}
+
+
 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
   ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
   ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
@@ -3039,6 +3055,17 @@
       node->field().Offset(),
       AbstractType::ZoneHandle(node->field().type()));
   load->set_field(&node->field());
+  if (owner()->exit_collector() != NULL) {
+    // While inlining into an optimized function, the field has
+    // to be added to the list of guarded fields of the caller.
+    if (node->field().guarded_cid() != kIllegalCid) {
+      if (!node->field().is_nullable() ||
+          (node->field().guarded_cid() == kNullCid)) {
+        load->set_result_cid(node->field().guarded_cid());
+      }
+      owner()->AddToGuardedFields(node->field());
+    }
+  }
   ReturnDefinition(load);
 }
 
@@ -3768,7 +3795,7 @@
   TargetEntryInstr* normal_entry =
       new TargetEntryInstr(AllocateBlockId(),
                            CatchClauseNode::kInvalidTryIndex);
-  graph_entry_ = new GraphEntryInstr(*parsed_function(), normal_entry, osr_id_);
+  graph_entry_ = new GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
   EffectGraphVisitor for_effect(this, 0);
   // This check may be deleted if the generated code is leaf.
   // Native functions don't need a stack check at entry.
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index e3d01c3..2b9f455 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -20,21 +20,21 @@
 // (factory-name-symbol, result-cid, fingerprint).
 // TODO(srdjan): Store the values in the snapshot instead.
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(ObjectArrayFactory, kArrayCid, 1930677134)                                 \
-  V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 1012992871)          \
-  V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1707369421)           \
-  V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 1340298556)                     \
-  V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1775618642)                   \
-  V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 264668024)      \
-  V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 1095249987)                   \
-  V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 1275304272)                 \
-  V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 523449884)                    \
-  V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 458531362)                  \
-  V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1753070829)                   \
-  V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 1561660391)                 \
-  V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 245916452)                \
-  V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 368082071)                \
-  V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 1674296969)           \
+  V(ObjectArrayFactory, kArrayCid, 1558200848)                                 \
+  V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 619965861)           \
+  V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 1180134731)           \
+  V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 810750844)                      \
+  V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1246070930)                   \
+  V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1882603960)     \
+  V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 565702275)                    \
+  V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 745756560)                  \
+  V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 2141385820)                   \
+  V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 2076467298)                 \
+  V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1223523117)                   \
+  V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 1032112679)                 \
+  V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 1863852388)               \
+  V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 1986018007)               \
+  V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 1144749257)           \
 
 
 // A class to collect the exits from an inlined function during graph
@@ -98,13 +98,14 @@
 
 
 // Build a flow graph from a parsed function's AST.
-class FlowGraphBuilder: public ValueObject {
+class FlowGraphBuilder: public ZoneAllocated {
  public:
   // The inlining context is NULL if not inlining.  The osr_id is the deopt
   // id of the OSR entry or Isolate::kNoDeoptId if not compiling for OSR.
   FlowGraphBuilder(ParsedFunction* parsed_function,
                    const Array& ic_data_array,
                    InlineExitCollector* exit_collector,
+                   GrowableArray<const Field*>* guarded_fields,
                    intptr_t osr_id);
 
   FlowGraph* BuildGraph();
@@ -147,6 +148,12 @@
   bool IsInlining() const { return (exit_collector_ != NULL); }
   InlineExitCollector* exit_collector() const { return exit_collector_; }
 
+  GrowableArray<const Field*>* guarded_fields() const {
+    return guarded_fields_;
+  }
+
+  void AddToGuardedFields(const Field& field) const;
+
   intptr_t args_pushed() const { return args_pushed_; }
   void add_args_pushed(intptr_t n) { args_pushed_ += n; }
 
@@ -169,6 +176,7 @@
   const intptr_t num_non_copied_params_;
   const intptr_t num_stack_locals_;  // Does not include any parameters.
   InlineExitCollector* const exit_collector_;
+  GrowableArray<const Field*>* guarded_fields_;
 
   intptr_t last_used_block_id_;
   intptr_t context_level_;
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index fbe3484..42df32d 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -468,7 +468,7 @@
   Smi& reason = Smi::Handle();
   for (intptr_t i = 0; i < deopt_infos_.length(); i++) {
     offset = Smi::New(deopt_infos_[i]->pc_offset());
-    info = deopt_infos_[i]->CreateDeoptInfo(this, &builder);
+    info = deopt_infos_[i]->CreateDeoptInfo(this, &builder, array);
     reason = Smi::New(deopt_infos_[i]->reason());
     DeoptTable::SetEntry(array, i, offset, info, reason);
   }
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 3d174c2..f53ad0f 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -120,7 +120,8 @@
   }
 
   RawDeoptInfo* CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                DeoptInfoBuilder* builder);
+                                DeoptInfoBuilder* builder,
+                                const Array& deopt_table);
 
 
   // No code needs to be generated.
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 0854649..7353b27 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -44,7 +44,8 @@
 
 
 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder) {
+                                                 DeoptInfoBuilder* builder,
+                                                 const Array& deopt_table) {
   if (deopt_env_ == NULL) return DeoptInfo::null();
 
   intptr_t stack_height = compiler->StackSize();
@@ -133,7 +134,8 @@
     builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
   }
 
-  const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
+  const DeoptInfo& deopt_info =
+      DeoptInfo::Handle(builder->CreateDeoptInfo(deopt_table));
   return deopt_info.raw();
 }
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 151ca9f..2ea07d5 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -48,7 +48,8 @@
 
 
 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder) {
+                                                 DeoptInfoBuilder* builder,
+                                                 const Array& deopt_table) {
   if (deopt_env_ == NULL) return DeoptInfo::null();
 
   intptr_t stack_height = compiler->StackSize();
@@ -132,7 +133,8 @@
     builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
   }
 
-  const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
+  const DeoptInfo& deopt_info =
+      DeoptInfo::Handle(builder->CreateDeoptInfo(deopt_table));
   return deopt_info.raw();
 }
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 8e51051..03b0a9a 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -44,7 +44,8 @@
 
 
 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder) {
+                                                 DeoptInfoBuilder* builder,
+                                                 const Array& deopt_table) {
   if (deopt_env_ == NULL) return DeoptInfo::null();
 
   intptr_t stack_height = compiler->StackSize();
@@ -133,7 +134,8 @@
     builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
   }
 
-  const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
+  const DeoptInfo& deopt_info =
+      DeoptInfo::Handle(builder->CreateDeoptInfo(deopt_table));
   return deopt_info.raw();
 }
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index e08d1ab..d3c4095 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -45,7 +45,8 @@
 
 
 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
-                                                 DeoptInfoBuilder* builder) {
+                                                 DeoptInfoBuilder* builder,
+                                                 const Array& deopt_table) {
   if (deopt_env_ == NULL) return DeoptInfo::null();
 
   intptr_t stack_height = compiler->StackSize();
@@ -129,7 +130,8 @@
     builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
   }
 
-  const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
+  const DeoptInfo& deopt_info =
+      DeoptInfo::Handle(builder->CreateDeoptInfo(deopt_table));
   return deopt_info.raw();
 }
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 692c0f8..f58a97b 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -364,6 +364,7 @@
   bool CheckNonInlinedDuplicate(const Function& target);
 
   bool TryInlining(const Function& target);
+  bool TryInlineRecognizedMethod(const Function& target);
 
   TargetEntryInstr* BuildDecisionGraph();
 
@@ -381,8 +382,7 @@
 
 class CallSiteInliner : public ValueObject {
  public:
-  CallSiteInliner(FlowGraph* flow_graph,
-                  GrowableArray<const Field*>* guarded_fields)
+  explicit CallSiteInliner(FlowGraph* flow_graph)
       : caller_graph_(flow_graph),
         inlined_(false),
         initial_size_(flow_graph->InstructionCount()),
@@ -390,8 +390,7 @@
         inlining_depth_(1),
         collected_call_sites_(NULL),
         inlining_call_sites_(NULL),
-        function_cache_(),
-        guarded_fields_(guarded_fields) { }
+        function_cache_() { }
 
   FlowGraph* caller_graph() const { return caller_graph_; }
 
@@ -543,17 +542,19 @@
       // Build the callee graph.
       InlineExitCollector* exit_collector =
           new InlineExitCollector(caller_graph_, call);
-      FlowGraphBuilder builder(parsed_function,
-                               ic_data_array,
-                               exit_collector,
-                               Isolate::kNoDeoptId);
-      builder.SetInitialBlockId(caller_graph_->max_block_id());
+      GrowableArray<const Field*> inlined_guarded_fields;
+      FlowGraphBuilder* builder = new FlowGraphBuilder(parsed_function,
+                                                       ic_data_array,
+                                                       exit_collector,
+                                                       &inlined_guarded_fields,
+                                                       Isolate::kNoDeoptId);
+      builder->SetInitialBlockId(caller_graph_->max_block_id());
       FlowGraph* callee_graph;
       {
         TimerScope timer(FLAG_compiler_stats,
                          &CompilerStats::graphinliner_build_timer,
                          isolate);
-        callee_graph = builder.BuildGraph();
+        callee_graph = builder->BuildGraph();
       }
 
       // The parameter stubs are a copy of the actual arguments providing
@@ -606,7 +607,7 @@
                          &CompilerStats::graphinliner_opt_timer,
                          isolate);
         // TODO(zerny): Do more optimization passes on the callee graph.
-        FlowGraphOptimizer optimizer(callee_graph, guarded_fields_);
+        FlowGraphOptimizer optimizer(callee_graph);
         optimizer.ApplyICData();
         DEBUG_ASSERT(callee_graph->VerifyUseLists());
       }
@@ -667,6 +668,13 @@
       call_data->callee_graph = callee_graph;
       call_data->parameter_stubs = param_stubs;
       call_data->exit_collector = exit_collector;
+
+      // When inlined, we add the guarded fields of the callee to the caller's
+      // list of guarded fields.
+      for (intptr_t i = 0; i < inlined_guarded_fields.length(); ++i) {
+        caller_graph_->builder().AddToGuardedFields(*inlined_guarded_fields[i]);
+      }
+
       TRACE_INLINING(OS::Print("     Success\n"));
       return true;
     } else {
@@ -681,6 +689,8 @@
   }
 
  private:
+  friend class PolymorphicInliner;
+
   void InlineCall(InlinedCallData* call_data) {
     TimerScope timer(FLAG_compiler_stats,
                      &CompilerStats::graphinliner_subst_timer,
@@ -995,7 +1005,6 @@
   CallSites* collected_call_sites_;
   CallSites* inlining_call_sites_;
   GrowableArray<ParsedFunction*> function_cache_;
-  GrowableArray<const Field*>* guarded_fields_;
 
   DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
 };
@@ -1083,8 +1092,13 @@
 
 bool PolymorphicInliner::TryInlining(const Function& target) {
   if (!target.is_optimizable()) {
+    if (TryInlineRecognizedMethod(target)) {
+      owner_->inlined_ = true;
+      return true;
+    }
     return false;
   }
+
   GrowableArray<Value*> arguments(call_->ArgumentCount());
   for (int i = 0; i < call_->ArgumentCount(); ++i) {
     arguments.Add(call_->PushArgumentAt(i)->value());
@@ -1144,6 +1158,41 @@
 }
 
 
+bool PolymorphicInliner::TryInlineRecognizedMethod(const Function& target) {
+  FlowGraphOptimizer optimizer(owner_->caller_graph());
+  TargetEntryInstr* entry;
+  Definition* last;
+  if (optimizer.TryInlineRecognizedMethod(target,
+                                          call_,
+                                          call_->ic_data(),
+                                          &entry, &last)) {
+    // Create a graph fragment.
+    InlineExitCollector* exit_collector =
+        new InlineExitCollector(owner_->caller_graph(), call_);
+
+    ReturnInstr* result =
+        new ReturnInstr(call_->instance_call()->token_pos(),
+                        new Value(last));
+    owner_->caller_graph()->AppendTo(
+        last,
+        result,
+        call_->env(),  // Return can become deoptimization target.
+        Definition::kEffect);
+    entry->set_last_instruction(result);
+    exit_collector->AddExit(result);
+    GraphEntryInstr* graph_entry =
+        new GraphEntryInstr(NULL,  // No parsed function.
+                            entry,
+                            Isolate::kNoDeoptId);  // No OSR id.
+    // Update polymorphic inliner state.
+    inlined_entries_.Add(graph_entry);
+    exit_collector_->Union(exit_collector);
+    return true;
+  }
+  return false;
+}
+
+
 // Build a DAG to dispatch to the inlined function bodies.  Load the class
 // id of the receiver and make explicit comparisons for each inlined body,
 // in frequency order.  If all variants are inlined, the entry to the last
@@ -1431,7 +1480,7 @@
     printer.PrintBlocks();
   }
 
-  CallSiteInliner inliner(flow_graph_, guarded_fields_);
+  CallSiteInliner inliner(flow_graph_);
   inliner.InlineCalls();
 
   if (inliner.inlined()) {
diff --git a/runtime/vm/flow_graph_inliner.h b/runtime/vm/flow_graph_inliner.h
index 57318e3..dfee0d5 100644
--- a/runtime/vm/flow_graph_inliner.h
+++ b/runtime/vm/flow_graph_inliner.h
@@ -15,9 +15,7 @@
 
 class FlowGraphInliner : ValueObject {
  public:
-  FlowGraphInliner(FlowGraph* flow_graph,
-                   GrowableArray<const Field*>* guarded_fields)
-      : flow_graph_(flow_graph), guarded_fields_(guarded_fields) {}
+  explicit FlowGraphInliner(FlowGraph* flow_graph) : flow_graph_(flow_graph) { }
 
   // The flow graph is destructively updated upon inlining.
   void Inline();
@@ -26,7 +24,6 @@
 
  private:
   FlowGraph* flow_graph_;
-  GrowableArray<const Field*>* guarded_fields_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphInliner);
 };
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 53f4450..44aad69 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -160,6 +160,7 @@
       Object::empty_array(),  // Dummy argument descriptor.
       ic_data.deopt_id(),
       ic_data.num_args_tested()));
+  new_ic_data.set_deopt_reason(ic_data.deopt_reason());
 
   const Function& function =
       Function::Handle(ic_data.GetTargetForReceiverClassId(cid));
@@ -789,7 +790,6 @@
                call->env(),
                Definition::kEffect);
 
-
   if (class_id == kGrowableObjectArrayCid) {
     // Insert data elements load.
     LoadFieldInstr* elements =
@@ -996,11 +996,187 @@
 }
 
 
+static intptr_t MethodKindToCid(MethodRecognizer::Kind kind) {
+  switch (kind) {
+    case MethodRecognizer::kImmutableArrayGetIndexed:
+      return kImmutableArrayCid;
+
+    case MethodRecognizer::kObjectArrayGetIndexed:
+      return kArrayCid;
+
+    case MethodRecognizer::kGrowableArrayGetIndexed:
+      return kGrowableObjectArrayCid;
+
+    case MethodRecognizer::kFloat32ArrayGetIndexed:
+      return kTypedDataFloat32ArrayCid;
+
+    case MethodRecognizer::kFloat64ArrayGetIndexed:
+      return kTypedDataFloat64ArrayCid;
+
+    case MethodRecognizer::kInt8ArrayGetIndexed:
+      return kTypedDataInt8ArrayCid;
+
+    case MethodRecognizer::kUint8ArrayGetIndexed:
+      return kTypedDataUint8ArrayCid;
+
+    case MethodRecognizer::kUint8ClampedArrayGetIndexed:
+      return kTypedDataUint8ClampedArrayCid;
+
+    case MethodRecognizer::kExternalUint8ArrayGetIndexed:
+      return kExternalTypedDataUint8ArrayCid;
+
+    case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
+      return kExternalTypedDataUint8ClampedArrayCid;
+
+    case MethodRecognizer::kInt16ArrayGetIndexed:
+      return kTypedDataInt16ArrayCid;
+
+    case MethodRecognizer::kUint16ArrayGetIndexed:
+      return kTypedDataUint16ArrayCid;
+
+    case MethodRecognizer::kInt32ArrayGetIndexed:
+      return kTypedDataInt32ArrayCid;
+
+    case MethodRecognizer::kUint32ArrayGetIndexed:
+      return kTypedDataUint32ArrayCid;
+
+    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+      return kTypedDataFloat32x4ArrayCid;
+
+    default:
+      break;
+  }
+  return kIllegalCid;
+}
+
+
+bool FlowGraphOptimizer::TryInlineRecognizedMethod(const Function& target,
+                                                   Instruction* call,
+                                                   const ICData& ic_data,
+                                                   TargetEntryInstr** entry,
+                                                   Definition** last) {
+  MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target);
+  switch (kind) {
+    case MethodRecognizer::kImmutableArrayGetIndexed:
+    case MethodRecognizer::kObjectArrayGetIndexed:
+    case MethodRecognizer::kGrowableArrayGetIndexed:
+    case MethodRecognizer::kFloat32ArrayGetIndexed:
+    case MethodRecognizer::kFloat64ArrayGetIndexed:
+    case MethodRecognizer::kInt8ArrayGetIndexed:
+    case MethodRecognizer::kUint8ArrayGetIndexed:
+    case MethodRecognizer::kUint8ClampedArrayGetIndexed:
+    case MethodRecognizer::kExternalUint8ArrayGetIndexed:
+    case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed:
+    case MethodRecognizer::kInt16ArrayGetIndexed:
+    case MethodRecognizer::kUint16ArrayGetIndexed:
+    case MethodRecognizer::kInt32ArrayGetIndexed:
+    case MethodRecognizer::kUint32ArrayGetIndexed:
+    case MethodRecognizer::kFloat32x4ArrayGetIndexed:
+      return TryInlineGetIndexed(kind, call, ic_data, entry, last);
+    default:
+      return false;
+  }
+}
+
+
+bool FlowGraphOptimizer::TryInlineGetIndexed(MethodRecognizer::Kind kind,
+                                             Instruction* call,
+                                             const ICData& ic_data,
+                                             TargetEntryInstr** entry,
+                                             Definition** last) {
+  intptr_t array_cid = MethodKindToCid(kind);
+  ASSERT(array_cid != kIllegalCid);
+
+  // Insert index smi checks and attach a copy of the
+  // original environment because the operation can still deoptimize.
+  Definition* array = call->ArgumentAt(0);
+  Definition* index = call->ArgumentAt(1);
+  *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
+                                call->GetBlock()->try_index());
+  (*entry)->InheritDeoptTarget(call);
+
+  Instruction* cursor = *entry;
+  cursor = flow_graph()->AppendTo(cursor,
+                                  new CheckSmiInstr(new Value(index),
+                                                    call->deopt_id()),
+                                  call->env(),
+                                  Definition::kEffect);
+
+  // Insert array length load and bounds check.
+  const bool is_immutable =
+      CheckArrayBoundInstr::IsFixedLengthArrayType(array_cid);
+  LoadFieldInstr* length =
+      new LoadFieldInstr(new Value(array),
+                         CheckArrayBoundInstr::LengthOffsetFor(array_cid),
+                         Type::ZoneHandle(Type::SmiType()),
+                         is_immutable);
+  length->set_result_cid(kSmiCid);
+  length->set_recognized_kind(
+      LoadFieldInstr::RecognizedKindFromArrayCid(array_cid));
+  cursor = flow_graph()->AppendTo(cursor,
+                                  length,
+                                  NULL,
+                                  Definition::kValue);
+
+  cursor = flow_graph()->AppendTo(cursor,
+                                  new CheckArrayBoundInstr(
+                                      new Value(length),
+                                      new Value(index),
+                                      call->deopt_id()),
+                                  call->env(),
+                                  Definition::kEffect);
+
+  if (array_cid == kGrowableObjectArrayCid) {
+    // Insert data elements load.
+    LoadFieldInstr* elements =
+        new LoadFieldInstr(new Value(array),
+                           GrowableObjectArray::data_offset(),
+                           Type::ZoneHandle(Type::DynamicType()));
+    elements->set_result_cid(kArrayCid);
+    cursor = flow_graph()->AppendTo(cursor,
+                                    elements,
+                                    NULL,
+                                    Definition::kValue);
+    // Load from the data from backing store which is a fixed-length array.
+    array = elements;
+    array_cid = kArrayCid;
+  } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    LoadUntaggedInstr* elements =
+        new LoadUntaggedInstr(new Value(array),
+                              ExternalTypedData::data_offset());
+    cursor = flow_graph()->AppendTo(cursor,
+                                    elements,
+                                    NULL,
+                                    Definition::kValue);
+    array = elements;
+  }
+
+  intptr_t deopt_id = Isolate::kNoDeoptId;
+  if ((array_cid == kTypedDataInt32ArrayCid) ||
+      (array_cid == kTypedDataUint32ArrayCid)) {
+    // Set deopt_id if we can optimistically assume that the result is Smi.
+    // Assume mixed Mint/Smi if this instruction caused deoptimization once.
+    deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ?
+        call->deopt_id() : Isolate::kNoDeoptId;
+  }
+
+  // Array load and return.
+  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
+  *last = new LoadIndexedInstr(new Value(array),
+                               new Value(index),
+                               index_scale,
+                               array_cid,
+                               deopt_id);
+  flow_graph()->AppendTo(cursor,
+                         *last,
+                         deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
+                         Definition::kValue);
+  return true;
+}
+
 
 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
   const intptr_t class_id = ReceiverClassId(call);
-  // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt.
-  intptr_t deopt_id = Isolate::kNoDeoptId;
   switch (class_id) {
     case kArrayCid:
     case kImmutableArrayCid:
@@ -1021,31 +1197,43 @@
       }
       break;
     case kTypedDataInt32ArrayCid:
-    case kTypedDataUint32ArrayCid: {
+    case kTypedDataUint32ArrayCid:
         if (!CanUnboxInt32()) return false;
-
-        // Set deopt_id if we can optimistically assume that the result is Smi.
-        // Assume mixed Mint/Smi if this instruction caused deoptimization once.
-        ASSERT(call->HasICData());
-        const ICData& ic_data = *call->ic_data();
-        deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ?
-            call->deopt_id() : Isolate::kNoDeoptId;
-      }
       break;
     default:
       return false;
   }
-  Definition* array = call->ArgumentAt(0);
-  Definition* index = call->ArgumentAt(1);
-  intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index);
-  intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
-  Definition* array_op =
-      new LoadIndexedInstr(new Value(array),
-                           new Value(index),
-                           index_scale,
-                           array_cid,
-                           deopt_id);
-  ReplaceCall(call, array_op);
+
+  const Function& target =
+      Function::Handle(call->ic_data()->GetTargetAt(0));
+  TargetEntryInstr* entry;
+  Definition* last;
+  ASSERT(class_id == MethodKindToCid(MethodRecognizer::RecognizeKind(target)));
+  bool success = TryInlineRecognizedMethod(target,
+                                           call,
+                                           *call->ic_data(),
+                                           &entry, &last);
+  ASSERT(success);
+  // Insert receiver class check.
+  AddReceiverCheck(call);
+  // Remove the original push arguments.
+  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+    PushArgumentInstr* push = call->PushArgumentAt(i);
+    push->ReplaceUsesWith(push->value()->definition());
+    push->RemoveFromGraph();
+  }
+  // Replace all uses of this definition with the result.
+  call->ReplaceUsesWith(last);
+  // Finally insert the sequence other definition in place of this one in the
+  // graph.
+  call->previous()->LinkTo(entry->next());
+  entry->UnuseAllInputs();  // Entry block is not in the graph.
+  last->LinkTo(call);
+  // Remove through the iterator.
+  ASSERT(current_iterator()->Current() == call);
+  current_iterator()->RemoveCurrentFromGraph();
+  call->set_previous(NULL);
+  call->set_next(NULL);
   return true;
 }
 
@@ -1382,20 +1570,6 @@
 }
 
 
-void FlowGraphOptimizer::AddToGuardedFields(const Field& field) {
-  if ((field.guarded_cid() == kDynamicCid) ||
-      (field.guarded_cid() == kIllegalCid)) {
-    return;
-  }
-  for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
-    if ((*guarded_fields_)[j]->raw() == field.raw()) {
-      return;
-    }
-  }
-  guarded_fields_->Add(&field);
-}
-
-
 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
   const ICData& ic_data = *call->ic_data();
@@ -1422,7 +1596,7 @@
     if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
       load->set_result_cid(field.guarded_cid());
     }
-    AddToGuardedFields(field);
+    flow_graph_->builder().AddToGuardedFields(field);
   }
 
   // Discard the environment from the original instruction because the load
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 4243eba..8c9f6fe 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -16,11 +16,9 @@
 
 class FlowGraphOptimizer : public FlowGraphVisitor {
  public:
-  FlowGraphOptimizer(FlowGraph* flow_graph,
-                     GrowableArray<const Field*>* guarded_fields)
+  explicit FlowGraphOptimizer(FlowGraph* flow_graph)
       : FlowGraphVisitor(flow_graph->reverse_postorder()),
-        flow_graph_(flow_graph),
-        guarded_fields_(guarded_fields) { }
+        flow_graph_(flow_graph) { }
   virtual ~FlowGraphOptimizer() {}
 
   FlowGraph* flow_graph() const { return flow_graph_; }
@@ -46,6 +44,12 @@
 
   void AnalyzeTryCatch();
 
+  bool TryInlineRecognizedMethod(const Function& target,
+                                 Instruction* call,
+                                 const ICData& ic_data,
+                                 TargetEntryInstr** entry,
+                                 Definition** last);
+
   // Remove environments from the instructions which do not deoptimize.
   void EliminateEnvironments();
 
@@ -77,6 +81,11 @@
                          const ICData& value_check,
                          intptr_t class_id);
   bool TryReplaceWithLoadIndexed(InstanceCallInstr* call);
+  bool TryInlineGetIndexed(MethodRecognizer::Kind kind,
+                           Instruction* call,
+                           const ICData& ic_data,
+                           TargetEntryInstr** entry,
+                           Definition** last);
 
   bool TryReplaceWithBinaryOp(InstanceCallInstr* call, Token::Kind op_kind);
   bool TryReplaceWithUnaryOp(InstanceCallInstr* call, Token::Kind op_kind);
@@ -185,10 +194,7 @@
                                     Definition* left_instr,
                                     Definition* right_instr);
 
-  void AddToGuardedFields(const Field& field);
-
   FlowGraph* flow_graph_;
-  GrowableArray<const Field*>* guarded_fields_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer);
 };
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 355949f..147ea56 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -265,7 +265,7 @@
 }
 
 
-GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function,
+GraphEntryInstr::GraphEntryInstr(const ParsedFunction* parsed_function,
                                  TargetEntryInstr* normal_entry,
                                  intptr_t osr_id)
     : BlockEntryInstr(0, CatchClauseNode::kInvalidTryIndex),
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 33cde45..84e9f9d 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -39,11 +39,11 @@
 // See intrinsifier for fingerprint computation.
 #define RECOGNIZED_LIST(V)                                                     \
   V(::, identical, ObjectIdentical, 496869842)                                 \
-  V(Object, Object., ObjectConstructor, 1058525712)                            \
-  V(Object, get:_cid, ObjectCid, 1498661928)                                   \
-  V(_ObjectArray, get:length, ObjectArrayLength, 259323113)                    \
-  V(_ImmutableArray, get:length, ImmutableArrayLength, 1341942416)             \
-  V(_TypedList, get:length, TypedDataLength, 26556746)                         \
+  V(Object, Object., ObjectConstructor, 1058585294)                            \
+  V(Object, get:_cid, ObjectCid, 1498721510)                                   \
+  V(_ObjectArray, get:length, ObjectArrayLength, 259382695)                    \
+  V(_ImmutableArray, get:length, ImmutableArrayLength, 1342001998)             \
+  V(_TypedList, get:length, TypedDataLength, 26616328)                         \
   V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 272598802)                     \
   V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 831354841)                   \
   V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1832126257)                  \
@@ -53,25 +53,25 @@
   V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 185163470)               \
   V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1356392173)              \
   V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1239681356)          \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 742201367)                     \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1163140155)                  \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1106354531)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 545390027)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1963924310)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 724748139)                 \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 756330666)               \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1495546688)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 560495357)           \
-  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160357614)         \
-  V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 1509781988)    \
-  V(_GrowableObjectArray, _setData, GrowableArraySetData, 236295352)           \
-  V(_GrowableObjectArray, _setLength, GrowableArraySetLength, 1922121178)      \
-  V(_StringBase, get:length, StringBaseLength, 1483460481)                     \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1588094430)                   \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1443265945)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1864204733)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1807419109)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 1246454605)                \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 517505240)                   \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1425812717)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1457395244)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 49127618)                \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1261559935)          \
+  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160417196)         \
+  V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 1509841570)    \
+  V(_GrowableObjectArray, _setData, GrowableArraySetData, 1574432374)          \
+  V(_GrowableObjectArray, _setLength, GrowableArraySetLength, 1112774552)      \
+  V(_StringBase, get:length, StringBaseLength, 1483520063)                     \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 879849436)                    \
   V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1958436584)                 \
-  V(_StringBase, [], StringBaseCharAt, 1799392702)                             \
-  V(_OneByteString, _setAt, OneByteStringSetAt, 1754827784)                    \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 2141284842)             \
+  V(_StringBase, [], StringBaseCharAt, 990046076)                              \
+  V(_OneByteString, _setAt, OneByteStringSetAt, 308408714)                     \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 2011998508)             \
   V(_IntegerImplementation, _leftShiftWithMask32, IntegerLeftShiftWithMask32,  \
       2095943661)                                                              \
   V(_Double, toInt, DoubleToInteger, 1328149975)                               \
@@ -83,18 +83,18 @@
   V(::, sqrt, MathSqrt, 465520247)                                             \
   V(::, sin, MathSin, 730107143)                                               \
   V(::, cos, MathCos, 1282146521)                                              \
-  V(::, min, MathMin, 1584022354)                                              \
-  V(::, max, MathMax, 328632232)                                               \
-  V(::, _doublePow, MathDoublePow, 2002448359)                                 \
-  V(Float32x4, Float32x4., Float32x4Constructor, 1876089990)                   \
-  V(Float32x4, Float32x4.zero, Float32x4Zero, 1903586222)                      \
-  V(Float32x4, Float32x4.splat, Float32x4Splat, 38462589)                      \
+  V(::, min, MathMin, 1602283410)                                              \
+  V(::, max, MathMax, 997766696)                                               \
+  V(::, _doublePow, MathDoublePow, 1728171041)                                 \
+  V(Float32x4, Float32x4., Float32x4Constructor, 786169160)                    \
+  V(Float32x4, Float32x4.zero, Float32x4Zero, 1589383280)                      \
+  V(Float32x4, Float32x4.splat, Float32x4Splat, 62513275)                    \
   V(_Float32x4, shuffle, Float32x4Shuffle, 1178727105)                         \
-  V(_Float32x4, get:x, Float32x4ShuffleX, 1351658256)                          \
-  V(_Float32x4, get:y, Float32x4ShuffleY, 217326828)                           \
-  V(_Float32x4, get:z, Float32x4ShuffleZ, 2144864139)                          \
-  V(_Float32x4, get:w, Float32x4ShuffleW, 1447639537)                          \
-  V(_Float32x4, get:signMask, Float32x4GetSignMask, 1198789765)                \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 1351717838)                          \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 217386410)                           \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 2144923721)                          \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 1447699119)                          \
+  V(_Float32x4, get:signMask, Float32x4GetSignMask, 1198849347)                \
   V(_Float32x4, _cmpequal, Float32x4Equal, 2141256163)                         \
   V(_Float32x4, _cmpgt, Float32x4GreaterThan, 696292270)                       \
   V(_Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 1199333164)              \
@@ -120,30 +120,46 @@
   V(_Float32x4, interleaveZW, Float32x4InterleaveZW, 928280031)                \
   V(_Float32x4, interleaveXYPairs, Float32x4InterleaveXYPairs, 1046078993)     \
   V(_Float32x4, interleaveZWPairs, Float32x4InterleaveZWPairs, 1001751955)     \
-  V(Uint32x4, Uint32x4.bool, Uint32x4BoolConstructor, 733327933)               \
-  V(_Uint32x4, get:flagX, Uint32x4GetFlagX, 1674637210)                        \
-  V(_Uint32x4, get:flagY, Uint32x4GetFlagY, 2013140570)                        \
-  V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 944674353)                         \
-  V(_Uint32x4, get:flagW, Uint32x4GetFlagW, 22686587)                          \
-  V(_Uint32x4, get:signMask, Uint32x4GetSignMask, 1858084501)                  \
-  V(_Uint32x4, select, Uint32x4Select, 881590808)                              \
+  V(Uint32x4, Uint32x4.bool, Uint32x4BoolConstructor, 517444095)               \
+  V(_Uint32x4, get:flagX, Uint32x4GetFlagX, 1674696792)                        \
+  V(_Uint32x4, get:flagY, Uint32x4GetFlagY, 2013200152)                        \
+  V(_Uint32x4, get:flagZ, Uint32x4GetFlagZ, 944733935)                         \
+  V(_Uint32x4, get:flagW, Uint32x4GetFlagW, 22746169)                          \
+  V(_Uint32x4, get:signMask, Uint32x4GetSignMask, 1858144083)                  \
+  V(_Uint32x4, select, Uint32x4Select, 72244182)                               \
   V(_Uint32x4, withFlagX, Uint32x4WithFlagX, 1475542073)                       \
   V(_Uint32x4, withFlagY, Uint32x4WithFlagY, 830610988)                        \
   V(_Uint32x4, withFlagZ, Uint32x4WithFlagZ, 1714792414)                       \
   V(_Uint32x4, withFlagW, Uint32x4WithFlagW, 1516924162)                       \
   V(_Uint32x4, _toFloat32x4, Uint32x4ToUint32x4, 2054503505)                   \
+  V(_ObjectArray, [], ObjectArrayGetIndexed, 544020319)                        \
+  V(_ImmutableArray, [], ImmutableArrayGetIndexed, 1345387065)                 \
+  V(_GrowableObjectArray, [], GrowableArrayGetIndexed, 951312767)              \
+  V(_Float32Array, [], Float32ArrayGetIndexed, 1225286513)                     \
+  V(_Float64Array, [], Float64ArrayGetIndexed, 871118335)                      \
+  V(_Int8Array, [], Int8ArrayGetIndexed, 199925538)                            \
+  V(_Uint8Array, [], Uint8ArrayGetIndexed, 502448555)                          \
+  V(_Uint8ClampedArray, [], Uint8ClampedArrayGetIndexed, 1292893603)           \
+  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 1831383216)         \
+  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
+    1831906095)                                                                \
+  V(_Int16Array, [], Int16ArrayGetIndexed, 1191799443)                         \
+  V(_Uint16Array, [], Uint16ArrayGetIndexed, 814177144)                        \
+  V(_Int32Array, [], Int32ArrayGetIndexed, 787321640)                          \
+  V(_Uint32Array, [], Uint32ArrayGetIndexed, 1421922726)                       \
+  V(_Float32x4Array, [], Float32x4ArrayGetIndexed, 1901126825)                 \
 
 
 // A list of core function that should always be inlined.
 #define INLINE_WHITE_LIST(V)                                                   \
-  V(_ObjectArray, get:length, ObjectArrayLength, 259323113)                    \
-  V(_ImmutableArray, get:length, ImmutableArrayLength, 1341942416)             \
-  V(_TypedList, get:length, TypedDataLength, 26556746)                         \
-  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160357614)         \
-  V(_StringBase, get:length, StringBaseLength, 1483460481)                     \
-  V(ListIterator, moveNext, ListIteratorMoveNext, 657540761)                   \
-  V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 281980741)      \
-  V(_GrowableObjectArray, forEach, GrowableArrayForEach, 334448248)
+  V(_ObjectArray, get:length, ObjectArrayLength, 259382695)                    \
+  V(_ImmutableArray, get:length, ImmutableArrayLength, 1342001998)             \
+  V(_TypedList, get:length, TypedDataLength, 26616328)                         \
+  V(_GrowableObjectArray, get:length, GrowableArrayLength, 1160417196)         \
+  V(_StringBase, get:length, StringBaseLength, 1483520063)                     \
+  V(ListIterator, moveNext, ListIteratorMoveNext, 90930587)                    \
+  V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 2129691657)     \
+  V(_GrowableObjectArray, forEach, GrowableArrayForEach, 1669274418)
 
 
 // Class that recognizes the name and owner of a function and returns the
@@ -1326,7 +1342,7 @@
 
 class GraphEntryInstr : public BlockEntryInstr {
  public:
-  GraphEntryInstr(const ParsedFunction& parsed_function,
+  GraphEntryInstr(const ParsedFunction* parsed_function,
                   TargetEntryInstr* normal_entry,
                   intptr_t osr_id);
 
@@ -1371,7 +1387,7 @@
   TargetEntryInstr* normal_entry() const { return normal_entry_; }
 
   const ParsedFunction& parsed_function() const {
-    return parsed_function_;
+    return *parsed_function_;
   }
 
   const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const {
@@ -1384,7 +1400,7 @@
   virtual void ClearPredecessors() {}
   virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
 
-  const ParsedFunction& parsed_function_;
+  const ParsedFunction* parsed_function_;
   TargetEntryInstr* normal_entry_;
   GrowableArray<CatchBlockEntryInstr*> catch_entries_;
   GrowableArray<Definition*> initial_definitions_;
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 9b54c7f..de6d92e 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -16,83 +16,83 @@
 // When adding a new function for intrinsification add a 0 as fingerprint,
 // build and run to get the correct fingerprint from the mismatch error.
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 635678453)                                         \
-  V(_Smi, get:bitLength, Smi_bitLength, 383357874)                             \
-  V(_Double, >, Double_greaterThan, 1021232334)                                \
-  V(_Double, >=, Double_greaterEqualThan, 324955595)                           \
-  V(_Double, <, Double_lessThan, 978151157)                                    \
-  V(_Double, <=, Double_lessEqualThan, 1169397675)                             \
-  V(_Double, ==, Double_equal, 223604237)                                      \
-  V(_Double, +, Double_add, 295873577)                                         \
-  V(_Double, -, Double_sub, 1180117486)                                        \
-  V(_Double, *, Double_mul, 1999983053)                                        \
-  V(_Double, /, Double_div, 1904009451)                                        \
-  V(_Double, get:isNaN, Double_getIsNaN, 916506740)                            \
-  V(_Double, get:isNegative, Double_getIsNegative, 1711332287)                 \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 930284178)                \
-  V(_Double, .fromInteger, Double_fromInteger, 475441744)                      \
-  V(_ObjectArray, ., ObjectArray_Allocate, 1930677134)                         \
-  V(_ObjectArray, get:length, Array_getLength, 259323113)                      \
-  V(_ObjectArray, [], Array_getIndexed, 1353366945)                            \
-  V(_ObjectArray, []=, Array_setIndexed, 1492559642)                           \
-  V(_GrowableObjectArray, .withData, GrowableArray_Allocate, 1012992871)       \
-  V(_GrowableObjectArray, get:length, GrowableArray_getLength, 1160357614)     \
-  V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 1509781988)\
-  V(_GrowableObjectArray, [], GrowableArray_getIndexed, 1760659393)            \
-  V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 407626503)            \
-  V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 1922121178)     \
-  V(_GrowableObjectArray, _setData, GrowableArray_setData, 236295352)          \
-  V(_GrowableObjectArray, add, GrowableArray_add, 1442410650)                  \
-  V(_ImmutableArray, [], ImmutableArray_getIndexed, 7250043)                   \
-  V(_ImmutableArray, get:length, ImmutableArray_getLength, 1341942416)         \
-  V(Object, ==, Object_equal, 677817295)                                       \
-  V(_StringBase, get:hashCode, String_getHashCode, 654483446)                  \
-  V(_StringBase, get:isEmpty, String_getIsEmpty, 1588094430)                   \
-  V(_StringBase, get:length, String_getLength, 1483460481)                     \
+  V(_Smi, ~, Smi_bitNegate, 692936755)                                         \
+  V(_Smi, get:bitLength, Smi_bitLength, 383417456)                             \
+  V(_Double, >, Double_greaterThan, 1187341070)                                \
+  V(_Double, >=, Double_greaterEqualThan, 1770896399)                          \
+  V(_Double, <, Double_lessThan, 1238163699)                                   \
+  V(_Double, <=, Double_lessEqualThan, 467854831)                              \
+  V(_Double, ==, Double_equal, 1917937673)                                     \
+  V(_Double, +, Double_add, 461982313)                                         \
+  V(_Double, -, Double_sub, 1346226222)                                        \
+  V(_Double, *, Double_mul, 18608141)                                          \
+  V(_Double, /, Double_div, 2070118187)                                        \
+  V(_Double, get:isNaN, Double_getIsNaN, 916566322)                            \
+  V(_Double, get:isNegative, Double_getIsNegative, 1711391869)                 \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 1238321808)               \
+  V(_Double, .fromInteger, Double_fromInteger, 82414734)                       \
+  V(_ObjectArray, ., ObjectArray_Allocate, 1558200848)                         \
+  V(_ObjectArray, get:length, Array_getLength, 259382695)                      \
+  V(_ObjectArray, [], Array_getIndexed, 544020319)                             \
+  V(_ObjectArray, []=, Array_setIndexed, 304306010)                            \
+  V(_GrowableObjectArray, .withData, GrowableArray_Allocate, 619965861)        \
+  V(_GrowableObjectArray, get:length, GrowableArray_getLength, 1160417196)     \
+  V(_GrowableObjectArray, get:_capacity, GrowableArray_getCapacity, 1509841570)\
+  V(_GrowableObjectArray, [], GrowableArray_getIndexed, 951312767)             \
+  V(_GrowableObjectArray, []=, GrowableArray_setIndexed, 1366856519)           \
+  V(_GrowableObjectArray, _setLength, GrowableArray_setLength, 1112774552)     \
+  V(_GrowableObjectArray, _setData, GrowableArray_setData, 1574432374)         \
+  V(_GrowableObjectArray, add, GrowableArray_add, 635801182)                   \
+  V(_ImmutableArray, [], ImmutableArray_getIndexed, 1345387065)                \
+  V(_ImmutableArray, get:length, ImmutableArray_getLength, 1342001998)         \
+  V(Object, ==, Object_equal, 936042315)                                       \
+  V(_StringBase, get:hashCode, String_getHashCode, 654543028)                  \
+  V(_StringBase, get:isEmpty, String_getIsEmpty, 879849436)                    \
+  V(_StringBase, get:length, String_getLength, 1483520063)                     \
   V(_StringBase, codeUnitAt, String_codeUnitAt, 1958436584)                    \
-  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1236404434)       \
+  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 1236464016)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
       OneByteString_substringUnchecked, 25652388)                              \
-  V(_OneByteString, _setAt, OneByteString_setAt, 1754827784)                   \
-  V(_OneByteString, _allocate, OneByteString_allocate, 1064009711)             \
+  V(_OneByteString, _setAt, OneByteString_setAt, 308408714)                    \
+  V(_OneByteString, _allocate, OneByteString_allocate, 1744068081)             \
 
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
   V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
     740884607)                                                                 \
-  V(_IntegerImplementation, +, Integer_add, 714540399)                         \
+  V(_IntegerImplementation, +, Integer_add, 772815665)                         \
   V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
     584777821)                                                                 \
-  V(_IntegerImplementation, -, Integer_sub, 1880284412)                        \
+  V(_IntegerImplementation, -, Integer_sub, 1938559678)                        \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
     1757603756)                                                                \
-  V(_IntegerImplementation, *, Integer_mul, 1935440252)                        \
-  V(_IntegerImplementation, remainder, Integer_remainder, 2140653009)          \
+  V(_IntegerImplementation, *, Integer_mul, 1993715518)                        \
+  V(_IntegerImplementation, remainder, Integer_remainder, 1331308305)          \
   V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
     1398988805)                                                                \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 250357385)                \
-  V(_IntegerImplementation, unary-, Integer_negate, 732448114)                 \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 41718791)                 \
+  V(_IntegerImplementation, unary-, Integer_negate, 341268208)                 \
   V(_IntegerImplementation, _bitAndFromInteger,                                \
     Integer_bitAndFromInteger, 512285096)                                      \
-  V(_IntegerImplementation, &, Integer_bitAnd, 1677634910)                     \
+  V(_IntegerImplementation, &, Integer_bitAnd, 1735910176)                     \
   V(_IntegerImplementation, _bitOrFromInteger,                                 \
     Integer_bitOrFromInteger, 333543947)                                       \
-  V(_IntegerImplementation, |, Integer_bitOr, 1062616305)                      \
+  V(_IntegerImplementation, |, Integer_bitOr, 1120891571)                      \
   V(_IntegerImplementation, _bitXorFromInteger,                                \
     Integer_bitXorFromInteger, 1746295953)                                     \
-  V(_IntegerImplementation, ^, Integer_bitXor, 2111001841)                     \
+  V(_IntegerImplementation, ^, Integer_bitXor, 21793459)                       \
   V(_IntegerImplementation,                                                    \
     _greaterThanFromInteger,                                                   \
     Integer_greaterThanFromInt, 1883218996)                                    \
-  V(_IntegerImplementation, >, Integer_greaterThan, 195542579)                 \
-  V(_IntegerImplementation, ==, Integer_equal, 288044426)                      \
+  V(_IntegerImplementation, >, Integer_greaterThan, 253817845)                 \
+  V(_IntegerImplementation, ==, Integer_equal, 1899239372)                     \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
     111745915)                                                                 \
-  V(_IntegerImplementation, <, Integer_lessThan, 1133694259)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 1724243945)             \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 879801865)           \
-  V(_IntegerImplementation, <<, Integer_shl, 1508088336)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 1786839625)                       \
+  V(_IntegerImplementation, <, Integer_lessThan, 1393706801)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 1022701101)             \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 178259021)           \
+  V(_IntegerImplementation, <<, Integer_shl, 1566363602)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 1845114891)                       \
   V(_Double, toInt, Double_toInt, 1328149975)
 
 
@@ -100,35 +100,35 @@
   V(::, sqrt, Math_sqrt, 465520247)                                            \
   V(::, sin, Math_sin, 730107143)                                              \
   V(::, cos, Math_cos, 1282146521)                                             \
-  V(_Random, _nextState, Random_nextState, 1088413969)                         \
+  V(_Random, _nextState, Random_nextState, 1145672271)                         \
 
 
 #define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
-  V(_TypedList, get:length, TypedData_getLength, 26556746)                     \
-  V(_Int8Array, _new, TypedData_Int8Array_new, 1145746295)                     \
-  V(_Uint8Array, _new, TypedData_Uint8Array_new, 1097983968)                   \
-  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 2036179275)     \
-  V(_Int16Array, _new, TypedData_Int16Array_new, 1550281862)                   \
-  V(_Uint16Array, _new, TypedData_Uint16Array_new, 381457023)                  \
-  V(_Int32Array, _new, TypedData_Int32Array_new, 1331503368)                   \
-  V(_Uint32Array, _new, TypedData_Uint32Array_new, 2068855037)                 \
-  V(_Int64Array, _new, TypedData_Int64Array_new, 2608399)                      \
-  V(_Uint64Array, _new, TypedData_Uint64Array_new, 1855520143)                 \
-  V(_Float32Array, _new, TypedData_Float32Array_new, 1251124964)               \
-  V(_Float64Array, _new, TypedData_Float64Array_new, 1439361428)               \
-  V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 1902726893)           \
-  V(_Int8Array, ., TypedData_Int8Array_factory, 1340298556)                    \
-  V(_Uint8Array, ., TypedData_Uint8Array_factory, 1775618642)                  \
-  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 264668024)     \
-  V(_Int16Array, ., TypedData_Int16Array_factory, 1095249987)                  \
-  V(_Uint16Array, ., TypedData_Uint16Array_factory, 1275304272)                \
-  V(_Int32Array, ., TypedData_Int32Array_factory, 523449884)                   \
-  V(_Uint32Array, ., TypedData_Uint32Array_factory, 458531362)                 \
-  V(_Int64Array, ., TypedData_Int64Array_factory, 1753070829)                  \
-  V(_Uint64Array, ., TypedData_Uint64Array_factory, 1561660391)                \
-  V(_Float32Array, ., TypedData_Float32Array_factory, 368082071)               \
-  V(_Float64Array, ., TypedData_Float64Array_factory, 245916452)               \
-  V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 1674296969)          \
+  V(_TypedList, get:length, TypedData_getLength, 26616328)                     \
+  V(_Int8Array, _new, TypedData_Int8Array_new, 1825804665)                     \
+  V(_Uint8Array, _new, TypedData_Uint8Array_new, 1778042338)                   \
+  V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 568753997)      \
+  V(_Int16Array, _new, TypedData_Int16Array_new, 82856584)                     \
+  V(_Uint16Array, _new, TypedData_Uint16Array_new, 1061515393)                 \
+  V(_Int32Array, _new, TypedData_Int32Array_new, 2011561738)                   \
+  V(_Uint32Array, _new, TypedData_Uint32Array_new, 601429759)                  \
+  V(_Int64Array, _new, TypedData_Int64Array_new, 682666769)                    \
+  V(_Uint64Array, _new, TypedData_Uint64Array_new, 388094865)                  \
+  V(_Float32Array, _new, TypedData_Float32Array_new, 1931183334)               \
+  V(_Float64Array, _new, TypedData_Float64Array_new, 2119419798)               \
+  V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 435301615)            \
+  V(_Int8Array, ., TypedData_Int8Array_factory, 810750844)                     \
+  V(_Uint8Array, ., TypedData_Uint8Array_factory, 1246070930)                  \
+  V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 1882603960)    \
+  V(_Int16Array, ., TypedData_Int16Array_factory, 565702275)                   \
+  V(_Uint16Array, ., TypedData_Uint16Array_factory, 745756560)                 \
+  V(_Int32Array, ., TypedData_Int32Array_factory, 2141385820)                  \
+  V(_Uint32Array, ., TypedData_Uint32Array_factory, 2076467298)                \
+  V(_Int64Array, ., TypedData_Int64Array_factory, 1223523117)                  \
+  V(_Uint64Array, ., TypedData_Uint64Array_factory, 1032112679)                \
+  V(_Float32Array, ., TypedData_Float32Array_factory, 1986018007)              \
+  V(_Float64Array, ., TypedData_Float64Array_factory, 1863852388)              \
+  V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 1144749257)          \
 
 // TODO(srdjan): Implement _FixedSizeArrayIterator, get:current and
 //   _FixedSizeArrayIterator, moveNext.
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index cdfa888..83180be 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -915,11 +915,12 @@
 // can be Smi, Mint, Bigint or double.
 void Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
   Label fall_through, true_label, check_for_mint;
+  const intptr_t kReceiverOffset = 2;
+  const intptr_t kArgumentOffset = 1;
+
   // For integer receiver '===' check first.
-  // Entering a dart frame so we can use the PP for loading True and False.
-  __ EnterDartFrame(0);
-  __ movq(RAX, Address(RSP, + 4 * kWordSize));
-  __ movq(RCX, Address(RSP, + 5 * kWordSize));
+  __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
+  __ movq(RCX, Address(RSP, + kReceiverOffset * kWordSize));
   __ cmpq(RAX, RCX);
   __ j(EQUAL, &true_label, Assembler::kNearJump);
   __ orq(RAX, RCX);
@@ -927,28 +928,25 @@
   __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
   // Both arguments are smi, '===' is good enough.
   __ LoadObject(RAX, Bool::False(), PP);
-  __ LeaveFrameWithPP();
   __ ret();
   __ Bind(&true_label);
   __ LoadObject(RAX, Bool::True(), PP);
-  __ LeaveFrameWithPP();
   __ ret();
 
   // At least one of the arguments was not Smi.
   Label receiver_not_smi;
   __ Bind(&check_for_mint);
-  __ movq(RAX, Address(RSP, + 5 * kWordSize));  // Receiver.
+  __ movq(RAX, Address(RSP, + kReceiverOffset * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &receiver_not_smi);
 
   // Left (receiver) is Smi, return false if right is not Double.
   // Note that an instance of Mint or Bigint never contains a value that can be
   // represented by Smi.
-  __ movq(RAX, Address(RSP, + 4 * kWordSize));
+  __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
   __ CompareClassId(RAX, kDoubleCid);
   __ j(EQUAL, &fall_through);
   __ LoadObject(RAX, Bool::False(), PP);
-  __ LeaveFrameWithPP();
   __ ret();
 
   __ Bind(&receiver_not_smi);
@@ -956,17 +954,15 @@
   __ CompareClassId(RAX, kMintCid);
   __ j(NOT_EQUAL, &fall_through);
   // Receiver is Mint, return false if right is Smi.
-  __ movq(RAX, Address(RSP, + 4 * kWordSize));  // Right argument.
+  __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
   __ testq(RAX, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &fall_through);
   // Smi == Mint -> false.
   __ LoadObject(RAX, Bool::False(), PP);
-  __ LeaveFrameWithPP();
   __ ret();
   // TODO(srdjan): Implement Mint == Mint comparison.
 
   __ Bind(&fall_through);
-  __ LeaveFrameWithPP();
 }
 
 
@@ -1351,24 +1347,19 @@
   __ ret();
 }
 
-
 // Identity comparison.
 void Intrinsifier::Object_equal(Assembler* assembler) {
   Label is_true;
-  // This intrinsic is used from the API even when we have not entered any
-  // Dart frame, yet, so the PP would otherwise be null in this case unless
-  // we enter a Dart frame here.
-  __ EnterDartFrame(0);
-  __ movq(RAX, Address(RSP, + 4 * kWordSize));
-  __ cmpq(RAX, Address(RSP, + 5 * kWordSize));
+  const intptr_t kReceiverOffset = 2;
+  const intptr_t kArgumentOffset = 1;
+
+  __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize));
+  __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize));
   __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ movq(RAX, Immediate(reinterpret_cast<int64_t>(Bool::False().raw())));
   __ LoadObject(RAX, Bool::False(), PP);
-  __ LeaveFrameWithPP();
   __ ret();
   __ Bind(&is_true);
   __ LoadObject(RAX, Bool::True(), PP);
-  __ LeaveFrameWithPP();
   __ ret();
 }
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c3d31e7..85f0f08 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2926,15 +2926,48 @@
 
 
 void Class::PrintToJSONStream(JSONStream* stream, bool ref) const {
-  const char* class_name = String::Handle(UserVisibleName()).ToCString();
-  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
-  intptr_t id = ring->GetIdForObject(raw());
   JSONObject jsobj(stream);
+  if ((raw() == Class::null()) || (id() == kFreeListElement)) {
+    jsobj.AddProperty("type", "Null");
+    return;
+  }
+  const char* internal_class_name = String::Handle(Name()).ToCString();
+  const char* user_visible_class_name =
+      String::Handle(UserVisibleName()).ToCString();
   jsobj.AddProperty("type", JSONType(ref));
-  jsobj.AddProperty("id", id);
-  jsobj.AddProperty("name", class_name);
+  jsobj.AddProperty("id", id());
+  jsobj.AddProperty("name", internal_class_name);
+  jsobj.AddProperty("user_name", user_visible_class_name);
   if (!ref) {
+    jsobj.AddProperty("implemented", is_implemented());
+    jsobj.AddProperty("abstract", is_abstract());
+    jsobj.AddProperty("patch", is_patch());
+    jsobj.AddProperty("finalized", is_finalized());
+    jsobj.AddProperty("const", is_const());
+    jsobj.AddProperty("super", Class::Handle(SuperClass()));
     jsobj.AddProperty("library", Object::Handle(library()));
+    {
+      JSONArray fields_array(&jsobj, "fields");
+      const Array& field_array = Array::Handle(fields());
+      Field& field = Field::Handle();
+      if (!field_array.IsNull()) {
+        for (intptr_t i = 0; i < field_array.Length(); ++i) {
+          field ^= field_array.At(i);
+          fields_array.AddValue(field);
+        }
+      }
+    }
+    {
+      JSONArray functions_array(&jsobj, "functions");
+      const Array& function_array = Array::Handle(functions());
+      Function& function = Function::Handle();
+      if (!function_array.IsNull()) {
+        for (intptr_t i = 0; i < function_array.Length(); i++) {
+          function ^= function_array.At(i);
+          functions_array.AddValue(function);
+        }
+      }
+    }
   }
 }
 
@@ -5090,6 +5123,7 @@
 
 
 void Function::PrintToJSONStream(JSONStream* stream, bool ref) const {
+  const char* internal_function_name = String::Handle(name()).ToCString();
   const char* function_name =
       String::Handle(QualifiedUserVisibleName()).ToCString();
   ObjectIdRing* ring = Isolate::Current()->object_id_ring();
@@ -5097,7 +5131,8 @@
   JSONObject jsobj(stream);
   jsobj.AddProperty("type", JSONType(ref));
   jsobj.AddProperty("id", id);
-  jsobj.AddProperty("name", function_name);
+  jsobj.AddProperty("name", internal_function_name);
+  jsobj.AddProperty("user_name", function_name);
   if (ref) return;
   jsobj.AddProperty("is_static", is_static());
   jsobj.AddProperty("is_const", is_const());
@@ -5412,6 +5447,44 @@
 
 void Field::PrintToJSONStream(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
+  const char* internal_field_name = String::Handle(name()).ToCString();
+  const char* field_name = String::Handle(UserVisibleName()).ToCString();
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  jsobj.AddProperty("type", JSONType(ref));
+  jsobj.AddProperty("id", id);
+  jsobj.AddProperty("name", internal_field_name);
+  jsobj.AddProperty("user_name", field_name);
+  if (ref) {
+    return;
+  }
+  Class& cls = Class::Handle(owner());
+  jsobj.AddProperty("type", "Field");
+  jsobj.AddProperty("id", id);
+  jsobj.AddProperty("name", internal_field_name);
+  jsobj.AddProperty("user_name", field_name);
+  jsobj.AddProperty("class", cls);
+  jsobj.AddProperty("static", is_static());
+  jsobj.AddProperty("final", is_final());
+  jsobj.AddProperty("const", is_const());
+  jsobj.AddProperty("guard_nullable", is_nullable());
+  if (guarded_cid() == kIllegalCid) {
+    jsobj.AddProperty("guard_class", "unknown");
+  } else if (guarded_cid() == kDynamicCid) {
+    jsobj.AddProperty("guard_class", "dynamic");
+  } else {
+    ClassTable* table = Isolate::Current()->class_table();
+    ASSERT(table->IsValidIndex(guarded_cid()));
+    cls ^= table->At(guarded_cid());
+    jsobj.AddProperty("guard_class", cls);
+  }
+  if (guarded_list_length() == kUnknownFixedLength) {
+    jsobj.AddProperty("guard_length", "unknown");
+  } else if (guarded_list_length() == kNoFixedLength) {
+    jsobj.AddProperty("guard_length", "variable");
+  } else {
+    jsobj.AddProperty("guard_length", guarded_list_length());
+  }
 }
 
 
@@ -6052,7 +6125,9 @@
 }
 
 
-TokenStream::Iterator::Iterator(const TokenStream& tokens, intptr_t token_pos)
+TokenStream::Iterator::Iterator(const TokenStream& tokens,
+                                intptr_t token_pos,
+                                Iterator::StreamType stream_type)
     : tokens_(TokenStream::Handle(tokens.raw())),
       data_(ExternalTypedData::Handle(tokens.GetStream())),
       stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()),
@@ -6060,7 +6135,8 @@
       obj_(Object::Handle()),
       cur_token_pos_(token_pos),
       cur_token_kind_(Token::kILLEGAL),
-      cur_token_obj_index_(-1) {
+      cur_token_obj_index_(-1),
+      stream_type_(stream_type) {
   SetCurrentPosition(token_pos);
 }
 
@@ -6092,7 +6168,10 @@
   intptr_t count = 0;
   while (count < num_tokens && value != Token::kEOS) {
     value = ReadToken();
-    count += 1;
+    if ((stream_type_ == kAllTokens) ||
+        (static_cast<Token::Kind>(value) != Token::kNEWLINE)) {
+      count += 1;
+    }
   }
   if (value < Token::kNumTokens) {
     kind = static_cast<Token::Kind>(value);
@@ -6124,8 +6203,12 @@
 
 
 void TokenStream::Iterator::Advance() {
-  cur_token_pos_ = stream_.Position();
-  intptr_t value = ReadToken();
+  intptr_t value;
+  do {
+    cur_token_pos_ = stream_.Position();
+    value = ReadToken();
+  } while ((stream_type_ == kNoNewlines) &&
+           (static_cast<Token::Kind>(value) == Token::kNEWLINE));
   if (value < Token::kNumTokens) {
     cur_token_kind_ = static_cast<Token::Kind>(value);
     cur_token_obj_index_ = -1;
@@ -7839,6 +7922,7 @@
   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
   all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
   RECOGNIZED_LIST(CHECK_FINGERPRINTS);
+  INLINE_WHITE_LIST(CHECK_FINGERPRINTS);
 
   all_libs.Clear();
   all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
@@ -8567,6 +8651,20 @@
 }
 
 
+// Returns a bool so it can be asserted.
+bool DeoptInfo::VerifyDecompression(const GrowableArray<DeoptInstr*>& original,
+                                    const Array& deopt_table) const {
+  intptr_t length = TranslationLength();
+  GrowableArray<DeoptInstr*> unpacked(length);
+  ToInstructions(deopt_table, &unpacked);
+  ASSERT(unpacked.length() == original.length());
+  for (intptr_t i = 0; i < unpacked.length(); ++i) {
+    ASSERT(unpacked[i]->Equals(*original[i]));
+  }
+  return true;
+}
+
+
 void DeoptInfo::PrintToJSONStream(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
 }
@@ -9573,6 +9671,7 @@
       Array::Handle(arguments_descriptor()),
       deopt_id(),
       kNumArgsTested));
+  result.set_deopt_reason(deopt_reason());
   const intptr_t len = NumberOfChecks();
   for (intptr_t i = 0; i < len; i++) {
     const intptr_t class_id = GetClassIdAt(i, arg_nr);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 56ce807..d5c8cad 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2175,7 +2175,14 @@
   // in a TokenStream object.
   class Iterator : ValueObject {
    public:
-    Iterator(const TokenStream& tokens, intptr_t token_pos);
+    enum StreamType {
+      kNoNewlines,
+      kAllTokens
+    };
+
+    Iterator(const TokenStream& tokens,
+                   intptr_t token_pos,
+                   Iterator::StreamType stream_type = kNoNewlines);
 
     void SetStream(const TokenStream& tokens, intptr_t token_pos);
     bool IsValid() const;
@@ -2212,6 +2219,7 @@
     intptr_t cur_token_pos_;
     Token::Kind cur_token_kind_;
     intptr_t cur_token_obj_index_;
+    Iterator::StreamType stream_type_;
   };
 
  private:
@@ -2940,6 +2948,12 @@
   void ToInstructions(const Array& table,
                       GrowableArray<DeoptInstr*>* instructions) const;
 
+
+  // Returns true iff decompression yields the same instructions as the
+  // original.
+  bool VerifyDecompression(const GrowableArray<DeoptInstr*>& original,
+                           const Array& deopt_table) const;
+
  private:
   intptr_t* EntryAddr(intptr_t index, intptr_t entry_offset) const {
     ASSERT((index >=0) && (index < Length()));
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 82a5d8d..dcb3bbe 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2080,8 +2080,8 @@
   EXPECT_EQ(0, first_idx);  // Token 'main' is first token.
   EXPECT_EQ(3, last_idx);   // Token { is last token.
   script.TokenRangeAtLine(5, &first_idx, &last_idx);
-  EXPECT_EQ(7, first_idx);  // Token } is first and only token.
-  EXPECT_EQ(7, last_idx);
+  EXPECT_EQ(9, first_idx);  // Token } is first and only token.
+  EXPECT_EQ(9, last_idx);
 }
 
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 81407aa..aeb31c6 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -1351,12 +1351,16 @@
 void Parser::SkipBlock() {
   ASSERT(CurrentToken() == Token::kLBRACE);
   GrowableArray<Token::Kind> token_stack(8);
+  // Adding the first kLBRACE here, because it will be consumed in the loop
+  // right away.
+  token_stack.Add(CurrentToken());
   const intptr_t block_start_pos = TokenPos();
   bool is_match = true;
   bool unexpected_token_found = false;
   Token::Kind token;
   intptr_t token_pos;
   do {
+    ConsumeToken();
     token = CurrentToken();
     token_pos = TokenPos();
     switch (token) {
@@ -1381,7 +1385,6 @@
         // nothing.
         break;
     }
-    ConsumeToken();
   } while (!token_stack.is_empty() && is_match && !unexpected_token_found);
   if (!is_match) {
     ErrorMsg(token_pos, "unbalanced '%s'", Token::Str(token));
@@ -1420,9 +1423,6 @@
     this_seen = true;
     parameter.is_field_initializer = true;
   }
-  if (params->implicitly_final) {
-    parameter.is_final = true;
-  }
   if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) {
     ConsumeToken();
     // This must later be changed to a closure type if we recognize
@@ -1582,6 +1582,9 @@
   if (parameter.type->IsVoidType()) {
     ErrorMsg("parameter '%s' may not be 'void'", parameter.name->ToCString());
   }
+  if (params->implicitly_final) {
+    parameter.is_final = true;
+  }
   params->parameters->Add(parameter);
 }
 
@@ -1897,7 +1900,7 @@
       negate_result = true;
     }
 
-    ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kBIT_OR));
+    ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kEQ));
     AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1);
 
     ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos);
@@ -2349,18 +2352,6 @@
   TRACE_PARSER("ParseInitializers");
   bool super_init_seen = false;
   if (CurrentToken() == Token::kCOLON) {
-    if ((LookaheadToken(1) == Token::kTHIS) &&
-        ((LookaheadToken(2) == Token::kLPAREN) ||
-        ((LookaheadToken(2) == Token::kPERIOD) &&
-            (LookaheadToken(4) == Token::kLPAREN)))) {
-      // Either we see this(...) or this.xxx(...) which is a
-      // redirected constructor. We don't need to check whether
-      // const fields are initialized. The other constructor will
-      // guarantee that.
-      ConsumeToken();  // Colon.
-      ParseConstructorRedirection(cls, receiver);
-      return;
-    }
     do {
       ConsumeToken();  // Colon or comma.
       AstNode* init_statement;
@@ -2388,6 +2379,7 @@
 void Parser::ParseConstructorRedirection(const Class& cls,
                                          LocalVariable* receiver) {
   TRACE_PARSER("ParseConstructorRedirection");
+  ExpectToken(Token::kCOLON);
   ASSERT(CurrentToken() == Token::kTHIS);
   const intptr_t call_pos = TokenPos();
   ConsumeToken();
@@ -2568,24 +2560,36 @@
   // Now populate function scope with the formal parameters.
   AddFormalParamsToScope(&params, current_block_->scope);
 
-  // Initialize instance fields that have an explicit initializer expression.
-  // The formal parameter names must not be visible to the instance
-  // field initializer expressions, yet the parameters must be added to
-  // the scope so the expressions use the correct offsets for 'this' when
-  // storing values. We make the formal parameters temporarily invisible
-  // while parsing the instance field initializer expressions.
-  params.SetInvisible(true);
-  GrowableArray<Field*> initialized_fields;
-  LocalVariable* receiver = current_block_->scope->VariableAt(0);
-  OpenBlock();
-  ParseInitializedInstanceFields(cls, receiver, &initialized_fields);
-  // Make the parameters (which are in the outer scope) visible again.
-  params.SetInvisible(false);
+  const bool is_redirecting_constructor =
+      (CurrentToken() == Token::kCOLON) &&
+          ((LookaheadToken(1) == Token::kTHIS) &&
+              ((LookaheadToken(2) == Token::kLPAREN) ||
+              ((LookaheadToken(2) == Token::kPERIOD) &&
+              (LookaheadToken(4) == Token::kLPAREN))));
 
-  // Turn formal field parameters into field initializers or report error
-  // if the function is not a constructor.
+  GrowableArray<Field*> initialized_fields;
+  LocalVariable* receiver = (*params.parameters)[0].var;
+  OpenBlock();
+
+  // If this is not a redirecting constructor, initialize
+  // instance fields that have an explicit initializer expression.
+  if (!is_redirecting_constructor) {
+    // The formal parameter names must not be visible to the instance
+    // field initializer expressions, yet the parameters must be added to
+    // the scope so the expressions use the correct offsets for 'this' when
+    // storing values. We make the formal parameters temporarily invisible
+    // while parsing the instance field initializer expressions.
+    params.SetInvisible(true);
+    ParseInitializedInstanceFields(cls, receiver, &initialized_fields);
+    // Make the parameters (which are in the outer scope) visible again.
+    params.SetInvisible(false);
+  }
+
+  // Turn formal field parameters into field initializers.
   if (params.has_field_initializer) {
-    for (int i = 0; i < params.parameters->length(); i++) {
+    // First two parameters are implicit receiver and phase.
+    ASSERT(params.parameters->length() >= 2);
+    for (int i = 2; i < params.parameters->length(); i++) {
       ParamDesc& param = (*params.parameters)[i];
       if (param.is_field_initializer) {
         const String& field_name = *param.name;
@@ -2595,6 +2599,11 @@
                    "unresolved reference to instance field '%s'",
                    field_name.ToCString());
         }
+        if (is_redirecting_constructor) {
+          ErrorMsg(param.name_pos,
+                   "redirecting constructors may not have "
+                   "initializing formal parameters");
+        }
         CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field);
         AstNode* instance = new LoadLocalNode(param.name_pos, receiver);
         // Initializing formals cannot be used in the explicit initializer
@@ -2612,8 +2621,11 @@
     }
   }
 
-  // Now parse the explicit initializer list or constructor redirection.
-  ParseInitializers(cls, receiver, &initialized_fields);
+  if (is_redirecting_constructor) {
+    ParseConstructorRedirection(cls, receiver);
+  } else {
+    ParseInitializers(cls, receiver, &initialized_fields);
+  }
 
   SequenceNode* init_statements = CloseBlock();
   if (init_statements->length() > 0) {
@@ -2660,6 +2672,11 @@
     // saves the evaluated actual arguments in temporary variables.
     // The temporary variables are necessary so that the argument
     // expressions are not evaluated twice.
+    // Note: we should never get here in the case of a redirecting
+    // constructor. In that case, the call to the target constructor
+    // is the "super call" and is implicitly at the end of the
+    // initializer list.
+    ASSERT(!is_redirecting_constructor);
     ArgumentListNode* ctor_args = super_call->arguments();
     // The super initializer call has at least 2 arguments: the
     // implicit receiver, and the hidden construction phase.
@@ -2719,6 +2736,9 @@
   }
 
   if (CurrentToken() == Token::kLBRACE) {
+    // We checked in the top-level parse phase that a redirecting
+    // constructor does not have a body.
+    ASSERT(!is_redirecting_constructor);
     ConsumeToken();
     ParseStatementSequence();
     ExpectToken(Token::kRBRACE);
@@ -2888,6 +2908,7 @@
   } else {
     UnexpectedToken();
   }
+
   ASSERT(func.end_token_pos() == func.token_pos() ||
          func.end_token_pos() == end_token_pos);
   func.set_end_token_pos(end_token_pos);
@@ -3171,12 +3192,14 @@
     }
     if (CurrentToken() == Token::kLBRACE) {
       SkipBlock();
+      method_end_pos = TokenPos();
+      ExpectToken(Token::kRBRACE);
     } else {
       ConsumeToken();
       SkipExpr();
+      method_end_pos = TokenPos();
       ExpectSemicolon();
     }
-    method_end_pos = TokenPos() - 1;
   } else if (IsLiteral("native")) {
     if (method->has_abstract) {
       ErrorMsg(method->name_pos,
@@ -3806,6 +3829,7 @@
     ErrorMsg("{ expected");
   }
   SkipBlock();
+  ExpectToken(Token::kRBRACE);
 }
 
 
@@ -4564,7 +4588,8 @@
     ExpectSemicolon();
   } else if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
-    function_end_pos = TokenPos() - 1;
+    function_end_pos = TokenPos();
+    ExpectToken(Token::kRBRACE);
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
     SkipExpr();
@@ -4692,7 +4717,8 @@
     ExpectSemicolon();
   } else if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
-    accessor_end_pos = TokenPos() - 1;
+    accessor_end_pos = TokenPos();
+    ExpectToken(Token::kRBRACE);
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
     SkipExpr();
@@ -7345,7 +7371,7 @@
 
 AstNode* Parser::ParseBinaryExpr(int min_preced) {
   TRACE_PARSER("ParseBinaryExpr");
-  ASSERT(min_preced >= 4);
+  ASSERT(min_preced >= Token::Precedence(Token::kOR));
   AstNode* left_operand = ParseUnaryExpr();
   if (left_operand->IsPrimaryNode() &&
       (left_operand->AsPrimaryNode()->IsSuper())) {
@@ -9561,6 +9587,50 @@
 }
 
 
+AstNode* Parser::ParseSymbolLiteral() {
+  ASSERT(CurrentToken() == Token::kHASH);
+  ConsumeToken();
+  intptr_t symbol_pos = TokenPos();
+  String& symbol = String::Handle();
+  if (IsIdentifier()) {
+    symbol = CurrentLiteral()->raw();
+    ConsumeToken();
+    while (CurrentToken() == Token::kPERIOD) {
+      symbol = String::Concat(symbol, Symbols::Dot());
+      ConsumeToken();
+      symbol = String::Concat(symbol,
+                              *ExpectIdentifier("identifier expected"));
+    }
+  } else if (Token::CanBeOverloaded(CurrentToken())) {
+    symbol = String::New(Token::Str(CurrentToken()));
+    ConsumeToken();
+  } else {
+    ErrorMsg("illegal symbol literal");
+  }
+  // Lookup class Symbol from collection_dev library and call the
+  // constructor to create a symbol instance.
+  const Library& lib = Library::Handle(Library::CollectionDevLibrary());
+  const Class& symbol_class = Class::Handle(lib.LookupClass(Symbols::Symbol()));
+  ASSERT(!symbol_class.IsNull());
+  ArgumentListNode* constr_args = new ArgumentListNode(symbol_pos);
+  constr_args->Add(new LiteralNode(
+      symbol_pos, String::ZoneHandle(Symbols::New(symbol))));
+  const Function& constr = Function::ZoneHandle(
+      symbol_class.LookupConstructor(Symbols::SymbolCtor()));
+  ASSERT(!constr.IsNull());
+  const Object& result = Object::Handle(
+      EvaluateConstConstructorCall(symbol_class,
+                                   TypeArguments::Handle(),
+                                   constr,
+                                   constr_args));
+  if (result.IsUnhandledException()) {
+    return GenerateRethrow(symbol_pos, result);
+  }
+  const Instance& instance = Instance::Cast(result);
+  return new LiteralNode(symbol_pos, Instance::ZoneHandle(instance.raw()));
+}
+
+
 static const String& BuildConstructorName(const String& type_class_name,
                                           const String* named_constructor) {
   // By convention, the static function implementing a named constructor 'C'
@@ -10051,6 +10121,8 @@
              CurrentToken() == Token::kINDEX ||
              CurrentToken() == Token::kLBRACE) {
     primary = ParseCompoundLiteral();
+  } else if (CurrentToken() == Token::kHASH) {
+    primary = ParseSymbolLiteral();
   } else if (CurrentToken() == Token::kSUPER) {
     if (current_function().is_static()) {
       ErrorMsg("cannot access superclass from static method");
@@ -10137,6 +10209,7 @@
   }
   if (CurrentToken() == Token::kLBRACE) {
     SkipBlock();
+    ExpectToken(Token::kRBRACE);
   } else if (CurrentToken() == Token::kARROW) {
     ConsumeToken();
     SkipExpr();
@@ -10233,6 +10306,22 @@
 }
 
 
+void Parser::SkipSymbolLiteral() {
+  ConsumeToken();  // Hash sign.
+  if (IsIdentifier()) {
+    ConsumeToken();
+    while (CurrentToken() == Token::kPERIOD) {
+      ConsumeToken();
+      ExpectIdentifier("identifier expected");
+    }
+  } else if (Token::CanBeOverloaded(CurrentToken())) {
+    ConsumeToken();
+  } else {
+    UnexpectedToken();
+  }
+}
+
+
 void Parser::SkipNewOperator() {
   ConsumeToken();  // Skip new or const keyword.
   if (IsIdentifier()) {
@@ -10310,6 +10399,9 @@
     case Token::kINDEX:
       SkipCompoundLiteral();
       break;
+    case Token::kHASH:
+      SkipSymbolLiteral();
+      break;
     default:
       if (IsIdentifier()) {
         ConsumeToken();  // Handle pseudo-keyword identifiers.
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index b286b69..20fc8ca 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -296,6 +296,7 @@
   void SkipSelectors();
   void SkipPrimary();
   void SkipCompoundLiteral();
+  void SkipSymbolLiteral();
   void SkipNewOperator();
   void SkipActualParameters();
   void SkipMapLiteral();
@@ -555,6 +556,7 @@
   AstNode* ParseStringLiteral();
   String* ParseImportStringLiteral();
   AstNode* ParseCompoundLiteral();
+  AstNode* ParseSymbolLiteral();
   AstNode* ParseListLiteral(intptr_t type_pos,
                             bool is_const,
                             const AbstractTypeArguments& type_arguments);
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index ec87bd7..ecbe709 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -42,10 +42,18 @@
 
 
 void Scanner::Reset() {
+  // Non-chaning newline properties.
+  newline_token_.kind = Token::kNEWLINE;
+  newline_token_.literal = NULL;
+  newline_token_.length = 1;
+  // We don't preserve the column information.
+  newline_token_.position.column = 0;
+
   lookahead_pos_ = -1;
   token_start_ = 0;
   c0_ = '\0';
   newline_seen_ = false;
+  prev_token_line_ = 1;
   while (saved_context_ != NULL) {
     ScanContext* ctx = saved_context_;
     saved_context_ = ctx->next;
@@ -400,17 +408,11 @@
 
 void Scanner::ScanScriptTag() {
   ReadChar();
-  if (c0_ == '!') {
-    Recognize(Token::kSCRIPTTAG);
-    // The script tag extends to the end of the line. Just treat this
-    // similar to a line comment.
-    SkipLine();
-    return;
-  } else {
-    ErrorMsg("unexpected character: '#'");
-    SkipLine();
-    return;
-  }
+  ASSERT(c0_ == '!');
+  Recognize(Token::kSCRIPTTAG);
+  // The script tag extends to the end of the line. Just treat this
+  // similar to a line comment.
+  SkipLine();
 }
 
 
@@ -837,7 +839,11 @@
         break;
 
       case '#':
-        ScanScriptTag();
+        if (LookaheadChar(1) == '!') {
+          ScanScriptTag();
+        } else {
+          Recognize(Token::kHASH);
+        }
         break;
 
       default:
@@ -865,7 +871,16 @@
   Reset();
   do {
     Scan();
+
+    for (intptr_t diff = current_token_.position.line - prev_token_line_;
+         diff > 0;
+         diff--) {
+      newline_token_.position.line = current_token_.position.line - diff;
+      token_stream->Add(newline_token_);
+    }
+
     token_stream->Add(current_token_);
+    prev_token_line_ = current_token_.position.line;
   } while (current_token_.kind != Token::kEOS);
 }
 
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 316ac98..5d59dee 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -203,6 +203,7 @@
   static void PrintTokens(const GrowableTokenStream& ts);
 
   TokenDescriptor current_token_;  // Current token.
+  TokenDescriptor newline_token_;  // Newline token.
   const String& source_;           // The source text being tokenized.
   intptr_t source_length_;     // The length of the source text.
   intptr_t lookahead_pos_;     // Position of lookahead character
@@ -210,6 +211,7 @@
   intptr_t token_start_;       // Begin of current token in src_.
   int32_t c0_;                 // Lookahead character.
   bool newline_seen_;          // Newline before current token.
+  intptr_t prev_token_line_;   // Line number of the previous token.
 
   // The following fields keep track whether we are scanning a string literal
   // and its interpolated expressions.
diff --git a/runtime/vm/scanner_test.cc b/runtime/vm/scanner_test.cc
index d4a653a..bf56873 100644
--- a/runtime/vm/scanner_test.cc
+++ b/runtime/vm/scanner_test.cc
@@ -122,13 +122,14 @@
       Scan("Foo( /*block \n"
            "comment*/ 0xff) // line comment;");
 
-  CheckNumTokens(tokens, 5);
+  CheckNumTokens(tokens, 6);
   CheckIdent(tokens, 0, "Foo");
   CheckLineNumber(tokens, 0, 1);
   CheckKind(tokens, 1, Token::kLPAREN);
-  CheckInteger(tokens, 2, "0xff");
-  CheckKind(tokens, 3, Token::kRPAREN);
-  CheckLineNumber(tokens, 3, 2);
+  CheckKind(tokens, 2, Token::kNEWLINE);
+  CheckInteger(tokens, 3, "0xff");
+  CheckKind(tokens, 4, Token::kRPAREN);
+  CheckLineNumber(tokens, 4, 2);
 }
 
 
@@ -270,14 +271,16 @@
   // |2''';
   const Scanner::GrowableTokenStream& tokens = Scan("mls = '''\n1' x\n2''';");
 
-  EXPECT_EQ(5, tokens.length());
+  EXPECT_EQ(7, tokens.length());
   CheckIdent(tokens, 0, "mls");
   CheckKind(tokens, 1, Token::kASSIGN);
   CheckKind(tokens, 2, Token::kSTRING);
-  CheckKind(tokens, 3, Token::kSEMICOLON);
-  CheckKind(tokens, 4, Token::kEOS);
+  CheckKind(tokens, 3, Token::kNEWLINE);
+  CheckKind(tokens, 4, Token::kNEWLINE);
+  CheckKind(tokens, 5, Token::kSEMICOLON);
+  CheckKind(tokens, 6, Token::kEOS);
   CheckLineNumber(tokens, 0, 1);
-  CheckLineNumber(tokens, 4, 3);  // Semicolon is on line 3.
+  CheckLineNumber(tokens, 5, 3);  // Semicolon is on line 3.
   const char* litchars = (tokens)[2].literal->ToCString();
   EXPECT_EQ(6, (tokens)[2].literal->Length());
 
@@ -429,6 +432,39 @@
 }
 
 
+void NewlinesTest() {
+  const char* source =
+      "var es = /* a\n"
+      "            b\n"
+      "          */ \"\"\"\n"
+      "c\n"
+      "d\n"
+      "\"\"\";";
+
+  const Scanner::GrowableTokenStream& tokens = Scan(source);
+
+  EXPECT_EQ(11, tokens.length());
+  CheckKind(tokens, 0, Token::kVAR);
+  CheckIdent(tokens, 1, "es");
+  CheckKind(tokens, 2, Token::kASSIGN);
+  CheckKind(tokens, 3, Token::kNEWLINE);
+  CheckKind(tokens, 4, Token::kNEWLINE);
+  CheckKind(tokens, 5, Token::kSTRING);
+  CheckKind(tokens, 6, Token::kNEWLINE);
+  CheckKind(tokens, 7, Token::kNEWLINE);
+  CheckKind(tokens, 8, Token::kNEWLINE);
+  CheckKind(tokens, 9, Token::kSEMICOLON);
+  CheckKind(tokens, 10, Token::kEOS);
+
+  EXPECT_EQ(4, (tokens)[5].literal->Length());
+  const char* litchars = (tokens)[5].literal->ToCString();
+  EXPECT_EQ('c',  litchars[0]);  // First newline is dropped.
+  EXPECT_EQ('\n', litchars[1]);
+  EXPECT_EQ('d',  litchars[2]);
+  EXPECT_EQ('\n', litchars[3]);
+}
+
+
 TEST_CASE(Scanner_Test) {
   ScanLargeText();
 
@@ -444,6 +480,7 @@
   NumberLiteral();
   InvalidText();
   FindLineTest();
+  NewlinesTest();
 }
 
 }  // namespace dart
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index d7cea49..2b3e633 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -149,6 +149,14 @@
 }
 
 
+static void PrintGenericError(JSONStream* js) {
+  JSONObject jsobj(js);
+  jsobj.AddProperty("type", "error");
+  jsobj.AddProperty("text", "Invalid request.");
+  PrintArgumentsAndOptions(jsobj, js);
+}
+
+
 static void HandleName(Isolate* isolate, JSONStream* js) {
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "IsolateName");
@@ -197,6 +205,7 @@
   PrintArgumentsAndOptions(jsobj, js);
 }
 
+
 // Print an error message if there is no ID argument.
 #define REQUIRE_COLLECTION_ID(collection)                                      \
   if (js->num_arguments() == 1) {                                              \
@@ -204,46 +213,44 @@
     return;                                                                    \
   }
 
-// Print a Dart object to the stream if found in ring. Otherwise print null.
-#define PRINT_RING_OBJ(type)                                                   \
-  ASSERT(js->num_arguments() >= 2);                                            \
-  ObjectIdRing* ring = isolate->object_id_ring();                              \
-  ASSERT(ring != NULL);                                                        \
-  intptr_t id = atoi(js->GetArgument(1));                                      \
-  Object& obj = Object::Handle(ring->GetObjectForId(id));                      \
-  if (!obj.Is##type()) {                                                       \
-    /* Object is not type, replace with null. */                               \
-    obj = Object::null();                                                      \
-  }                                                                            \
-  obj.PrintToJSONStream(js, false)
 
-
-static void HandleLibraries(Isolate* isolate, JSONStream* js) {
+static void HandleClasses(Isolate* isolate, JSONStream* js) {
   if (js->num_arguments() == 1) {
-    const Library& lib =
-        Library::Handle(isolate->object_store()->root_library());
-    lib.PrintToJSONStream(js, true);
+    ClassTable* table = isolate->class_table();
+    table->PrintToJSONStream(js);
+    return;
+  }
+  ASSERT(js->num_arguments() >= 2);
+  intptr_t id = atoi(js->GetArgument(1));
+  ClassTable* table = isolate->class_table();
+  if (!table->IsValidIndex(id)) {
+    Object::null_object().PrintToJSONStream(js, false);
   } else {
-    PRINT_RING_OBJ(Library);
+    Class& cls = Class::Handle(table->At(id));
+    cls.PrintToJSONStream(js, false);
   }
 }
 
 
-static void HandleFunctions(Isolate* isolate, JSONStream* js) {
-  REQUIRE_COLLECTION_ID("functions");
-  PRINT_RING_OBJ(Function);
+static void HandleLibrary(Isolate* isolate, JSONStream* js) {
+  if (js->num_arguments() == 1) {
+    const Library& lib =
+        Library::Handle(isolate->object_store()->root_library());
+    lib.PrintToJSONStream(js, false);
+    return;
+  }
+  PrintGenericError(js);
 }
 
 
-static void HandleClasses(Isolate* isolate, JSONStream* js) {
-  REQUIRE_COLLECTION_ID("classes");
-  PRINT_RING_OBJ(Class);
-}
-
-
-static void HandleCodes(Isolate* isolate, JSONStream* js) {
-  REQUIRE_COLLECTION_ID("codes");
-  PRINT_RING_OBJ(Code);
+static void HandleObjects(Isolate* isolate, JSONStream* js) {
+  REQUIRE_COLLECTION_ID("objects");
+  ASSERT(js->num_arguments() >= 2);
+  ObjectIdRing* ring = isolate->object_id_ring();
+  ASSERT(ring != NULL);
+  intptr_t id = atoi(js->GetArgument(1));
+  Object& obj = Object::Handle(ring->GetObjectForId(id));
+  obj.PrintToJSONStream(js, false);
 }
 
 
@@ -251,10 +258,9 @@
   { "name", HandleName },
   { "stacktrace", HandleStackTrace },
   { "objecthistogram", HandleObjectHistogram},
-  { "libraries", HandleLibraries },
-  { "functions", HandleFunctions },
+  { "library", HandleLibrary },
   { "classes", HandleClasses },
-  { "codes", HandleCodes },
+  { "objects", HandleObjects },
   { "_echo", HandleEcho },
 };
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index a9d3777..7d47618 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -765,12 +765,20 @@
 //   RCX : new context containing the current isolate pointer.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
-  __ EnterStubFrame();
+  __ EnterStubFrameWithPP();
 
+  // At this point, the stack looks like:
+  // | saved RC15/PP                                  | <-- RSP / TOS
+  // | "saved PC area" = 0                            |
+  // | saved RBP                                      | <-- RBP
+  // | saved PC (return to DartEntry::InvokeFunction) |
+
+  // The old frame pointer, the return address, the old R15 (for PP).
+  const intptr_t kInitialOffset = 3;
   // Save arguments descriptor array and new context.
-  const intptr_t kArgumentsDescOffset = -2 * kWordSize;
+  const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize;
   __ pushq(RSI);
-  const intptr_t kNewContextOffset = -3 * kWordSize;
+  const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize;
   __ pushq(RCX);
 
   // Save C++ ABI callee-saved registers.
@@ -778,7 +786,11 @@
   __ pushq(R12);
   __ pushq(R13);
   __ pushq(R14);
-  __ pushq(R15);
+  // R15 is already saved above by EnterStubFrameWithPP.
+
+  // If any additional (or fewer) values are pushed, the offsets in
+  // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be
+  // changed.
 
   // The new Context structure contains a pointer to the current Isolate
   // structure. Cache the Context pointer in the CTX register so that it is
@@ -866,14 +878,14 @@
   __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX);
 
   // Restore C++ ABI callee-saved registers.
-  __ popq(R15);
+  // R15 will be restored below by LeaveFrameWithPP.
   __ popq(R14);
   __ popq(R13);
   __ popq(R12);
   __ popq(RBX);
 
   // Restore the frame pointer.
-  __ LeaveFrame();
+  __ LeaveFrameWithPP();
 
   __ ret();
 }
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 4f4a670..987eb45 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -41,6 +41,8 @@
   V(AbstractClassInstantiationError, "AbstractClassInstantiationError")        \
   V(NoSuchMethodError, "NoSuchMethodError")                                    \
   V(ThrowNew, "_throwNew")                                                     \
+  V(Symbol, "Symbol")                                                          \
+  V(SymbolCtor, "Symbol.")                                                     \
   V(List, "List")                                                              \
   V(ListLiteralFactory, "List._fromLiteral")                                   \
   V(ListFactory, "List.")                                                      \
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index a52c97a..00c90bf 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -14,11 +14,11 @@
 //  13  multiplicative  * / ~/ %
 //  12  additive        + -
 //  11  shift           << >>
-//  10  relational      >= > <= < is as
-//   9  equality        == != === !==
-//   8  bitwise and     &
-//   7  bitwise xor     ^
-//   6  bitwise or      |
+//  10  bitwise and     &
+//   9  bitwise xor     ^
+//   8  bitwise or      |
+//   7  relational      >= > <= < is as
+//   6  equality        == != === !==
 //   5  logical and     &&
 //   4  logical or      ||
 //   3  conditional     ?
@@ -67,9 +67,9 @@
   TOK(kCOMMA, ",", 1, kNoAttribute)                                            \
   TOK(kOR, "||", 4, kNoAttribute)                                              \
   TOK(kAND, "&&", 5, kNoAttribute)                                             \
-  TOK(kBIT_OR, "|", 6, kNoAttribute)                                           \
-  TOK(kBIT_XOR, "^", 7, kNoAttribute)                                          \
-  TOK(kBIT_AND, "&", 8, kNoAttribute)                                          \
+  TOK(kBIT_OR, "|", 8, kNoAttribute)                                           \
+  TOK(kBIT_XOR, "^", 9, kNoAttribute)                                          \
+  TOK(kBIT_AND, "&", 10, kNoAttribute)                                         \
   TOK(kBIT_NOT, "~", 0, kNoAttribute)                                          \
                                                                                \
   /* Shift operators. */                                                       \
@@ -92,18 +92,18 @@
   /* Equality operators.                             */                        \
   /* Please update IsEqualityOperator() if you make  */                        \
   /* any changes to this block.                      */                        \
-  TOK(kEQ, "==", 9, kNoAttribute)                                              \
-  TOK(kNE, "!=", 9, kNoAttribute)                                              \
-  TOK(kEQ_STRICT, "===", 9, kNoAttribute)                                      \
-  TOK(kNE_STRICT, "!==", 9, kNoAttribute)                                      \
+  TOK(kEQ, "==", 6, kNoAttribute)                                              \
+  TOK(kNE, "!=", 6, kNoAttribute)                                              \
+  TOK(kEQ_STRICT, "===", 6, kNoAttribute)                                      \
+  TOK(kNE_STRICT, "!==", 6, kNoAttribute)                                      \
                                                                                \
   /* Relational operators.                             */                      \
   /* Please update IsRelationalOperator() if you make  */                      \
   /* any changes to this block.                        */                      \
-  TOK(kLT, "<", 10, kNoAttribute)                                              \
-  TOK(kGT, ">", 10, kNoAttribute)                                              \
-  TOK(kLTE, "<=", 10, kNoAttribute)                                            \
-  TOK(kGTE, ">=", 10, kNoAttribute)                                            \
+  TOK(kLT, "<", 7, kNoAttribute)                                               \
+  TOK(kGT, ">", 7, kNoAttribute)                                               \
+  TOK(kLTE, "<=", 7, kNoAttribute)                                             \
+  TOK(kGTE, ">=", 7, kNoAttribute)                                             \
                                                                                \
   /* Internal token for !(expr is Type) negative type test operator */         \
   TOK(kISNOT, "", 10, kNoAttribute)                                            \
@@ -122,7 +122,9 @@
   TOK(kINTERPOL_END, "}", 0, kNoAttribute)                                     \
                                                                                \
   TOK(kAT, "@", 0, kNoAttribute)                                               \
+  TOK(kHASH, "#", 0, kNoAttribute)                                             \
                                                                                \
+  TOK(kNEWLINE, "\n", 0, kNoAttribute)                                         \
   TOK(kWHITESP, "", 0, kNoAttribute)                                           \
   TOK(kERROR, "", 0, kNoAttribute)                                             \
   TOK(kILLEGAL, "", 0, kNoAttribute)                                           \
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index 04a316e..084df7e 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -33,7 +33,7 @@
   # Stdout is a terminal.
   if test 8 -le `tput colors`; then
     # Stdout has at least 8 colors, so enable colors.
-    EXTRA_OPTIONS[${#EXTRA_OPTIONS[@]}]='--enable-diagnostic-colors'
+    EXTRA_OPTIONS+=('--enable-diagnostic-colors')
   fi
 fi
 
@@ -41,7 +41,7 @@
 declare -a EXTRA_VM_OPTIONS
 
 if test -f "$SNAPSHOT"; then
-  EXTRA_OPTIONS[${#EXTRA_OPTIONS[@]}]="--library-root=$SDK_DIR"
+  EXTRA_OPTIONS+=("--library-root=$SDK_DIR")
 fi
 
 # Tell the VM to grow the heap more aggressively. This should only
@@ -52,10 +52,16 @@
 
 case $0 in
   *_developer)
-    EXTRA_VM_OPTIONS[${#EXTRA_VM_OPTIONS[@]}]='--checked'
+    EXTRA_VM_OPTIONS+=('--checked')
     ;;
 esac
 
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+  read -a OPTIONS <<< "$DART_VM_OPTIONS"
+  EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
 if test -f "$SNAPSHOT"; then
   exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "${EXTRA_OPTIONS[@]}" "$@"
 else
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index ae7612c..e324121 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -35,6 +35,11 @@
 rem See comments regarding options below in dart2js shell script.
 set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% --heap_growth_rate=512
 
+rem We allow extra vm options to be passed in through an environment variable.
+if not _%DART_VM_OPTIONS%_ == __ (
+  set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
 if exist "%SNAPSHOT%" (
   "%DART%" %EXTRA_VM_OPTIONS% "%SNAPSHOT%" %EXTRA_OPTIONS% %*
 ) else (
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 5832103..6986414 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -164,7 +164,7 @@
 
     // TODO(johnniwinther): Add [:report(..., {Element element}):] to
     // report methods in Compiler.
-    void reportReadError(String exception) {
+    void reportReadError(exception) {
       withCurrentElement(element, () {
         reportError(node,
                     leg.MessageKind.READ_SCRIPT_ERROR,
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 432292e..a91f9ab 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -247,10 +247,6 @@
 
   final Set<Element> usedVariablesInTry;
 
-  // A map from the parameter element to the variable element that
-  // holds the sentinel check.
-  final Map<Element, Element> parametersWithSentinel;
-
   ClosureClassMap(this.closureElement,
                   this.closureClassElement,
                   this.callElement,
@@ -258,18 +254,25 @@
       : this.freeVariableMapping = new Map<Element, Element>(),
         this.capturedFieldMapping = new Map<Element, Element>(),
         this.capturingScopes = new Map<Node, ClosureScope>(),
-        this.usedVariablesInTry = new Set<Element>(),
-        this.parametersWithSentinel = new Map<Element, Element>();
+        this.usedVariablesInTry = new Set<Element>();
 
   bool isClosure() => closureElement != null;
 
   bool isVariableCaptured(Element element) {
-    return freeVariableMapping.containsKey(element);
+    return freeVariableMapping.containsKey(element)
+        || capturingScopesBox(element);
+  }
+
+  bool capturingScopesBox(Element element) {
+    return capturingScopes.values.any((scope) {
+      return scope.boxedLoopVariables.contains(element);
+    });
   }
 
   bool isVariableBoxed(Element element) {
     Element copy = freeVariableMapping[element];
-    return copy != null && !copy.isMember();
+    if (copy != null && !copy.isMember()) return true;
+    return capturingScopesBox(element);
   }
 
   void forEachCapturedVariable(void f(Element local, Element field)) {
@@ -277,6 +280,9 @@
       if (variable is BoxElement) return;
       f(variable, copy);
     });
+    capturingScopes.values.forEach((scope) {
+      scope.capturedVariableMapping.forEach(f);
+    });
   }
 
   void forEachBoxedVariable(void f(Element local, Element field)) {
@@ -284,6 +290,9 @@
       if (!isVariableBoxed(variable)) return;
       f(variable, copy);
     });
+    capturingScopes.values.forEach((scope) {
+      scope.capturedVariableMapping.forEach(f);
+    });
   }
 
   void forEachNonBoxedCapturedVariable(void f(Element local, Element field)) {
@@ -536,6 +545,9 @@
     } else if (node.isTypeCast) {
       DartType type = elements.getType(node.arguments.head);
       analyzeType(type);
+    } else if (element == compiler.assertMethod
+               && !compiler.enableUserAssertions) {
+      return;
     }
     node.visitChildren(this);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index f9339f0..5c2e393 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -205,7 +205,7 @@
                   node, MessageKind.NOT_ASSIGNABLE.error,
                   {'fromType': constantType, 'toType': elementType});
             } else {
-              // If the field can be lazily initialized, we will throw
+              // If the field cannot be lazily initialized, we will throw
               // the exception at runtime.
               value = null;
             }
@@ -386,46 +386,53 @@
     if (!node.isConst()) {
       return signalNotCompileTimeConstant(node);
     }
-    List<StringConstant> keys = <StringConstant>[];
-    Map<StringConstant, Constant> map = new Map<StringConstant, Constant>();
+    List<Constant> keys = <Constant>[];
+    Map<Constant, Constant> map = new Map<Constant, Constant>();
     for (Link<Node> link = node.entries.nodes;
          !link.isEmpty;
          link = link.tail) {
       LiteralMapEntry entry = link.head;
       Constant key = evaluateConstant(entry.key);
-      if (!key.isString() || entry.key.asStringNode() == null) {
-        compiler.reportFatalError(
-            entry.key, MessageKind.KEY_NOT_A_STRING_LITERAL);
-      }
-      StringConstant keyConstant = key;
       if (!map.containsKey(key)) keys.add(key);
       map[key] = evaluateConstant(entry.value);
     }
-    List<Constant> values = <Constant>[];
+
+    bool onlyStringKeys = true;
     Constant protoValue = null;
-    for (StringConstant key in keys) {
-      if (key.value == MapConstant.PROTO_PROPERTY) {
-        protoValue = map[key];
+    for (var key in keys) {
+      if (key.isString()) {
+        if (key.value == MapConstant.PROTO_PROPERTY) {
+          protoValue = map[key];
+        }
       } else {
-        values.add(map[key]);
+        onlyStringKeys = false;
+        // Don't handle __proto__ values specially in the general map case.
+        protoValue = null;
+        break;
       }
     }
+
     bool hasProtoKey = (protoValue != null);
+    List<Constant> values = map.values.toList();
     InterfaceType sourceType = elements.getType(node);
     Link<DartType> arguments =
         new Link<DartType>.fromList([compiler.stringClass.rawType]);
     DartType keysType = new InterfaceType(compiler.listClass, arguments);
     ListConstant keysList = new ListConstant(keysType, keys);
-    handler.registerCompileTimeConstant(keysList, elements);
-    SourceString className = hasProtoKey
-                             ? MapConstant.DART_PROTO_CLASS
-                             : MapConstant.DART_CLASS;
+    if (onlyStringKeys) {
+      handler.registerCompileTimeConstant(keysList, elements);
+    }
+    SourceString className = onlyStringKeys
+        ? (hasProtoKey ? MapConstant.DART_PROTO_CLASS
+                       : MapConstant.DART_STRING_CLASS)
+        : MapConstant.DART_GENERAL_CLASS;
     ClassElement classElement = compiler.jsHelperLibrary.find(className);
     classElement.ensureResolved(compiler);
-    Link<DartType> typeArgument = sourceType.typeArguments.tail;
+    Link<DartType> typeArgument = sourceType.typeArguments;
     InterfaceType type = new InterfaceType(classElement, typeArgument);
     handler.registerInstantiatedType(type, elements);
-    Constant constant = new MapConstant(type, keysList, values, protoValue);
+    Constant constant =
+        new MapConstant(type, keysList, values, protoValue, onlyStringKeys);
     handler.registerCompileTimeConstant(constant, elements);
     return constant;
   }
@@ -713,6 +720,9 @@
       type = constructor.computeTargetType(compiler, type);
     }
 
+    // The redirection chain of this element may not have been resolved through
+    // a post-process action, so we have to make sure it is done here.
+    compiler.resolver.resolveRedirectionChain(constructor, node);
     constructor = constructor.redirectionTarget;
     ClassElement classElement = constructor.getEnclosingClass();
     // The constructor must be an implementation to ensure that field
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index 4ff011c..bca6524 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -374,19 +374,26 @@
 
   /** The dart class implementing constant map literals. */
   static const SourceString DART_CLASS = const SourceString("ConstantMap");
+  static const SourceString DART_STRING_CLASS =
+      const SourceString("ConstantStringMap");
   static const SourceString DART_PROTO_CLASS =
       const SourceString("ConstantProtoMap");
+  static const SourceString DART_GENERAL_CLASS =
+      const SourceString("GeneralConstantMap");
   static const SourceString LENGTH_NAME = const SourceString("length");
   static const SourceString JS_OBJECT_NAME = const SourceString("_jsObject");
   static const SourceString KEYS_NAME = const SourceString("_keys");
   static const SourceString PROTO_VALUE = const SourceString("_protoValue");
+  static const SourceString JS_DATA_NAME = const SourceString("_jsData");
 
   final ListConstant keys;
   final List<Constant> values;
   final Constant protoValue;
   final int hashCode;
+  final bool onlyStringKeys;
 
-  MapConstant(DartType type, this.keys, List<Constant> values, this.protoValue)
+  MapConstant(DartType type, this.keys, List<Constant> values, this.protoValue,
+              this.onlyStringKeys)
       : this.values = values,
         this.hashCode = computeHash(type, values),
         super(type);
@@ -415,7 +422,14 @@
   }
 
   List<Constant> getDependencies() {
-    List<Constant> result = <Constant>[keys];
+    List<Constant> result = <Constant>[];
+    if (onlyStringKeys) {
+      result.add(keys);
+    } else {
+      // Add the keys individually to avoid generating a unused list constant
+      // for the keys.
+      result.addAll(keys.entries);
+    }
     result.addAll(values);
     return result;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index eb211bb..a4e367f 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -44,9 +44,9 @@
 class SendVisitor extends ResolvedVisitor {
   final PlaceholderCollector collector;
 
-  get compiler => collector.compiler;
-
-  SendVisitor(this.collector, TreeElements elements) : super(elements);
+  SendVisitor(collector, TreeElements elements)
+      : this.collector = collector,
+        super(elements, collector.compiler);
 
   visitOperatorSend(Send node) {
   }
@@ -104,6 +104,10 @@
     }
   }
 
+  visitAssert(node) {
+    visitStaticSend(node);
+  }
+
   visitStaticSend(Send node) {
     final element = elements[node];
     collector.backend.registerStaticSend(element, node);
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index fda82a7..82f5e73 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1189,28 +1189,32 @@
    * exception/call.
    */
   bool isCompatibleWith(FunctionSignature signature) {
-    if (optionalParametersAreNamed != signature.optionalParametersAreNamed) {
-      return false;
-    }
     if (optionalParametersAreNamed) {
+      if (!signature.optionalParametersAreNamed) {
+        return requiredParameterCount == signature.parameterCount;
+      }
+      // If both signatures have named parameters, then they must have
+      // the same number of required parameters, and the names in
+      // [signature] must all be in [:this:].
       if (requiredParameterCount != signature.requiredParameterCount) {
         return false;
       }
+      Set<String> names = optionalParameters.toList().map(
+          (Element element) => element.name.slowToString()).toSet();
       for (Element namedParameter in signature.optionalParameters) {
-        if (!optionalParameters.contains(namedParameter)) {
+        if (!names.contains(namedParameter.name.slowToString())) {
           return false;
         }
       }
     } else {
+      if (signature.optionalParametersAreNamed) return false;
       // There must be at least as many arguments as in the other signature, but
       // this signature must not have more required parameters.  Having more
       // optional parameters is not a problem, they simply are never provided
       // by call sites of a call to a method with the other signature.
-      if (requiredParameterCount > signature.requiredParameterCount ||
-          requiredParameterCount < signature.parameterCount ||
-          parameterCount < signature.parameterCount) {
-        return false;
-      }
+      int otherTotalCount = signature.parameterCount;
+      return requiredParameterCount <= otherTotalCount
+          && parameterCount >= otherTotalCount;
     }
     return true;
   }
@@ -1275,22 +1279,20 @@
 
   bool get isRedirectingFactory => defaultImplementation != this;
 
-  FunctionElement get redirectionTarget {
-    if (this == defaultImplementation) return this;
-    var target = defaultImplementation;
-    Set<Element> seen = new Set<Element>();
-    seen.add(target);
-    while (!target.isErroneous() && target != target.defaultImplementation) {
-      target = target.defaultImplementation;
-      if (seen.contains(target)) {
-        // TODO(ahe): This is expedient for now, but it should be
-        // checked by the resolver.  Keeping http://dartbug.com/3970
-        // open to track this.
-        throw new SpannableAssertionFailure(
-            target, 'redirecting factory leads to cycle');
-      }
+  /// This field is set by the post process queue when checking for cycles.
+  FunctionElement internalRedirectionTarget;
+
+  set redirectionTarget(FunctionElement constructor) {
+    assert(constructor != null && internalRedirectionTarget == null);
+    internalRedirectionTarget = constructor;
+  }
+
+  get redirectionTarget {
+    if (Elements.isErroneousElement(defaultImplementation)) {
+      return defaultImplementation;
     }
-    return target;
+    assert(!isRedirectingFactory || internalRedirectionTarget != null);
+    return isRedirectingFactory ? internalRedirectionTarget : this;
   }
 
   InterfaceType computeTargetType(Compiler compiler,
@@ -1962,6 +1964,9 @@
   }
 
   void addToScope(Element element, DiagnosticListener listener) {
+    if (element.isField() && element.name == name) {
+      listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME);
+    }
     localScope.add(element, listener);
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
index 2324884a4..d1ee2cc 100644
--- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
+++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
@@ -423,7 +423,7 @@
     if (selector.isGetter()) {
       processInstanceFunctions(methodName, (Element member) {
         if (selector.appliesUnnamed(member, compiler)) {
-          registerBoundClosure();
+          registerClosurizedMember(member, compiler.globalDependencies);
           return true;
         }
         return false;
@@ -517,18 +517,22 @@
   }
 
   void registerClosurizedMember(Element element, TreeElements elements) {
-    if (element.computeType(compiler).containsTypeVariables) {
-      registerClosurizedGenericMember(element, elements);
-    } else {
-      registerBoundClosure();
-    }
+    assert(element.isInstanceMember());
+    registerIfGeneric(element, elements);
+    registerBoundClosure();
     universe.closurizedMembers.add(element);
   }
 
-  void registerClosurizedGenericMember(Element element, TreeElements elements) {
-    registerBoundClosure();
-    compiler.backend.registerGenericClosure(element, this, elements);
-    universe.closurizedGenericMembers.add(element);
+
+  void registerIfGeneric(Element element, TreeElements elements) {
+    if (element.computeType(compiler).containsTypeVariables) {
+      compiler.backend.registerGenericClosure(element, this, elements);
+      universe.genericClosures.add(element);
+    }
+  }
+
+  void registerClosure(Element element, TreeElements elements) {
+    registerIfGeneric(element, elements);
   }
 
   void forEach(f(WorkItem work)) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 703979d..376fdfc 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -1167,14 +1167,17 @@
   }
 
   void registerConstantMap(TreeElements elements) {
-    Element e = compiler.findHelper(const SourceString('ConstantMap'));
-    if (e != null) {
-      enqueueClass(compiler.enqueuer.resolution, e, elements);
+    void enqueue(SourceString name) {
+      Element e = compiler.findHelper(name);
+      if (e != null) {
+        enqueueClass(compiler.enqueuer.resolution, e, elements);
+      }
     }
-    e = compiler.findHelper(const SourceString('ConstantProtoMap'));
-    if (e != null) {
-      enqueueClass(compiler.enqueuer.resolution, e, elements);
-    }
+
+    enqueue(MapConstant.DART_CLASS);
+    enqueue(MapConstant.DART_PROTO_CLASS);
+    enqueue(MapConstant.DART_STRING_CLASS);
+    enqueue(MapConstant.DART_GENERAL_CLASS);
   }
 
   void codegen(CodegenWorkItem work) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index 9ed0647..16ffce5 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -215,7 +215,6 @@
   jsAst.Expression visitMap(MapConstant constant) {
     jsAst.Expression jsMap() {
       List<jsAst.Property> properties = <jsAst.Property>[];
-      int valueIndex = 0;
       for (int i = 0; i < constant.keys.entries.length; i++) {
         StringConstant key = constant.keys.entries[i];
         if (key.value == MapConstant.PROTO_PROPERTY) continue;
@@ -223,21 +222,27 @@
         // Keys in literal maps must be emitted in place.
         jsAst.Literal keyExpression = _visit(key);
         jsAst.Expression valueExpression =
-            _reference(constant.values[valueIndex++]);
+            _reference(constant.values[i]);
         properties.add(new jsAst.Property(keyExpression, valueExpression));
       }
-      if (valueIndex != constant.values.length) {
-        compiler.internalError("Bad value count.");
-      }
       return new jsAst.ObjectInitializer(properties);
     }
 
-    void badFieldCountError() {
-      compiler.internalError(
-          "Compiler and ConstantMap disagree on number of fields.");
+    jsAst.Expression jsGeneralMap() {
+      List<jsAst.Expression> data = <jsAst.Expression>[];
+      for (int i = 0; i < constant.keys.entries.length; i++) {
+        jsAst.Expression keyExpression =
+            _reference(constant.keys.entries[i]);
+        jsAst.Expression valueExpression =
+            _reference(constant.values[i]);
+        data.add(keyExpression);
+        data.add(valueExpression);
+      }
+      return new jsAst.ArrayInitializer.from(data);
     }
 
     ClassElement classElement = constant.type.element;
+    SourceString className = classElement.name;
 
     List<jsAst.Expression> arguments = <jsAst.Expression>[];
 
@@ -256,16 +261,24 @@
           } else if (field.name == MapConstant.PROTO_VALUE) {
             assert(constant.protoValue != null);
             arguments.add(_reference(constant.protoValue));
+          } else if (field.name == MapConstant.JS_DATA_NAME) {
+            arguments.add(jsGeneralMap());
           } else {
-            badFieldCountError();
+            compiler.internalError(
+                "Compiler has unexpected field ${field.name} for "
+                "${className}.");
           }
           emittedArgumentCount++;
         },
         includeSuperAndInjectedMembers: true);
-
-    if ((constant.protoValue == null && emittedArgumentCount != 3) ||
-        (constant.protoValue != null && emittedArgumentCount != 4)) {
-      badFieldCountError();
+    if ((className == MapConstant.DART_STRING_CLASS &&
+         emittedArgumentCount != 3) ||
+        (className == MapConstant.DART_PROTO_CLASS &&
+         emittedArgumentCount != 4) ||
+        (className == MapConstant.DART_GENERAL_CLASS &&
+         emittedArgumentCount != 1)) {
+      compiler.internalError(
+          "Compiler and ${className} disagree on number of fields.");
     }
 
     jsAst.Expression value = new jsAst.New(
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index 5f9041f..6a52399 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -183,8 +183,7 @@
               methodsNeedingRti.add(method);
             }
           }
-          compiler.resolverWorld.closurizedGenericMembers.forEach(
-              analyzeMethod);
+          compiler.resolverWorld.genericClosures.forEach(analyzeMethod);
           compiler.resolverWorld.genericCallMethods.forEach(analyzeMethod);
         }
       }
@@ -198,7 +197,7 @@
           methodsNeedingRti.add(method);
         }
       }
-      compiler.resolverWorld.closurizedGenericMembers.forEach(analyzeMethod);
+      compiler.resolverWorld.genericClosures.forEach(analyzeMethod);
       compiler.resolverWorld.genericCallMethods.forEach(analyzeMethod);
     }
     // Add the classes that need RTI because they use a type variable as
diff --git a/sdk/lib/_internal/compiler/implementation/patch_parser.dart b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
index 42d036f..88da806 100644
--- a/sdk/lib/_internal/compiler/implementation/patch_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
@@ -118,7 +118,6 @@
 
 import "tree/tree.dart" as tree;
 import "dart2jslib.dart" as leg;  // CompilerTask, Compiler.
-import "../compiler.dart" as api;
 import "scanner/scannerlib.dart";  // Scanner, Parsers, Listeners
 import "elements/elements.dart";
 import "elements/modelx.dart" show LibraryElementX, MetadataAnnotationX;
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 130943c..4135d0c 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -454,7 +454,7 @@
 
     if (Elements.isStaticOrTopLevelField(element)) {
       if (tree.asSendSet() != null) {
-        // TODO(ngeoffray): We could do better here by using the
+        // TODO(13429): We could do better here by using the
         // constant handler to figure out if it's a lazy field or not.
         compiler.backend.registerLazyField(visitor.mapping);
       } else {
@@ -494,6 +494,33 @@
     return result;
   }
 
+  void resolveRedirectionChain(FunctionElement constructor, Node node) {
+    FunctionElementX current = constructor;
+    List<Element> seen = new List<Element>();
+    // Follow the chain of redirections and check for cycles.
+    while (current != current.defaultImplementation) {
+      if (current.internalRedirectionTarget != null) {
+        // We found a constructor that already has been processed.
+        current = current.internalRedirectionTarget;
+        break;
+      }
+      Element target = current.defaultImplementation;
+      if (seen.contains(target)) {
+        error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
+        break;
+      }
+      seen.add(current);
+      current = target;
+    }
+    // [current] is now the actual target of the redirections.  Run through
+    // the constructors again and set their [redirectionTarget], so that we
+    // do not have to run the loop for these constructors again.
+    while (!seen.isEmpty) {
+      FunctionElementX factory = seen.removeLast();
+      factory.redirectionTarget = current;
+    }
+  }
+
   /**
    * Load and resolve the supertypes of [cls].
    *
@@ -2097,7 +2124,7 @@
     scope = oldScope;
     enclosingElement = previousEnclosingElement;
 
-    world.registerClosurizedMember(function, mapping);
+    world.registerClosure(function, mapping);
     world.registerInstantiatedClass(compiler.functionClass, mapping);
   }
 
@@ -2653,7 +2680,8 @@
     FunctionType targetType = redirectionTarget.computeType(compiler)
         .subst(type.typeArguments, targetClass.typeVariables);
     FunctionType constructorType = constructor.computeType(compiler);
-    if (!compiler.types.isSubtype(targetType, constructorType)) {
+    bool isSubtype = compiler.types.isSubtype(targetType, constructorType);
+    if (!isSubtype) {
       warning(node, MessageKind.NOT_ASSIGNABLE.warning,
               {'fromType': targetType, 'toType': constructorType});
     }
@@ -2663,22 +2691,16 @@
     FunctionSignature constructorSignature =
         constructor.computeSignature(compiler);
     if (!targetSignature.isCompatibleWith(constructorSignature)) {
+      assert(!isSubtype);
       compiler.backend.registerThrowNoSuchMethod(mapping);
     }
 
-    // TODO(ahe): Check that this doesn't lead to a cycle.  For now,
-    // just make sure that the redirection target isn't itself a
-    // redirecting factory.
-    { // This entire block is temporary code per the above TODO.
-      FunctionElement targetImplementation = redirectionTarget.implementation;
-      FunctionExpression function = targetImplementation.parseNode(compiler);
-      if (function != null
-          && function.body != null
-          && function.body.asReturn() != null
-          && function.body.asReturn().isRedirectingFactoryBody) {
-        unimplemented(node.expression, 'redirecting to redirecting factory');
-      }
-    }
+    // Register a post process to check for cycles in the redirection chain and
+    // set the actual generative constructor at the end of the chain.
+    compiler.enqueuer.resolution.addPostProcessAction(constructor, () {
+      compiler.resolver.resolveRedirectionChain(constructor, node);
+    });
+
     world.registerStaticUse(redirectionTarget);
     world.registerInstantiatedClass(
         redirectionTarget.enclosingElement.declaration, mapping);
@@ -2749,7 +2771,8 @@
     if (constructor.isFactoryConstructor() && !type.typeArguments.isEmpty) {
       world.registerFactoryWithTypeArguments(mapping);
     }
-    if (cls.isAbstract(compiler)) {
+    if (constructor.isGenerativeConstructor() && cls.isAbstract(compiler)) {
+      warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
       compiler.backend.registerAbstractClassInstantiation(mapping);
     }
 
@@ -3340,7 +3363,101 @@
     element.alias = compiler.computeFunctionType(
         element, element.functionSignature);
 
-    // TODO(johnniwinther): Check for cyclic references in the typedef alias.
+    void checkCyclicReference() {
+      var visitor = new TypedefCyclicVisitor(compiler, element);
+      type.accept(visitor, null);
+    }
+    compiler.enqueuer.resolution.addPostProcessAction(element,
+                                                      checkCyclicReference);
+  }
+}
+
+// TODO(johnniwinther): Replace with a traversal on the AST when the type
+// annotations in typedef alias are stored in a [TreeElements] mapping.
+class TypedefCyclicVisitor extends DartTypeVisitor {
+  final Compiler compiler;
+  final TypedefElement element;
+  bool hasCyclicReference = false;
+
+  /// Counter for how many bounds the visitor currently has on the call-stack.
+  /// Used to detect when to report [Messagekind.CYCLIC_TYPEDEF_TYPEVAR].
+  int seenBoundsCount = 0;
+
+  Link<TypedefElement> seenTypedefs = const Link<TypedefElement>();
+
+  int seenTypedefsCount = 0;
+
+  Link<TypeVariableElement> seenTypeVariables =
+      const Link<TypeVariableElement>();
+
+  TypedefCyclicVisitor(Compiler this.compiler, TypedefElement this.element);
+
+  visitType(DartType type, _) {
+    // Do nothing.
+  }
+
+  visitTypedefType(TypedefType type, _) {
+    TypedefElement typedefElement = type.element;
+    if (seenTypedefs.contains(typedefElement)) {
+      if (!hasCyclicReference && identical(element, typedefElement)) {
+        // Only report an error on the checked typedef to avoid generating
+        // multiple errors for the same cyclicity.
+        hasCyclicReference = true;
+        if (seenBoundsCount > 0) {
+          compiler.reportError(element, MessageKind.CYCLIC_TYPEDEF_TYPEVAR);
+        } else if (seenTypedefsCount == 1) {
+          // Direct cyclicity.
+          compiler.reportError(element,
+              MessageKind.CYCLIC_TYPEDEF,
+              {'typedefName': element.name});
+        } else if (seenTypedefsCount == 2) {
+          // Cyclicity through one other typedef.
+          compiler.reportError(element,
+              MessageKind.CYCLIC_TYPEDEF_ONE,
+              {'typedefName': element.name,
+               'otherTypedefName': seenTypedefs.head.name});
+        } else {
+          // Cyclicity through more than one other typedef.
+          for (TypedefElement cycle in seenTypedefs) {
+            if (!identical(typedefElement, cycle)) {
+              compiler.reportError(element,
+                  MessageKind.CYCLIC_TYPEDEF_ONE,
+                  {'typedefName': element.name,
+                   'otherTypedefName': cycle.name});
+            }
+          }
+        }
+      }
+    } else {
+      seenTypedefs = seenTypedefs.prepend(typedefElement);
+      seenTypedefsCount++;
+      type.visitChildren(this, null);
+      typedefElement.alias.accept(this, null);
+      seenTypedefs = seenTypedefs.tail;
+      seenTypedefsCount--;
+    }
+  }
+
+  visitFunctionType(FunctionType type, _) {
+    type.visitChildren(this, null);
+  }
+
+  visitInterfaceType(InterfaceType type, _) {
+    type.visitChildren(this, null);
+  }
+
+  visitTypeVariableType(TypeVariableType type, _) {
+    TypeVariableElement typeVariableElement = type.element;
+    if (seenTypeVariables.contains(typeVariableElement)) {
+      // Avoid running in cycles on cyclic type variable bounds.
+      // Cyclicity is reported elsewhere.
+      return;
+    }
+    seenTypeVariables = seenTypeVariables.prepend(typeVariableElement);
+    seenBoundsCount++;
+    typeVariableElement.bound.accept(this, null);
+    seenBoundsCount--;
+    seenTypeVariables = seenTypeVariables.tail;
   }
 }
 
@@ -3816,13 +3933,16 @@
       resolver.error(identifier, MessageKind.REFERENCE_IN_INITIALIZATION,
                      {'variableName': name.toString()});
     }
-    return visit(node.selector);
+    return name;
   }
 
   SourceString visitIdentifier(Identifier node) {
     // The variable is initialized to null.
     resolver.world.registerInstantiatedClass(compiler.nullClass,
                                              resolver.mapping);
+    if (definitions.modifiers.isConst()) {
+      compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER);
+    }
     return node.source;
   }
 
@@ -3879,6 +3999,9 @@
     if (definition is NodeList) {
       cancel(node, 'optional parameters are not implemented');
     }
+    if (node.modifiers.isConst()) {
+      error(node, MessageKind.FORMAL_DECLARED_CONST);
+    }
 
     if (currentDefinitions != null) {
       cancel(node, 'function type parameters not supported');
diff --git a/sdk/lib/_internal/compiler/implementation/resolved_visitor.dart b/sdk/lib/_internal/compiler/implementation/resolved_visitor.dart
index 9a85b9a..df68e6e 100644
--- a/sdk/lib/_internal/compiler/implementation/resolved_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolved_visitor.dart
@@ -5,9 +5,10 @@
 part of dart2js;
 
 abstract class ResolvedVisitor<R> extends Visitor<R> {
+  final Compiler compiler;
   TreeElements elements;
 
-  ResolvedVisitor(this.elements);
+  ResolvedVisitor(this.elements, this.compiler);
 
   R visitSend(Send node) {
     Element element = elements[node];
@@ -26,6 +27,9 @@
       return visitStaticSend(node);
     } else if (Elements.isClosureSend(node, element)) {
       return visitClosureSend(node);
+    } else if (element == compiler.assertMethod) {
+      assert(element != null);
+      return visitAssert(node);
     } else {
       if (Elements.isUnresolved(element)) {
         if (element == null) {
@@ -59,6 +63,7 @@
   R visitDynamicSend(Send node);
   R visitStaticSend(Send node);
   R visitTypeReferenceSend(Send node);
+  R visitAssert(Send node);
 
   void internalError(String reason, {Node node});
 
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 1e8f36a..dc912fb 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -1622,9 +1622,6 @@
   void endLiteralMapEntry(Token colon, Token endToken) {
     Expression value = popNode();
     Expression key = popNode();
-    if (key.asStringNode() == null) {
-      recoverableError('expected a string', node: key);
-    }
     pushNode(new LiteralMapEntry(key, colon, value));
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index 63e7da7..05b1acf 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -1581,6 +1581,12 @@
         }
         info = token.info;
         tokenLevel = info.precedence;
+        if (level == EQUALITY_PRECEDENCE || level == RELATIONAL_PRECEDENCE) {
+          // We don't allow (a == b == c) or (a < b < c).
+          // Continue the outer loop if we have matched one equality or
+          // relational operator.
+          break;
+        }
       }
     }
     return token;
@@ -1623,23 +1629,8 @@
     String value = token.stringValue;
     // Prefix:
     if (identical(value, '+')) {
-      // Dart only allows "prefix plus" as an initial part of a
-      // decimal literal. We scan it as a separate token and let
-      // the parser listener combine it with the digits.
-      Token next = token.next;
-      if (identical(next.charOffset, token.charOffset + 1)) {
-        if (identical(next.kind, INT_TOKEN)) {
-          listener.handleLiteralInt(token);
-          return next.next;
-        }
-        if (identical(next.kind, DOUBLE_TOKEN)) {
-          listener.handleLiteralDouble(token);
-          return next.next;
-        }
-      }
-      listener.recoverableError("Unexpected token '+'", token: token);
-      return parsePrecedenceExpression(next, POSTFIX_PRECEDENCE,
-                                       allowCascades);
+      // Dart no longer allows prefix-plus.
+      listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS);
     } else if ((identical(value, '!')) ||
                (identical(value, '-')) ||
                (identical(value, '~'))) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index e74c702..bda4b76 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -422,37 +422,49 @@
   const PrecedenceInfo(const SourceString('&&'), 5, AMPERSAND_AMPERSAND_TOKEN);
 
 const PrecedenceInfo BAR_INFO =
-  const PrecedenceInfo(const SourceString('|'), 6, BAR_TOKEN);
+  const PrecedenceInfo(const SourceString('|'), 8, BAR_TOKEN);
 
 const PrecedenceInfo CARET_INFO =
-  const PrecedenceInfo(const SourceString('^'), 7, CARET_TOKEN);
+  const PrecedenceInfo(const SourceString('^'), 9, CARET_TOKEN);
 
 const PrecedenceInfo AMPERSAND_INFO =
-  const PrecedenceInfo(const SourceString('&'), 8, AMPERSAND_TOKEN);
+  const PrecedenceInfo(const SourceString('&'), 10, AMPERSAND_TOKEN);
 
 // Equality operators.
+const int EQUALITY_PRECEDENCE = 6;
 const PrecedenceInfo BANG_EQ_EQ_INFO =
-  const PrecedenceInfo(const SourceString('!=='), 9, BANG_EQ_EQ_TOKEN);
+  const PrecedenceInfo(const SourceString('!=='),
+                       EQUALITY_PRECEDENCE, BANG_EQ_EQ_TOKEN);
 const PrecedenceInfo BANG_EQ_INFO =
-  const PrecedenceInfo(const SourceString('!='), 9, BANG_EQ_TOKEN);
+  const PrecedenceInfo(const SourceString('!='),
+                       EQUALITY_PRECEDENCE, BANG_EQ_TOKEN);
 const PrecedenceInfo EQ_EQ_EQ_INFO =
-  const PrecedenceInfo(const SourceString('==='), 9, EQ_EQ_EQ_TOKEN);
+  const PrecedenceInfo(const SourceString('==='),
+                       EQUALITY_PRECEDENCE, EQ_EQ_EQ_TOKEN);
 const PrecedenceInfo EQ_EQ_INFO =
-  const PrecedenceInfo(const SourceString('=='), 9, EQ_EQ_TOKEN);
+  const PrecedenceInfo(const SourceString('=='),
+                       EQUALITY_PRECEDENCE, EQ_EQ_TOKEN);
 
 // Relational operators.
+const int RELATIONAL_PRECEDENCE = 7;
 const PrecedenceInfo GT_EQ_INFO =
-  const PrecedenceInfo(const SourceString('>='), 10, GT_EQ_TOKEN);
+  const PrecedenceInfo(const SourceString('>='),
+                       RELATIONAL_PRECEDENCE, GT_EQ_TOKEN);
 const PrecedenceInfo GT_INFO =
-  const PrecedenceInfo(const SourceString('>'), 10, GT_TOKEN);
+  const PrecedenceInfo(const SourceString('>'),
+                       RELATIONAL_PRECEDENCE, GT_TOKEN);
 const PrecedenceInfo IS_INFO =
-  const PrecedenceInfo(const SourceString('is'), 10, KEYWORD_TOKEN);
+  const PrecedenceInfo(const SourceString('is'),
+                       RELATIONAL_PRECEDENCE, KEYWORD_TOKEN);
 const PrecedenceInfo AS_INFO =
-  const PrecedenceInfo(const SourceString('as'), 10, KEYWORD_TOKEN);
+  const PrecedenceInfo(const SourceString('as'),
+                       RELATIONAL_PRECEDENCE, KEYWORD_TOKEN);
 const PrecedenceInfo LT_EQ_INFO =
-  const PrecedenceInfo(const SourceString('<='), 10, LT_EQ_TOKEN);
+  const PrecedenceInfo(const SourceString('<='),
+                       RELATIONAL_PRECEDENCE, LT_EQ_TOKEN);
 const PrecedenceInfo LT_INFO =
-  const PrecedenceInfo(const SourceString('<'), 10, LT_TOKEN);
+  const PrecedenceInfo(const SourceString('<'),
+                       RELATIONAL_PRECEDENCE, LT_TOKEN);
 
 // Shift operators.
 const PrecedenceInfo GT_GT_INFO =
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 4e50630..9f0826b 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -935,7 +935,7 @@
       sourceElementStack = <Element>[work.element],
       inliningStack = <InliningState>[],
       rti = builder.backend.rti,
-      super(work.resolutionTree) {
+      super(work.resolutionTree, builder.compiler) {
     localsHandler = new LocalsHandler(this);
   }
 
@@ -3601,6 +3601,14 @@
     }
   }
 
+  visitAssert(node) {
+    if (!compiler.enableUserAssertions) {
+      stack.add(graph.addConstantNull(compiler));
+      return;
+    }
+    visitStaticSend(node);
+  }
+
   visitStaticSend(Send node) {
     Selector selector = elements.getSelector(node);
     Element element = elements[node];
@@ -3614,11 +3622,6 @@
                                 argumentNodes: node.arguments);
       return;
     }
-    if (identical(element, compiler.assertMethod)
-        && !compiler.enableUserAssertions) {
-      stack.add(graph.addConstantNull(compiler));
-      return;
-    }
     compiler.ensure(!element.isGenerativeConstructor());
     if (element.isFunction()) {
       var inputs = <HInstruction>[];
diff --git a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
index 372b4ae..6f3389a5 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
@@ -174,6 +174,7 @@
   Modifiers asModifiers() => null;
   NamedArgument asNamedArgument() => null;
   NamedMixinApplication asNamedMixinApplication() => null;
+  NewExpression asNewExpression() => null;
   NodeList asNodeList() => null;
   Operator asOperator() => null;
   ParenthesizedExpression asParenthesizedExpression() => null;
@@ -473,6 +474,8 @@
 
   NewExpression([this.newToken, this.send]);
 
+  NewExpression asNewExpression() => this;
+
   accept(Visitor visitor) => visitor.visitNewExpression(this);
 
   visitChildren(Visitor visitor) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
index 49d14b1..9dda20d 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -1666,7 +1666,7 @@
                       ConcreteTypesInferrer inferrer, this.environment)
       : this.inferrer = inferrer
       , this.backend = inferrer.compiler.backend
-      , super(elements) {
+      , super(elements, inferrer.compiler) {
         for (Element element in elements.otherDependencies) {
           if (element.isClass()) {
             inferrer.augmentSeenClasses(inferrer.normalize(element));
@@ -2378,6 +2378,14 @@
     return inferrer.unknownConcreteType;
   }
 
+  ConcreteType visitAssert(Send node) {
+    if (!compiler.enableUserAssertions) {
+      return inferrer.nullConcreteType;
+    } else {
+      return visitStaticSend(node);
+    }
+  }
+
   ConcreteType visitStaticSend(Send node) {
     if (elements.getSelector(node).name == const SourceString('JS')) {
       return inferrer.getNativeCallReturnType(node);
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
index 9569030..7f9cef0 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
@@ -554,7 +554,6 @@
   final Element analyzedElement;
   final TypeSystem<T> types;
   final E inferrer;
-  final Compiler compiler;
   final Map<TargetElement, List<LocalsHandler<T>>> breaksFor =
       new Map<TargetElement, List<LocalsHandler<T>>>();
   final Map<TargetElement, List<LocalsHandler>> continuesFor =
@@ -584,10 +583,10 @@
                   this.types,
                   Compiler compiler,
                   [LocalsHandler<T> handler])
-    : this.compiler = compiler,
-      this.analyzedElement = analyzedElement,
+    : this.analyzedElement = analyzedElement,
       this.locals = handler,
-      super(compiler.enqueuer.resolution.getCachedElements(analyzedElement)) {
+      super(compiler.enqueuer.resolution.getCachedElements(analyzedElement),
+            compiler) {
     if (handler != null) return;
     Node node = analyzedElement.parseNode(compiler);
     FieldInitializationScope<T> fieldScope =
@@ -615,6 +614,13 @@
 
   T visitFunctionExpression(FunctionExpression node);
 
+  T visitAssert(Send node) {
+    if (!compiler.enableUserAssertions) {
+      return types.nullType;
+    }
+    return visitStaticSend(node);
+  }
+
   T visitNode(Node node) {
     node.visitChildren(this);
   }
@@ -975,7 +981,7 @@
   T visitThrow(Throw node) {
     node.visitChildren(this);
     locals.seenReturnOrThrow = true;
-    return types.dynamicType;
+    return types.nonNullEmpty();
   }
 
   T visitCatchBlock(CatchBlock node) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index 4ff9f72..acacbe2 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -1665,12 +1665,9 @@
     ClosureClassMap closureData =
         compiler.closureToClassMapper.computeClosureToClassMapping(
             analyzedElement, node, elements);
-    ClosureScope scopeData = closureData.capturingScopes[node];
-    if (scopeData != null) {
-      scopeData.capturedVariableMapping.forEach((variable, field) {
-        locals.setCapturedAndBoxed(variable, field);
-      });
-    }
+    closureData.forEachBoxedVariable((variable, field) {
+      locals.setCapturedAndBoxed(variable, field);
+    });
     if (analyzedElement.isField()) {
       return visit(node.asSendSet().arguments.head);
     }
@@ -1784,8 +1781,10 @@
         compiler.closureToClassMapper.getMappingForNestedFunction(node);
     nestedClosureData.forEachCapturedVariable((variable, field) {
       if (!nestedClosureData.isVariableBoxed(variable)) {
-        // The type may be null for instance contexts: the 'this'
-        // variable and type parameters.
+        if (variable == nestedClosureData.thisElement) {
+          inferrer.recordType(field, thisType);
+        }
+        // The type is null for type parameters.
         if (locals.locals[variable] == null) return;
         inferrer.recordType(field, locals.locals[variable]);
       }
@@ -2269,10 +2268,15 @@
     returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
   }
 
-  void synthesizeForwardingCall(Spannable node, FunctionElement element) {
+  T synthesizeForwardingCall(Spannable node, FunctionElement element) {
     element = element.implementation;
     FunctionElement function = analyzedElement;
     FunctionSignature signature = function.computeSignature(compiler);
+    FunctionSignature calleeSignature = element.computeSignature(compiler);
+    if (!calleeSignature.isCompatibleWith(signature)) {
+      return types.nonNullEmpty();
+    }
+
     List<T> unnamed = <T>[];
     Map<SourceString, T> named = new Map<SourceString, T>();
     signature.forEachRequiredParameter((Element element) {
@@ -2295,6 +2299,7 @@
                                    null,
                                    sideEffects,
                                    inLoop);
+    return inferrer.returnTypeOfElement(element);
   }
 
   T visitReturn(Return node) {
@@ -2307,8 +2312,8 @@
         // the send is just a property access. Therefore we must
         // manually create the [ArgumentsTypes] of the call, and
         // manually register [analyzedElement] as a caller of [element].
-        synthesizeForwardingCall(node.expression, element);
-        recordReturnType(inferrer.returnTypeOfElement(element));
+        T mask = synthesizeForwardingCall(node.expression, element);
+        recordReturnType(mask);
       }
     } else {
       Node expression = node.expression;
diff --git a/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
index 730153d..10d96a0 100644
--- a/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/type_graph_inferrer.dart
@@ -1022,6 +1022,17 @@
         } else {
           recordTypeOfNonFinalField(node, element, type, null);
         }
+        if (Elements.isStaticOrTopLevelField(element)
+            && node.asSendSet() != null
+            && !element.modifiers.isConst()) {
+          var argument = node.asSendSet().arguments.head;
+          // TODO(13429): We could do better here by using the
+          // constant handler to figure out if it's a lazy field or not.
+          if (argument.asSend() != null
+              || (argument.asNewExpression() != null && !argument.isConst())) {
+            recordType(element, types.nullType);
+          }
+        }
       } else {
         recordReturnType(element, type);
       }
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index a192b65..6b7afbb 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -7,10 +7,8 @@
 import '../dart2jslib.dart' hide Selector, TypedSelector;
 import '../tree/tree.dart';
 import '../elements/elements.dart';
-import '../native_handler.dart' as native;
 import '../util/util.dart';
 import '../universe/universe.dart';
-import 'simple_types_inferrer.dart' show SimpleTypesInferrer;
 import 'type_graph_inferrer.dart' show TypeGraphInferrer;
 import 'concrete_types_inferrer.dart' show ConcreteTypesInferrer;
 import '../dart_types.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 5658fe1..4802139 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -54,11 +54,14 @@
   final Set<Element> genericCallMethods;
 
   /**
-   * Set of methods in instantiated classes that use type variables in their
-   * signature and have potentially been closurized.
+   * Set of closures that use type variables in their signature.
    */
-  final Set<Element> closurizedGenericMembers;
+  final Set<Element> genericClosures;
 
+  /**
+   * Set of methods in instantiated classes that are potentially
+   * closurized.
+   */
   final Set<Element> closurizedMembers;
 
   bool usingFactoryWithTypeArguments = false;
@@ -73,7 +76,7 @@
                fieldSetters = new Set<Element>(),
                isChecks = new Set<DartType>(),
                genericCallMethods = new Set<Element>(),
-               closurizedGenericMembers = new Set<Element>(),
+               genericClosures = new Set<Element>(),
                closurizedMembers = new Set<Element>();
 
   bool hasMatchingSelector(Set<Selector> selectors,
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 93a1a04..23ec164 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -169,9 +169,18 @@
       'Error: Cannot resolve constructor "#{constructorName}".');
 
   static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT =
-      const MessageKind(
-          'Error: cannot resolve constructor "#{constructorName}" for implicit'
-          'super call.');
+      const MessageKind('Error: cannot resolve constructor "#{constructorName}"'
+          ' for implicit super call.',
+      howToFix: 'Try explicitly invoking a constructor of the super class',
+      examples: const ["""
+class A {
+  A.foo() {}
+}
+class B extends A {
+  B();
+}
+main() => new B();
+"""]);
 
   static const MessageKind INVALID_UNNAMED_CONSTRUCTOR_NAME = const MessageKind(
       'Error: Unnamed constructor name must be "#{name}".');
@@ -266,6 +275,9 @@
   static const MessageKind CYCLIC_CLASS_HIERARCHY = const MessageKind(
       'Error: "#{className}" creates a cycle in the class hierarchy.');
 
+  static const MessageKind CYCLIC_REDIRECTING_FACTORY = const MessageKind(
+      'Error: Redirecting factory leads to a cyclic redirection.');
+
   static const MessageKind INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
       'Error: Field initializer expected.');
 
@@ -538,12 +550,52 @@
   F f;
 }"""]);
 
+  static const MessageKind FORMAL_DECLARED_CONST = const MessageKind(
+      "Error: A formal parameter can't be declared const.",
+      howToFix: "Try removing 'const'.",
+      examples: const ["""
+foo(const x) {}
+main() => foo(42);
+""", """
+foo({const x}) {}
+main() => foo(42);
+""", """
+foo([const x]) {}
+main() => foo(42);
+"""]);
+
   static const MessageKind CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
       'Error: Cannot instantiate type variable "#{typeVariableName}".');
 
   static const MessageKind CYCLIC_TYPE_VARIABLE = const MessageKind(
       'Warning: Type variable "#{typeVariableName}" is a supertype of itself.');
 
+  static const CYCLIC_TYPEDEF = const MessageKind(
+      "Error: A typedef can't refer to itself.",
+      howToFix: "Try removing all references to '#{typedefName}' "
+                "in the definition of '#{typedefName}'.",
+      examples: const ["""
+typedef F F(); // The return type 'F' is a self-reference.
+main() { F f = null; }"""]);
+
+  static const CYCLIC_TYPEDEF_ONE = const MessageKind(
+      "Error: A typedef can't refer to itself through another typedef.",
+      howToFix: "Try removing all references to "
+                "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
+      examples: const ["""
+typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
+typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
+main() { F f = null; }""",
+"""
+typedef G F(); // The return type 'G' creates a self-reference.
+typedef H G(); // The return type 'H' creates a self-reference.
+typedef H(F f); // The argument type 'F' creates a self-reference.
+main() { F f = null; }"""]);
+
+  static const CYCLIC_TYPEDEF_TYPEVAR = const MessageKind(
+      "Internal Error: Recursive type variable bounds are not "
+      "supported on typedefs.");
+
   static const MessageKind CLASS_NAME_EXPECTED = const MessageKind(
       'Error: Class name expected.');
 
@@ -757,6 +809,29 @@
 main() => foo(1);
 """]);
 
+  static const MessageKind CONST_WITHOUT_INITIALIZER = const MessageKind(
+      "Error: A constant variable must be initialized.",
+      howToFix: "Try adding an initializer or "
+                "removing the 'const' modifier.",
+      examples: const ["""
+void main() {
+  const c; // This constant variable must be initialized.
+}"""]);
+
+  static const MessageKind MEMBER_USES_CLASS_NAME = const MessageKind(
+      "Error: Member variable can't have the same name as the class it is "
+      "declared in.",
+      howToFix: "Try renaming the variable.",
+      examples: const ["""
+class A { var A; }
+main() {
+  var a = new A();
+  a.A = 1;
+}
+""", """
+class A { static var A; }
+main() => A.A = 1;
+"""]);
 
   static const MessageKind WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT =
       const MessageKind(
@@ -840,6 +915,13 @@
       'Error: "!==" is not an operator. '
       'Did you mean "#{lhs} != #{rhs}" or "!identical(#{lhs}, #{rhs})"?');
 
+  static const MessageKind UNSUPPORTED_PREFIX_PLUS = const MessageKind(
+      "Error: '+' is not a prefix operator. ",
+      howToFix: "Try removing '+'.",
+      examples: const [
+          "main() => +2;  // No longer a valid way to write '2'"
+      ]);
+
   static const MessageKind UNSUPPORTED_THROW_WITHOUT_EXP = const MessageKind(
       'Error: No expression after "throw". '
       'Did you mean "rethrow"?');
@@ -988,6 +1070,11 @@
           "static foo; main(){}",
           "external foo; main(){}"]);
 
+  static const MessageKind ABSTRACT_CLASS_INSTANTIATION = const MessageKind(
+      "Warning: Can't instantiate abstract class.",
+      howToFix: DONT_KNOW_HOW_TO_FIX,
+      examples: const ["abstract class A {} main() { new A(); }"]);
+
   static const MessageKind BODY_EXPECTED = const MessageKind(
       "Error: Expected a function body or '=>'.",
       // TODO(ahe): In some scenarios, we can suggest removing the 'static'
diff --git a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
index 4aa4935..be14aa0 100644
--- a/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
+++ b/sdk/lib/_internal/dartdoc/test/dartdoc_test.dart
@@ -17,6 +17,8 @@
 import 'markdown_test.dart';
 
 main() {
+  // Some tests take more than the default 20 second unittest timeout.
+  unittestConfiguration.timeout = null;
   group('isAbsolute', () {
     final doc = new dd.Dartdoc();
 
diff --git a/sdk/lib/_internal/lib/collection_patch.dart b/sdk/lib/_internal/lib/collection_patch.dart
index 670b4ab..7066b05 100644
--- a/sdk/lib/_internal/lib/collection_patch.dart
+++ b/sdk/lib/_internal/lib/collection_patch.dart
@@ -883,6 +883,30 @@
 }
 
 patch class HashSet<E> {
+  patch factory HashSet({ bool equals(E e1, E e2),
+                          int hashCode(E e),
+                          bool isValidKey(potentialKey) }) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _HashSet<E>();
+        }
+        if (identical(identical, equals)) {
+          return new _IdentityHashSet<E>();
+        }
+        hashCode = _defaultHashCode;
+      } else if (equals == null) {
+        equals = _defaultEquals;
+      }
+    } else {
+      if (hashCode == null) hashCode = _defaultHashCode;
+      if (equals == null) equals = _defaultEquals;
+    }
+    return new _CustomHashSet<E>(equals, hashCode, isValidKey);
+  }
+}
+
+class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
   int _length = 0;
 
   // The hash set contents are divided into three parts: one part for
@@ -904,18 +928,20 @@
   // guard against concurrent modifications.
   List _elements;
 
-  patch HashSet();
+  _HashSet();
+
+  Set<E> _newSet() => new _HashSet<E>();
 
   // Iterable.
-  patch Iterator<E> get iterator {
+  Iterator<E> get iterator {
     return new HashSetIterator<E>(this, _computeElements());
   }
 
-  patch int get length => _length;
-  patch bool get isEmpty => _length == 0;
-  patch bool get isNotEmpty => !isEmpty;
+  int get length => _length;
+  bool get isEmpty => _length == 0;
+  bool get isNotEmpty => !isEmpty;
 
-  patch bool contains(Object object) {
+  bool contains(Object object) {
     if (_isStringElement(object)) {
       var strings = _strings;
       return (strings == null) ? false : _hasTableEntry(strings, object);
@@ -931,7 +957,7 @@
   }
 
   // Collection.
-  patch void add(E element) {
+  void add(E element) {
     if (_isStringElement(element)) {
       var strings = _strings;
       if (strings == null) _strings = strings = _newHashTable();
@@ -957,13 +983,13 @@
     }
   }
 
-  patch void addAll(Iterable<E> objects) {
+  void addAll(Iterable<E> objects) {
     for (E each in objects) {
       add(each);
     }
   }
 
-  patch bool remove(Object object) {
+  bool remove(Object object) {
     if (_isStringElement(object)) {
       return _removeHashTableEntry(_strings, object);
     } else if (_isNumericElement(object)) {
@@ -985,21 +1011,25 @@
     }
   }
 
-  patch void removeAll(Iterable<Object> objectsToRemove) {
+  void removeAll(Iterable<Object> objectsToRemove) {
     for (var each in objectsToRemove) {
       remove(each);
     }
   }
 
-  patch void removeWhere(bool test(E element)) {
+  void retainAll(Iterable<Object> elements) {
+    super._retainAll(elements, (o) => o is E);
+  }
+
+  void removeWhere(bool test(E element)) {
     removeAll(_computeElements().where(test));
   }
 
-  patch void retainWhere(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     removeAll(_computeElements().where((E element) => !test(element)));
   }
 
-  patch void clear() {
+  void clear() {
     if (_length > 0) {
       _strings = _nums = _rest = _elements = null;
       _length = 0;
@@ -1063,7 +1093,7 @@
     _elements = null;
   }
 
-  bool _removeHashTableEntry(var table, E element) {
+  bool _removeHashTableEntry(var table, Object element) {
     if (table != null && _hasTableEntry(table, element)) {
       _deleteTableEntry(table, element);
       _length--;
@@ -1086,7 +1116,7 @@
         JS('bool', '(# & 0x3ffffff) === #', element, element);
   }
 
-  static int _computeHashCode(var element) {
+  int _computeHashCode(var element) {
     // We force the hash codes to be unsigned 30-bit integers to avoid
     // issues with problematic elements like '__proto__'. Another
     // option would be to throw an exception if the hash code isn't a
@@ -1111,12 +1141,12 @@
     JS('void', 'delete #[#]', table, key);
   }
 
-  static List _getBucket(var table, var element) {
+  List _getBucket(var table, var element) {
     var hash = _computeHashCode(element);
     return JS('var', '#[#]', table, hash);
   }
 
-  static int _findBucketIndex(var bucket, var element) {
+  int _findBucketIndex(var bucket, var element) {
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
@@ -1139,6 +1169,75 @@
   }
 }
 
+class _IdentityHashSet<E> extends _HashSet<E> {
+  Set<E> _newSet() => new _IdentityHashSet<E>();
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      if (identical(JS('var', '#[#]', bucket, i), element)) return i;
+    }
+    return -1;
+  }
+}
+
+class _CustomHashSet<E> extends _HashSet<E> {
+  _Equality<E> _equality;
+  _Hasher<E> _hasher;
+  _Predicate _validKey;
+  _CustomHashSet(this._equality, this._hasher, bool validKey(potentialKey))
+      : _validKey = (validKey != null) ? validKey : ((x) => x is E);
+
+  Set<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey);
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      if (_equality(JS('var', '#[#]', bucket, i), element)) return i;
+    }
+    return -1;
+  }
+
+  int _computeHashCode(var element) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic elements like '__proto__'. Another
+    // option would be to throw an exception if the hash code isn't a
+    // number.
+    return JS('int', '# & 0x3ffffff', _hasher(element));
+  }
+
+  bool contains(Object object) {
+    if (!_validKey(object)) return false;
+    return super.contains(object);
+  }
+
+  bool remove(Object object) {
+    if (!_validKey(object)) return false;
+    return super.remove(object);
+  }
+
+  bool containsAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (!_validKey(element) || !this.contains(element)) return false;
+    }
+    return true;
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (_validKey(element)) {
+        super.remove(element);
+      }
+    }
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    super._retainAll(elements, _validKey);
+  }
+}
+
 // TODO(kasperl): Share this code with HashMapKeyIterator<E>?
 class HashSetIterator<E> implements Iterator<E> {
   final _set;
@@ -1169,7 +1268,31 @@
   }
 }
 
-patch class LinkedHashSet<E> extends _HashSetBase<E> {
+patch class LinkedHashSet<E> {
+  patch factory LinkedHashSet({ bool equals(E e1, E e2),
+                                int hashCode(E e),
+                                bool isValidKey(potentialKey) }) {
+    if (isValidKey == null) {
+      if (hashCode == null) {
+        if (equals == null) {
+          return new _LinkedHashSet<E>();
+        }
+        if (identical(identical, equals)) {
+          return new _LinkedIdentityHashSet<E>();
+        }
+        hashCode = _defaultHashCode;
+      } else if (equals == null) {
+        equals = _defaultEquals;
+      }
+    } else {
+      if (hashCode == null) hashCode = _defaultHashCode;
+      if (equals == null) equals = _defaultEquals;
+    }
+    return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
+  }
+}
+
+class _LinkedHashSet<E> extends _HashSetBase<E> implements LinkedHashSet<E> {
   int _length = 0;
 
   // The hash set contents are divided into three parts: one part for
@@ -1195,22 +1318,24 @@
   // over.
   int _modifications = 0;
 
-  patch LinkedHashSet();
+  _LinkedHashSet();
+
+  Set<E> _newSet() => new _LinkedHashSet<E>();
 
   void _unsupported(String operation) {
     throw 'LinkedHashSet: unsupported $operation';
   }
 
   // Iterable.
-  patch Iterator<E> get iterator {
+  Iterator<E> get iterator {
     return new LinkedHashSetIterator(this, _modifications);
   }
 
-  patch int get length => _length;
-  patch bool get isEmpty => _length == 0;
-  patch bool get isNotEmpty => !isEmpty;
+  int get length => _length;
+  bool get isEmpty => _length == 0;
+  bool get isNotEmpty => !isEmpty;
 
-  patch bool contains(Object object) {
+  bool contains(Object object) {
     if (_isStringElement(object)) {
       var strings = _strings;
       if (strings == null) return false;
@@ -1229,7 +1354,7 @@
     }
   }
 
-  patch void forEach(void action(E element)) {
+  void forEach(void action(E element)) {
     LinkedHashSetCell cell = _first;
     int modifications = _modifications;
     while (cell != null) {
@@ -1241,18 +1366,18 @@
     }
   }
 
-  patch E get first {
+  E get first {
     if (_first == null) throw new StateError("No elements");
     return _first._element;
   }
 
-  patch E get last {
+  E get last {
     if (_last == null) throw new StateError("No elements");
     return _last._element;
   }
 
   // Collection.
-  patch void add(E element) {
+  void add(E element) {
     if (_isStringElement(element)) {
       var strings = _strings;
       if (strings == null) _strings = strings = _newHashTable();
@@ -1278,13 +1403,13 @@
     }
   }
 
-  patch void addAll(Iterable<E> objects) {
+  void addAll(Iterable<E> objects) {
     for (E object in objects) {
       add(object);
     }
   }
 
-  patch bool remove(Object object) {
+  bool remove(Object object) {
     if (_isStringElement(object)) {
       return _removeHashTableEntry(_strings, object);
     } else if (_isNumericElement(object)) {
@@ -1303,17 +1428,21 @@
     }
   }
 
-  patch void removeAll(Iterable objectsToRemove) {
+  void removeAll(Iterable objectsToRemove) {
     for (var each in objectsToRemove) {
       remove(each);
     }
   }
 
-  patch void removeWhere(bool test(E element)) {
+  void retainAll(Iterable<Object> elements) {
+    super._retainAll(elements, (o) => o is E);
+  }
+
+  void removeWhere(bool test(E element)) {
     _filterWhere(test, true);
   }
 
-  patch void retainWhere(bool test(E element)) {
+  void retainWhere(bool test(E element)) {
     _filterWhere(test, false);
   }
 
@@ -1332,7 +1461,7 @@
     }
   }
 
-  patch void clear() {
+  void clear() {
     if (_length > 0) {
       _strings = _nums = _rest = _first = _last = null;
       _length = 0;
@@ -1346,7 +1475,7 @@
     _setTableEntry(table, element, _newLinkedCell(element));
   }
 
-  bool _removeHashTableEntry(var table, E element) {
+  bool _removeHashTableEntry(var table, Object element) {
     if (table == null) return false;
     LinkedHashSetCell cell = _getTableEntry(table, element);
     if (cell == null) return false;
@@ -1409,7 +1538,7 @@
         JS('bool', '(# & 0x3ffffff) === #', element, element);
   }
 
-  static int _computeHashCode(var element) {
+  int _computeHashCode(var element) {
     // We force the hash codes to be unsigned 30-bit integers to avoid
     // issues with problematic elements like '__proto__'. Another
     // option would be to throw an exception if the hash code isn't a
@@ -1430,12 +1559,12 @@
     JS('void', 'delete #[#]', table, key);
   }
 
-  static List _getBucket(var table, var element) {
+  List _getBucket(var table, var element) {
     var hash = _computeHashCode(element);
     return JS('var', '#[#]', table, hash);
   }
 
-  static int _findBucketIndex(var bucket, var element) {
+  int _findBucketIndex(var bucket, var element) {
     if (bucket == null) return -1;
     int length = JS('int', '#.length', bucket);
     for (int i = 0; i < length; i++) {
@@ -1459,6 +1588,79 @@
   }
 }
 
+class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
+  Set<E> _newSet() => new _LinkedIdentityHashSet<E>();
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      if (identical(cell._element, element)) return i;
+    }
+    return -1;
+  }
+}
+
+class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
+  _Equality<E> _equality;
+  _Hasher<E> _hasher;
+  _Predicate _validKey;
+  _LinkedCustomHashSet(this._equality, this._hasher,
+                       bool validKey(potentialKey))
+      : _validKey = (validKey != null) ? validKey : ((x) => x is E);
+
+  Set<E> _newSet() =>
+      new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey);
+
+  int _findBucketIndex(var bucket, var element) {
+    if (bucket == null) return -1;
+    int length = JS('int', '#.length', bucket);
+    for (int i = 0; i < length; i++) {
+      LinkedHashSetCell cell = JS('var', '#[#]', bucket, i);
+      if (_equality(cell._element, element)) return i;
+    }
+    return -1;
+  }
+
+  int _computeHashCode(var element) {
+    // We force the hash codes to be unsigned 30-bit integers to avoid
+    // issues with problematic elements like '__proto__'. Another
+    // option would be to throw an exception if the hash code isn't a
+    // number.
+    return JS('int', '# & 0x3ffffff', _hasher(element));
+  }
+
+  bool contains(Object object) {
+    if (!_validKey(object)) return false;
+    return super.contains(object);
+  }
+
+  bool remove(Object object) {
+    if (!_validKey(object)) return false;
+    return super.remove(object);
+  }
+
+  bool containsAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (!_validKey(element) || !this.contains(element)) return false;
+    }
+    return true;
+  }
+
+  void removeAll(Iterable<Object> elements) {
+    for (Object element in elements) {
+      if (_validKey(element)) {
+        super.remove(element);
+      }
+    }
+  }
+
+  void retainAll(Iterable<Object> elements) {
+    super._retainAll(elements, _validKey);
+  }
+}
+
 class LinkedHashSetCell {
   final _element;
 
diff --git a/sdk/lib/_internal/lib/constant_map.dart b/sdk/lib/_internal/lib/constant_map.dart
index 60300fc..7febd18 100644
--- a/sdk/lib/_internal/lib/constant_map.dart
+++ b/sdk/lib/_internal/lib/constant_map.dart
@@ -4,40 +4,7 @@
 
 part of _js_helper;
 
-// This class has no constructor. This is on purpose since the instantiation
-// is shortcut by the compiler.
-class ConstantMap<V> implements Map<String, V> {
-  final int length;
-  // A constant map is backed by a JavaScript object.
-  final _jsObject;
-  final List<String> _keys;
-
-  bool containsValue(V needle) {
-    return values.any((V value) => value == needle);
-  }
-
-  bool containsKey(String key) {
-    if (key == '__proto__') return false;
-    return jsHasOwnProperty(_jsObject, key);
-  }
-
-  V operator [](String key) {
-    if (!containsKey(key)) return null;
-    return jsPropertyAccess(_jsObject, key);
-  }
-
-  void forEach(void f(String key, V value)) {
-    _keys.forEach((String key) => f(key, this[key]));
-  }
-
-  Iterable<String> get keys {
-    return new _ConstantMapKeyIterable(this);
-  }
-
-  Iterable<V> get values {
-    return _keys.map((String key) => this[key]);
-  }
-
+abstract class ConstantMap<K, V> implements Map<K, V> {
   bool get isEmpty => length == 0;
 
   bool get isNotEmpty => !isEmpty;
@@ -47,32 +14,109 @@
   _throwUnmodifiable() {
     throw new UnsupportedError("Cannot modify unmodifiable Map");
   }
-  void operator []=(String key, V val) => _throwUnmodifiable();
-  V putIfAbsent(String key, V ifAbsent()) => _throwUnmodifiable();
-  V remove(String key) => _throwUnmodifiable();
+  void operator []=(K key, V val) => _throwUnmodifiable();
+  V putIfAbsent(K key, V ifAbsent()) => _throwUnmodifiable();
+  V remove(K key) => _throwUnmodifiable();
   void clear() => _throwUnmodifiable();
-  void addAll(Map<String, V> other) => _throwUnmodifiable();
+  void addAll(Map<K, V> other) => _throwUnmodifiable();
 }
 
 // This class has no constructor. This is on purpose since the instantiation
 // is shortcut by the compiler.
-class ConstantProtoMap<V> extends ConstantMap<V> {
+class ConstantStringMap<K, V> extends ConstantMap<K, V> {
+  final int length;
+  // A constant map is backed by a JavaScript object.
+  final _jsObject;
+  final List<K> _keys;
+
+  bool containsValue(V needle) {
+    return values.any((V value) => value == needle);
+  }
+
+  bool containsKey(Object key) {
+    if (key is! String) return false;
+    if (key == '__proto__') return false;
+    return jsHasOwnProperty(_jsObject, key);
+  }
+
+  V operator [](Object key) {
+    if (key is! String) return null;
+    if (!containsKey(key)) return null;
+    return jsPropertyAccess(_jsObject, key);
+  }
+
+  void forEach(void f(K key, V value)) {
+    _keys.forEach((key) => f(key, this[key]));
+  }
+
+  Iterable<K> get keys {
+    return new _ConstantMapKeyIterable<K>(this);
+  }
+
+  Iterable<V> get values {
+    return _keys.map((key) => this[key]);
+  }
+}
+
+// This class has no constructor. This is on purpose since the instantiation
+// is shortcut by the compiler.
+class ConstantProtoMap<K, V> extends ConstantStringMap<K, V> {
   final V _protoValue;
 
-  bool containsKey(String key) {
+  bool containsKey(Object key) {
     if (key == '__proto__') return true;
     return super.containsKey(key);
   }
 
-  V operator [](String key) {
+  V operator [](Object key) {
     if (key == '__proto__') return _protoValue;
     return super[key];
   }
 }
 
-class _ConstantMapKeyIterable extends IterableBase<String> {
-  ConstantMap _map;
+class _ConstantMapKeyIterable<K> extends IterableBase<K> {
+  ConstantStringMap<K, dynamic> _map;
   _ConstantMapKeyIterable(this._map);
 
-  Iterator<String> get iterator => _map._keys.iterator;
+  Iterator<K> get iterator => _map._keys.iterator;
+}
+
+// This class has no constructor. This is on purpose since the instantiation
+// is shortcut by the compiler.
+class GeneralConstantMap<K, V> extends ConstantMap<K, V> {
+  // [_jsData] holds a key-value pair list.
+  final _jsData;
+
+  // We cannot create the backing map on creation since hashCode interceptors
+  // have not been defined when constants are created.
+  Map<K, V> _getMap() {
+    if (JS('bool', r'!this.$map')) {
+      JS('', r'this.$map = #', makeConstantMap(_jsData));
+    }
+    return JS('Map', r'this.$map');
+  }
+
+  bool containsValue(V needle) {
+    return _getMap().containsValue(needle);
+  }
+
+  bool containsKey(Object key) {
+    return _getMap().containsKey(key);
+  }
+
+  V operator [](Object key) {
+    return _getMap()[key];
+  }
+
+  void forEach(void f(K key, V value)) {
+    _getMap().forEach(f);
+  }
+
+  Iterable<K> get keys {
+    return _getMap().keys;
+  }
+
+  Iterable<V> get values {
+    return _getMap().values;
+  }
 }
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index 1837aaf..b87d045 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -59,6 +59,9 @@
   patch static _identical(String path1, String path2) {
     throw new UnsupportedError("FileSystemEntity._identical");
   }
+  patch static _resolveSymbolicLinks(String path) {
+    throw new UnsupportedError("FileSystemEntity._resolveSymbolicLinks");
+  }
 }
 
 patch class _File {
@@ -98,9 +101,6 @@
   patch static int _openStdio(int fd) {
     throw new UnsupportedError("File._openStdio");
   }
-  patch static _fullPath(String path) {
-    throw new UnsupportedError("File._fullPath");
-  }
 }
 
 patch class _RandomAccessFile {
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index f31a0b8..073436e 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -1422,17 +1422,35 @@
   }
 }
 
+int _objectHashCode(var object) {
+  if (object == null || JS('bool', "typeof # != 'object'", object)) {
+    return object.hashCode;
+  } else {
+    return Primitives.objectHashCode(object);
+  }
+}
+
 /**
  * Called by generated code to build a map literal. [keyValuePairs] is
  * a list of key, value, key, value, ..., etc.
  */
-makeLiteralMap(List keyValuePairs) {
-  Iterator iterator = keyValuePairs.iterator;
-  Map result = new LinkedHashMap();
-  while (iterator.moveNext()) {
-    String key = iterator.current;
-    iterator.moveNext();
-    var value = iterator.current;
+makeLiteralMap(keyValuePairs) {
+  return fillLiteralMap(keyValuePairs, new LinkedHashMap());
+}
+
+makeConstantMap(keyValuePairs) {
+  return fillLiteralMap(keyValuePairs,
+      new LinkedHashMap(equals: identical, hashCode: _objectHashCode));
+}
+
+fillLiteralMap(keyValuePairs, Map result) {
+  // TODO(johnniwinther): Use JSArray to optimize this code instead of calling
+  // [getLength] and [getIndex].
+  int index = 0;
+  int length = getLength(keyValuePairs);
+  while (index < length) {
+    var key = getIndex(keyValuePairs, index++);
+    var value = getIndex(keyValuePairs, index++);
     result[key] = value;
   }
   return result;
diff --git a/sdk/lib/_internal/lib/js_mirrors.dart b/sdk/lib/_internal/lib/js_mirrors.dart
index 948a0d8..cf002e8 100644
--- a/sdk/lib/_internal/lib/js_mirrors.dart
+++ b/sdk/lib/_internal/lib/js_mirrors.dart
@@ -418,10 +418,7 @@
 }
 
 ClassMirror reflectType(Type key) {
-  // TODO(ahe): Don't discard type arguments to support
-  // [ClassMirror.isOriginalDeclaration] and [ClassMirror.originalDeclaration]
-  // correctly.
-  return reflectClassByMangledName(getMangledTypeName(key).split('<')[0]);
+  return reflectClassByMangledName(getMangledTypeName(key));
 }
 
 ClassMirror reflectClassByMangledName(String mangledName) {
@@ -437,6 +434,15 @@
   var mirror = JsCache.fetch(classMirrors, mangledName);
   if (mirror != null) return mirror;
   disableTreeShaking();
+  int typeArgIndex = mangledName.indexOf("<");
+  if (typeArgIndex != -1) {
+    mirror = new JsTypeBoundClassMirror(
+        reflectClassByMangledName(mangledName.substring(0, typeArgIndex)),
+        // Remove the angle brackets enclosing the type arguments.
+        mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
+    JsCache.update(classMirrors, mangledName, mirror);
+    return mirror;
+  }
   var constructorOrInterceptor =
       Primitives.getConstructorOrInterceptor(mangledName);
   if (constructorOrInterceptor == null) {
@@ -581,11 +587,12 @@
 
   ClassMirror get originalDeclaration => this;
 
-  // TODO(ahe): Implement these.
-  Map<Symbol, TypeVariableMirror> get typeVariables {
+  // TODO(ahe): Implement this.
+  List<TypeVariableMirror> get typeVariables {
     throw new UnimplementedError();
   }
-  Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError();
+
+  List<TypeMirror> get typeArguments => new List();
 }
 
 abstract class JsObjectMirror implements ObjectMirror {
@@ -709,7 +716,7 @@
     // identical. Otherwise, use the primitive identity hash to maintain
     // correctness even if a user-defined hashCode returns different values for
     // successive invocations.
-    var h = ((JS('bool', 'typeof # != "object"', reflectee)) || 
+    var h = ((JS('bool', 'typeof # != "object"', reflectee)) ||
              (reflectee == null))
         ? reflectee.hashCode
         : Primitives.objectHashCode(reflectee);
@@ -724,6 +731,155 @@
   MirrorSystem get mirrors => currentJsMirrorSystem;
 }
 
+/**
+ * ClassMirror for generic classes where the type parameters are bound.
+ *
+ * [typeArguments] will return a list of the type arguments, in constrast
+ * to JsCLassMirror that returns an empty list since it represents original
+ * declarations and classes that are not generic.
+ */
+class JsTypeBoundClassMirror implements ClassMirror {
+  final JsClassMirror _class;
+
+  /**
+   * When instantiated this field will hold a string representing the list of
+   * type arguments for the class, i.e. what is inside the outermost angle
+   * brackets. Then, when get typeArguments is called the first time, the string
+   * is parsed into the actual list of TypeMirrors, and the field is overridden
+   * with this value.
+   */
+  var _typeArgs;
+
+  JsTypeBoundClassMirror(this._class, this._typeArgs);
+
+  List<TypeVariableMirror> get typeVariables => _class.typeVariables;
+
+  List<TypeMirror> get typeArguments {
+    if (_typeArgs is! String) return _typeArgs;
+    List result = new List();
+    if (_typeArgs.indexOf('<') == -1) {
+      for (String s in _typeArgs.split(',')) {
+        result.add(reflectClassByMangledName(s.trim()));
+      }
+    } else {
+      int level = 0;
+      StringBuffer currentTypeArg = new StringBuffer();
+
+      addCurrentTypeArg() {
+        var classMirror = reflectClassByMangledName(currentTypeArg.toString());
+        result.add(classMirror);
+        currentTypeArg.clear();
+      }
+
+      for (int i = 0; i < _typeArgs.length; i++) {
+        var character = _typeArgs[i];
+        if (character == ' ') {
+          continue;
+        } else if (character == '<') {
+          currentTypeArg.write(character);
+          level++;
+        } else if (character == '>') {
+          currentTypeArg.write(character);
+          level--;
+        } else if (character == ',') {
+          if (level > 0) {
+            currentTypeArg.write(character);
+          } else {
+            addCurrentTypeArg();
+          }
+        } else {
+          currentTypeArg.write(character);
+        }
+      }
+      addCurrentTypeArg();
+    }
+    return _typeArgs = new UnmodifiableListView(result);
+  }
+
+  Map<Symbol, MethodMirror> get constructors => _class.constructors;
+
+  Map<Symbol, MethodMirror> get methods => _class.methods;
+
+  Map<Symbol, MethodMirror> get getters => _class.getters;
+
+  Map<Symbol, MethodMirror> get setters => _class.setters;
+
+  Map<Symbol, VariableMirror> get variables => _class.variables;
+
+  Map<Symbol, Mirror> get members => _class.members;
+
+  InstanceMirror setField(Symbol fieldName, Object arg) {
+    return _class.setField(fieldName, arg);
+  }
+
+  InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName);
+
+  InstanceMirror newInstance(Symbol constructorName,
+                             List positionalArguments,
+                             [Map<Symbol, dynamic> namedArguments]) {
+    return _class.newInstance(constructorName,
+                              positionalArguments,
+                              namedArguments);
+  }
+
+  Future<InstanceMirror> newInstanceAsync(
+      Symbol constructorName,
+      List positionalArguments,
+      [Map<Symbol, dynamic> namedArguments]) {
+    return _class.newInstanceAsync(constructorName,
+                                   positionalArguments,
+                                   namedArguments);
+  }
+
+  JsLibraryMirror get owner => _class.owner;
+
+  List<InstanceMirror> get metadata => _class.metadata;
+
+  ClassMirror get superclass => _class.superclass;
+
+  InstanceMirror invoke(Symbol memberName,
+                        List positionalArguments,
+                        [Map<Symbol,dynamic> namedArguments]) {
+    return _class.invoke(memberName, positionalArguments, namedArguments);
+  }
+
+  bool get isOriginalDeclaration => false;
+
+  ClassMirror get originalDeclaration => _class;
+
+  List<ClassMirror> get superinterfaces => _class.superinterfaces;
+
+  Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
+    return _class.getFieldAsync(fieldName);
+  }
+
+  bool get hasReflectedType => _class.hasReflectedType;
+
+  Future<InstanceMirror> invokeAsync(Symbol memberName,
+                                     List positionalArguments,
+                                     [Map<Symbol, dynamic> namedArguments]) {
+    return _class.invokeAsync(memberName, positionalArguments, namedArguments);
+  }
+
+  bool get isPrivate => _class.isPrivate;
+
+  bool get isTopLevel => _class.isTopLevel;
+
+  SourceLocation get location => _class.location;
+
+  MirrorSystem get mirrors => _class.mirrors;
+
+  Symbol get qualifiedName => _class.qualifiedName;
+
+  Type get reflectedType => _class.reflectedType;
+
+  Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
+    return _class.setFieldAsync(fieldName, value);
+  }
+
+  Symbol get simpleName => _class.simpleName;
+}
+
 class JsClassMirror extends JsTypeMirror with JsObjectMirror
     implements ClassMirror {
   final String _mangledName;
@@ -1088,9 +1244,9 @@
   }
 
   // TODO(ahe): Implement these.
-  Map<Symbol, TypeVariableMirror> get typeVariables
+  List<TypeVariableMirror> get typeVariables
       => throw new UnimplementedError();
-  Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError();
+  List<TypeMirror> get typeArguments => new List();
 }
 
 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
@@ -1460,6 +1616,10 @@
   JsFunctionTypeMirror get value => referent;
 
   String get _prettyName => 'TypedefMirror';
+
+  // TODO(zarah): This method doesn't belong here, since TypedefMirror shouldn't
+  // be a subtype of ClassMirror.
+  ClassMirror get originalDeclaration => this;
 }
 
 class JsFunctionTypeMirror implements FunctionTypeMirror {
diff --git a/sdk/lib/_internal/lib/mirrors_patch.dart b/sdk/lib/_internal/lib/mirrors_patch.dart
index 2fddaef..4700984 100644
--- a/sdk/lib/_internal/lib/mirrors_patch.dart
+++ b/sdk/lib/_internal/lib/mirrors_patch.dart
@@ -18,4 +18,6 @@
 
 patch InstanceMirror reflect(Object reflectee) => js.reflect(reflectee);
 
-patch ClassMirror reflectClass(Type key) => js.reflectType(key);
+patch ClassMirror reflectClass(Type key) {
+  return js.reflectType(key).originalDeclaration;
+}
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 9dd5a3c..bb850fa 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -18,8 +18,10 @@
 test/install/hosted/install_test: Pass, Fail # Issue 12837
 test/install/hosted/install_transitive_test: Pass, Fail # Issue 12837
 test/install/hosted/repair_cache_test: Pass, Fail # Issue 12837
+test/install/hosted/stay_locked_if_compatible_test: Pass, Fail # Issue 12837
 test/install/hosted/stay_locked_if_new_is_satisfied_test: Pass, Fail # Issue 12837
 test/install/hosted/stay_locked_test: Pass, Fail # Issue 12837
+test/install/hosted/resolve_constraints_test: Pass, Fail # Issue 12837
 test/install/hosted/unlock_if_incompatible_test: Pass, Fail # Issue 12837
 test/install/hosted/unlock_if_new_is_unsatisfied_test: Pass, Fail # Issue 12837
 test/install/hosted/version_negotiation_test: Pass, Fail # Issue 12837
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 6b6c760..ab4b666 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -138,11 +138,11 @@
    * A future whose value is available in the next event-loop iteration.
    *
    * If [value] is not a [Future], using this constructor is equivalent
-   * to [:new Future.sync(() => value):].
+   * to [:new Future<T>.sync(() => value):].
    *
    * See [Completer] to create a Future and complete it later.
    */
-  factory Future.value([T value]) {
+  factory Future.value([value]) {
     return new _Future<T>.immediate(value);
   }
 
@@ -365,7 +365,7 @@
  *
  * If you already have a Future, you probably don't need a Completer.
  * Instead, you can usually use [Future.then], which returns a Future:
- * 
+ *
  *     Future doStuff(){
  *       return someAsyncOperation().then((result) {
  *         // Do something.
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index ea8f902..a149161 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -143,7 +143,8 @@
       : _onValueCallback = null, _errorTestCallback = null,
         _onErrorCallback = null, _whenCompleteActionCallback = null;
 
-  _Future.immediate(T value)
+  /// Valid types for value: `T` or `Future<T>`.
+  _Future.immediate(value)
         : _onValueCallback = null, _errorTestCallback = null,
           _onErrorCallback = null, _whenCompleteActionCallback = null {
     _asyncComplete(value);
@@ -321,6 +322,14 @@
     // Otherwise the value could complete with an error and report an
     // unhandled error, even though we know we are already going to listen to
     // it.
+
+    // Assign to typed variables so we get earlier checks in checked mode.
+    if (value is Future) {
+      Future<T> typedFuture = value;
+    } else {
+      T typedValue = value;
+    }
+
     if (value is Future &&
         (value is! _Future || !(value as _Future)._isComplete)) {
       // Case 2 from above. We need to register.
diff --git a/sdk/lib/collection/hash_set.dart b/sdk/lib/collection/hash_set.dart
index 147d1ca..f1241a8 100644
--- a/sdk/lib/collection/hash_set.dart
+++ b/sdk/lib/collection/hash_set.dart
@@ -16,7 +16,7 @@
   }
 
   /** Create a new Set of the same type as this. */
-  Set _newSet();
+  HashSet<E> _newSet();
 
   Set<E> intersection(Set<Object> other) {
     Set<E> result = _newSet();
@@ -44,16 +44,27 @@
     return result;
   }
 
-  void retainAll(Iterable objectsToRetain) {
-    Set retainSet;
-    if (objectsToRetain is Set) {
-      retainSet = objectsToRetain;
-    } else {
-      retainSet = objectsToRetain.toSet();
+  void _retainAll(Iterable objectsToRetain, bool isValidKey(Object o)) {
+    // TODO(lrn): Consider optimizing table based versions by
+    // building a new table of the entries to retain.
+    Set retainSet = _newSet();
+    for (Object o in objectsToRetain) {
+      if (isValidKey(o)) {
+        retainSet.add(o);
+      }
     }
     retainWhere(retainSet.contains);
   }
 
+  List<E> toList({bool growable: true}) {
+    List<E> result = new List<E>()..length = this.length;
+    int i = 0;
+    for (E element in this) result[i++] = element;
+    return result;
+  }
+
+  Set<E> toSet() => _newSet()..addAll(this);
+
   // TODO(zarah) Remove this, and let it be inherited by IterableBase
   String toString() => IterableMixinWorkaround.toStringIterable(this, '{', '}');
 }
@@ -61,49 +72,50 @@
 /**
  * A [HashSet] is a hash-table based [Set] implementation.
  *
- * The elements of a `HashSet` must have consistent [Object.operator==]
- * and [Object.hashCode] implementations. This means that the `==` operator
+ * The elements of a `HashSet` must have consistent equality
+ * and hashCode implementations. This means that the equals operation
  * must define a stable equivalence relation on the elements (reflexive,
- * anti-symmetric, transitive, and consistent over time), and that `hashCode`
- * must be the same for objects that are considered equal by `==`.
+ * anti-symmetric, transitive, and consistent over time), and that the hashCode
+ * must consistent with equality, so that the same for objects that are
+ * considered equal.
  *
  * The set allows `null` as an element.
  *
  * Most simple operations on `HashSet` are done in constant time: [add],
  * [contains], [remove], and [length].
  */
-class HashSet<E> extends _HashSetBase<E> {
-  external HashSet();
+class HashSet<E> implements Set<E> {
+  /**
+   * Create a hash set using the provided [equals] as equality.
+   *
+   * The provided [equals] must define a stable equivalence relation, and
+   * [hashCode] must be consistent with [equals]. If the [equals] or [hashCode]
+   * methods won't work on all objects, but only to instances of E, the
+   * [isValidKey] predicate can be used to restrict the keys that they are
+   * applied to. Any key for which [isValidKey] returns false is automatically
+   * assumed to not be in the set.
+   *
+   * If [equals], [hashCode] and [isValidKey] are omitted, the set uses
+   * the objects' intrinsic [Object.operator==] and [Object.hashCode].
+   *
+   * If [isValidKey] is omitted, it defaults to testing if the object is an
+   * [E] instance.
+   *
+   * If [equals] is [identical], this creates an identity set. Any hashCode
+   * is compatible with [identical], and it applies to all objects, so
+   * [hashCode] and [isValidKey] can safely be omitted.
+   */
+  external factory HashSet({ bool equals(E e1, E e2),
+                             int hashCode(E e),
+                             bool isValidKey(potentialKey) });
 
+  /**
+   * Create a hash set containing the elements of [iterable].
+   *
+   * Creates a hash set as by `new HashSet<E>()` and adds each element of
+   * `iterable` to this set in the order they are iterated.
+   */
   factory HashSet.from(Iterable<E> iterable) {
     return new HashSet<E>()..addAll(iterable);
   }
-
-  // Iterable.
-  external Iterator<E> get iterator;
-
-  external int get length;
-
-  external bool get isEmpty;
-
-  external bool get isNotEmpty;
-
-  external bool contains(Object object);
-
-  // Set.
-  external void add(E element);
-
-  external void addAll(Iterable<E> objects);
-
-  external bool remove(Object object);
-
-  external void removeAll(Iterable<Object> objectsToRemove);
-
-  external void removeWhere(bool test(E element));
-
-  external void retainWhere(bool test(E element));
-
-  external void clear();
-
-  Set<E> _newSet() => new HashSet<E>();
 }
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index 28b7ce2..d9aadf2 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -21,55 +21,13 @@
  * Most simple operations on `HashSet` are done in constant time: [add],
  * [contains], [remove], and [length].
  */
-class LinkedHashSet<E> extends _HashSetBase<E> {
+class LinkedHashSet<E> implements HashSet<E> {
 
-  external LinkedHashSet();
+  external factory LinkedHashSet({ bool equals(E e1, E e2),
+                                   int hashCode(E e),
+                                   bool isValidKey(potentialKey) });
 
   factory LinkedHashSet.from(Iterable<E> iterable) {
     return new LinkedHashSet<E>()..addAll(iterable);
   }
-
-  // Iterable.
-
-  /** Return an iterator that iterates over elements in insertion order. */
-  external Iterator<E> get iterator;
-
-  external int get length;
-
-  external bool get isEmpty;
-
-  external bool get isNotEmpty;
-
-  external bool contains(Object object);
-
-  /** Perform an operation on each element in insertion order. */
-  external void forEach(void action(E element));
-
-  external E get first;
-
-  external E get last;
-
-  E get single {
-    if (length == 1) return first;
-    var message = (length == 0) ? "No Elements" : "Too many elements";
-    throw new StateError(message);
-  }
-
-  // Collection.
-  external void add(E element);
-
-  external void addAll(Iterable<E> objects);
-
-  external bool remove(Object object);
-
-  external void removeAll(Iterable objectsToRemove);
-
-  external void removeWhere(bool test(E element));
-
-  external void retainWhere(bool test(E element));
-
-  external void clear();
-
-  // Set.
-  Set<E> _newSet() => new LinkedHashSet<E>();
 }
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 3c27d04..d311785 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -192,7 +192,7 @@
    * Removes all objects from this list;
    * the length of the list becomes zero.
    *
-   * Throws an [UnsupportedError], and retains all objects, if this 
+   * Throws an [UnsupportedError], and retains all objects, if this
    * is a fixed-length list.
    */
   void clear();
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 9c9eb23..8e4cf12 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -88,6 +88,10 @@
    */
   Directory createTempSync();
 
+  Future<String> resolveSymbolicLinks();
+
+  String resolveSymbolicLinksSync();
+
   /**
    * Renames this directory. Returns a [:Future<Directory>:] that completes
    * with a [Directory] instance for the renamed directory.
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index ae08c22..2e9df8e 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -156,14 +156,23 @@
   /**
    * Get the canonical full path corresponding to the file path.
    * Returns a [:Future<String>:] that completes with the path.
+   *
+   * *FullPath is deprecated.  Use absolutePath or resolveSymbolicLinks
+   * instead.  FullPath will be removed the 23rd of September, 2013.*
    */
+  @deprecated
   Future<String> fullPath();
 
   /**
    * Synchronously get the canonical full path corresponding to the file path.
    *
    * Throws a [FileException] if the operation fails.
+   *
+   * *FullPathSync is deprecated.  Use absolutePathSync or
+   * resolveSymbolicLinksSync instead.  FullPathSync will be removed
+   * the 23rd of September, 2013.*
    */
+  @deprecated
   String fullPathSync();
 
   /**
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 86acf77..1ec4b11 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -204,7 +204,7 @@
 const int _DELETE_REQUEST = 2;
 const int _RENAME_REQUEST = 3;
 const int _OPEN_REQUEST = 4;
-const int _FULL_PATH_REQUEST = 5;
+const int _RESOLVE_SYMBOLIC_LINKS_REQUEST = 5;
 const int _CLOSE_REQUEST = 6;
 const int _POSITION_REQUEST = 7;
 const int _SET_POSITION_REQUEST = 8;
@@ -446,28 +446,9 @@
     return new _RandomAccessFile(id, "");
   }
 
-  Future<String> fullPath() {
-    _ensureFileService();
-    List request = new List(2);
-    request[0] = _FULL_PATH_REQUEST;
-    request[1] = path;
-    return _fileService.call(request).then((response) {
-      if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response,
-                                     "Cannot retrieve full path",
-                                     path);
-      }
-      return response;
-    });
-  }
+  Future<String> fullPath() => resolveSymbolicLinks();
 
-  external static _fullPath(String path);
-
-  String fullPathSync() {
-    var result = _fullPath(path);
-    throwIfError(result, "Cannot retrieve full path", path);
-    return result;
-  }
+  String fullPathSync() => resolveSymbolicLinksSync();
 
   Stream<List<int>> openRead([int start, int end]) {
     return new _FileStream(path, start, end);
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index ab2b7d3..10d632b 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -221,6 +221,68 @@
   FileSystemEntity renameSync(String newPath);
 
   /**
+   * Resolves the path of a file system object relative to the
+   * current working directory, resolving all symbolic links on
+   * the path and resolving all '..' and '.' path segments.
+   * [resolveSymbolicLinks] returns a [:Future<String>:]
+   *
+   * [resolveSymbolicLinks] uses the operating system's native filesystem api
+   * to resolve the path, using the realpath function on linux and
+   * Mac OS, and the GetFinalPathNameByHandle function on Windows.
+   * If the path does not point to an existing file system object,
+   * [resolveSymbolicLinks] completes the returned Future with an FileException.
+   *
+   * On Windows, symbolic links are resolved to their target before applying
+   * a '..' that follows, and on other platforms, the '..' is applied to the
+   * symbolic link without resolving it.  The second behavior can be emulated
+   * on Windows by processing any '..' segments before calling
+   * [resolveSymbolicLinks].  One way of doing this is with the URI class:
+   * [:new Uri.parse('.').resolveUri(new Uri.file(input)).toFilePath();],
+   * since [resolve] removes '..' segments.
+   */
+  Future<String> resolveSymbolicLinks() {
+    // Get a new file service port for each request.  We could also cache one.
+    var service = _FileUtils._newServicePort();
+    List request = new List(2);
+    request[0] = _RESOLVE_SYMBOLIC_LINKS_REQUEST;
+    request[1] = path;
+    return service.call(request).then((response) {
+      if (_isErrorResponse(response)) {
+        throw _exceptionFromResponse(response,
+                                     "Cannot resolve symbolic links",
+                                     path);
+      }
+      return response;
+    });
+  }
+
+  /**
+   * Resolves the path of a file system object relative to the
+   * current working directory, resolving all symbolic links on
+   * the path and resolving all '..' and '.' path segments.
+   *
+   * [resolveSymbolicLinksSync] uses the operating system's native
+   * filesystem api to resolve the path, using the realpath function
+   * on linux and Mac OS, and the GetFinalPathNameByHandle function on Windows.
+   * If the path does not point to an existing file system object,
+   * [resolveSymbolicLinksSync] throws a FileException.
+   *
+   * On Windows, symbolic links are resolved to their target before applying
+   * a '..' that follows, and on other platforms, the '..' is applied to the
+   * symbolic link without resolving it.  The second behavior can be emulated
+   * on Windows by processing any '..' segments before calling
+   * [resolveSymbolicLinks].  One way of doing this is with the URI class:
+   * [:new Uri.parse('.').resolveUri(new Uri.file(input)).toFilePath();],
+   * since [resolve] removes '..' segments.
+   */
+  String resolveSymbolicLinksSync() {
+    var result = _resolveSymbolicLinks(path);
+    _throwIfError(result, "Cannot resolve symbolic links", path);
+    return result;
+  }
+
+
+  /**
    * Calls the operating system's stat() function on the [path] of this
    * [FileSystemEntity].  Identical to [:FileStat.stat(this.path):].
    *
@@ -316,7 +378,7 @@
   void _deleteSync({recursive: false});
 
   /**
-   * Synchronously checks whether two paths refer to the same object in the
+   * Checks whether two paths refer to the same object in the
    * file system. Returns a [:Future<bool>:] that completes with the result.
    *
    * Comparing a link to its target returns false, as does comparing two links
@@ -481,6 +543,7 @@
 
   external static _getType(String path, bool followLinks);
   external static _identical(String path1, String path2);
+  external static _resolveSymbolicLinks(String path);
 
   static int _getTypeSync(String path, bool followLinks) {
     var result = _getType(path, followLinks);
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 474aa51..c889a70 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -65,6 +65,10 @@
    */
   Future<Link> update(String target);
 
+  Future<String> resolveSymbolicLinks();
+
+  String resolveSymbolicLinksSync();
+
   /**
    * Renames this link. Returns a `Future<Link>` that completes
    * with a [Link] instance for the renamed link.
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 313026f..f6fc7fa 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -748,32 +748,30 @@
   Map<Symbol, MethodMirror> get constructors;
 
   /**
-   * An immutable map from names to mirrors for all type variables for
-   * this type.
-   * If this type is a generic declaration or an invocation of
-   * a generic declaration, the returned map has the names of the formal
-   * type parameters of the original declaration as its keys, and
-   * each such key maps to a TypeVariableMirror on the corresponding
-   * type variable. Otherwise, the returned map is empty.
+   * An immutable list with mirrors for all type variables for this type.
    *
-   * This map preserves the order of declaration of the type variables.
+   * If this type is a generic declaration or an invocation of a generic
+   * declaration, the returned list contains mirrors on the type variables.
+   * Otherwise, the returned list is empty.
+   *
+   * This list preserves the order of declaration of the type variables.
    */
-  Map<Symbol, TypeVariableMirror> get typeVariables;
+  List<TypeVariableMirror> get typeVariables;
 
   /**
-   * An immutable map from names to mirrors for all type arguments for
-   * this type.  The keys of the map are the names of the
-   * corresponding type variables.
+   * An immutable list with mirrors for all type arguments for
+   * this type.
    *
    * If the the reflectee is an invocation of a generic class,
    * the type arguments are the bindings of its type parameters.
    * If the reflectee is the original declaration of a generic,
-   * it has no type arguments and this method returns an empty map.
+   * it has no type arguments and this method returns an empty list.
    * If the reflectee is a not generic, then
-   * it has no type arguments and this method returns an empty map.
-   * This map preserves the order of declaration of the type variables.
+   * it has no type arguments and this method returns an empty list.
+   *
+   * This list preserves the order of declaration of the type variables.
    */
-  Map<Symbol, TypeMirror> get typeArguments;
+  List<TypeMirror> get typeArguments;
 
   /**
    * Is this the original declaration of this type?
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index 8befe3d..845974e 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -40,14 +40,11 @@
 LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
 
 # co19 issue #380, Strings class has been removed
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: fail, OK
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
 
 # co19 issue #400, collection library reorg
-LibTest/core/String/String_class_A01_t01: fail, OK
 LibTest/core/String/concat_A01_t01: fail, OK
 LibTest/core/String/concat_A02_t01: fail, OK
-LibTest/core/String/hashCode_A01_t01: fail, OK
 LibTest/core/Set/isSubsetOf_A01_t01: fail, OK
 LibTest/core/Set/isSubsetOf_A01_t02: fail, OK
 
@@ -64,20 +61,9 @@
 Language/05_Variables/05_Variables_A13_t01: fail, OK
 Language/07_Classes/07_Classes_A02_t11: fail, OK
 
-# co19 issue #464, not initialized final instance variable is warning, not error
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: fail
-
 # co19 issue #442, undefined name "Expect"
 Language/15_Types/4_Interface_Types_A08_t03: fail, OK
 
-# co19 issue #448, Collection was removed
-LibTest/collection/Queue/Queue.from_A01_t01: fail, OK
-LibTest/collection/Queue/Queue.from_A01_t02: fail, OK
-LibTest/core/Set/intersection_A01_t02: fail, OK
-
-# co19 issue 452, more method in Iterable
-LibTest/core/Set/Set.from_A01_t02: fail, OK
-
 # co19 issue #455, undeclared identifier is static warning
 Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t10: fail, OK
 Language/13_Statements/04_Local_Function_Declaration_A02_t02: fail, OK
@@ -131,120 +117,8 @@
 Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail, OK
 Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail, OK
 
-# co19 issue #565: not implemented members in non-abstract class
-LibTest/async/EventTransformStream/asBroadcastStream_A01_t02: fail, OK
-LibTest/async/Stream/asBroadcastStream_A01_t02: fail, OK
-LibTest/async/Stream/asBroadcastStream_A02_t01: fail, OK
-LibTest/async/Stream/isBroadcast_A01_t01: fail, OK
-LibTest/async/Stream/isBroadcast_A01_t02: fail, OK
+Language/07_Classes/1_Instance_Methods_A03_t06: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
 
-# co19 issue #566: Undefined class 'T'
-LibTest/async/EventTransformStream/distinct_A01_t02: fail, OK
-LibTest/async/EventTransformStream/EventTransformStream_A01_t02: fail, OK
-LibTest/async/EventTransformStream/expand_A01_t01: fail, OK
-LibTest/async/Stream/contains_A03_t01: fail, OK
-LibTest/async/Stream/distinct_A01_t01: fail, OK
-LibTest/async/Stream/distinct_A01_t02: fail, OK
-LibTest/async/Stream/expand_A01_t01: fail, OK
-LibTest/core/List/List.filled_A01_t01: fail, OK
-LibTest/core/List/List.generate_A01_t01: fail, OK
-LibTest/core/List/List.generate_A01_t02: fail, OK
-LibTest/core/List/List.generate_A01_t03: fail, OK
-LibTest/core/List/replaceRange_A01_t01: fail, OK
-LibTest/core/List/replaceRange_A01_t02: fail, OK
-LibTest/core/List/skipWhile_A02_t01: fail, OK
-LibTest/core/List/takeWhile_A02_t01: fail, OK
-
-# co19 issue #567: Undefined name 'value'
-LibTest/async/EventTransformStream/drain_A02_t01: fail, OK
-LibTest/async/EventTransformStream/drain_A02_t02: fail, OK
-LibTest/async/Stream/drain_A02_t01: fail, OK
-LibTest/async/Stream/drain_A02_t02: fail, OK
-
-# co19 issue #568: Undefined name 'Expec'
-LibTest/async/EventTransformStream/first_A02_t01: fail, OK
-
-# co19 issue #569: There is no such getter 'message' in 'Object'
-LibTest/async/EventTransformStream/handleError_A03_t01: fail, OK
-LibTest/async/EventTransformStream/listen_A03_t01: fail, OK
-LibTest/async/Stream/handleError_A03_t01: fail, OK
-LibTest/async/Stream/listen_A03_t01: fail, OK
-
-# co19 issue #570: undefined name 'events1'
-LibTest/async/StreamController/hasListener_A01_t01: fail, OK
-LibTest/async/StreamController/hasListener_A01_t02: fail, OK
-LibTest/async/StreamController/isPaused_A01_t01: fail, OK
-LibTest/async/StreamController/isPaused_A01_t03: fail, OK
-
-# co19 issue #571: There is no such getter 'hasListener' in 'EventSink'
-LibTest/async/StreamController/sink_A01_t01: fail, OK
-
-# co19 issue #572: Undefined class 'boolean'; did you mean 'bool'?
-LibTest/async/StreamController/StreamController.broadcast_A04_t01: fail, OK
-LibTest/async/StreamIterator/cancel_A01_t01: fail, OK
-LibTest/core/List/map_A02_t01: fail, OK
-
-# co19 issue #573: There is no such operator '<' in 'Object'
-LibTest/async/StreamEventTransformer/handleData_A01_t01: fail, OK
-LibTest/async/StreamEventTransformer/handleDone_A01_t01: fail, OK
-LibTest/async/StreamEventTransformer/handleError_A01_t01: fail, OK
-
-# co19 issue #574: Abstract classes cannot be created with a 'new' expression
-LibTest/async/Stream/Stream_A01_t01: fail, OK
-
-# co19 issue #575: Error has not constructor parameters
-LibTest/async/Stream/Stream.fromFuture_A02_t01: fail, OK
-LibTest/async/Stream/Stream.fromFuture_A02_t02: fail, OK
-LibTest/async/Stream/Stream.fromIterable_A01_t02: fail, OK
-
-# co19 issue #576: The name 'timer' cannot be referenced in the initializer of a variable with the same name
-LibTest/async/Timer/cancel_A01_t01: fail, OK
-
-# co19 issue #577: The argument type 'int' cannot be assigned to the parameter type 'Duration'
-LibTest/core/DateTime/subtract_A02_t01: fail, OK
-
-# co19 issue #578: Undefined class 'long'
-LibTest/core/Duration/operator_div_A01_t01: fail, OK
-LibTest/core/Duration/operator_eq_A01_t01: fail, OK
-LibTest/core/Duration/operator_gt_A01_t01: fail, OK
-LibTest/core/Duration/operator_lt_A01_t01: fail, OK
-LibTest/core/Duration/operator_lte_A01_t01: fail, OK
-LibTest/core/Duration/operator_minus_A01_t01: fail, OK
-LibTest/core/Duration/operator_mult_A01_t01: fail, OK
-LibTest/core/Duration/operator_plus_A01_t01: fail, OK
-
-# co19 issue #579: The argument type 'bool' cannot be assigned to the parameter type '(String) -> bool'
-LibTest/core/List/every_A03_t01: fail, OK
-LibTest/core/List/forEach_A01_t02: fail, OK
-
-# co19 issue #580: Undefined name 'faled'
-LibTest/core/List/lastWhere_A03_t01: fail, OK
-
-# co19 issue #581: Undefined name 'Expect'
-LibTest/core/List/List_A01_t03: fail, OK
-LibTest/core/List/List.from_A01_t03: fail, OK
-LibTest/core/List/toList_A01_t03: fail, OK
-
-# co19 issue #582: The method 'addAll' is not defined for the class 'StringBuffer'
-LibTest/core/StringBuffer/writeAll_A03_t01: fail, OK
-
-# co19 issue #583: The method 'close' is not defined for the class 'SendPort'
-LibTest/isolate/isolate_api/streamSpawnFunction_A01_t01: fail, OK
-LibTest/isolate/IsolateSink/add_A01_t02: fail, OK
-LibTest/isolate/IsolateSink/operator_equality_A01_t01: fail, OK
-
-# co19 issue #584: Undefined name 'received
-LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: fail, OK
-
-# co19 issue #585: Undefined name 'messagesList'
-LibTest/isolate/IsolateSink/addError_A01_t01: fail, OK
-
-# co19 issue #586: Undefined name 'message'
-LibTest/isolate/IsolateSink/addError_A01_t02: fail, OK
-
-# co19 issue #587: Missing dart:async import and other mistypes
-LibTest/isolate/IsolateStream/any_A02_t01: fail, OK
-LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: fail, OK
-LibTest/isolate/IsolateStream/contains_A01_t01: fail, OK
-LibTest/isolate/IsolateStream/contains_A02_t01: fail, OK
-LibTest/isolate/IsolateStream/isBroadcast_A01_t02: fail, OK
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index cdcaa67..8a26565 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -33,14 +33,11 @@
 LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
 
 # co19 issue #380, Strings class has been removed
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: fail, OK
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A04_t01: fail, OK
 
 # co19 issue #400, collection library reorg
-LibTest/core/String/String_class_A01_t01: fail, OK
 LibTest/core/String/concat_A01_t01: fail, OK
 LibTest/core/String/concat_A02_t01: fail, OK
-LibTest/core/String/hashCode_A01_t01: fail, OK
 
 # co19 issue #424, Uninitialized finals are warnings not errors
 Language/05_Variables/05_Variables_A07_t05: fail, OK
@@ -55,19 +52,9 @@
 Language/05_Variables/05_Variables_A13_t01: fail, OK
 Language/07_Classes/07_Classes_A02_t11: fail, OK
 
-# co19 issue #464, not initialized final instance variable is warning, not error
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: fail
-
 # co19 issue #442, undefined name "Expect"
 Language/15_Types/4_Interface_Types_A08_t03: fail, OK
 
-# co19 issue #448, Collection was removed
-LibTest/collection/Queue/Queue.from_A01_t01: fail, OK
-LibTest/collection/Queue/Queue.from_A01_t02: fail, OK
-
-# co19 issue 452, more method in Iterable
-LibTest/core/Set/Set.from_A01_t02: fail, OK
-
 # co19 issue #455, undeclared identifier is static warning
 Language/12_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t10: fail, OK
 Language/13_Statements/04_Local_Function_Declaration_A02_t02: fail, OK
@@ -100,6 +87,10 @@
 # co19 issue #543: invocation of a non-function
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A03_t02: fail, OK
 
+Language/07_Classes/1_Instance_Methods_A03_t06: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/4_Abstract_Instance_Members_A07_t08: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
 Language/13_Statements/11_Return_A07_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t27: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t47: fail # co19-roll r546: Please triage this failure
@@ -109,78 +100,6 @@
 Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail # co19-roll r546: Please triage this failure
 Language/15_Types/6_Type_dynamic_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/15_Types/6_Type_dynamic_A04_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/asBroadcastStream_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/distinct_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/drain_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/drain_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/EventTransformStream_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/expand_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/first_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/handleError_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/EventTransformStream/listen_A03_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Future/asStream_A01_t02: pass # co19-roll r546: Please triage this failure
 LibTest/async/Future/asStream_A02_t01: pass # co19-roll r546: Please triage this failure
 LibTest/async/Future/whenComplete_A03_t01: pass # co19-roll r546: Please triage this failure
-LibTest/async/Stream/asBroadcastStream_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/asBroadcastStream_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/contains_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamController/hasListener_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamController/hasListener_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamController/isPaused_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamController/isPaused_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamController/sink_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamController/StreamController.broadcast_A04_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/distinct_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/distinct_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/drain_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/drain_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamEventTransformer/handleData_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamEventTransformer/handleDone_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamEventTransformer/handleError_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/expand_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/handleError_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/isBroadcast_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/isBroadcast_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/StreamIterator/cancel_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/listen_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.fromFuture_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.fromFuture_A02_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Stream/Stream.fromIterable_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/async/Timer/cancel_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/subtract_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_div_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_eq_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_gt_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_lt_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_lte_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_minus_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_mult_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/Duration/operator_plus_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/every_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/forEach_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/lastWhere_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List.filled_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List.from_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List.generate_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List.generate_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/List.generate_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/map_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/replaceRange_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/replaceRange_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/skipWhile_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/takeWhile_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/core/List/toList_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/core/StringBuffer/writeAll_A03_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/isolate_api/streamSpawnFunction_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: fail # co19-roll r576: Please triage this failure
-LibTest/isolate/IsolateSink/add_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/addError_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/addError_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/operator_equality_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/contains_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateStream/isBroadcast_A01_t02: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 5ded114..d2a26cd 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -10,12 +10,10 @@
 
 
 [ $runtime == vm || $compiler == dart2dart || $compiler == dart2js ]
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A12_t02: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/1_Generative_Constructors_A20_t02: fail # co19-roll r587: Please triage this failure
 LibTest/core/Uri/decodeQueryComponent_A02_t01: fail # co19 Issue 591
-LibTest/core/Uri/encodeComponent_A01_t02: fail # Issue 13251, co19 Issues 588, 589
 LibTest/core/Uri/toFilePath_A01_t01: pass, fail, ok # co19 Issue 592
-LibTest/core/Uri/Uri_A03_t01: fail # Issue 13250, co19 Issue 588
-LibTest/core/Uri/Uri.http_A02_t01: fail # Issue 13250, co19 Issue 588
-LibTest/core/Uri/Uri.https_A02_t01: fail # Issue 13250, co19 Issue 588
 # Maybe we should wait until isolate library is sealed before triaging these.
 LibTest/isolate/isolate_api/spawnFunction_A04_t01: fail, timeout # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/streamSpawnFunction_A02_t01: fail, timeout # co19-roll r546: Please triage this failure
@@ -36,7 +34,6 @@
 LibTest/math/exp_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/max_A01_t03: FAIL, OK # co19 issue 467
 LibTest/math/min_A01_t03: FAIL, OK # co19 issue 467
-LibTest/math/pow_A01_t01: FAIL, OK # co19 issue 44
 LibTest/math/sin_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/tan_A01_t01: PASS, FAIL, OK  # co19 issue 44
 
@@ -96,18 +93,17 @@
 LibTest/typed_data/Uint8List/removeAll_A01_t01: Fail  # co19 issue 548
 LibTest/typed_data/Uint8List/retainAll_A01_t01: Fail  # co19 issue 548
 
-Language/12_Expressions/06_Lists_A08_t01: Fail  # co19 issue 561
-LibTest/core/String/String_class_A01_t01: Fail  # co19 issue 561
 LibTest/core/String/concat_A01_t01: Fail  # co19 issue 561
 LibTest/core/String/concat_A02_t01: Fail  # co19 issue 561
-LibTest/core/String/hashCode_A01_t01: Fail  # co19 issue 561
 
-[ $compiler == dart2dart || $compiler == dart2js ]
-Language/14_Libraries_and_Scripts/1_Imports_A03_t49: Fail # co19 Issue 590
+[ $compiler != dartanalyzer ]
+# Dart2js/Dart2dart succeedes due to a bug in their parser (issue 13223).
+Language/12_Expressions/21_Bitwise_Expressions_A01_t01: Fail # co19 Issue 595
 
 ### CHECKED MODE FAILURES ###
 
 [ ($runtime == vm || $compiler == dart2js) && $checked]
+Language/07_Classes/6_Constructors/2_Factories_A12_t02: fail # co19-roll r587: Please triage this failure
 Language/13_Statements/09_Switch_A05_t01: FAIL, OK # co19 issue 498
 Language/14_Libraries_and_Scripts/1_Imports_A03_t26: FAIL, OK  # co19 issue 498
 Language/14_Libraries_and_Scripts/1_Imports_A03_t46: PASS, FAIL, OK # co19 issue 560
@@ -123,4 +119,3 @@
 LibTest/core/TypeError/line_A01_t01: FAIL, OK # co19 issue 510
 LibTest/core/TypeError/srcType_A01_t01: FAIL, OK # co19 issue 510
 LibTest/core/TypeError/url_A01_t01: FAIL, OK # co19 issue 510
-LibTest/core/Uri/encodeFull_A01_t02: fail # co19 Issue 589
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 369134f..4d70e82 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -24,15 +24,12 @@
 Language/05_Variables/05_Variables_A01_t12: Fail # http://dartbug.com/5519
 Language/05_Variables/05_Variables_A01_t13: Fail # http://dartbug.com/5519
 Language/05_Variables/05_Variables_A01_t14: Fail # http://dartbug.com/5519
-Language/05_Variables/05_Variables_A07_t05: Fail # Inherited from dart2js
-Language/05_Variables/05_Variables_A07_t06: Fail # Inherited from dart2js
 Language/05_Variables/05_Variables_A07_t07: Fail # Inherited from dart2js
 Language/05_Variables/05_Variables_A07_t08: Fail # Inherited from dart2js
 Language/05_Variables/05_Variables_A08_t01: Fail # Inherited from dart2js
 Language/05_Variables/05_Variables_A08_t02: Fail # Inherited from dart2js
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: Fail # Inherited from VM (circular initialization?).
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t05: Fail # Inherited from dart2js
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t03: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # http://dartbug.com/5519
@@ -40,12 +37,6 @@
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A02_t02: Fail # http://dartbug.com/5519
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # inherited from VM
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters_A03_t01: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters_A03_t02: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters_A03_t03: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters_A03_t04: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters_A03_t05: Fail # http://dartbug.com/5519
-Language/06_Functions/2_Formal_Parameters_A03_t06: Fail # http://dartbug.com/5519
 Language/06_Functions/4_External_Functions_A01_t01: Fail # inherited from VM
 Language/07_Classes/07_Classes_A02_t11: Fail # http://dartbug.com/5519
 Language/07_Classes/3_Setters_A04_t01: Fail # inherited from VM
@@ -56,7 +47,6 @@
 Language/07_Classes/3_Setters_A04_t06: Fail # inherited from VM
 Language/07_Classes/3_Setters_A04_t07: Fail # inherited from VM
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Fail # http://dartbug.com/5519
-Language/07_Classes/6_Constructors/2_Factories_A07_t01: Fail # inherited from VM
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t01: Fail # inherited from VM
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t02: Fail # inherited from VM
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A04_t03: Fail # inherited from VM
@@ -64,6 +54,7 @@
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t02: Fail # inherited from VM
 Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t03: Fail # inherited from VM
 Language/07_Classes/6_Constructors_A02_t01: Fail # http://dartbug.com/5519
+Language/12_Expressions/07_Maps_A12_t03: Fail # http://dartbug.com/5519
 LibTest/core/Match/operator_subscript_A01_t01: Fail # inherited from VM
 LibTest/core/Match/operator_subscript_A01_t01: Fail, OK # co19 issue 294
 LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # inherited from VM
@@ -88,7 +79,6 @@
 LibTest/isolate/isolate_api/spawnUri_A01_t04: Fail, OK # Problems with the test: encoded file name
 LibTest/isolate/isolate_api/spawnUri_A01_t05: Fail, OK # Problems with the test: encoded file name
 LibTest/math/exp_A01_t01: Fail # Issue co19 - 44
-LibTest/math/pow_A01_t01: Fail # Inherited from VM.
 LibTest/math/sin_A01_t01: Fail # Inherited from VM.
 LibTest/math/tan_A01_t01: Fail # Issue co19 - 44
 
@@ -125,8 +115,7 @@
 Language/05_Variables/05_Variables_A06_t04: fail # co19-roll r546: Please triage this failure
 Language/05_Variables/05_Variables_A06_t05: fail # co19-roll r546: Please triage this failure
 Language/05_Variables/05_Variables_A06_t06: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/07_Classes_A11_t01: fail # co19-roll r546: Please triage this failure
-Language/07_Classes/07_Classes_A11_t03: fail # co19-roll r546: Please triage this failure
+Language/07_Classes/1_Instance_Methods/2_Operators_A09_t01: fail # co19-roll r587: Please triage this failure
 Language/07_Classes/1_Instance_Methods_A01_t01: Fail # co19-roll r559: Please triage this failure
 Language/07_Classes/1_Instance_Methods_A01_t02: Fail # co19-roll r559: Please triage this failure
 Language/07_Classes/1_Instance_Methods_A01_t03: Fail # co19-roll r559: Please triage this failure
@@ -138,7 +127,8 @@
 Language/07_Classes/4_Abstract_Instance_Members_A03_t03: Fail # co19-roll r559: Please triage this failure
 Language/07_Classes/4_Abstract_Instance_Members_A03_t04: Fail # co19-roll r559: Please triage this failure
 Language/07_Classes/4_Abstract_Instance_Members_A03_t05: Fail # co19-roll r559: Please triage this failure
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: fail # co19-roll r546: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A10_t01: crash # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A10_t04: crash # co19-roll r587: Please triage this failure
 Language/12_Expressions/01_Constants_A03_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/01_Constants_A03_t03: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/01_Constants_A03_t04: fail # co19-roll r546: Please triage this failure
@@ -191,16 +181,9 @@
 Language/12_Expressions/05_Strings_A20_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/06_Lists_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/06_Lists_A03_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/07_Maps_A02_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/07_Maps_A02_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A08_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/07_Maps_A12_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t07: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A02_t03: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A02_t05: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A02_t06: fail # co19-roll r546: Please triage this failure
@@ -219,15 +202,9 @@
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A05_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t09: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/22_Equality_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/22_Equality_A01_t15: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/22_Equality_A01_t16: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/22_Equality_A01_t19: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/22_Equality_A01_t20: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/22_Equality_A05_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/23_Relational_Expressions_A01_t10: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/23_Relational_Expressions_A01_t11: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/23_Relational_Expressions_A01_t12: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/23_Relational_Expressions_A01_t13: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/27_Unary_Expressions_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/30_Identifier_Reference_A04_t09: fail # co19-roll r546: Please triage this failure
@@ -254,20 +231,13 @@
 Language/14_Libraries_and_Scripts/1_Imports_A03_t28: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t29: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t30: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t49: fail # co19-roll r546: Please triage this failure
+Language/14_Libraries_and_Scripts/1_Imports_A03_t65: pass, fail, ok # co19 issue 560
 Language/14_Libraries_and_Scripts/1_Imports_A04_t03: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t11: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/5_URIs_A01_t21: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail # co19-roll r546: Please triage this failure
-Language/14_Libraries_and_Scripts/1_Imports_A03_t65: pass, fail, ok # co19 issue 560
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t01: fail # co19-roll r546: Please triage this failure
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t02: fail # co19-roll r546: Please triage this failure
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t03: fail # co19-roll r546: Please triage this failure
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t04: fail # co19-roll r546: Please triage this failure
 Language/15_Types/4_Interface_Types_A11_t01: crash # co19-roll r546: Please triage this failure
 Language/15_Types/4_Interface_Types_A11_t02: crash # co19-roll r546: Please triage this failure
 Language/15_Types/5_Function_Types_A06_t01: fail # co19-roll r546: Please triage this failure
@@ -286,8 +256,12 @@
 LibTest/isolate/SendPort/send_A02_t03: timeout # co19-roll r546: Please triage this failure
 
 [ $compiler == dart2dart && $minified ]
-Language/13_Statements/11_Try_A06_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/17_Getter_Invocation_A02_t01: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/18_Assignment_A05_t02: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/18_Assignment_A05_t04: fail # co19-roll r559: Please triage this failure
+Language/13_Statements/11_Try_A06_t01: fail # co19-roll r546: Please triage this failure
+LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/stringify_A03_t02: fail # co19-roll r587: Please triage this failure
+
+
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 8f61e3a..b8db1bf 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -22,13 +22,11 @@
 Language/03_Overview/1_Scoping_A02_t05: Fail # TODO(ahe): Please triage this failure.
 Language/03_Overview/1_Scoping_A02_t06: Fail # TODO(ahe): Please triage this failure.
 Language/05_Variables/1_Evaluation_of_Implicit_Variable_Getters_A01_t02: fail # co19-roll r576: Please triage this failure
-Language/07_Classes/6_Constructors/2_Factories_A07_t01: Fail # TODO(ahe): Please triage this failure.
 Language/13_Statements/11_Try_A07_t03: fail # co19-roll r576: Please triage this failure
 LibTest/core/double/INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/List/List_A03_t01: Fail # TODO(kasperl): Please triage this failure.
 LibTest/core/List/sort_A01_t04: Pass, Slow # http://dartbug.com/11846
-LibTest/math/pow_A13_t01: FAIL, OK # co19 issue 507
 LibTest/math/pow_A18_t01: FAIL, OK # co19 issue 507
 
 LibTest/typed_data/ByteData/getFloat32_A02_t02: fail # co19-roll r569: Please triage this failure
@@ -80,14 +78,6 @@
 
 LibTest/isolate/ReceivePort/receive_A01_t02: Fail # Issue 6750
 
-LibTest/typed_data/Float64List/Float64List.view_A01_t01: Fail, OK # Issue 12928
-LibTest/typed_data/Float32List/Float32List.view_A01_t01: Fail, OK # Issue 12928
-LibTest/typed_data/Uint16List/Uint16List.view_A01_t01: Fail, OK # Issue 12928
-LibTest/typed_data/Uint32List/Uint32List.view_A01_t01: Fail, OK # Issue 12928
-LibTest/typed_data/Int32List/Int32List.view_A01_t01: Fail, OK # Issue 12928
-LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t01: Fail, OK # Issue 12928
-
-
 [ $compiler == dart2js && $runtime == ie9 ]
 LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Issue 8920
 LibTest/async/Stream/listen_A04_t01: Pass, Timeout # Issue: 8920
@@ -280,6 +270,40 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Expect.fail('Some exception expected')
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Expect.fail('Some exception expected')
 
+
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+LibTest/isolate/IsolateSink/add_A01_t02: Pass # TODO(kasperl): Please triage.
+LibTest/isolate/IsolateSink/operator_equality_A01_t01: Pass # TODO(kasperl): Please triage.
+
+Language/12_Expressions/05_Strings_A06_t01: Pass, Slow # TODO(kasperl): Please triage.
+LibTest/core/Set/removeAll_A01_t02: Pass, Slow # TODO(kasperl): Please triage.
+LibTest/typed_data/Float64List/join_A01_t01: Pass, Slow # TODO(kasperl): Please triage.
+LibTest/typed_data/Int8List/sublist_A02_t01: Pass, Slow # TODO(kasperl): Please triage.
+LibTest/typed_data/Int16List/single_A01_t02: Pass, Slow # TODO(kasperl): Please triage.
+LibTest/typed_data/Uint8ClampedList/map_A02_t01: Pass, Slow # TODO(kasperl): Please triage.
+
+LibTest/isolate/isolate_api/spawnUri_A01_t01: Timeout # TODO(kasperl): Please triage.
+LibTest/isolate/isolate_api/spawnUri_A01_t02: Timeout # TODO(kasperl): Please triage.
+LibTest/isolate/isolate_api/spawnUri_A01_t03: Timeout # TODO(kasperl): Please triage.
+LibTest/isolate/isolate_api/spawnUri_A01_t04: Timeout # TODO(kasperl): Please triage.
+LibTest/isolate/isolate_api/spawnUri_A01_t05: Timeout # TODO(kasperl): Please triage.
+
+LibTest/core/int/compareTo_A01_t01: Fail # TODO(kasperl): Please triage.
+LibTest/core/int/operator_left_shift_A01_t01: Fail # TODO(kasperl): Please triage.
+LibTest/core/int/operator_remainder_A01_t03: Fail # TODO(kasperl): Please triage.
+LibTest/core/int/operator_truncating_division_A01_t02: Fail # TODO(kasperl): Please triage.
+LibTest/core/int/remainder_A01_t01: Fail # TODO(kasperl): Please triage.
+LibTest/core/int/remainder_A01_t03: Fail # TODO(kasperl): Please triage.
+LibTest/core/int/toRadixString_A01_t01: Fail # TODO(kasperl): Please triage.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # TODO(kasperl): Please triage.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # TODO(kasperl): Please triage.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # TODO(kasperl): Please triage.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # TODO(kasperl): Please triage.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # TODO(kasperl): Please triage.
+LibTest/isolate/ReceivePort/toSendPort_A01_t02: Fail # TODO(kasperl): Please triage.
+LibTest/math/log_A01_t01: Fail # TODO(kasperl): Please triage.
+
+
 [ $compiler == dart2js && ($runtime == ie10 || $runtime == ff || $runtime == chrome || $runtime == drt || $runtime == safari || $runtime == opera) ]
 *: Skip
 
@@ -294,46 +318,22 @@
 Language/05_Variables/05_Variables_A01_t12: Fail # Checks that variable declaration cannot contain both 'const' and 'var'.
 Language/05_Variables/05_Variables_A01_t13: Fail # Checks that variable declaration cannot contain both 'const' and 'final'.
 Language/05_Variables/05_Variables_A01_t14: Fail # Checks that variable declaration cannot contain 'const', 'final' and 'var' simultaneously.
-Language/05_Variables/05_Variables_A07_t05: Fail # Checks that a compile-time error occurs if a local constant variable is not initialized at declaration.
-Language/05_Variables/05_Variables_A07_t06: Fail # Checks that a compile-time error occurs if a local typed constant variable is not initialized at declaration.
 Language/05_Variables/05_Variables_A07_t07: Fail # Checks that a compile-time error occurs if a global constant variable is not initialized at declaration.
 Language/05_Variables/05_Variables_A07_t08: Fail # Checks that a compile-time error occurs if a global typed constant variable is not initialized at declaration.
 Language/05_Variables/05_Variables_A08_t01: Fail # Checks that a compile-time error occurs if a constant variable is not initialized.
-Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t03: Fail # Checks that a required parameter can be constant. Reassigning it should produce a compile-time error.
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t04: Fail # Checks that static variable declaration can't be a required formal parameter
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t06: Fail # Checks that a functionSignature parameter cannot be final.
 Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t07: Fail # Checks that a functionSignature parameter cannot be declared as variable.
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t03: Fail # TODO(ahe): Enforce optional parameter semantics.
 Language/06_Functions/2_Formal_Parameters/2_Optional_Formals_A03_t04: Fail # TODO(ahe): Enforce optional parameter semantics.
-Language/06_Functions/2_Formal_Parameters_A03_t01: Fail # Checks that it is a compile-time error if a required parameter is declared as a constant variable.
-Language/06_Functions/2_Formal_Parameters_A03_t02: Fail # Checks that it is a compile-time error if a required parameter is declared as a constant typed variable.
-Language/06_Functions/2_Formal_Parameters_A03_t03: Fail # TODO(ahe): Enforce optional parameter semantics.
-Language/06_Functions/2_Formal_Parameters_A03_t04: Fail # TODO(ahe): Enforce optional parameter semantics.
-Language/06_Functions/2_Formal_Parameters_A03_t05: Fail # Checks that it is a compile-time error if an optional named parameter is declared as a constant typed variable.
-Language/06_Functions/2_Formal_Parameters_A03_t05: Fail # Checks that it is a compile-time error if an optional positional parameter is declared as a constant variable.
-Language/06_Functions/2_Formal_Parameters_A03_t06: Fail # TODO(ahe): Enforce optional parameter semantics.
 Language/07_Classes/07_Classes_A02_t11: Fail # Checks that it is a compile-time error if a static final variable declaration does not include explicit initializer.
-Language/07_Classes/07_Classes_A11_t01: Fail # Checks that a class name cannot be used as a name of a member variable.
-Language/07_Classes/07_Classes_A11_t03: Fail # Checks that a class name cannot be used as a name of a static variable.
 Language/12_Expressions/01_Constants_A20_t03: Fail # Checks that an identifier expression that denotes a type parameter  can not be assigned to a constant variable.
 Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t09: Fail # Checks that it is a compile-time error if a string interpolation construct does not start with IDENTIFIER_NO_DOLLAR or opening brace.
 Language/12_Expressions/05_Strings_A02_t46: Fail # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
 Language/12_Expressions/05_Strings_A02_t48: Fail # Checks that multi-line strings that contain characters and sequences prohibited by this grammar, cause compile-time errors.
-Language/12_Expressions/22_Equality_A01_t15: Fail # Checks that equality expressions cannot be operands of another equality expression.
-Language/12_Expressions/22_Equality_A01_t16: Fail # Checks that equality expressions cannot be operands of another equality expression.
-Language/12_Expressions/23_Relational_Expressions_A01_t10: Fail # Checks that a relational expression cannot be the operand of another relational expression.
-Language/12_Expressions/23_Relational_Expressions_A01_t11: Fail # Checks that a relational expression cannot be the operand of another relational expression.
-Language/12_Expressions/23_Relational_Expressions_A01_t12: Fail # Checks that a relational expression cannot be the operand of another relational expression.
-Language/12_Expressions/23_Relational_Expressions_A01_t13: Fail # Checks that a relational expression cannot be the operand of another relational expression.
 Language/12_Expressions/30_Identifier_Reference_A04_t09: Fail # Checks that it is a compile-time error when a built-in identifier dynamic is used as the declared name of a type variable.
 Language/12_Expressions/30_Identifier_Reference_A05_t01: Fail # Checks that it is a compile-time error when a built-in identifier "abstract" is used as a type annotation of a local variable.
 Language/12_Expressions/30_Identifier_Reference_A05_t12: Fail # Checks that it is a compile-time error when a built-in identifier "static" is used as a type annotation of a local variable.
-Language/14_Libraries_and_Scripts/5_URIs_A01_t24: Fail # Checks that it is a compile-time error when the URI in a part directive consists of two adjacent string literals instead of one.
-Language/14_Libraries_and_Scripts/5_URIs_A01_t25: Fail # Checks that it is a compile-time error when the URI in a part directive consists of two adjacent multi-line string literals  instead of one.
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t01: Fail # Checks that self-referencing typedef is not allowed (return value type annotation has the same name as the type alias).
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t02: Fail # Checks that self-referencing typedef is not allowed (positional formal parameter type annotation has the same name as the type alias).
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t03: Fail # Checks that self-referencing typedef is not allowed (positional optional parameter type annotation has the same name as the type alias).
-Language/15_Types/3_Type_Declarations/1_Typedef_A07_t04: Fail # Checks that self-referencing typedef is not allowed (named optional parameter type annotation has the same name as the type alias).
 Language/16_Reference/1_Lexical_Rules/1_Reserved_Words_A40_t04: Fail # Checks that other Unicode whitespaces are not allowed:  check NO-BREAK SPACE (U+00A0)
 Language/16_Reference/1_Lexical_Rules_A02_t06: Fail # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
 
@@ -436,21 +436,12 @@
 Language/07_Classes/4_Abstract_Instance_Members_A03_t04: fail # co19-roll r559: Please triage this failure
 Language/07_Classes/4_Abstract_Instance_Members_A03_t05: fail # co19-roll r559: Please triage this failure
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A02_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/00_Object_Identity/1_Object_Identity_A04_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A06_t02: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/01_Constants_A03_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/03_Numbers_A01_t06: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/03_Numbers_A01_t09: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/05_Strings_A20_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A01_t01: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A08_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t02: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t04: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t05: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t06: fail # co19-roll r546: Please triage this failure
-Language/12_Expressions/07_Maps_A12_t07: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A02_t03: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A02_t05: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/12_Instance_Creation/1_New_A02_t06: fail # co19-roll r546: Please triage this failure
@@ -503,27 +494,20 @@
 LibTest/isolate/isolate_api/spawnFunction_A04_t03: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/spawnUri_A02_t02: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/spawnUri_A02_t03: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/isolate_api/streamSpawnFunction_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/isolate_api/streamSpawnFunction_A02_t02: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateSink/add_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/add_A01_t02: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateSink/addError_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateSink/addError_A01_t02: fail # co19-roll r546: Please triage this failure
-LibTest/isolate/IsolateSink/operator_equality_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/any_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/IsolateStream/contains_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/isolate/SendPort/send_A01_t01: fail # co19-roll r546: Please triage this failure
-LibTest/typed_data/Float32List/buffer_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Float32List/Float32List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Float32List/Float32List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/Float32List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/Float32List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/fold_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/join_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/join_A01_t02: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32List/offsetInBytes_A01_t01: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Float32x4/clamp_A01_t01: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Float32x4List/Float32x4List.view_A02_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
@@ -531,39 +515,24 @@
 LibTest/typed_data/Float32x4List/fold_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32x4List/join_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32x4List/join_A01_t02: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float64List/buffer_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Float64List/Float64List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Float64List/Float64List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/Float64List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/Float64List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/fold_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/join_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/join_A01_t02: fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Float64List/offsetInBytes_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Int16List/buffer_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Int16List/Int16List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Int16List/Int16List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/Int16List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/Int16List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int16List/offsetInBytes_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Int32List/buffer_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Int32List/Int32List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Int32List/Int32List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/Int32List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/Int32List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int32List/offsetInBytes_A01_t01: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Int8List/Int8List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int8List/Int8List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int8List/Int8List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint16List/buffer_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Uint16List/offsetInBytes_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Uint16List/Uint16List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Uint16List/Uint16List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/Uint16List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/Uint16List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint32List/buffer_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Uint32List/offsetInBytes_A01_t01: Fail, Ok # co19 issue: 549
-LibTest/typed_data/Uint32List/Uint32List.view_A01_t02: Fail, Ok # co19 issue: 549
 LibTest/typed_data/Uint32List/Uint32List.view_A05_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/Uint32List.view_A05_t02: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/Uint32List.view_A05_t03: Fail # co19-roll r559: Please triage this failure
@@ -595,14 +564,18 @@
 LibTest/typed_data/Float32x4List/reduce_A01_t01: Fail # co19-roll r559: Please triage this failure
 
 [ $compiler == dart2js && $runtime == jsshell ]
+LibTest/typed_data/Float32List/Float32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Float32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/toList_A01_t01: fail, timeout # co19-roll r559: Please triage this failure
+LibTest/typed_data/Float64List/Float64List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Float64List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/toList_A01_t01: fail, timeout # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int16List/Int16List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Int16List/toList_A01_t01: pass, fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/toList_A01_t01: timeout # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
+LibTest/typed_data/Int32List/Int32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Int32List/toList_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/toList_A01_t01: pass, timeout # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int8List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
@@ -610,8 +583,10 @@
 LibTest/typed_data/Uint16List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/toList_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/toList_A01_t01: timeout # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint16List/Uint16List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Uint32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/toList_A01_t01: fail, timeout # co19-roll r559: Please triage this failure
+LibTest/typed_data/Uint32List/Uint32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/toList_A01_t01: fail, timeout # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
@@ -629,6 +604,8 @@
 LibTest/async/Stream/Stream.periodic_A02_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Timer/cancel_A01_t01: fail # co19-roll r546: Please triage this failure
 LibTest/async/Timer/Timer_A01_t01: fail # co19-roll r546: Please triage this failure
+LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t02: fail # co19-roll r587: Please triage this failure
+LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 
 [ $compiler == dart2js && $minified ]
 Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: fail # co19-roll r559: Please triage this failure
@@ -651,8 +628,31 @@
 LibTest/typed_data/Uint8List/runtimeType_A01_t01: fail # co19-roll r559: Please triage this failure
 
 [ $compiler == dart2js || $compiler == dart2dart ]
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A15_t08: fail # co19-roll r569: Please triage this failure
-LibTest/core/NoSuchMethodError/NoSuchMethodError_A01_t01: fail # co19-roll r576: Please triage this failure
-LibTest/core/Uri/Uri_A06_t02: fail # co19-roll r576: Please triage this failure
-LibTest/core/Uri/Uri_A06_t03: fail # co19-roll r576: Please triage this failure
+Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t08: fail # co19-roll r587: Please triage this failure
+Language/06_Functions/2_Formal_Parameters/1_Required_Formals_A02_t09: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/1_Instance_Methods_A03_t06: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/1_Instance_Methods_A07_t01: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A08_t02: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A09_t01: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A09_t02: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A10_t02: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/2_Factories_A10_t03: fail # co19-roll r587: Please triage this failure
+Language/10_Generics/09_Generics_A01_t17: fail # co19-roll r587: Please triage this failure
+LibTest/json/parse_A01_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/parse_A02_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A01_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A02_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A03_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A03_t02: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A03_t03: fail # co19-roll r587: Please triage this failure
+LibTest/json/printOn_A04_t01: fail # co19-roll r587: Please triage this failure
+
+[ $compiler == dart2js ]
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail # co19-roll r587: Please triage this failure
+Language/07_Classes/6_Constructors/3_Constant_Constructors_A05_t04: fail # co19-roll r587: Please triage this failure
+LibTest/json/stringify_A01_t01: fail # co19-roll r587: Please triage this failure
+LibTest/json/stringify_A02_t01: fail # co19-roll r587: Please triage this failure
+LibTest/math/pow_A04_t01: fail # co19-roll r587: Please triage this failure
+LibTest/math/pow_A14_t01: fail # co19-roll r587: Please triage this failure
+LibTest/math/pow_A16_t01: fail # co19-roll r587: Please triage this failure
 
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index f160171..33966f7 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -5,40 +5,6 @@
 [ $runtime == vm ]
 Language/12_Expressions/01_Constants_A16_t04: fail # Issue 392
 Language/12_Expressions/01_Constants_A16_t05: fail # Issue 392
-LibTest/typed_data/Float32List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Float32List/Float32List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Float32List/Float32List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Float32List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Float32x4List/Float32x4List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Float64List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Float64List/Float64List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Float64List/Float64List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Float64List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Int16List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Int16List/Int16List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Int16List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Int32List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Int32List/Int32List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Int32List/Int32List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Int32List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Int64List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Int64List/Int64List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Int64List/Int64List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Int64List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint16List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint16List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint16List/Uint16List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint16List/Uint16List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Uint32List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint32List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint32List/Uint32List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint32List/Uint32List.view_A01_t02: fail # Issue 549
-LibTest/typed_data/Uint64List/buffer_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint64List/offsetInBytes_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint64List/Uint64List.view_A01_t01: fail # Issue 549
-LibTest/typed_data/Uint64List/Uint64List.view_A01_t02: fail # Issue 549
 
 [ $runtime == vm && $system == windows ]
 LibTest/core/Stopwatch/elapsed_A01_t01: Pass, Fail # Issue 11382.
@@ -90,10 +56,6 @@
 LibTest/math/log_A01_t01: Fail
 LibTest/core/double/toInt_A01_t01: Fail
 
-[ $compiler == none && $runtime == vm && $arch == arm ]
-LibTest/typed_data/Float32List/Float32List.view_A01_t02: Crash  # Issue 12868
-LibTest/typed_data/Float64List/Float64List.view_A01_t02: Crash  # Issue 12868
-
 [ $compiler == none && $runtime == vm && ($arch == simarm || $arch == simmips) ]
 LibTest/core/Uri/Uri_A06_t03: Pass, Timeout # co19-roll r576: Please triage this failure
 
@@ -155,6 +117,9 @@
 LibTest/isolate/isolate_api/spawnUri_A02_t02: Fail # VM triage, check spec.
 LibTest/isolate/isolate_api/spawnUri_A02_t03: Fail # VM triage, check spec.
 
+Language/14_Libraries_and_Scripts/5_URIs_A01_t24: fail # co19-roll r587: Please triage this failure
+Language/14_Libraries_and_Scripts/5_URIs_A01_t25: fail # co19-roll r587: Please triage this failure
+
 
 [ $compiler == none && $runtime == vm && $checked ]
 LibTest/typed_data/Float32x4List/elementAt_A01_t01: Fail # Dart issue 12861
@@ -184,7 +149,3 @@
 Language/15_Types/4_Interface_Types_A11_t01: pass, timeout # Issue 13349
 Language/15_Types/4_Interface_Types_A11_t02: pass, timeout # Issue 13349
 
-[ $compiler == none && $runtime == vm && $system == windows ]
-LibTest/core/Uri/toFilePath_A02_t01: fail # co19 Issue 594
-LibTest/core/Uri/Uri.file_A01_t01: fail # co19 Issue 594
-
diff --git a/tests/compiler/dart2js/dart_backend_test.dart b/tests/compiler/dart2js/dart_backend_test.dart
index 608ec55..355d2cf 100644
--- a/tests/compiler/dart2js/dart_backend_test.dart
+++ b/tests/compiler/dart2js/dart_backend_test.dart
@@ -63,6 +63,7 @@
 const helperLib = r'''
 library js_helper;
 class JSInvocationMirror {}
+assertHelper(a) {}
 ''';
 
 const foreignLib = r'''
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 8ebdf7d..135b025 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -33,8 +33,9 @@
       return super.readStringFromUri(resourceUri);
     }
     String source = memorySourceFiles[resourceUri.path];
-    // TODO(ahe): Return new Future.error(...) ?
-    if (source == null) return new Future.error('No such file $resourceUri');
+    if (source == null) {
+      return new Future.error(new Exception('No such file $resourceUri'));
+    }
     String resourceName = '$resourceUri';
     this.sourceFiles[resourceName] = new SourceFile(resourceName, source);
     return new Future.value(source);
diff --git a/tests/compiler/dart2js/missing_file_test.dart b/tests/compiler/dart2js/missing_file_test.dart
index 349b61c..06b75dd 100644
--- a/tests/compiler/dart2js/missing_file_test.dart
+++ b/tests/compiler/dart2js/missing_file_test.dart
@@ -69,10 +69,10 @@
 void main() {

   runCompiler(Uri.parse('memory:main.dart'),

               "Error: Can't read 'memory:foo.dart' "

-              "(No such file memory:foo.dart).");

+              "(Exception: No such file memory:foo.dart).");

   runCompiler(Uri.parse('memory:foo.dart'),

               "Error: Can't read 'memory:foo.dart' "

-              "(No such file memory:foo.dart).");

+              "(Exception: No such file memory:foo.dart).");

   runCompiler(Uri.parse('dart:foo'),

               'Error: Library not found "dart:foo".');

 }

diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 0a6bfc2..5fb2d85 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -253,7 +253,7 @@
     libraryLoader.importLibrary(interceptorsLibrary, coreLibrary, null);
     libraryLoader.importLibrary(isolateHelperLibrary, coreLibrary, null);
 
-    assertMethod = jsHelperLibrary.find(buildSourceString('assert'));
+    assertMethod = jsHelperLibrary.find(buildSourceString('assertHelper'));
     identicalFunction = coreLibrary.find(buildSourceString('identical'));
 
     mainApp = mockLibrary(this, "");
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index ef06d96..a8093aa 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -5,6 +5,7 @@
 import 'package:expect/expect.dart';
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'parser_helper.dart' show buildSourceString;
 
 const String TEST = """
 returnInt1() {
@@ -82,6 +83,23 @@
   return a;
 }
 
+returnIntOrNull() {
+  for (var b in [42]) {
+    var bar = 42;
+    f() => bar;
+    bar = null;
+    return f();
+  }
+  return 42;
+}
+
+class A {
+  foo() {
+    f() => this;
+    return f();
+  }
+}
+
 main() {
   returnInt1();
   returnDyn1();
@@ -91,6 +109,8 @@
   returnDyn3();
   returnInt4();
   returnNum1();
+  returnIntOrNull();
+  new A().foo();
 }
 """;
 
@@ -111,10 +131,20 @@
     checkReturn('returnInt2', compiler.typesTask.intType);
     checkReturn('returnInt3', compiler.typesTask.intType);
     checkReturn('returnInt4', compiler.typesTask.intType);
+    checkReturn('returnIntOrNull', compiler.typesTask.intType.nullable());
 
     checkReturn('returnDyn1', compiler.typesTask.dynamicType.nonNullable());
     checkReturn('returnDyn2', compiler.typesTask.dynamicType.nonNullable());
     checkReturn('returnDyn3', compiler.typesTask.dynamicType.nonNullable());
     checkReturn('returnNum1', compiler.typesTask.numType);
+
+    checkReturnInClass(String className, String methodName, type) {
+      var cls = findElement(compiler, className);
+      var element = cls.lookupLocalMember(buildSourceString(methodName));
+      Expect.equals(type,
+          typesInferrer.getReturnTypeOfElement(element).simplify(compiler));
+    }
+    var cls = findElement(compiler, 'A');
+    checkReturnInClass('A', 'foo', new TypeMask.nonNullExact(cls.rawType));
   }));
 }
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/unparser_test.dart
index 38e9bdb..c00d6e2 100644
--- a/tests/compiler/dart2js/unparser_test.dart
+++ b/tests/compiler/dart2js/unparser_test.dart
@@ -29,13 +29,8 @@
 }
 
 testSignedConstants() {
-  testUnparse('var x=+42;');
-  testUnparse('var x=+.42;');
   testUnparse('var x=-42;');
   testUnparse('var x=-.42;');
-  testUnparse('var x=+0;');
-  testUnparse('var x=+0.0;');
-  testUnparse('var x=+.0;');
   testUnparse('var x=-0;');
   testUnparse('var x=-0.0;');
   testUnparse('var x=-.0;');
@@ -342,7 +337,7 @@
 }
 
 testSymbolLiterals() {
-  testUnparse("#+;");  
+  testUnparse("#+;");
   testUnparse("#-;");
   testUnparse("#*;");
   testUnparse("#/;");
@@ -356,7 +351,7 @@
   testUnparse("#&;");
   testUnparse("#|;");
   testUnparse("#^;");
-  
+
   testUnparse("#a;");
   testUnparse("#a.b;");
   testUnparse("#a.b.c;");
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 31e3827..4e065b9 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -22,6 +22,9 @@
 class_test: Fail
 deferred/*: Skip # http://dartbug.com/12635
 
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+no_such_method_mirrors_test: Pass, Slow # TODO(kasperl): Please triage.
+
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index e46b59f..e58bc11 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -53,6 +53,9 @@
 string_base_vm_test: Fail # BUG(3304): Maybe this doesn't time out?
 list_test: Fail # IE doesn't support typed data.
 
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+list_as_map_test: Pass, Slow # TODO(kasperl): Please triage.
+
 [ $compiler == dart2js && ($runtime == firefox || $runtime == safari || $runtime == chrome || $runtime == drt) ]
 
 [ $compiler == dart2dart ]
diff --git a/tests/corelib/hash_set_test.dart b/tests/corelib/hash_set_test.dart
index ee4bd16..175cba5 100644
--- a/tests/corelib/hash_set_test.dart
+++ b/tests/corelib/hash_set_test.dart
@@ -10,6 +10,7 @@
 import 'dart:collection';
 
 testSet(Set newSet(), Set newSetFrom(Set from)) {
+
   Set gen(int from, int to) =>
       new Set.from(new Iterable.generate(to - from, (n) => n + from));
 
@@ -22,6 +23,7 @@
     for (int i = 0; i < 256; i++) {
       set.add(i);
     }
+
     set.addAll(gen(256, 512));
     set.addAll(newSetFrom(gen(512, 1000)));
     Expect.equals(1000, set.length);
diff --git a/tests/corelib/map_test.dart b/tests/corelib/map_test.dart
index a700027..7e9d50d 100644
--- a/tests/corelib/map_test.dart
+++ b/tests/corelib/map_test.dart
@@ -456,8 +456,24 @@
 
 void testLength(int length, Map map) {
   Expect.equals(length, map.length);
-  (length == 0 ? Expect.isTrue : Expect.isFalse)(map.isEmpty);
-  (length != 0 ? Expect.isTrue : Expect.isFalse)(map.isNotEmpty);
+  Expect.equals(length, map.keys.length);
+  Expect.equals(length, map.values.length);
+  // Check being-empty.
+  var ifEmpty = (length == 0) ? Expect.isTrue : Expect.isFalse;
+  var ifNotEmpty = (length != 0) ? Expect.isTrue : Expect.isFalse;
+  ifEmpty(map.isEmpty);
+  ifNotEmpty(map.isNotEmpty);
+  ifEmpty(map.keys.isEmpty);
+  ifNotEmpty(map.keys.isNotEmpty);
+  ifEmpty(map.values.isEmpty);
+  ifNotEmpty(map.values.isNotEmpty);
+  // Test key/value iterators match their isEmpty/isNotEmpty.
+  ifNotEmpty(map.keys.iterator.moveNext());
+  ifNotEmpty(map.values.iterator.moveNext());
+  if (length == 0) {
+    for (var k in map.keys) Expect.fail("contains key when iterating: $k");
+    for (var v in map.values) Expect.fail("contains values when iterating: $v");
+  }
 }
 
 
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index f085835..b0246f0 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -9,7 +9,13 @@
 import "dart:collection";
 
 void testMain(Set create()) {
+  testInts(create);
+  testStrings(create);
+}
+
+void testInts(Set create()) {
   Set set = create();
+
   testLength(0, set);
   set.add(1);
   testLength(1, set);
@@ -186,9 +192,145 @@
   Expect.equals(length, set.length);
   (length == 0 ? Expect.isTrue : Expect.isFalse)(set.isEmpty);
   (length != 0 ? Expect.isTrue : Expect.isFalse)(set.isNotEmpty);
+  if (length == 0) {
+    for (var e in set) { Expect.fail("contains element when iterated: $e"); }
+  }
+  (length == 0 ? Expect.isFalse : Expect.isTrue)(set.iterator.moveNext());
 }
 
+void testStrings(Set create()) {
+  var set = create();
+  var strings = ["foo", "bar", "baz", "qux", "fisk", "hest", "svin", "pigvar"];
+  set.addAll(strings);
+  testLength(8, set);
+  set.removeAll(strings.where((x) => x.length == 3));
+  testLength(4, set);
+  set.add("bar");
+  set.add("qux");
+  testLength(6, set);
+  set.addAll(strings);
+  testLength(8, set);
+  set.removeWhere((x) => x.length != 3);
+  testLength(4, set);
+  set.retainWhere((x) => x[1] == "a");
+  testLength(2, set);
+  Expect.isTrue(set.containsAll(["baz", "bar"]));
+
+  set = set.union(strings.where((x) => x.length != 3).toSet());
+  testLength(6, set);
+  set = set.intersection(["qux", "baz", "fisk", "egern"].toSet());
+  testLength(2, set);
+  Expect.isTrue(set.containsAll(["baz", "fisk"]));
+}
+
+void testTypeAnnotations(Set<int> set) {
+  set.add(0);
+  set.add(999);
+  set.add(0x800000000);
+  set.add(0x20000000000000);
+  Expect.isFalse(set.contains("not an it"));
+  Expect.isFalse(set.remove("not an it"));
+  Expect.isFalse(set.containsAll(["Not an int", "Also no an int"]));
+
+  testLength(4, set);
+  set.removeAll(["Not an int", 999, "Also no an int"]);
+  testLength(3, set);
+  set.retainAll(["Not an int", 0, "Also no an int"]);
+  testLength(1, set);
+}
+
+void testRetainWhere(Set create([equals, hashCode, validKey])) {
+  // The retainWhere method must not collapse the argument Iterable
+  // in a way that doesn't match the equality of the set.
+  // It must not throw away equal elements that are different in the
+  // equality of the set.
+  // It must not consider objects to be not there if they are equal
+  // in the equality of the set.
+
+  // If set equality is natural equality, using different but equal objects
+  // must work. Can't use an identity set internally (as was done at some point
+  // during development).
+  Set set = create();
+  set.addAll([new EO(0), new EO(1), new EO(2)]);
+  Expect.equals(3, set.length);  // All different.
+  set.retainAll([new EO(0), new EO(2)]);
+  Expect.equals(2, set.length);
+  Expect.isTrue(set.contains(new EO(0)));
+  Expect.isTrue(set.contains(new EO(2)));
+
+  // If equality of set is identity, we can't internally use a non-identity
+  // based set because it might throw away equal objects that are not identical.
+  var elems = [new EO(0), new EO(1), new EO(2), new EO(0)];
+  set = create(identical);
+  set.addAll(elems);
+  Expect.equals(4, set.length);
+  set.retainAll([elems[0], elems[2], elems[3]]);
+  Expect.equals(3, set.length);
+  Expect.isTrue(set.contains(elems[0]));
+  Expect.isTrue(set.contains(elems[2]));
+  Expect.isTrue(set.contains(elems[3]));
+
+  // If set equality is less precise than equality, we must not use equality
+  // internally to see if the element is there:
+  set = create(customEq(3), customHash(3), validKey);
+  set.addAll([new EO(0), new EO(1), new EO(2)]);
+  Expect.equals(3, set.length);
+  set.retainAll([new EO(3), new EO(5)]);
+  Expect.equals(2, set.length);
+  Expect.isTrue(set.contains(new EO(6)));
+  Expect.isTrue(set.contains(new EO(8)));
+
+  // It shouldn't matter if the input is a set.
+  set.clear();
+  set.addAll([new EO(0), new EO(1), new EO(2)]);
+  Expect.equals(3, set.length);
+  set.retainAll(new Set.from([new EO(3), new EO(5)]));
+  Expect.equals(2, set.length);
+  Expect.isTrue(set.contains(new EO(6)));
+  Expect.isTrue(set.contains(new EO(8)));
+}
+
+// Objects that are equal based on data.
+class EO {
+  final int id;
+  const EO(this.id);
+  int get hashCode => id;
+  bool operator==(Object other) => other is EO && id == (other as EO).id;
+}
+
+// Equality of Id objects based on id modulo value.
+Function customEq(int mod) => (EO e1, EO e2) => ((e1.id - e2.id) % mod) == 0;
+Function customHash(int mod) => (EO e) => e.id % mod;
+bool validKey(Object o) => o is EO;
+
+
 main() {
-  testMain(() => new Set());
   testMain(() => new HashSet());
+  testMain(() => new LinkedHashSet());
+  testMain(() => new HashSet(equals: identical));
+  testMain(() => new LinkedHashSet(equals: identical));
+  testMain(() => new HashSet(equals: (a, b) => a == b,
+                             hashCode: (a) => -a.hashCode,
+                             isValidKey: (a) => true));
+  testMain(() => new LinkedHashSet(
+      equals: (a, b) => a == b,
+      hashCode: (a) => -a.hashCode,
+      isValidKey: (a) => true));
+
+  testTypeAnnotations(new HashSet<int>());
+  testTypeAnnotations(new LinkedHashSet<int>());
+  testTypeAnnotations(new HashSet<int>(equals: identical));
+  testTypeAnnotations(new LinkedHashSet<int>(equals: identical));
+  testTypeAnnotations(new HashSet<int>(equals: (int a, int b) => a == b,
+                                       hashCode: (int a) => a.hashCode,
+                                       isValidKey: (a) => a is int));
+  testTypeAnnotations(new LinkedHashSet<int>(equals: (int a, int b) => a == b,
+                                             hashCode: (int a) => a.hashCode,
+                                             isValidKey: (a) => a is int));
+
+  testRetainWhere(([equals, hashCode, validKey]) =>
+      new HashSet(equals: equals, hashCode: hashCode, isValidKey: validKey));
+  testRetainWhere(([equals, hashCode, validKey]) =>
+      new LinkedHashSet(equals: equals, hashCode: hashCode,
+                        isValidKey: validKey));
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index ac55ad5..e27c033 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -33,6 +33,31 @@
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
 
+
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+crypto_test/functional: Pass, Slow # TODO(kasperl): Please triage.
+input_element_test/supported_datetime-local: Pass, Slow # TODO(kasperl): Please triage.
+
+fileapi_test/entry: Fail, Pass # TODO(kasperl): Please triage.
+fileapi_test/fileEntry: Fail, Pass # TODO(kasperl): Please triage.
+fileapi_test/getDirectory: Fail, Pass # TODO(kasperl): Please triage.
+fileapi_test/getFile: Fail, Pass # TODO(kasperl): Please triage.
+
+audiobuffersourcenode_test/supported: Fail # TODO(kasperl): Please triage.
+canvasrenderingcontext2d_test/drawImage_video_element: Fail # TODO(kasperl): Please triage.
+canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # TODO(kasperl): Please triage.
+dromaeo_smoke_test: Fail # TODO(kasperl): Please triage.
+element_types_test/supported_datalist: Fail # TODO(kasperl): Please triage.
+fileapi_test/directoryReader: Fail # TODO(kasperl): Please triage.
+input_element_test/supported_week: Fail # TODO(kasperl): Please triage.
+media_stream_test/supported_media: Fail # TODO(kasperl): Please triage.
+notifications_test/supported: Fail # TODO(kasperl): Please triage.
+rtc_test/supported: Fail # TODO(kasperl): Please triage.
+speechrecognition_test/supported: Fail # TODO(kasperl): Please triage.
+speechrecognition_test/types: Fail # TODO(kasperl): Please triage.
+xhr_test/json: Fail # TODO(kasperl): Please triage.
+
+
 [ $compiler == dart2js && $runtime == ie10 ]
 async_test: Pass, Fail # timers test fails on ie10.
 indexeddb_5_test: Fail # Issue 12893
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index d96a036..a3a9274 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -78,6 +78,12 @@
 isolate2_negative_test: Fail # Issue 12628
 illegal_msg_test: Pass # Issue 12628
 
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+isolate_stress_test: Pass, Slow # TODO(kasperl): Please triage.
+mandel_isolate_stream_test: Pass, Slow # TODO(kasperl): Please triage.
+
+mandel_isolate_test: Pass, Timeout # TODO(kasperl): Please triage.
+
 [ $compiler == dart2dart ]
 *: Skip # Issue 12629
 
diff --git a/tests/language/bit_operations_test.dart b/tests/language/bit_operations_test.dart
index dc548d1..6c7b106 100644
--- a/tests/language/bit_operations_test.dart
+++ b/tests/language/bit_operations_test.dart
@@ -6,174 +6,190 @@
 
 import "package:expect/expect.dart";
 
-class BitOperationsTest {
-  static testMain() {
-    for (int i = 0; i < 4; i++) {
-      testOne();
-    }
+void main() {
+  for (int i = 0; i < 4; i++) {
+    test();
   }
-  static testOne() {
-    Expect.equals(3, (3 & 7));
-    Expect.equals(7, (3 | 7));
-    Expect.equals(4, (3 ^ 7));
-    Expect.equals(25, (100 >> 2));
-    Expect.equals(400, (100 << 2));
-    Expect.equals(-25, (-100 >> 2));
-    Expect.equals(-101, ~100);
-    Expect.equals(0x10000000000000000, 1 << 64);
-    Expect.equals(-0x10000000000000000, -1 << 64);
-    Expect.equals(0x40000000, 0x04000000 << 4);
-    Expect.equals(0x4000000000000000, 0x0400000000000000 << 4);
-    Expect.equals(0, ~-1);
-    Expect.equals(-1, ~0);
-
-    Expect.equals(0, 1 >> 160);
-    Expect.equals(-1, -1 >> 160);
-
-    Expect.equals(0x100000000000000001,
-        0x100000000000000001 & 0x100000100F00000001);
-    Expect.equals(0x1, 0x1 & 0x100000100F00000001);
-    Expect.equals(0x1, 0x100000100F00000001 & 0x1);
-
-    Expect.equals(0x100000100F00000001,
-        0x100000000000000001 | 0x100000100F00000001);
-    Expect.equals(0x100000100F00000011, 0x11 | 0x100000100F00000001);
-    Expect.equals(0x100000100F00000011, 0x100000100F00000001 | 0x11);
-
-    Expect.equals(0x0F000F00000000000000,
-        0x0F00F00000000000001 ^ 0xFF00000000000000001);
-    Expect.equals(0x31, 0xF00F00000000000001 ^ 0xF00F00000000000030);
-    Expect.equals(0xF00F00000000000031, 0xF00F00000000000001 ^ 0x30);
-    Expect.equals(0xF00F00000000000031, 0x30 ^ 0xF00F00000000000001);
-
-    Expect.equals(0xF0000000000000000F, 0xF0000000000000000F7 >> 4);
-    Expect.equals(15, 0xF00000000 >> 32);
-    Expect.equals(1030792151040, 16492674416655 >> 4);
-
-    Expect.equals(0xF0000000000000000F0, 0xF0000000000000000F << 4);
-    Expect.equals(0xF00000000, 15 << 32);
-
-    TestNegativeValueShifts();
-    TestPositiveValueShifts();
-    TestNoMaskingOfShiftCount();
-    TestNegativeCountShifts();
-    for (int i = 0; i < 20; i++) {
-      TestCornerCasesRightShifts();
-      TestRightShift64Bit();
-      TestLeftShift64Bit();
-      TestLeftShift64BitWithOverflow1();
-      TestLeftShift64BitWithOverflow2();
-      TestLeftShift64BitWithOverflow3();
-    }
-  }
-
-  static void TestCornerCasesRightShifts() {
-    var v32 = 0xFF000000;
-    var v64 = 0xFF00000000000000;
-    Expect.equals(0x3, v32 >> 0x1E);
-    Expect.equals(0x1, v32 >> 0x1F);
-    Expect.equals(0x0, v32 >> 0x20);
-    Expect.equals(0x3, v64 >> 0x3E);
-    Expect.equals(0x1, v64 >> 0x3F);
-    Expect.equals(0x0, v64 >> 0x40);
-  }
-
-  static void TestRightShift64Bit() {
-    var t = 0x1ffffffff;
-    Expect.equals(0xffffffff, t >> 1);
-  }
-
-  static void TestLeftShift64Bit() {
-    var t = 0xffffffff;
-    Expect.equals(0xffffffff, t << 0);
-    Expect.equals(0x1fffffffe, t << 1);
-    Expect.equals(0x7fffffff80000000, t << 31);
-    Expect.equals(0x10000000000000000, 2*(t+1) << 31);
-    Expect.equals(0x20000000000000000, 4*(t+1) << 31);
-    Expect.equals(0x8000000000000000, (t+1) << 31);
-  }
-
-  static void TestLeftShift64BitWithOverflow1() {
-    var t = 0xffffffff;
-    Expect.equals(0x10000000000000000, 2*(t+1) << 31);
-  }
-
-  static void TestLeftShift64BitWithOverflow2() {
-    var t = 0xffffffff;
-    Expect.equals(0x20000000000000000, 4*(t+1) << 31);
-  }
-
-  static void TestLeftShift64BitWithOverflow3() {
-    var t = 0xffffffff;
-    Expect.equals(0x8000000000000000, (t+1) << 31);
-  }
-
-  static void TestNegativeCountShifts() {
-    bool throwOnLeft(a, b) {
-      try {
-        var x = a << b;
-        return false;
-      } catch (e) {
-        return true;
-      }
-    }
-
-    bool throwOnRight(a, b) {
-      try {
-        var x = a >> b;
-        return false;
-      } catch (e) {
-        return true;
-      }
-    }
-
-    Expect.isTrue(throwOnLeft(12, -3));
-    Expect.isTrue(throwOnRight(12, -3));
-    for (int i = 0; i < 20; i++) {
-      Expect.isFalse(throwOnLeft(12, 3));
-      Expect.isFalse(throwOnRight(12, 3));
-    }
-  }
-
-  static void TestNegativeValueShifts() {
-    for (int value = 0; value > -100; value--) {
-      for (int i = 0; i < 300; i++) {
-        int b = (value << i) >> i;
-        Expect.equals(value, b);
-      }
-    }
-  }
-
-  static void TestPositiveValueShifts() {
-    for (int value = 0; value < 100; value++) {
-      for (int i = 0; i < 300; i++) {
-        int b = (value << i) >> i;
-        Expect.equals(value, b);
-      }
-    }
-  }
-
-  static void TestNoMaskingOfShiftCount() {
-    // Shifts which would behave differently if shift count was masked into a
-    // range.
-    Expect.equals(0, 0 >> 256);
-    Expect.equals(0, 1 >> 256);
-    Expect.equals(0, 2 >> 256);
-    Expect.equals(0, ShiftRight(0, 256));
-    Expect.equals(0, ShiftRight(1, 256));
-    Expect.equals(0, ShiftRight(2, 256));
-
-    for (int shift = 1; shift <= 256; shift++) {
-      Expect.equals(0, ShiftRight(1, shift));
-      Expect.equals(-1, ShiftRight(-1, shift));
-      Expect.equals(true, ShiftLeft(1, shift) > ShiftLeft(1, shift - 1));
-    }
-  }
-
-  static int ShiftLeft(int a, int b) { return a << b; }
-  static int ShiftRight(int a, int b) { return a >> b; }
 }
 
-main() {
-  BitOperationsTest.testMain();
+void test() {
+  Expect.equals(3, (3 & 7));
+  Expect.equals(7, (3 | 7));
+  Expect.equals(4, (3 ^ 7));
+  Expect.equals(25, (100 >> 2));
+  Expect.equals(400, (100 << 2));
+  Expect.equals(-25, (-100 >> 2));
+  Expect.equals(-101, ~100);
+  Expect.equals(0x10000000000000000, 1 << 64);
+  Expect.equals(-0x10000000000000000, -1 << 64);
+  Expect.equals(0x40000000, 0x04000000 << 4);
+  Expect.equals(0x4000000000000000, 0x0400000000000000 << 4);
+  Expect.equals(0, ~-1);
+  Expect.equals(-1, ~0);
+
+  Expect.equals(0, 1 >> 160);
+  Expect.equals(-1, -1 >> 160);
+
+  Expect.equals(0x100000000000000001,
+      0x100000000000000001 & 0x100000100F00000001);
+  Expect.equals(0x1, 0x1 & 0x100000100F00000001);
+  Expect.equals(0x1, 0x100000100F00000001 & 0x1);
+
+  Expect.equals(0x100000100F00000001,
+      0x100000000000000001 | 0x100000100F00000001);
+  Expect.equals(0x100000100F00000011, 0x11 | 0x100000100F00000001);
+  Expect.equals(0x100000100F00000011, 0x100000100F00000001 | 0x11);
+
+  Expect.equals(0x0F000F00000000000000,
+      0x0F00F00000000000001 ^ 0xFF00000000000000001);
+  Expect.equals(0x31, 0xF00F00000000000001 ^ 0xF00F00000000000030);
+  Expect.equals(0xF00F00000000000031, 0xF00F00000000000001 ^ 0x30);
+  Expect.equals(0xF00F00000000000031, 0x30 ^ 0xF00F00000000000001);
+
+  Expect.equals(0xF0000000000000000F, 0xF0000000000000000F7 >> 4);
+  Expect.equals(15, 0xF00000000 >> 32);
+  Expect.equals(1030792151040, 16492674416655 >> 4);
+
+  Expect.equals(0xF0000000000000000F0, 0xF0000000000000000F << 4);
+  Expect.equals(0xF00000000, 15 << 32);
+
+  testNegativeValueShifts();
+  testPositiveValueShifts();
+  testNoMaskingOfShiftCount();
+  testNegativeCountShifts();
+  for (int i = 0; i < 20; i++) {
+    testCornerCasesRightShifts();
+    testRightShift64Bit();
+    testLeftShift64Bit();
+    testLeftShift64BitWithOverflow1();
+    testLeftShift64BitWithOverflow2();
+    testLeftShift64BitWithOverflow3();
+  }
+
+  // Test precedence.
+  testPrecedence(4,5,3,1);
+  testPrecedence(3,4,5,9);
+  testPrecedence(0x5c71, 0x6b92, 0x7654, 0x7d28);
+}
+
+void testCornerCasesRightShifts() {
+  var v32 = 0xFF000000;
+  var v64 = 0xFF00000000000000;
+  Expect.equals(0x3, v32 >> 0x1E);
+  Expect.equals(0x1, v32 >> 0x1F);
+  Expect.equals(0x0, v32 >> 0x20);
+  Expect.equals(0x3, v64 >> 0x3E);
+  Expect.equals(0x1, v64 >> 0x3F);
+  Expect.equals(0x0, v64 >> 0x40);
+}
+
+void testRightShift64Bit() {
+  var t = 0x1ffffffff;
+  Expect.equals(0xffffffff, t >> 1);
+}
+
+void testLeftShift64Bit() {
+  var t = 0xffffffff;
+  Expect.equals(0xffffffff, t << 0);
+  Expect.equals(0x1fffffffe, t << 1);
+  Expect.equals(0x7fffffff80000000, t << 31);
+  Expect.equals(0x10000000000000000, 2*(t+1) << 31);
+  Expect.equals(0x20000000000000000, 4*(t+1) << 31);
+  Expect.equals(0x8000000000000000, (t+1) << 31);
+}
+
+void testLeftShift64BitWithOverflow1() {
+  var t = 0xffffffff;
+  Expect.equals(0x10000000000000000, 2*(t+1) << 31);
+}
+
+void testLeftShift64BitWithOverflow2() {
+  var t = 0xffffffff;
+  Expect.equals(0x20000000000000000, 4*(t+1) << 31);
+}
+
+void testLeftShift64BitWithOverflow3() {
+  var t = 0xffffffff;
+  Expect.equals(0x8000000000000000, (t+1) << 31);
+}
+
+void testNegativeCountShifts() {
+  bool throwOnLeft(a, b) {
+    try {
+      var x = a << b;
+      return false;
+    } catch (e) {
+      return true;
+    }
+  }
+
+  bool throwOnRight(a, b) {
+    try {
+      var x = a >> b;
+      return false;
+    } catch (e) {
+      return true;
+    }
+  }
+
+  Expect.isTrue(throwOnLeft(12, -3));
+  Expect.isTrue(throwOnRight(12, -3));
+  for (int i = 0; i < 20; i++) {
+    Expect.isFalse(throwOnLeft(12, 3));
+    Expect.isFalse(throwOnRight(12, 3));
+  }
+}
+
+void testNegativeValueShifts() {
+  for (int value = 0; value > -100; value--) {
+    for (int i = 0; i < 300; i++) {
+      int b = (value << i) >> i;
+      Expect.equals(value, b);
+    }
+  }
+}
+
+void testPositiveValueShifts() {
+  for (int value = 0; value < 100; value++) {
+    for (int i = 0; i < 300; i++) {
+      int b = (value << i) >> i;
+      Expect.equals(value, b);
+    }
+  }
+}
+
+void testNoMaskingOfShiftCount() {
+  // Shifts which would behave differently if shift count was masked into a
+  // range.
+  Expect.equals(0, 0 >> 256);
+  Expect.equals(0, 1 >> 256);
+  Expect.equals(0, 2 >> 256);
+  Expect.equals(0, shiftRight(0, 256));
+  Expect.equals(0, shiftRight(1, 256));
+  Expect.equals(0, shiftRight(2, 256));
+
+  for (int shift = 1; shift <= 256; shift++) {
+    Expect.equals(0, shiftRight(1, shift));
+    Expect.equals(-1, shiftRight(-1, shift));
+    Expect.equals(true, shiftLeft(1, shift) > shiftLeft(1, shift - 1));
+  }
+}
+
+int shiftLeft(int a, int b) { return a << b; }
+int shiftRight(int a, int b) { return a >> b; }
+
+void testPrecedence(int a, int b, int c, int d) {
+  // & binds stronger than ^, which binds stronger than |.
+  int result = a & b ^ c | d & b ^ c;
+  Expect.equals(((a & b) ^ c) | ((d & b) ^ c), result);     // &^|
+  Expect.notEquals((a & (b ^ c)) | (d & (b ^ c)), result);  // ^&|
+  Expect.notEquals((a & b) ^ (c | (d & b)) ^ c, result);    // &|^
+  Expect.notEquals((a & b) ^ ((c | d) & b) ^ c, result);    // |&^
+  Expect.notEquals(a & (b ^ (c | d)) & (b ^ c), result);    // |^&
+  Expect.notEquals(a & ((b ^ c) | d) & (b ^ c), result);    // ^|&
+  // Binds stronger than relational operators.
+  Expect.equals((a & b) < (c & d), a & b < c & d);
+  // Binds weaker than shift operators.
+  Expect.equals((a & (b << c)) ^ d, a & b << c ^ d);
+  Expect.notEquals((a & b) << (c ^ d), a & b << c ^ d);
 }
diff --git a/tests/language/cyclic_typedef_test.dart b/tests/language/cyclic_typedef_test.dart
new file mode 100644
index 0000000..61d8d0b
--- /dev/null
+++ b/tests/language/cyclic_typedef_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+// Check that cyclic reference of a typedef is a compile-time error.
+
+// To test various cyclic references the definition of the [:typedef A():] is
+// split over several lines:
+typedef
+
+// Cyclic through return type.
+A /// 01: compile-time error
+
+A // The name of the typedef
+
+( // The left parenthesis of the typedef arguments.
+
+// Cyclic through parameter type.
+A a /// 02: compile-time error
+
+// Cyclic through optional parameter type.
+[A a] /// 03: compile-time error
+
+// Cyclic through named parameter type.
+{A a} /// 04: compile-time error
+
+// Cyclic through generic parameter type.
+List<A> a /// 05: compile-time error
+
+// Cyclic through return type of function typed parameter.
+A f() /// 06: compile-time error
+
+// Cyclic through parameter type of function typed parameter.
+f(A a) /// 07: compile-time error
+
+// Cyclic through another typedef.
+B b /// 08: compile-time error
+
+// Cyclic through another more typedefs.
+C c /// 09: compile-time error
+
+); // The right parenthesis of the typedef arguments.
+
+typedef B(A a);
+typedef C(B b);
+
+void testA(A a) {}
+
+void main() {
+  testA(null);
+}
\ No newline at end of file
diff --git a/tests/language/factory_redirection3_cyclic_test.dart b/tests/language/factory_redirection3_cyclic_test.dart
new file mode 100644
index 0000000..4662911
--- /dev/null
+++ b/tests/language/factory_redirection3_cyclic_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that a cycle in redirecting factories leads to a compile-time error.
+
+class A {
+  factory A.foo() = B;
+}
+
+class B implements A {
+  factory B() = C.bar;
+}
+
+class C implements B {
+  factory C.bar() = C.foo;
+  factory C.foo() = C
+    .bar /// 01: compile-time error
+;
+  C();
+}
+
+main() {
+  new A.foo();
+}
diff --git a/tests/language/function_type_parameter_test.dart b/tests/language/function_type_parameter_test.dart
index 7ffe052..94ce81e 100644
--- a/tests/language/function_type_parameter_test.dart
+++ b/tests/language/function_type_parameter_test.dart
@@ -10,6 +10,7 @@
 class A {
   final f;
   A(int this.f());
+  const A.nother(int this.f());
 
   static Function func;
 
@@ -28,4 +29,5 @@
   Expect.equals(null, A.func);
 
   Expect.equals(42, new A(() => 42).f());
+  Expect.equals(42, new A.nother(() => 42).f());
 }
diff --git a/tests/language/issue10561_test.dart b/tests/language/issue10561_test.dart
index 7ff80be..24c308c 100644
--- a/tests/language/issue10561_test.dart
+++ b/tests/language/issue10561_test.dart
@@ -9,9 +9,9 @@
 
 import 'dart:collection';
 
-class Foo extends HashSet {
+class Foo extends Expando {
 }
 
 main() {
-  Expect.equals(0, new Foo().length);
+  Expect.isNull(new Foo()[new Object()]);
 }
diff --git a/tests/language/issue9949_test.dart b/tests/language/issue9949_test.dart
index d5df0ca..46c73d2 100644
--- a/tests/language/issue9949_test.dart
+++ b/tests/language/issue9949_test.dart
@@ -8,11 +8,11 @@
 import "package:expect/expect.dart";
 import 'dart:collection';
 
-class Crash extends HashSet<String> {
+class Crash extends Expando<String> {
   Crash(): super();
 }
 
 void main() {
-  Crash map = new Crash();
-  Expect.isTrue(map is HashSet);
+  Crash expando = new Crash();
+  Expect.isTrue(expando is Expando);
 }
diff --git a/tests/language/language.status b/tests/language/language.status
index 60a165a..67a94c1 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -12,8 +12,7 @@
 library_juxtaposition_test: Fail # Issue 6877
 switch_int_double_test/01: Fail # Issue 7307
 switch_int_double_test/02: Fail # Issue 7307
-symbol_literal_test: Fail # Issue 12171
-evaluation_redirecting_constructor_test: Fail # Issue 13347
+throwing_lazy_variable_test: Fail # Issue 5802
 
 # These bugs refer currently ongoing language discussions.
 constructor_initializer_test/none: Fail # Issue 12633
@@ -28,6 +27,9 @@
 on_catch_malformed_type_test: Fail # Issue 8601
 mixin_mixin_test: Fail # Issue 9683
 mixin_mixin2_test: Fail # Issue 9683
+mixin_mixin3_test: Fail # Issue 9683
+mixin_mixin4_test: Fail # Issue 9683
+mixin_mixin5_test: Fail # Issue 9683
 mixin_issue10216_2_test: Fail # Issue 9683
 mixin_illegal_object_test/01: Crash # Issue 10952
 mixin_illegal_object_test/02: Crash # Issue 10952
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 87285e6..c71efb6 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -4,7 +4,6 @@
 
 [ $compiler == dart2js || $compiler == dart2dart ]
 block_scope_test: Fail # Issue 13204.
-compile_time_constant_c_test/none: Fail # Issue 11583
 null_test/03: Fail # Issue 12445.
 black_listed_test/none: Fail # Issue 12446.
 malformed_test/none: Fail # Issue 12695
@@ -38,7 +37,6 @@
 redirecting_factory_malbounded_test/01: Fail # Issue 12825
 
 [ $compiler == dart2js && $unchecked ]
-factory_redirection_test/14: Fail # Issue 10959
 type_checks_in_factory_method_test: Fail # Issue 12746
 assertion_test: Fail # Issue 12748
 double_to_string_as_exponential2_test: Fail # Issue 12749
@@ -67,10 +65,13 @@
 [ $compiler == dart2js && $minified ]
 f_bounded_quantification4_test: Fail # Issue 12605.
 f_bounded_quantification5_test: Fail # Issue 12605.
+mixin_generic_test: Fail # Issue 12605.
 mixin_mixin2_test: Fail # Issue 12605.
+mixin_mixin3_test: Fail # Issue 12605.
+mixin_mixin4_test: Fail # Issue 12605.
+mixin_mixin5_test: Fail # Issue 12605.
 
 [ $compiler == dart2js ]
-function_type_alias6_test/00: Crash # Issue 9792
 function_type_alias9_test/00: Crash # Issue 9792
 branch_canonicalization_test: Fail # Issue 638.
 div_with_power_of_two_test: Fail # Issue 8301.
@@ -113,6 +114,7 @@
 infinity_test: Fail # Issue 4984
 positive_bit_operations_test: Fail # Issue 12795
 mixin_mixin2_test: Fail # Issue 13109.
+mixin_mixin3_test: Fail # Issue 13109.
 
 # Compilation errors.
 const_var_test: Fail # Issue 12793
@@ -136,8 +138,6 @@
 map_literal4_test: Fail # Issue 12891
 built_in_identifier_test/01: Fail # Issue 13022
 
-const_syntax_test/01: Fail # Issue 12932
-const_syntax_test/02: Fail # Issue 12932
 const_syntax_test/03: Fail # Issue 12932
 const_syntax_test/04: Fail # Issue 12932
 constructor9_test/01: Fail # Issue 12934
@@ -168,6 +168,8 @@
 [ $compiler == dart2js && ($runtime == ff || $runtime == jsshell || $runtime == ie9 || $runtime == safari)]
 round_test: Fail, OK # Common JavaScript engine Math.round bug.
 
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+override_field_test/02: Pass, Slow # TODO(kasperl): Please triage.
 
 [ $compiler == dart2js && $runtime == ie9 ]
 double_to_string_as_exponential3_test: Fail # Issue 12750
@@ -194,9 +196,7 @@
 [ $compiler == dart2dart ]
 mixin_super_constructor_named_test: Fail # Issue 12631
 mixin_super_constructor_positionals_test: Fail # Issue 12631
-function_type_alias6_test/00: Fail # Issue 11986
 function_type_alias9_test/00: Crash # Issue 11986
-symbol_literal_test: Fail # Issue 12171
 
 built_in_identifier_prefix_test: Fail # Issue 6972
 constructor_initializer_test/none: Fail # Issue 12633
@@ -208,6 +208,9 @@
 # Mixins fail on the VM.
 mixin_mixin_test: Fail # Issue 9683
 mixin_mixin2_test: Fail # Issue 9683
+mixin_mixin3_test: Fail # Issue 9683
+mixin_mixin4_test: Fail # Issue 9683
+mixin_mixin5_test: Fail # Issue 9683
 mixin_issue10216_2_test: Fail # Issue 9683
 mixin_forwarding_constructor2_test: Fail # Issue 11888
 mixin_typedef_constructor_test: Fail # Issue 11888
@@ -249,8 +252,6 @@
 compile_time_constant_arguments_test/03: Fail # Issue 5519
 compile_time_constant_arguments_test/05: Fail # Issue 5519
 compile_time_constant_arguments_test/06: Fail # Issue 5519
-const_syntax_test/01: Fail # Issue 12933
-const_syntax_test/02: Fail # Issue 12933
 const_syntax_test/03: Fail # Issue 12933
 const_syntax_test/04: Fail # Issue 12933
 const_syntax_test/05: Fail # Issue 12933
@@ -258,6 +259,8 @@
 const_syntax_test/07: Fail # Issue 12933
 const_syntax_test/08: Fail # Issue 12933
 const_syntax_test/10: Fail # Issue 12933
+map_literal11_test: Fail # Issue 12933
+compile_time_constant_c_test/02: Fail # Issue 12933
 constructor9_test/01: Fail # Issue 12935
 constructor_named_arguments_test/01: Fail # Issue 5519
 final_syntax_test/01: Fail # Issue 13020
@@ -295,7 +298,6 @@
 factory_redirection_test/03: Crash # Issue 12753
 factory_redirection_test/07: Fail # Issue 12753
 factory_redirection_test/09: Fail # Issue 12753
-factory_redirection_test/14: Fail # Issue 10959
 function_type_alias5_test/00: Fail # Issue 12755
 function_type_alias5_test/01: Fail # Issue 12755
 function_type_alias5_test/02: Fail # Issue 12755
@@ -306,7 +308,8 @@
 constructor6_test: Fail
 closure_in_initializer_test: Fail
 super_first_constructor_test: Fail
-evaluation_redirecting_constructor_test: Fail # Issue 13347
+throwing_lazy_variable_test: Fail # Issue 5802
+
 # Minified mode failures.
 
 new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
diff --git a/tests/language/map_literal10_test.dart b/tests/language/map_literal10_test.dart
new file mode 100644
index 0000000..d1d3886
--- /dev/null
+++ b/tests/language/map_literal10_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use of '__proto__' keys in maps.
+
+library map_literal10_test;
+
+import "package:expect/expect.dart";
+
+void main() {
+  var m1 = const {"__proto__": 0, 1: 1};
+  Expect.isTrue(m1.containsKey("__proto__"));
+  Expect.equals(0, m1["__proto__"]);
+  Expect.isTrue(m1.containsKey(1));
+  Expect.equals(1, m1[1]);
+  Expect.listEquals(["__proto__", 1], m1.keys.toList());
+
+  var m2 = const {1: 0, "__proto__": 1};
+  Expect.isTrue(m2.containsKey(1));
+  Expect.equals(0, m2[1]);
+  Expect.isTrue(m2.containsKey("__proto__"));
+  Expect.equals(1, m2["__proto__"]);
+  Expect.listEquals([1, "__proto__"], m2.keys.toList());
+
+  var m3 = const {"1": 0, "__proto__": 1};
+  Expect.isTrue(m3.containsKey("1"));
+  Expect.equals(0, m3["1"]);
+  Expect.isTrue(m3.containsKey("__proto__"));
+  Expect.equals(1, m3["__proto__"]);
+  Expect.listEquals(["1", "__proto__"], m3.keys.toList());
+
+  var m4 = const {"__proto__": 1, "1": 2};
+  Expect.isTrue(m4.containsKey("1"));
+  Expect.equals(2, m4["1"]);
+  Expect.isTrue(m4.containsKey("__proto__"));
+  Expect.equals(1, m4["__proto__"]);
+  Expect.listEquals(["__proto__", "1"], m4.keys.toList());
+}
diff --git a/tests/language/map_literal11_test.dart b/tests/language/map_literal11_test.dart
new file mode 100644
index 0000000..7461b80
--- /dev/null
+++ b/tests/language/map_literal11_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use of reliance on identity for keys in constant maps.
+
+library map_literal11_test;
+
+import "package:expect/expect.dart";
+
+
+class A {
+  static int accessCount = 0;
+
+  final int field;
+
+  const A(this.field);
+  int get hashCode => accessCount++;
+}
+
+void main() {
+  // Non-constant map are not based on identity.
+  var m1 = {const A(0): 0, const A(1): 1, null: 2, "3": 3, 4: 4};
+  Expect.isFalse(m1.containsKey(const A(0)));
+  Expect.isFalse(m1.containsKey(const A(1)));
+  Expect.isTrue(m1.containsKey(null));
+  Expect.isTrue(m1.containsKey("3"));
+  Expect.isTrue(m1.containsKey(4));
+  Expect.isNull(m1[const A(0)]);
+  Expect.isNull(m1[const A(1)]);
+  Expect.equals(2, m1[null]);
+  Expect.equals(3, m1["3"]);
+  Expect.equals(4, m1[4]);
+
+  // Constant map are based on identity.
+  var m2 = const {const A(0): 0, const A(1): 1, null: 2, "3": 3, 4: 4};
+  Expect.isTrue(m2.containsKey(const A(0)));
+  Expect.isTrue(m2.containsKey(const A(1)));
+  Expect.isTrue(m2.containsKey(null));
+  Expect.isTrue(m2.containsKey("3"));
+  Expect.isTrue(m2.containsKey(4));
+  Expect.equals(0, m2[const A(0)]);
+  Expect.equals(1, m2[const A(1)]);
+  Expect.equals(2, m2[null]);
+  Expect.equals(3, m2["3"]);
+  Expect.equals(4, m2[4]);
+}
diff --git a/tests/language/map_literal5_test.dart b/tests/language/map_literal5_test.dart
new file mode 100644
index 0000000..365f218
--- /dev/null
+++ b/tests/language/map_literal5_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use of general expression as keys in map literals.
+
+library map_literal5_test;
+
+import "package:expect/expect.dart";
+
+void main() {
+  test(true);
+  test(false);
+}
+
+void test(bool b) {
+  var m = create(b);
+  Expect.equals(b, m.containsKey(true));
+  Expect.equals(b, m.containsKey(2));
+  Expect.equals(b, m.containsKey(1));
+  Expect.equals(!b, m.containsKey(false));
+  Expect.equals(!b, m.containsKey("bar"));
+  Expect.equals(!b, m.containsKey("foo"));
+  if (b) {
+    Expect.equals(0, m[true]);
+    Expect.equals(3, m[2]);
+    Expect.equals(2, m[1]);
+  } else {
+    Expect.equals(0, m[false]);
+    Expect.equals("baz", m["bar"]);
+    Expect.equals(2, m["foo"]);
+  }
+}
+
+create(bool b) {
+  return {
+    b: 0,
+    m(b): n(b),
+    b ? 1 : "foo": 2,
+  };
+}
+
+m(bool b) => b ? 2 : "bar";
+n(bool b) => b ? 3 : "baz";
\ No newline at end of file
diff --git a/tests/language/map_literal6_test.dart b/tests/language/map_literal6_test.dart
new file mode 100644
index 0000000..24935bf
--- /dev/null
+++ b/tests/language/map_literal6_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use of general expression as keys in const map literals.
+
+library map_literal6_test;
+
+import "package:expect/expect.dart";
+
+class A {
+  const A();
+}
+class B {
+  final a;
+  const B(this.a);
+}
+
+void main() {
+  var m1 = const {
+    const A(): 0,
+    const B(0): 1,
+    const B(1): 2,
+    const B(const A()): 3,
+    const B(0): 4,
+  };
+  Expect.isTrue(m1.containsKey(const A()));
+  Expect.isTrue(m1.containsKey(const B(0)));
+  Expect.isTrue(m1.containsKey(const B(1)));
+  Expect.isTrue(m1.containsKey(const B(const A())));
+  Expect.equals(0, m1[const A()]);
+  Expect.equals(4, m1[const B(0)]);
+  Expect.equals(2, m1[const B(1)]);
+  Expect.equals(3, m1[const B(const A())]);
+}
diff --git a/tests/language/map_literal7_test.dart b/tests/language/map_literal7_test.dart
new file mode 100644
index 0000000..a1d53c4
--- /dev/null
+++ b/tests/language/map_literal7_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use type arguments on constant maps.
+
+library map_literal7_test;
+
+import "package:expect/expect.dart";
+
+void main() {
+  var m1 = const {"0": 0, "1": 1};
+  Expect.isTrue(m1 is Map);
+  Expect.isTrue(m1 is Map<String,int>);
+  Expect.isTrue(m1 is Map<int,dynamic>);
+  Expect.isTrue(m1 is Map<dynamic,String>);
+
+  var m2 = const <String,int>{"0": 0, "1": 1};
+  Expect.isTrue(m2 is Map);
+  Expect.isTrue(m2 is Map<String,int>);
+  Expect.isFalse(m2 is Map<int,dynamic>);
+  Expect.isFalse(m2 is Map<dynamic,String>);
+}
diff --git a/tests/language/map_literal8_test.dart b/tests/language/map_literal8_test.dart
new file mode 100644
index 0000000..ac68d84
--- /dev/null
+++ b/tests/language/map_literal8_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use of type arguments on const map literals using general expression
+// as keys.
+
+library map_literal8_test;
+
+import "package:expect/expect.dart";
+
+class A {
+  const A();
+}
+class B extends A {
+  final a;
+  const B(this.a);
+}
+
+void main() {
+  var m1 = const {
+    const A(): 0,
+    const B(0): 1,
+    const B(1): 2,
+    const B(const A()): 3,
+    const B(0): 4,
+  };
+  Expect.isTrue(m1 is Map);
+  Expect.isTrue(m1 is Map<A,int>);
+  Expect.isTrue(m1 is Map<int, dynamic>);
+  Expect.isTrue(m1 is Map<dynamic, A>);
+
+  var m2 = const <A, int>{
+    const A(): 0,
+    const B(0): 1,
+    const B(1): 2,
+    const B(const A()): 3,
+    const B(0): 4,
+  };
+  Expect.isTrue(m2 is Map);
+  Expect.isTrue(m2 is Map<A, int>);
+  Expect.isFalse(m2 is Map<int, dynamic>);
+  Expect.isFalse(m2 is Map<dynamic, A>);
+}
diff --git a/tests/language/map_literal9_test.dart b/tests/language/map_literal9_test.dart
new file mode 100644
index 0000000..cc12411
--- /dev/null
+++ b/tests/language/map_literal9_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test the use type arguments on constant maps.
+
+library map_literal9_test;
+
+import "package:expect/expect.dart";
+
+void main() {
+  var m1 = const {"[object Object]": 0, "1": 1};
+  Expect.isFalse(m1.containsKey(new Object()));
+  Expect.isNull(m1[new Object()]);
+  Expect.isFalse(m1.containsKey(1));
+  Expect.isNull(m1[1]);
+
+  var m2 = const {"[object Object]": 0, "1": 1, "__proto__": 2};
+  Expect.isFalse(m2.containsKey(new Object()));
+  Expect.isNull(m2[new Object()]);
+  Expect.isFalse(m2.containsKey(1));
+  Expect.isNull(m2[1]);
+}
diff --git a/tests/language/mixin_generic_test.dart b/tests/language/mixin_generic_test.dart
new file mode 100644
index 0000000..445fbed
--- /dev/null
+++ b/tests/language/mixin_generic_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class S<T> {
+  s() { return T; }
+}
+
+class M<T> {
+  m() { return T; }
+}
+
+class N<T> {
+  n() { return T; }
+}
+
+class C<U, V> extends S<Map<U, V>> with M<List<U>>, N<Set<V>> { }
+
+main() {
+  var c = new C<int, bool>();
+  Expect.isTrue(c is S<Map<int, bool>>);
+  Expect.equals("Map<int, bool>", c.s().toString());
+  Expect.isTrue(c is M<List<int>>);
+  Expect.equals("List<int>", c.m().toString());
+  Expect.isTrue(c is N<Set<bool>>);
+  Expect.equals("Set<bool>", c.n().toString());
+}
diff --git a/tests/language/mixin_mixin3_test.dart b/tests/language/mixin_mixin3_test.dart
new file mode 100644
index 0000000..844dd30
--- /dev/null
+++ b/tests/language/mixin_mixin3_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class M<T> {
+  t() { return T; }
+}
+
+typedef A<U> = Object with M<List<U>>;
+
+typedef B0 = Object with A<Set<bool>>;
+
+typedef B1 = Object with A<Set<int>>;
+
+class C0 extends B0 { }
+
+class C1 extends B1 { }
+
+typedef A2<K, V> = Object with M<Map<K, V>>;
+
+typedef B2<V> = Object with A2<Set<V>, List<V>>;
+
+typedef B3<K, V> = Object with A2<Set<K>, List<V>>;
+
+class C2<T> extends B2<T> { }
+
+class C3<T> extends B3<T, int> { }
+
+class N {
+  q() { return 42; }
+}
+
+typedef O<U> = Object with N;
+
+typedef P<K, V> = Object with O<V>;
+
+class Q<K, V> extends P<K, V> { }
+
+main() {
+  Expect.equals("List<Set<bool>>", new C0().t().toString());
+  Expect.equals("List<Set<int>>", new C1().t().toString());
+  Expect.equals("Map<Set<bool>, List<bool>>", new C2<bool>().t().toString());
+  Expect.equals("Map<Set<bool>, List<int>>", new C3<bool>().t().toString());
+  Expect.equals(42, new Q<bool, int>().q());
+}
diff --git a/tests/language/mixin_mixin4_test.dart b/tests/language/mixin_mixin4_test.dart
new file mode 100644
index 0000000..61815b4
--- /dev/null
+++ b/tests/language/mixin_mixin4_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class I<T> { }
+
+class J<T> { }
+
+class S<T> { }
+
+class M<T> {
+  t() { return T; }
+}
+
+typedef A<U, V> = Object with M<Map<U, V>> implements I<V>;
+
+typedef C<T, K> = S<T> with A<T, List<K>> implements J<K>;
+
+main() {
+  var c = new C<int, bool>();
+  Expect.equals("Map<int, List<bool>>", c.t().toString());
+  Expect.isTrue(c is I<List<bool>>);
+  Expect.isTrue(c is J<bool>);
+  Expect.isTrue(c is S<int>);
+  Expect.isTrue(c is A<int, List<bool>>);
+  Expect.isTrue(c is M<Map<int, List<bool>>>);
+}
diff --git a/tests/language/mixin_mixin5_test.dart b/tests/language/mixin_mixin5_test.dart
new file mode 100644
index 0000000..2ee8be7
--- /dev/null
+++ b/tests/language/mixin_mixin5_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class I<T> { }
+
+class J<T> { }
+
+class K<T> { }
+
+class S<T> { }
+
+class M<T> {
+  m() { return T; }
+}
+
+typedef A<U, V> = Object with M<Map<U, V>> implements I<V>;
+
+typedef B<T> = Object with A<T, Set<T>> implements J<T>;
+
+typedef C<T> = S<List<T>> with B<List<T>> implements K<T>;
+
+main() {
+  var c = new C<int>();
+  Expect.equals("Map<List<int>, Set<List<int>>>", c.m().toString());
+  Expect.isTrue(c is K<int>);
+  Expect.isTrue(c is J<List<int>>);
+  Expect.isTrue(c is I<Set<List<int>>>);
+  Expect.isTrue(c is S<List<int>>);
+  Expect.isTrue(c is A<List<int>, Set<List<int>>>);
+  Expect.isTrue(c is M<Map<List<int>, Set<List<int>>>>);
+}
diff --git a/tests/language/redirecting_factory_incompatible_signature_test.dart b/tests/language/redirecting_factory_incompatible_signature_test.dart
new file mode 100644
index 0000000..18129a0
--- /dev/null
+++ b/tests/language/redirecting_factory_incompatible_signature_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.
+
+// Test that incompatible signatures in a forwarding factory
+// constructor leads to a [NoSuchMethodError].
+
+import "package:expect/expect.dart";
+
+class A {
+  A(a, b);
+  factory A.f() = A;
+}
+
+main() {
+  Expect.throws(() => new A.f(), (e) => e is NoSuchMethodError);
+}
diff --git a/tests/language/throwing_lazy_variable_test.dart b/tests/language/throwing_lazy_variable_test.dart
new file mode 100644
index 0000000..c97d2fb
--- /dev/null
+++ b/tests/language/throwing_lazy_variable_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that engines will not infer that [a] is always of type int.
+
+var a = foo();
+
+foo() {
+  () => 42;
+  if (true) throw 'Sorry';
+  return 42;
+}
+
+main() {
+  try {
+    a;
+  } catch (e) {
+    // Ignore.
+  }
+  if (a is num) throw 'Test failed';
+}
diff --git a/tests/language/vm/optimized_guarded_field_test.dart b/tests/language/vm/optimized_guarded_field_test.dart
new file mode 100644
index 0000000..2ef5dcb
--- /dev/null
+++ b/tests/language/vm/optimized_guarded_field_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test correct handling of phis with only environment uses that were inserted
+// by store to load forwarding.
+// VMOptions=--optimization_counter_threshold=10
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo;
+}
+
+class B {
+  get foo => null;
+}
+
+test(obj) => obj.foo == null ? "null" : "other";
+
+main() {
+  var a = new A();
+  var b = new B();
+  // Trigger optimization of test with a polymorphic load.
+  // The guarded type of foo is null.
+  test(a);
+  test(b);
+  for (var i = 0; i < 20; ++i) test(a);
+  Expect.equals("null", test(a));
+  Expect.equals("null", test(b));
+
+  // Store a non-null object into foo to trigger deoptimization of test.
+  a.foo = 123;
+  Expect.equals("other", test(a));
+  Expect.equals("null", test(b));
+}
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 1594832..5fa450c 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -617,6 +617,19 @@
   completer.complete(21);
 }
 
+void testSyncFuture_i13368() {
+  asyncStart();
+
+  final future = new Future<int>.sync(() {
+      return new Future<int>.value(42);
+    });
+
+  future.then((int val) {
+      Expect.equals(val, 42);
+      asyncEnd();
+    });
+}
+
 main() {
   testValue();
   testSync();
@@ -658,4 +671,6 @@
   testChainedFutureValue();
   testChainedFutureValueDelay();
   testChainedFutureError();
+
+  testSyncFuture_i13368();
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index d0b9b70..098b947 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -11,10 +11,10 @@
 math/low_test: Fail
 math/random_test: Fail
 mirrors/class_mirror_type_variables_test: Fail # Issue 12087
-mirrors/equality_test: Fail # Issue 12333
+mirrors/equality_test/02: Fail # Issue 12333
 mirrors/fake_function_test: Fail # Issue 11612
 mirrors/function_type_mirror_test: Fail # Issue 12166
-mirrors/generics_test: Fail # Issue 12333
+mirrors/generics_test/01: Fail # Issue 12333
 mirrors/hierarchy_invariants_test: Fail # Issue 11863
 mirrors/invoke_test: Fail # Issue 11954
 mirrors/invoke_named_test: Fail # Issue 10471, 12863
@@ -29,7 +29,7 @@
 mirrors/mixin_test/none: Fail # Issue 12464
 mirrors/new_instance_with_type_arguments_test: Fail # Issue 12333
 mirrors/null_test : Fail # Issue 12129
-mirrors/parameter_test: Fail # Issue 6490
+mirrors/parameter_test/none: Fail # Issue 6490
 mirrors/parameter_metadata_test: Fail # Issue 10905
 mirrors/reflected_type_test: Fail # Issue 12607
 mirrors/typedef_metadata_test: Fail # Issue 12785
@@ -164,6 +164,8 @@
 [ $compiler == dartanalyzer ]
 mirrors/library_metadata2_test/01: Fail # http://dartbug.com/12950
 mirrors/typedef_test/none: Fail # Issue 13093
+mirrors/generics_test/none: Fail # Issue 13432
 
 [ $compiler == dart2analyzer ]
 mirrors/library_metadata2_test/01: Fail # http://dartbug.com/12950
+
diff --git a/tests/lib/mirrors/class_mirror_type_variables_test.dart b/tests/lib/mirrors/class_mirror_type_variables_test.dart
index 2b02bad..c4149e4 100644
--- a/tests/lib/mirrors/class_mirror_type_variables_test.dart
+++ b/tests/lib/mirrors/class_mirror_type_variables_test.dart
@@ -7,9 +7,9 @@
 import "package:expect/expect.dart";
 
 class C<R,S,T> {
-  R foo(R r) => r; 
-  S bar(S s) => s; 
-  T baz(T t) => t; 
+  R foo(R r) => r;
+  S bar(S s) => s;
+  T baz(T t) => t;
 }
 
 class NoTypeParams {}
@@ -18,10 +18,7 @@
   ClassMirror cm;
   cm = reflectClass(C);
   Expect.equals(3, cm.typeVariables.length);
-  Expect.equals(true, cm.typeVariables.containsKey(const Symbol("R")));
-  Expect.equals(true, cm.typeVariables.containsKey(const Symbol("S")));
-  Expect.equals(true, cm.typeVariables.containsKey(const Symbol("T")));
-  var values = cm.typeVariables.values;
+  var values = cm.typeVariables;
   values.forEach((e) {
     Expect.equals(true, e is TypeVariableMirror);
   });
diff --git a/tests/lib/mirrors/equality_dart2js_test.dart b/tests/lib/mirrors/equality_dart2js_test.dart
deleted file mode 100644
index 15c036d..0000000
--- a/tests/lib/mirrors/equality_dart2js_test.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.class_equality_test;
-
-import 'dart:mirrors';
-
-import 'package:expect/expect.dart';
-
-class A<T> {}
-class B extends A<int> {}
-
-class BadEqualityHash {
-  int count = 0;
-  bool operator ==(other) => true;
-  int get hashCode => count++;
-}
-
-checkEquality(List<Map> equivalenceClasses) {
-  for (var equivalenceClass in equivalenceClasses) {
-    equivalenceClass.forEach((name, member) {
-      equivalenceClass.forEach((otherName, otherMember) {
-        // Reflexivity, symmetry and transitivity.
-        Expect.equals(member, 
-                      otherMember,
-                      "$name == $otherName");
-        Expect.equals(member.hashCode,
-                      otherMember.hashCode,
-                      "$name.hashCode == $otherName.hashCode");
-      });
-      for (var otherEquivalenceClass in equivalenceClasses) {
-        if (otherEquivalenceClass == equivalenceClass) continue;
-        otherEquivalenceClass.forEach((otherName, otherMember) {
-          Expect.notEquals(member,
-                           otherMember,
-                           "$name != $otherName");  // Exclusion.
-          // Hash codes may or may not be equal.
-        });
-      }
-    });
-  }
-}
-
-void subroutine() {
-}
-
-main() {
-  LibraryMirror thisLibrary =
-      currentMirrorSystem()
-      .findLibrary(const Symbol('test.class_equality_test'))
-      .single;
-
-  var o1 = new Object();
-  var o2 = new Object();
-
-  var badEqualityHash1 = new BadEqualityHash();
-  var badEqualityHash2 = new BadEqualityHash();
-
-  checkEquality([
-    {'reflect(o1)' : reflect(o1),
-     'reflect(o1), again' : reflect(o1)},
-
-    {'reflect(o2)' : reflect(o2),
-     'reflect(o2), again' : reflect(o2)},
-
-    {'reflect(badEqualityHash1)' : reflect(badEqualityHash1),
-     'reflect(badEqualityHash1), again' : reflect(badEqualityHash1)},
-
-    {'reflect(badEqualityHash2)' : reflect(badEqualityHash2),
-     'reflect(badEqualityHash2), again' : reflect(badEqualityHash2)},
-
-    {'reflect(true)' : reflect(true),
-     'reflect(true), again' : reflect(true)},
-
-    {'reflect(false)' : reflect(false),
-     'reflect(false), again' : reflect(false)},
-
-    {'reflect(null)' : reflect(null),
-     'reflect(null), again' : reflect(null)},
-
-    {'reflect(3.5+4.5)' : reflect(3.5+4.5),
-     'reflect(6.5+1.5)' : reflect(6.5+1.5)},
-
-    {'reflect(3+4)' : reflect(3+4),
-     'reflect(6+1)' : reflect(6+1)},
-
-    {'reflect("foo")' : reflect("foo"),
-     'reflect("foo"), again' : reflect("foo")},
-
-    {'currentMirrorSystem().voidType' : currentMirrorSystem().voidType},
-
-    {'currentMirrorSystem().dynamicType' : currentMirrorSystem().dynamicType,
-     'thisLibrary.functions[#main].returnType' :
-          thisLibrary.functions[const Symbol('main')].returnType},
-
-    {'reflectClass(A)' : reflectClass(A),
-     'thisLibrary.classes[#A]' : thisLibrary.classes[const Symbol('A')],
-     'reflect(new A<int>()).type.originalDeclaration' :
-          reflect(new A<int>()).type.originalDeclaration},
-
-    {'reflectClass(B)' : reflectClass(B),
-     'thisLibrary.classes[#B]' : thisLibrary.classes[const Symbol('B')],
-     'reflect(new B()).type' : reflect(new B()).type},
-
-    {'thisLibrary' : thisLibrary,
-     'reflectClass(A).owner' : reflectClass(A).owner,
-     'reflectClass(B).owner' : reflectClass(B).owner,
-     'reflect(new A()).type.owner' : reflect(new A()).type.owner,
-     'reflect(new A()).type.owner' : reflect(new A()).type.owner},
-  ]);
-}
diff --git a/tests/lib/mirrors/equality_test.dart b/tests/lib/mirrors/equality_test.dart
index 1a08b59..1b3b798 100644
--- a/tests/lib/mirrors/equality_test.dart
+++ b/tests/lib/mirrors/equality_test.dart
@@ -2,6 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// This tests uses the multi-test "ok" feature:
+// none: Trimmed behaviour. Passing on the VM.
+// 01: Trimmed version for dart2js.
+// 02: Full version passing in the VM.
+//
+// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par.
+
 library test.class_equality_test;
 
 import 'dart:mirrors';
@@ -88,9 +95,11 @@
     {'reflect("foo")' : reflect("foo"),
      'reflect("foo"), again' : reflect("foo")},
 
-    {'currentMirrorSystem().voidType' : currentMirrorSystem().voidType,
-     'thisLibrary.functions[#subroutine].returnType' :
-          thisLibrary.functions[const Symbol('subroutine')].returnType},
+    {'currentMirrorSystem().voidType' : currentMirrorSystem().voidType},  /// 01: ok
+
+    {'currentMirrorSystem().voidType' : currentMirrorSystem().voidType,   /// 02: ok
+     'thisLibrary.functions[#subroutine].returnType' :                    /// 02: ok
+          thisLibrary.functions[const Symbol('subroutine')].returnType},  /// 02: ok
 
     {'currentMirrorSystem().dynamicType' : currentMirrorSystem().dynamicType,
      'thisLibrary.functions[#main].returnType' :
@@ -101,8 +110,8 @@
      'reflect(new A<int>()).type.originalDeclaration' :
           reflect(new A<int>()).type.originalDeclaration},
 
-    {'reflectClass(B).superclass' : reflectClass(B).superclass,
-     'reflect(new A<int>()).type' : reflect(new A<int>()).type},
+    {'reflectClass(B).superclass' : reflectClass(B).superclass,  /// 02: ok
+     'reflect(new A<int>()).type' : reflect(new A<int>()).type}, /// 02: ok
 
     {'reflectClass(B)' : reflectClass(B),
      'thisLibrary.classes[#B]' : thisLibrary.classes[const Symbol('B')],
@@ -112,6 +121,6 @@
      'reflectClass(A).owner' : reflectClass(A).owner,
      'reflectClass(B).owner' : reflectClass(B).owner,
      'reflect(new A()).type.owner' : reflect(new A()).type.owner,
-     'reflect(new A()).type.owner' : reflect(new A()).type.owner},
+     'reflect(new B()).type.owner' : reflect(new B()).type.owner},
   ]);
 }
diff --git a/tests/lib/mirrors/generics_test.dart b/tests/lib/mirrors/generics_test.dart
index e5e2c2f..d1f05d2 100644
--- a/tests/lib/mirrors/generics_test.dart
+++ b/tests/lib/mirrors/generics_test.dart
@@ -10,7 +10,9 @@
 
 class A<T> {}
 class B extends A {}            // Same as class B extends A<dynamic>.
-class C extends A<num, int> {}  // Same as class C extends A<dynamic>.
+class C extends A
+<num, int> // TODO(zarah): Should be "01: static warning".
+{} // Same as class C extends A<dynamic>.
 class D extends A<int> {}
 class E<S> extends A<S> {}
 class F<R> extends A<int> {}
@@ -19,27 +21,22 @@
 
 typeParameters(mirror, parameterNames) {
   Expect.listEquals(parameterNames.map((n) => new Symbol(n)).toList(),
-                    mirror.typeVariables.keys.toList());
+                    mirror.typeVariables.map((v) => v.simpleName).toList());
 }
 
 typeArguments(mirror, argumentMirrors) {
-  Expect.listEquals(argumentMirrors,
-                    mirror.typeArguments.values.toList());
-  if (!mirror.isOriginalDeclaration) {
-    Expect.listEquals(mirror.typeVariables.keys.toList(),
-                      mirror.typeArguments.keys.toList());
-  }
+  Expect.listEquals(argumentMirrors, mirror.typeArguments);
 }
 
 main() {
   // Declarations.
-  typeParameters(reflectClass(A), ['T']);
-  typeParameters(reflectClass(B), []);
-  typeParameters(reflectClass(C), []);
-  typeParameters(reflectClass(D), []);
-  typeParameters(reflectClass(E), ['S']);
-  typeParameters(reflectClass(F), ['R']);
-  typeParameters(reflectClass(G), []);
+  typeParameters(reflectClass(A), ['T']); /// 01: ok
+  typeParameters(reflectClass(B), []); /// 01: ok
+  typeParameters(reflectClass(C), []); /// 01: ok
+  typeParameters(reflectClass(D), []); /// 01: ok
+  typeParameters(reflectClass(E), ['S']); /// 01: ok
+  typeParameters(reflectClass(F), ['R']); /// 01: ok
+  typeParameters(reflectClass(G), []); /// 01: ok
 
   typeArguments(reflectClass(A), []);
   typeArguments(reflectClass(B), []);
@@ -66,32 +63,32 @@
   Expect.equals(reflectClass(G), reflectClass(G).originalDeclaration);
 
   // Instantiations.
-  typeParameters(reflect(new A<num>()).type, ['T']);
-  typeParameters(reflect(new B<num>()).type, []);
-  typeParameters(reflect(new C()).type, []);
-  typeParameters(reflect(new D()).type, []);
-  typeParameters(reflect(new E()).type, ['S']);
-  typeParameters(reflect(new F<num>()).type, ['R']);
-  typeParameters(reflect(new G()).type, []);
-  typeParameters(reflect(new H()).type, ['A', 'B', 'C']);
+  typeParameters(reflect(new A<num>()).type, ['T']); /// 01: ok
+  typeParameters(reflect(new B<num>()).type, []); /// 01: ok
+  typeParameters(reflect(new C()).type, []); /// 01: ok
+  typeParameters(reflect(new D()).type, []); /// 01: ok
+  typeParameters(reflect(new E()).type, ['S']); /// 01: ok
+  typeParameters(reflect(new F<num>()).type, ['R']); /// 01: ok
+  typeParameters(reflect(new G()).type, []); /// 01: ok
+  typeParameters(reflect(new H()).type, ['A', 'B', 'C']); /// 01: ok
 
   var numMirror = reflectClass(num);
   var dynamicMirror = currentMirrorSystem().dynamicType;
   typeArguments(reflect(new A<num>()).type, [numMirror]);
-  typeArguments(reflect(new A<dynamic>()).type, [dynamicMirror]);
-  typeArguments(reflect(new A()).type, [dynamicMirror]);
+  typeArguments(reflect(new A<dynamic>()).type, [dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new A()).type, [dynamicMirror]); /// 01: ok
   typeArguments(reflect(new B()).type, []);
   typeArguments(reflect(new C()).type, []);
   typeArguments(reflect(new D()).type, []);
   typeArguments(reflect(new E<num>()).type, [numMirror]);
-  typeArguments(reflect(new E<dynamic>()).type, [dynamicMirror]);
-  typeArguments(reflect(new E()).type, [dynamicMirror]);
+  typeArguments(reflect(new E<dynamic>()).type, [dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new E()).type, [dynamicMirror]); /// 01: ok
   typeArguments(reflect(new F<num>()).type, [numMirror]);
-  typeArguments(reflect(new F<dynamic>()).type, [dynamicMirror]);
-  typeArguments(reflect(new F()).type, [dynamicMirror]);
+  typeArguments(reflect(new F<dynamic>()).type, [dynamicMirror]); /// 01: ok
+  typeArguments(reflect(new F()).type, [dynamicMirror]); /// 01: ok
   typeArguments(reflect(new G()).type, []);
-  typeArguments(reflect(new H<dynamic, num, dynamic>()).type,
-      [dynamicMirror, numMirror, dynamicMirror]);
+  typeArguments(reflect(new H<dynamic, num, dynamic>()).type, /// 01: ok
+      [dynamicMirror, numMirror, dynamicMirror]); /// 01: ok
 
   Expect.isFalse(reflect(new A<num>()).type.isOriginalDeclaration);
   Expect.isTrue(reflect(new B()).type.isOriginalDeclaration);
@@ -100,7 +97,7 @@
   Expect.isFalse(reflect(new E<num>()).type.isOriginalDeclaration);
   Expect.isFalse(reflect(new F<num>()).type.isOriginalDeclaration);
   Expect.isTrue(reflect(new G()).type.isOriginalDeclaration);
-  Expect.isFalse(reflect(new H()).type.isOriginalDeclaration);
+  Expect.isFalse(reflect(new H()).type.isOriginalDeclaration); /// 01: ok
 
   Expect.equals(reflectClass(A),
                 reflect(new A<num>()).type.originalDeclaration);
@@ -133,8 +130,8 @@
                    reflect(new F<num>()).type.originalDeclaration);
   Expect.equals(reflect(new G()).type,
                 reflect(new G()).type.originalDeclaration);
-  Expect.notEquals(reflect(new H()).type,
-                   reflect(new H()).type.originalDeclaration);
+  Expect.notEquals(reflect(new H()).type, /// 01: ok
+                   reflect(new H()).type.originalDeclaration); /// 01: ok
 
   // Library members are all uninstantaited generics or non-generics.
   currentMirrorSystem().libraries.values.forEach((libraryMirror) {
diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart
index df1f9b0..b86acd6 100644
--- a/tests/lib/mirrors/mirrors_test.dart
+++ b/tests/lib/mirrors/mirrors_test.dart
@@ -45,7 +45,7 @@
          equals("DNU"));
   expect(instMirror.invoke(const Symbol("m"), []).reflectee,
          equals("DNU"));  // Wrong arity.
-  // TODO(rmacnak): Implement access to private members. 
+  // TODO(rmacnak): Implement access to private members.
   // expect(instMirror.invoke(const Symbol("_n"), [3, 4]).reflectee,
   //        equals(7));
 
@@ -240,7 +240,7 @@
   expect(classMirror.qualifiedName, equals(const Symbol('MirrorsTest.Class')));
 
   if (!isDart2js) { // TODO(ahe): Implement this in dart2js.
-    TypeVariableMirror typeVariable = classMirror.typeVariables.values.single;
+    TypeVariableMirror typeVariable = classMirror.typeVariables.single;
     expect(typeVariable.simpleName, equals(const Symbol('T')));
     expect(typeVariable.qualifiedName,
            equals(const Symbol('MirrorsTest.Class.T')));
diff --git a/tests/lib/mirrors/parameter_dart2js_test.dart b/tests/lib/mirrors/parameter_dart2js_test.dart
deleted file mode 100644
index aa5cdee..0000000
--- a/tests/lib/mirrors/parameter_dart2js_test.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Test of [ParameterMirror].
-library test.parameter_test;
-
-@MirrorsUsed(targets: 'test.parameter_test', override: '*')
-import 'dart:mirrors';
-
-import 'stringify.dart';
-
-class B {
-  B();
-  B.foo(int x);
-  B.bar(int z, x);
-}
-
-main() {
-  var constructors = reflectClass(B).constructors;
-
-  expect('{B: Method(s(B) in s(B), constructor), '
-         'B.bar: Method(s(B.bar) in s(B), constructor), '
-         'B.foo: Method(s(B.foo) in s(B), constructor)}',
-         constructors);
-
-  var unnamedConstructor = constructors[new Symbol('B')];
-
-  expect('[]', unnamedConstructor.parameters);
-  expect('Class(s(B) in s(test.parameter_test), top-level)',
-         unnamedConstructor.returnType);
-
-  var fooConstructor = constructors[new Symbol('B.foo')];
-  expect('[Parameter(s(x) in s(B.foo),'
-         ' type = Class(s(int) in s(dart.core), top-level))]',
-         fooConstructor.parameters);
-  expect('Class(s(B) in s(test.parameter_test), top-level)',
-         fooConstructor.returnType);
-
-  var barConstructor = constructors[new Symbol('B.bar')];
-  expect('[Parameter(s(z) in s(B.bar),'
-         ' type = Class(s(int) in s(dart.core), top-level)), '
-         'Parameter(s(x) in s(B.bar),'
-         ' type = Type(s(dynamic), top-level))]',
-         barConstructor.parameters);
-  expect('Class(s(B) in s(test.parameter_test), top-level)',
-         barConstructor.returnType);
-
-  print(constructors);
-}
diff --git a/tests/lib/mirrors/parameter_test.dart b/tests/lib/mirrors/parameter_test.dart
index 6a86c53..5e3518b 100644
--- a/tests/lib/mirrors/parameter_test.dart
+++ b/tests/lib/mirrors/parameter_test.dart
@@ -2,7 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/// Test of [ParameterMirror].
+// This tests uses the multi-test "ok" feature:
+// none: Desired behaviour, passing on the VM.
+// 01: Trimmed version for dart2js.
+//
+// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par.
+
+/** Test of [ParameterMirror]. */
 library test.parameter_test;
 
 @MirrorsUsed(targets: 'test.parameter_test', override: '*')
@@ -26,9 +32,9 @@
   get x =>  _x;
   set x(final value) { _x = value; }
 
-  grault([int x]);
-  garply({int y});
-  waldo(int z);
+  grault([int x]) {}
+  garply({int y}) {}
+  waldo(int z) {}
 }
 
 class C <S extends int, T> {
@@ -71,6 +77,9 @@
   expect('Class(s(B) in s(test.parameter_test), top-level)',
          barConstructor.returnType);
 
+  // dart2js stops testing here.
+  return;  /// 01: ok
+
   MethodMirror bazConstructor = constructors[const Symbol('B.baz')];
   expect('Method(s(B.baz) in s(B), constructor)', bazConstructor);
   expect('[Parameter(s(x) in s(B.baz), final,'
diff --git a/tests/lib/mirrors/typearguments_mirror_test.dart b/tests/lib/mirrors/typearguments_mirror_test.dart
new file mode 100644
index 0000000..855d842
--- /dev/null
+++ b/tests/lib/mirrors/typearguments_mirror_test.dart
@@ -0,0 +1,65 @@
+// 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 lib;
+
+import 'package:expect/expect.dart';
+import 'stringify.dart';
+import 'dart:mirrors';
+
+class Foo<T> {}
+class Bar<T, R> {}
+
+main() {
+  var cm = reflectClass(Foo);
+  var cm1 = reflect((new Foo<String>())).type;
+
+  Expect.notEquals(cm, cm1);
+  Expect.isFalse(cm1.isOriginalDeclaration);
+  Expect.isTrue(cm.isOriginalDeclaration);
+
+  Expect.equals(cm, cm1.originalDeclaration);
+
+  Expect.equals(cm, reflectClass(Foo));
+  Expect.equals(cm, reflectClass((new Foo().runtimeType)));
+  print((reflect(new Foo()).type).runtimeType);
+  print(cm.runtimeType);
+  Expect.equals(cm1, reflect(new Foo<String>()).type);
+
+  expect('[]', cm.typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]', cm1.typeArguments);
+
+  cm = reflect(new Bar<List, Set>()).type;
+  cm1 = reflect(new Bar<List, Set<String>>()).type;
+
+  var cm2 = reflect(new Bar<List<String>, Set>()).type;
+  var cm3 = reflect(new Bar<List<String>, Set<String>>()).type;
+
+  expect('[Class(s(List) in s(dart.core), top-level),'
+         ' Class(s(Set) in s(dart.core), top-level)]', cm.typeArguments);
+  expect('[Class(s(List) in s(dart.core), top-level),'
+         ' Class(s(Set) in s(dart.core), top-level)]', cm1.typeArguments);
+  expect('[Class(s(List) in s(dart.core), top-level),'
+         ' Class(s(Set) in s(dart.core), top-level)]', cm2.typeArguments);
+  expect('[Class(s(List) in s(dart.core), top-level),'
+         ' Class(s(Set) in s(dart.core), top-level)]', cm3.typeArguments);
+
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+         cm1.typeArguments[1].typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+         cm2.typeArguments[0].typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+         cm3.typeArguments[0].typeArguments);
+  expect('[Class(s(String) in s(dart.core), top-level)]',
+         cm3.typeArguments[1].typeArguments);
+
+  var cm4 = reflect(new Bar<Bar<List, Set>, String>()).type;
+
+  expect('[Class(s(Bar) in s(lib), top-level),'
+         ' Class(s(String) in s(dart.core), top-level)]',
+         cm4.typeArguments);
+  expect('[Class(s(List) in s(dart.core), top-level), '
+         'Class(s(Set) in s(dart.core), top-level)]',
+         cm4.typeArguments[0].typeArguments);
+}
diff --git a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
index 77f226b..9994988 100644
--- a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
+++ b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart
@@ -32,17 +32,17 @@
 main() {
   ClassMirror cm;
   cm = reflectClass(A);
-  checkMetadata(cm.typeVariables[const Symbol('S')], []);
-  checkMetadata(cm.typeVariables[const Symbol('T')], [m1, m2]);
+  checkMetadata(cm.typeVariables[0], []);
+  checkMetadata(cm.typeVariables[1], [m1, m2]);
   // Check for conflicts.
   checkMetadata(cm.methods[const Symbol('T')], [m3]);
 
   cm = reflectClass(B);
-  checkMetadata(cm.typeVariables[const Symbol('T')], [m3]);
+  checkMetadata(cm.typeVariables[0], [m3]);
   // Check for conflicts.
   checkMetadata(cm.members[const Symbol('T')], [m1, m2]);
 
   TypedefMirror tm = reflectClass(Predicate);
   FunctionTypeMirror ftm = tm.referent;
-  checkMetadata(ftm.typeVariables[const Symbol('G')], [m1, m2]);
+  checkMetadata(ftm.typeVariables[0], [m1, m2]);
 }
diff --git a/tests/standalone/io/file_error_test.dart b/tests/standalone/io/file_error_test.dart
index d8dc8aa..8b1049a 100644
--- a/tests/standalone/io/file_error_test.dart
+++ b/tests/standalone/io/file_error_test.dart
@@ -130,29 +130,29 @@
   });
 }
 
-bool checkFullPathOnNonExistentDirectoryException(e) {
+bool checkResolveSymbolicLinksOnNonExistentDirectoryException(e) {
   Expect.isTrue(e is FileException);
   Expect.isTrue(e.osError != null);
-  Expect.isTrue(e.toString().indexOf("Cannot retrieve full path") != -1);
+  Expect.isTrue(e.toString().indexOf("Cannot resolve symbolic links") != -1);
   // File not not found has error code 2 on all supported platforms.
   Expect.equals(2, e.osError.errorCode);
 
   return true;
 }
 
-void testFullPathOnNonExistentDirectory() {
+void testResolveSymbolicLinksOnNonExistentDirectory() {
   asyncStart();
   Directory temp = tempDir();
   var file = new File("${temp.path}/nonExistentDirectory");
 
   // Full path non-existent directory should throw exception.
-  Expect.throws(() => file.fullPathSync(),
-                (e) => checkFullPathOnNonExistentDirectoryException(e));
+  Expect.throws(() => file.resolveSymbolicLinksSync(),
+      (e) => checkResolveSymbolicLinksOnNonExistentDirectoryException(e));
 
-  var fullPathFuture = file.fullPath();
-  fullPathFuture.then((path) => Expect.fail("Unreachable code $path"))
+  var resolvedFuture = file.resolveSymbolicLinks();
+  resolvedFuture.then((path) => Expect.fail("Unreachable code $path"))
   .catchError((error) {
-    checkFullPathOnNonExistentDirectoryException(error);
+    checkResolveSymbolicLinksOnNonExistentDirectoryException(error);
     temp.deleteSync(recursive: true);
     asyncEnd();
   });
@@ -424,7 +424,7 @@
   testDeleteNonExistent();
   testLengthNonExistent();
   testCreateInNonExistentDirectory();
-  testFullPathOnNonExistentDirectory();
+  testResolveSymbolicLinksOnNonExistentDirectory();
   testReadAsBytesNonExistent();
   testReadAsTextNonExistent();
   testReadAsLinesNonExistent();
diff --git a/tests/standalone/io/file_test.dart b/tests/standalone/io/file_test.dart
index 14e4780..1c5f860 100644
--- a/tests/standalone/io/file_test.dart
+++ b/tests/standalone/io/file_test.dart
@@ -920,16 +920,6 @@
     }
   }
 
-  static void testOpenFile() {
-    var name = getFilename("tests/vm/data/fixed_length_file");
-    var f = new File(name);
-    Expect.isTrue(f.existsSync());
-    name = f.fullPathSync();
-    var g = new File(name);
-    Expect.isTrue(g.existsSync());
-    Expect.equals(name, g.fullPathSync());
-  }
-
   static void testReadAsBytes() {
     asyncTestStarted();
     var name = getFilename("tests/vm/data/fixed_length_file");
@@ -1269,7 +1259,6 @@
     testPositionSync();
     testOpenDirectoryAsFile();
     testOpenDirectoryAsFileSync();
-    testOpenFile();
     testReadAsBytesSync();
     testReadAsBytesSyncEmptyFile();
     testReadAsTextSync();
diff --git a/tests/standalone/io/resolve_symbolic_links_test.dart b/tests/standalone/io/resolve_symbolic_links_test.dart
new file mode 100644
index 0000000..485f84e
--- /dev/null
+++ b/tests/standalone/io/resolve_symbolic_links_test.dart
@@ -0,0 +1,147 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing FileSystemEntity.resolveSymbolicLinks
+
+import "package:expect/expect.dart";
+import "package:path/path.dart";
+import "package:async_helper/async_helper.dart";
+import 'dart:async';
+import 'dart:io';
+
+main() {
+  String testsDir = dirname(dirname(dirname(Platform.script)));
+  // All of these tests test that resolveSymbolicLinks gives a path
+  // that points to the same place as the original, and that it removes
+  // all links, .., and . segments, and that it produces an absolute path.
+  asyncTest(() => testFile(join(
+      testsDir, 'standalone', 'io', 'resolve_symbolic_links_test.dart')));
+  asyncTest(() => testFile(join(testsDir, 'standalone', 'io', '..', 'io',
+                                'resolve_symbolic_links_test.dart')));
+
+  asyncTest(() => testDir(join(testsDir, 'standalone', 'io')));
+  asyncTest(() => testDir(join(testsDir, 'lib', '..', 'standalone', 'io')));
+  // Test a relative path.
+  asyncTest(() => testDir('.'));
+  if (Platform.isWindows) {
+    asyncTest(() =>testFile(join('\\\\?\\$testsDir', 'standalone', 'io',
+                                 'resolve_symbolic_links_test.dart')));
+    asyncTest(() => testDir('\\\\?\\$testsDir'));
+  }
+  asyncTest(() => new Directory('').createTemp().then((tempDir) {
+    String temp = tempDir.path;
+    return makeEntities(temp).then((_) => Future.wait(
+        [testFile(join(temp, 'dir1', 'file1')),
+         testFile(join(temp, 'link1', 'file2')),
+         testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
+         testDir(join(temp, 'dir1', 'dir2', '..', '.', '..', 'dir1')),
+         testLink(join(temp, 'link1'))]))
+    .then((_) {
+      if (Platform.isWindows) {
+        // Windows applies '..' to a link without resolving the link first.
+        return Future.wait([
+            testFile(join(
+                temp, 'dir1', '..', 'link1', '..', 'dir1', 'dir2', 'file2')),
+            testDir(join(temp, 'dir1', '..', 'link1', '..', 'dir1')),
+            testLink(join(temp, 'link1', '..', 'link1'))]);
+      } else {
+       // Non-Windows platforms resolve the link before adding the '..'.
+        return Future.wait([
+            testFile(join(
+                temp, 'dir1', '..', 'link1', '..', 'dir2', 'file2')),
+            testDir(join(temp, 'dir1', '..', 'link1', '..', 'dir2')),
+            testLink(join(temp, 'link1', '..', '..', 'link1'))]);
+      }
+    })
+    .then((_) {
+      Directory.current = temp;
+      return Future.wait([
+          testFile('dir1/dir2/file2'),  // Test forward slashes on Windows too.
+          testFile('link1/file2'),
+          testFile(join('dir1', '..', 'dir1', '.', 'file1')),
+          testDir('.'),
+          testLink('link1')]);
+    })
+    .then((_) {
+      Directory.current = 'link1';
+      if (Platform.isWindows) {
+        return Future.wait([
+          testFile('file2'),
+          // Windows applies '..' to a link without resolving the link first.
+          testFile('..\\dir1\\file1'),
+          testLink('.'),
+          testDir('..'),
+          testLink('..\\link1')]);
+      } else {
+        return Future.wait([
+          testFile('file2'),
+          // On non-Windows the link is changed to dir1/dir2 before .. happens.
+          testFile('../dir2/file2'),
+          testDir('.'),
+          testDir('..'),
+          testLink('../../link1')]);
+      }
+    })
+    .whenComplete(() {
+      Directory.current = testsDir;
+      tempDir.delete(recursive: true);
+    });
+  }));
+}
+
+Future makeEntities(String temp) {
+  return new Directory(join(temp, 'dir1', 'dir2')).create(recursive: true)
+      .then((_) => new File(join(temp, 'dir1', 'dir2', 'file2')).create())
+      .then((_) => new File(join(temp, 'dir1', 'file1')).create())
+      .then((_) => new Link(join(temp, 'link1'))
+            .create(join(temp, 'dir1', 'dir2')));
+}
+
+Future testFile(String name) {
+  // We test that f.resolveSymbolicLinks points to the same place
+  // as f, because the actual resolved path is not easily predictable.
+  // The location of the temp directory varies from system to system,
+  // and its path includes symbolic links on some systems.
+  //Expect.isTrue(FileSystemEntity.identicalSync(name,
+  //   new File(name).resolveSymbolicLinksSync()));
+  return new File(name).resolveSymbolicLinks().then((String resolved) {
+  //Expect.isTrue(FileSystemEntity.identicalSync(name, resolved));
+    Expect.isTrue(isAbsolute(resolved));
+    // Test that resolveSymbolicLinks removes all links, .., and . segments.
+    Expect.isFalse(resolved.contains('..'));
+    Expect.isFalse(resolved.contains('./'));
+    Expect.isFalse(resolved.contains('link1'));
+  });
+}
+
+Future testDir(String name) {
+  Expect.isTrue(FileSystemEntity.identicalSync(name,
+      new Directory(name).resolveSymbolicLinksSync()));
+  return new Directory(name).resolveSymbolicLinks().then((String resolved) {
+    Expect.isTrue(FileSystemEntity.identicalSync(name, resolved));
+    Expect.isTrue(isAbsolute(resolved));
+    // Test that resolveSymbolicLinks removes all links, .., and . segments.
+    Expect.isFalse(resolved.contains('..'));
+    Expect.isFalse(resolved.contains('./'));
+    Expect.isFalse(resolved.contains('link1'));
+  });
+}
+
+Future testLink(String name) {
+  Expect.isFalse(FileSystemEntity.identicalSync(name,
+      new Link(name).resolveSymbolicLinksSync()));
+  Expect.isTrue(FileSystemEntity.identicalSync(new Link(name).targetSync(),
+      new Link(name).resolveSymbolicLinksSync()));
+  return new Link(name).resolveSymbolicLinks().then((String resolved) {
+    Expect.isFalse(FileSystemEntity.identicalSync(name, resolved));
+    Expect.isTrue(isAbsolute(resolved));
+    // Test that resolveSymbolicLinks removes all links, .., and . segments.
+    Expect.isFalse(resolved.contains('..'));
+    Expect.isFalse(resolved.contains('./'));
+    Expect.isFalse(resolved.contains('link1'));
+    return new Link(name).target()
+        .then((targetName) => FileSystemEntity.identical(targetName, resolved))
+        .then((identical) => Expect.isTrue(identical));
+  });
+}
diff --git a/tests/standalone/vmservice/field_script.dart b/tests/standalone/vmservice/field_script.dart
new file mode 100644
index 0000000..824a502
--- /dev/null
+++ b/tests/standalone/vmservice/field_script.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library unknown_command_script;
+
+import 'dart:io';
+import 'dart:typed_data';
+
+class Banana {
+  final Float32List final_fixed_length_list = new Float32List(4);
+  Float32List fixed_length_list = new Float32List(4);
+  String name = '';
+  var a = 44;
+}
+
+
+class BadBanana {
+  final Float32List final_fixed_length_list;
+  final List fixed_length_array = new List(3);
+  num v;
+  const c = 4;
+  BadBanana() : final_fixed_length_list = new Float32List(1);
+  BadBanana.variable() : final_fixed_length_list = new Float32List(2);
+}
+
+main() {
+  for (int i = 0; i < 2000; i++) {
+    Banana b = new Banana();
+    b.name = 'Banana';
+    BadBanana bb = new BadBanana();
+    bb.v = 1.0;
+  }
+  var bb = new BadBanana.variable();
+  bb.v = 2.0;
+  var b = new Banana();
+  b.a = 'foo';
+  print(''); // Print blank line to signal that we are ready.
+  // Wait until signaled from spawning test.
+  stdin.first.then((_) => exit(0));
+}
diff --git a/tests/standalone/vmservice/isolate_bad_class_test.dart b/tests/standalone/vmservice/isolate_bad_class_test.dart
index 4d84afa..8e0b2d3 100644
--- a/tests/standalone/vmservice/isolate_bad_class_test.dart
+++ b/tests/standalone/vmservice/isolate_bad_class_test.dart
@@ -45,7 +45,7 @@
     test.makeRequest().then((_) {
       var badCollectionRequest =
           new BadCollectionTest(port, test._isolateId,
-                                'classes').makeRequest();
+                                'foobar').makeRequest();
       var nullCollectionRequest =
           new NullCollectionTest(port, test._isolateId,
                                  'classes').makeRequest();
diff --git a/tests/standalone/vmservice/isolate_bad_function_test.dart b/tests/standalone/vmservice/isolate_bad_function_test.dart
deleted file mode 100644
index 3b6c414..0000000
--- a/tests/standalone/vmservice/isolate_bad_function_test.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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 isolate_bad_function_test;
-
-import 'dart:async';
-import 'test_helper.dart';
-import 'package:expect/expect.dart';
-
-class NullCollectionTest extends VmServiceRequestHelper {
-  NullCollectionTest(port, id, collection) :
-      super('http://127.0.0.1:$port/isolates/$id/$collection/-99');
-
-  onRequestCompleted(Map reply) {
-    Expect.equals('null', reply['type']);
-  }
-}
-
-class BadCollectionTest extends VmServiceRequestHelper {
-  BadCollectionTest(port, id, collection) :
-      super('http://127.0.0.1:$port/isolates/$id/$collection');
-
-  onRequestCompleted(Map reply) {
-    Expect.equals('error', reply['type']);
-  }
-}
-
-class IsolateListTest extends VmServiceRequestHelper {
-  IsolateListTest(port) : super('http://127.0.0.1:$port/isolates');
-
-  int _isolateId;
-  onRequestCompleted(Map reply) {
-    IsolateListTester tester = new IsolateListTester(reply);
-    tester.checkIsolateCount(1);
-    tester.checkIsolateNameContains('unknown_isolate_command_script.dart');
-    _isolateId = reply['members'][0]['id'];
-  }
-}
-
-main() {
-  var process = new TestLauncher('unknown_isolate_command_script.dart');
-  process.launch().then((port) {
-    var test = new IsolateListTest(port);
-    test.makeRequest().then((_) {
-      var badCollectionRequest =
-          new BadCollectionTest(port, test._isolateId,
-                                'functions').makeRequest();
-      var nullCollectionRequest =
-          new NullCollectionTest(port, test._isolateId,
-                                 'functions').makeRequest();
-      var requests = Future.wait([badCollectionRequest, nullCollectionRequest]);
-      requests.then((_) {
-        process.requestExit();
-      });
-    });
-  });
-}
diff --git a/tests/standalone/vmservice/isolate_bad_library_test.dart b/tests/standalone/vmservice/isolate_bad_library_test.dart
deleted file mode 100644
index c7d2c54..0000000
--- a/tests/standalone/vmservice/isolate_bad_library_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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 isolate_bad_library_test;
-
-import 'dart:async';
-import 'test_helper.dart';
-import 'package:expect/expect.dart';
-
-class NullCollectionTest extends VmServiceRequestHelper {
-  NullCollectionTest(port, id, collection) :
-      super('http://127.0.0.1:$port/isolates/$id/$collection/-100');
-
-  onRequestCompleted(Map reply) {
-    Expect.equals('null', reply['type']);
-  }
-}
-
-class BadCollectionTest extends VmServiceRequestHelper {
-  BadCollectionTest(port, id, collection) :
-      super('http://127.0.0.1:$port/isolates/$id/$collection');
-
-  onRequestCompleted(Map reply) {
-    Expect.equals('error', reply['type']);
-  }
-}
-
-class IsolateListTest extends VmServiceRequestHelper {
-  IsolateListTest(port) : super('http://127.0.0.1:$port/isolates');
-
-  int _isolateId;
-  onRequestCompleted(Map reply) {
-    IsolateListTester tester = new IsolateListTester(reply);
-    tester.checkIsolateCount(1);
-    tester.checkIsolateNameContains('unknown_isolate_command_script.dart');
-    _isolateId = reply['members'][0]['id'];
-  }
-}
-
-main() {
-  var process = new TestLauncher('unknown_isolate_command_script.dart');
-  process.launch().then((port) {
-    var test = new IsolateListTest(port);
-    test.makeRequest().then((_) {
-      var nullCollectionRequest =
-          new NullCollectionTest(port, test._isolateId,
-                                 'libraries').makeRequest();
-      var requests = Future.wait([nullCollectionRequest]);
-      requests.then((_) {
-        process.requestExit();
-      });
-    });
-  });
-}
diff --git a/tests/standalone/vmservice/isolate_bad_code_test.dart b/tests/standalone/vmservice/isolate_bad_object_test.dart
similarity index 76%
rename from tests/standalone/vmservice/isolate_bad_code_test.dart
rename to tests/standalone/vmservice/isolate_bad_object_test.dart
index fc6ef68..b7d2ef5 100644
--- a/tests/standalone/vmservice/isolate_bad_code_test.dart
+++ b/tests/standalone/vmservice/isolate_bad_object_test.dart
@@ -9,8 +9,8 @@
 import 'package:expect/expect.dart';
 
 class NullCollectionTest extends VmServiceRequestHelper {
-  NullCollectionTest(port, id, collection) :
-      super('http://127.0.0.1:$port/isolates/$id/$collection/50');
+  NullCollectionTest(port, id) :
+      super('http://127.0.0.1:$port/isolates/$id/objects/50');
 
   onRequestCompleted(Map reply) {
     Expect.equals('null', reply['type']);
@@ -18,8 +18,8 @@
 }
 
 class BadCollectionTest extends VmServiceRequestHelper {
-  BadCollectionTest(port, id, collection) :
-      super('http://127.0.0.1:$port/isolates/$id/$collection');
+  BadCollectionTest(port, id) :
+      super('http://127.0.0.1:$port/isolates/$id/objects');
 
   onRequestCompleted(Map reply) {
     Expect.equals('error', reply['type']);
@@ -44,11 +44,9 @@
     var test = new IsolateListTest(port);
     test.makeRequest().then((_) {
       var badCollectionRequest =
-          new BadCollectionTest(port, test._isolateId,
-                                'codes').makeRequest();
+          new BadCollectionTest(port, test._isolateId).makeRequest();
       var nullCollectionRequest =
-          new NullCollectionTest(port, test._isolateId,
-                                 'codes').makeRequest();
+          new NullCollectionTest(port, test._isolateId).makeRequest();
       var requests = Future.wait([badCollectionRequest, nullCollectionRequest]);
       requests.then((_) {
         process.requestExit();
diff --git a/tests/standalone/vmservice/isolate_class_field_test.dart b/tests/standalone/vmservice/isolate_class_field_test.dart
new file mode 100644
index 0000000..68877a4
--- /dev/null
+++ b/tests/standalone/vmservice/isolate_class_field_test.dart
@@ -0,0 +1,189 @@
+// 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 isolate_class_list_test;
+
+import 'dart:async';
+import 'test_helper.dart';
+import 'package:expect/expect.dart';
+
+class BananaClassTest {
+  int port;
+  int isolate_id;
+  int class_id;
+  BananaClassTest(this.port, this.isolate_id, this.class_id);
+
+  _testFieldA(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('a', field['user_name']);
+    Expect.equals('a', field['name']);
+    Expect.equals(false, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals('dynamic', field['guard_class']);
+    Expect.equals(true, field['guard_nullable']);
+    Expect.equals('variable', field['guard_length']);
+  }
+
+  _testFieldFinalFixedLengthList(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('final_fixed_length_list', field['user_name']);
+    Expect.equals('final_fixed_length_list', field['name']);
+    Expect.equals('Float32List', field['guard_class']['user_name']);
+    Expect.equals(true, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals(4, field['guard_length']);
+  }
+
+  _testFieldFixedLengthList(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('fixed_length_list', field['user_name']);
+    Expect.equals('fixed_length_list', field['name']);
+    Expect.equals(false, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals('Float32List', field['guard_class']['user_name']);
+    Expect.equals('variable', field['guard_length']);
+  }
+
+  _testFieldName(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('name', field['user_name']);
+    Expect.equals('name', field['name']);
+    Expect.equals(false, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals('String', field['guard_class']['user_name']);
+    Expect.equals(false, field['guard_nullable']);
+    Expect.equals('variable', field['guard_length']);
+  }
+
+  Future makeRequest() {
+    var fields = ['final_fixed_length_list', 'fixed_length_list', 'name', 'a'];
+    var helper =
+      new ClassFieldRequestHelper(port, isolate_id, class_id, fields);
+    return helper.makeRequest().then((_) {
+      _testFieldA(helper.fields['a']);
+      _testFieldFinalFixedLengthList(helper.fields['final_fixed_length_list']);
+      _testFieldFixedLengthList(helper.fields['fixed_length_list']);
+      _testFieldName(helper.fields['name']);
+    });
+  }
+}
+
+class BadBananaClassTest {
+  int port;
+  int isolate_id;
+  int class_id;
+  BadBananaClassTest(this.port, this.isolate_id, this.class_id);
+
+  _testFieldV(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('v', field['user_name']);
+    Expect.equals('v', field['name']);
+    Expect.equals(false, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals('double', field['guard_class']['user_name']);
+    Expect.equals(true, field['guard_nullable']);
+    Expect.equals('variable', field['guard_length']);
+  }
+
+  _testFieldC(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('c', field['user_name']);
+    Expect.equals('c', field['name']);
+    Expect.equals(true, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(true, field['const']);
+    Expect.equals('int', field['guard_class']['user_name']);
+    Expect.equals(false, field['guard_nullable']);
+    Expect.equals('variable', field['guard_length']);
+  }
+
+  _testFieldFinalFixedLengthList(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('final_fixed_length_list', field['user_name']);
+    Expect.equals('final_fixed_length_list', field['name']);
+    Expect.equals('Float32List', field['guard_class']['user_name']);
+    Expect.equals(true, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals('variable', field['guard_length']);
+  }
+
+  _testFieldFixedLengthArray(Map field) {
+    Expect.equals('Field', field['type']);
+    Expect.equals('fixed_length_array', field['user_name']);
+    Expect.equals('fixed_length_array', field['name']);
+    Expect.equals('List', field['guard_class']['user_name']);
+    Expect.equals(true, field['final']);
+    Expect.equals(false, field['static']);
+    Expect.equals(false, field['const']);
+    Expect.equals(3, field['guard_length']);
+  }
+
+  Future makeRequest() {
+    var fields = ['final_fixed_length_list', 'fixed_length_array', 'v', 'c'];
+    var helper =
+      new ClassFieldRequestHelper(port, isolate_id, class_id, fields);
+    return helper.makeRequest().then((_) {
+      _testFieldV(helper.fields['v']);
+      _testFieldC(helper.fields['c']);
+      _testFieldFinalFixedLengthList(helper.fields['final_fixed_length_list']);
+      _testFieldFixedLengthArray(helper.fields['fixed_length_array']);
+    });
+  }
+}
+
+class ClassTableTest extends VmServiceRequestHelper {
+  ClassTableTest(port, id) :
+      super('http://127.0.0.1:$port/isolates/$id/classes/');
+
+  int banana_class_id;
+  int bad_banana_class_id;
+
+  onRequestCompleted(Map reply) {
+    ClassTableHelper helper = new ClassTableHelper(reply);
+    Expect.isTrue(helper.classExists('Banana'));
+    banana_class_id = helper.classId('Banana');
+    Expect.isTrue(helper.classExists('BadBanana'));
+    bad_banana_class_id = helper.classId('BadBanana');
+  }
+}
+
+class IsolateListTest extends VmServiceRequestHelper {
+  IsolateListTest(port) : super('http://127.0.0.1:$port/isolates');
+
+  int _isolateId;
+  onRequestCompleted(Map reply) {
+    IsolateListTester tester = new IsolateListTester(reply);
+    tester.checkIsolateCount(1);
+    tester.checkIsolateNameContains('field_script.dart');
+    _isolateId = tester.checkIsolateNameContains('field_script');
+  }
+}
+
+main() {
+  var process = new TestLauncher('field_script.dart');
+  process.launch().then((port) {
+    var test = new IsolateListTest(port);
+    test.makeRequest().then((_) {
+      var classTableTest = new ClassTableTest(port, test._isolateId);
+      classTableTest.makeRequest().then((_) {
+        var bananaClassTest =
+            new BananaClassTest(port, test._isolateId,
+                                classTableTest.banana_class_id);
+        var badBananaClassTest =
+            new BadBananaClassTest(port, test._isolateId,
+                                   classTableTest.bad_banana_class_id);
+        Future.wait([bananaClassTest.makeRequest(),
+                     badBananaClassTest.makeRequest()]).then((_) {
+          process.requestExit();
+        });
+      });
+    });
+  });
+}
diff --git a/tests/standalone/vmservice/isolate_class_test.dart b/tests/standalone/vmservice/isolate_class_test.dart
index 3f9064e..9650443 100644
--- a/tests/standalone/vmservice/isolate_class_test.dart
+++ b/tests/standalone/vmservice/isolate_class_test.dart
@@ -22,7 +22,7 @@
 
 class LibraryTest extends VmServiceRequestHelper {
   LibraryTest(port, id, libId) :
-      super('http://127.0.0.1:$port/isolates/$id/libraries/$libId');
+      super('http://127.0.0.1:$port/isolates/$id/objects/$libId');
 
   int _classId;
   onRequestCompleted(Map reply) {
@@ -37,11 +37,11 @@
 
 class RootLibraryTest extends VmServiceRequestHelper {
   RootLibraryTest(port, id) :
-      super('http://127.0.0.1:$port/isolates/$id/libraries');
+      super('http://127.0.0.1:$port/isolates/$id/library');
 
   int _libId;
   onRequestCompleted(Map reply) {
-    Expect.equals('@Library', reply['type']);
+    Expect.equals('Library', reply['type']);
     Expect.equals('isolate_stacktrace_command_script', reply['name']);
     _libId = reply['id'];
   }
diff --git a/tests/standalone/vmservice/isolate_code_test.dart b/tests/standalone/vmservice/isolate_code_test.dart
index 8ce58dd..4df1e69 100644
--- a/tests/standalone/vmservice/isolate_code_test.dart
+++ b/tests/standalone/vmservice/isolate_code_test.dart
@@ -10,7 +10,7 @@
 
 class CodeATest extends VmServiceRequestHelper {
   CodeATest(port, id, codeId) :
-      super('http://127.0.0.1:$port/isolates/$id/codes/$codeId');
+      super('http://127.0.0.1:$port/isolates/$id/objects/$codeId');
 
   onRequestCompleted(Map reply) {
     Expect.equals('Code', reply['type']);
@@ -21,11 +21,11 @@
 
 class CodeCTest extends VmServiceRequestHelper {
   CodeCTest(port, id, codeId) :
-      super('http://127.0.0.1:$port/isolates/$id/codes/$codeId');
+      super('http://127.0.0.1:$port/isolates/$id/objects/$codeId');
 
   onRequestCompleted(Map reply) {
     Expect.equals('Code', reply['type']);
-    Expect.equals('C.c', reply['function']['name']);
+    Expect.equals('C.c', reply['function']['user_name']);
     Expect.isTrue(reply['disassembly'].length > 0);
   }
 }
diff --git a/tests/standalone/vmservice/isolate_function_test.dart b/tests/standalone/vmservice/isolate_function_test.dart
index 369616b..4831b61 100644
--- a/tests/standalone/vmservice/isolate_function_test.dart
+++ b/tests/standalone/vmservice/isolate_function_test.dart
@@ -10,17 +10,17 @@
 
 class MethodTest extends VmServiceRequestHelper {
   MethodTest(port, id, functionId) :
-      super('http://127.0.0.1:$port/isolates/$id/functions/$functionId');
+      super('http://127.0.0.1:$port/isolates/$id/objects/$functionId');
   onRequestCompleted(Map reply) {
     Expect.equals('Function', reply['type']);
-    Expect.equals('C.c', reply['name']);
+    Expect.equals('C.c', reply['user_name']);
     Expect.equals(false, reply['is_static']);
   }
 }
 
 class FunctionTest extends VmServiceRequestHelper {
   FunctionTest(port, id, functionId) :
-      super('http://127.0.0.1:$port/isolates/$id/functions/$functionId');
+      super('http://127.0.0.1:$port/isolates/$id/objects/$functionId');
 
   onRequestCompleted(Map reply) {
     Expect.equals('Function', reply['type']);
diff --git a/tests/standalone/vmservice/isolate_library_test.dart b/tests/standalone/vmservice/isolate_library_test.dart
index 31d269b..d27f403 100644
--- a/tests/standalone/vmservice/isolate_library_test.dart
+++ b/tests/standalone/vmservice/isolate_library_test.dart
@@ -10,7 +10,7 @@
 
 class LibraryTest extends VmServiceRequestHelper {
   LibraryTest(port, id, libId) :
-      super('http://127.0.0.1:$port/isolates/$id/libraries/$libId');
+      super('http://127.0.0.1:$port/isolates/$id/objects/$libId');
 
   onRequestCompleted(Map reply) {
     Expect.equals('Library', reply['type']);
@@ -20,11 +20,11 @@
 
 class RootLibraryTest extends VmServiceRequestHelper {
   RootLibraryTest(port, id) :
-      super('http://127.0.0.1:$port/isolates/$id/libraries');
+      super('http://127.0.0.1:$port/isolates/$id/library');
 
   int _libId;
   onRequestCompleted(Map reply) {
-    Expect.equals('@Library', reply['type']);
+    Expect.equals('Library', reply['type']);
     Expect.equals('isolate_stacktrace_command_script', reply['name']);
     _libId = reply['id'];
   }
diff --git a/tests/standalone/vmservice/test_helper.dart b/tests/standalone/vmservice/test_helper.dart
index 325ecb1..8157648 100644
--- a/tests/standalone/vmservice/test_helper.dart
+++ b/tests/standalone/vmservice/test_helper.dart
@@ -25,21 +25,21 @@
             .fold(new BytesBuilder(), (b, d) => b..add(d))
             .then((builder) {
               print('** GET: $uri');
-              _requestCompleted(builder.takeBytes(), response);
+              return _requestCompleted(builder.takeBytes(), response);
             });
       }).catchError((error) {
         onRequestFailed(error);
       });
   }
 
-  void _requestCompleted(List<int> data, HttpClientResponse response) {
+  Future _requestCompleted(List<int> data, HttpClientResponse response) {
     Expect.equals(200, response.statusCode, 'Invalid HTTP Status Code');
     var replyAsString;
     try {
       replyAsString = UTF8.decode(data);
     } catch (e) {
       onRequestFailed(e);
-      return;
+      return null;
     }
     print('** Response: $replyAsString');
     var reply;
@@ -47,28 +47,30 @@
       reply = JSON.decode(replyAsString);
     } catch (e) {
       onRequestFailed(e);
-      return;
+      return null;
     }
     if (reply is! Map) {
       onRequestFailed('Reply was not a map: $reply');
-      return;
+      return null;
     }
     if (reply['type'] == null) {
       onRequestFailed('Reply does not contain a type key: $reply');
-      return;
+      return null;
     }
+    var r;
     try {
-      onRequestCompleted(reply);
+      r = onRequestCompleted(reply);
     } catch (e) {
-      onRequestFailed('Test callback failed: $e');
+      r = onRequestFailed('Test callback failed: $e');
     }
+    return r;
   }
 
-  void onRequestFailed(dynamic error) {
+  Future onRequestFailed(dynamic error) {
     Expect.fail('Failed to make request: $error');
   }
 
-  void onRequestCompleted(Map response);
+  Future onRequestCompleted(Map response);
 }
 
 class TestLauncher {
@@ -179,3 +181,76 @@
     Expect.isTrue(exists, 'No isolate with id: $id');
   }
 }
+
+class ClassTableHelper {
+  final Map classTable;
+
+  ClassTableHelper(this.classTable) {
+    Expect.equals('ClassList', classTable['type'], 'Not a ClassTable.');
+  }
+
+  bool classExists(String user_name) {
+    List members = classTable['members'];
+    for (var i = 0; i < members.length; i++) {
+      Map klass = members[i];
+      if (klass['user_name'] == user_name) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  int classId(String user_name) {
+    List members = classTable['members'];
+    for (var i = 0; i < members.length; i++) {
+      Map klass = members[i];
+      if (klass['user_name'] == user_name) {
+        return klass['id'];
+      }
+    }
+    return -1;
+  }
+}
+
+class FieldRequestHelper extends VmServiceRequestHelper {
+  FieldRequestHelper(port, isolate_id, field_id) :
+      super('http://127.0.0.1:$port/isolates/$isolate_id/objects/$field_id');
+  Map field;
+  onRequestCompleted(Map reply) {
+    Expect.equals('Field', reply['type']);
+    field = reply;
+    return new Future.value(this);
+  }
+}
+
+class ClassFieldRequestHelper extends VmServiceRequestHelper {
+  final List<String> fieldNames;
+  int port_;
+  int isolate_id_;
+  ClassFieldRequestHelper(port, isolate_id, class_id, this.fieldNames) :
+      super('http://127.0.0.1:$port/isolates/$isolate_id/classes/$class_id') {
+    port_ = port;
+    isolate_id_ = isolate_id;
+  }
+  final Map<String, Map> fields = new Map<String, Map>();
+
+  onRequestCompleted(Map reply) {
+    Expect.equals('Class', reply['type']);
+    List<Map> class_fields = reply['fields'];
+    List<Future> requests = new List<Future>();
+    fieldNames.forEach((fn) {
+      class_fields.forEach((f) {
+        if (f['user_name'] == fn) {
+          var request = new FieldRequestHelper(port_, isolate_id_, f['id']);
+          requests.add(request.makeRequest());
+        }
+      });
+    });
+    return Future.wait(requests).then((a) {
+      a.forEach((FieldRequestHelper field) {
+        fields[field.field['user_name']] = field.field;
+      });
+      return this;
+    });
+  }
+}
diff --git a/tests/standalone/vmservice/unknown_isolate_command_test.dart b/tests/standalone/vmservice/unknown_isolate_command_test.dart
index b6abf0b..4ab81d2 100644
--- a/tests/standalone/vmservice/unknown_isolate_command_test.dart
+++ b/tests/standalone/vmservice/unknown_isolate_command_test.dart
@@ -2,17 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library unknown_isolate_command_test;
+library isolate_class_table_test;
 
+import 'dart:async';
 import 'test_helper.dart';
 import 'package:expect/expect.dart';
 
-class UnknownRequestTest extends VmServiceRequestHelper {
-  UnknownRequestTest(port, id) :
-      super('http://127.0.0.1:$port/isolates/$id/badrequest');
+class ClassTableTest extends VmServiceRequestHelper {
+  ClassTableTest(port, id) :
+      super('http://127.0.0.1:$port/isolates/$id/classes');
 
   onRequestCompleted(Map reply) {
-    Expect.equals('error', reply['type']);
+    ClassTableHelper helper = new ClassTableHelper(reply);
   }
 }
 
@@ -23,19 +24,18 @@
   onRequestCompleted(Map reply) {
     IsolateListTester tester = new IsolateListTester(reply);
     tester.checkIsolateCount(1);
-    tester.checkIsolateNameContains('unknown_isolate_command_script.dart');
-    _isolateId = reply['members'][0]['id'];
+    tester.checkIsolateNameContains('field_script.dart');
+    _isolateId = tester.checkIsolateNameContains('field_script');
   }
 }
 
-
 main() {
-  var process = new TestLauncher('unknown_isolate_command_script.dart');
+  var process = new TestLauncher('field_script.dart');
   process.launch().then((port) {
     var test = new IsolateListTest(port);
     test.makeRequest().then((_) {
-      var unknownRequestTest = new UnknownRequestTest(port, test._isolateId);
-      unknownRequestTest.makeRequest().then((_) {
+      var classTableTest = new ClassTableTest(port, test._isolateId);
+      classTableTest.makeRequest().then((_) {
         process.requestExit();
       });
     });
diff --git a/tools/VERSION b/tools/VERSION
index 1d4fee3..017668a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 7
-BUILD 4
-PATCH 1
+BUILD 5
+PATCH 0
diff --git a/tools/bots/cross-vm.py b/tools/bots/cross-vm.py
index 53a5d27..2c407d8 100644
--- a/tools/bots/cross-vm.py
+++ b/tools/bots/cross-vm.py
@@ -24,8 +24,8 @@
   sys.stdout.flush()
   bot.RunProcess(args)
 
-def tarball_name(arch, mode):
-  return 'cross_build_%s_%s.tar.bz2' % (arch, mode)
+def tarball_name(arch, mode, revision):
+  return 'cross_build_%s_%s_%s.tar.bz2' % (arch, mode, revision)
 
 def record_names(name, arch, mode):
   return ('record_%s_%s_%s.json' % (name, arch, mode),
@@ -33,8 +33,8 @@
 
 def cross_compiling_builder(arch, mode):
   build_py = os.path.join('tools', 'build.py')
-
-  tarball = tarball_name(arch, mode)
+  revision = int(os.environ['BUILDBOT_GOT_REVISION'])
+  tarball = tarball_name(arch, mode, revision)
   temporary_files = [tarball]
   bot.Clobber()
   try:
@@ -76,7 +76,8 @@
                '--time', '--compiler=none', '--runtime=vm', '--write-debug-log',
                '--mode=' + mode, '--arch=' + arch]
 
-  tarball = tarball_name(arch, mode)
+  revision = int(os.environ['BUILDBOT_GOT_REVISION'])
+  tarball = tarball_name(arch, mode, revision)
   temporary_files = [tarball]
   bot.Clobber()
   try:
diff --git a/tools/dom/docs/test/docs_test.dart b/tools/dom/docs/test/docs_test.dart
index 8f8dda8..6664aca 100644
--- a/tools/dom/docs/test/docs_test.dart
+++ b/tools/dom/docs/test/docs_test.dart
@@ -15,6 +15,8 @@
 final testJsonPath = path.normalize(path.join(scriptDir, 'test.json'));
 
 main() {
+  // Some tests take more than the default 20 second unittest timeout.
+  unittestConfiguration.timeout = null;
   group('docs', () {
     var oldJson = new File(json_path);
     var testJson = new File(testJsonPath);
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 994d0f2..dd92951 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -27,15 +27,21 @@
 
 import "../../../tests/co19/test_config.dart";
 
-const List<String> COMMON_ARGUMENTS = const <String>['--report'];
+const List<String> COMMON_ARGUMENTS =
+    const <String>['--report', '--progress=diff', 'co19'];
 
 const List<List<String>> COMMAND_LINES = const <List<String>>[
     const <String>['-mrelease,debug', '-rvm', '-cnone'],
     const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
     const <String>['-mrelease', '-rnone', '-cdartanalyzer'],
-    const <String>['-mrelease', '-rvm', '-cdart2dart'],
-    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk'],
-    const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk', '--checked']];
+    const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
+    const <String>['-mrelease', '-rvm', '-cdart2dart', '--use-sdk'],
+    const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
+    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
+                   '--minified'],
+    const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
+                   '--checked'],
+];
 
 void main() {
   Options options = new Options();
@@ -51,8 +57,6 @@
     arguments.addAll(COMMON_ARGUMENTS);
     arguments.addAll(options.arguments);
     arguments.addAll(commandLine);
-    arguments.add('co19');
-    arguments.add('--progress=diff');
     configurations.addAll(optionsParser.parse(arguments));
   }