Version 0.6.13.0 .

svn merge -r 25521:25579 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@25630 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/docgen/lib/dart2yaml.dart b/pkg/docgen/lib/dart2yaml.dart
index cccb8eb..57ca7fe 100644
--- a/pkg/docgen/lib/dart2yaml.dart
+++ b/pkg/docgen/lib/dart2yaml.dart
@@ -17,31 +17,44 @@
 }
 
 /**
- * This recursive function adds to its input StringBuffer and builds
- * a YAML string from the input Map.
+ * This recursive function builds a YAML string from [documentData] and
+ * adds it to [yaml].
+ * The [level] input determines the indentation of the block being processed.
+ * The [isList] input determines whether [documentData] is a member of an outer
+ * lists of maps. A map must be preceeded with a '-' if it is to exist at the
+ * same level of indentation in the YAML output as other members of the list.
  */
-// TODO(tmandel): Fix quotes with String objects.
-void _addLevel(StringBuffer yaml, Map documentData, int level) {
-  documentData.keys.forEach( (key) {
+void _addLevel(StringBuffer yaml, Map documentData, int level,
+               {bool isList: false}) {
+  // Since the ordering of the keys could be non-deterministic, the keys
+  // are sorted to ensure consistency in the output.
+  var keys = documentData.keys.toList();
+  keys.sort();
+  keys.forEach((key) {
     _calcSpaces(level, yaml);
+    // Only the first entry of the map should be preceeded with a '-' since
+    // the map is a member of an outer list and the map as a whole must be 
+    // marked as a single member of that list. See example 2.4 at
+    // http://www.yaml.org/spec/1.2/spec.html#id2759963
+    if (isList && key == keys.first) {
+      yaml.write("- ");
+      level++;
+    }
     yaml.write("\"$key\" : ");
-
     if (documentData[key] is Map) {
       yaml.write("\n");
       _addLevel(yaml, documentData[key], level + 1);
-
     } else if (documentData[key] is List) {
       var elements = documentData[key];
       yaml.write("\n");
       elements.forEach( (element) {
         if (element is Map) {
-          _addLevel(yaml, element, level + 1);
+          _addLevel(yaml, element, level + 1, isList: true);
         } else {
           _calcSpaces(level + 1, yaml);
           yaml.write("- ${_processElement(element)}");
         }
       });
-      
     } else {
       yaml.write(_processElement(documentData[key]));
     }
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index dc7069f..6ad2609 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -154,17 +154,10 @@
     bool parseSdk:false}) {
   var libraries = !parseSdk ? _listLibraries(args) : _listSdk();
   if (libraries.isEmpty) throw new StateError('No Libraries.');
-  // DART_SDK should be set to the root of the SDK library.
-  var sdkRoot = Platform.environment['DART_SDK'];
-  if (sdkRoot != null) {
-    logger.info('Using DART_SDK to find SDK at $sdkRoot');
-  } else {
-    // If DART_SDK is not defined in the environment,
-    // assuming the dart executable is from the Dart SDK folder inside bin.
-    sdkRoot = path.join(path.dirname(path.dirname(path.dirname(path.dirname(
+  // Finds the root of SDK library based off the location of docgen.
+  var sdkRoot = path.join(path.dirname(path.dirname(path.dirname(path.dirname(
         path.absolute(new Options().script))))), 'sdk');
-    logger.info('SDK Root: ${sdkRoot}');
-  }
+  logger.info('SDK Root: ${sdkRoot}');
   return _analyzeLibraries(libraries, sdkRoot, packageRoot: packageRoot);
 }
 
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index 8aeefdb..1462c63 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -113,9 +113,7 @@
           var libraryDocComment = fixReference('foobar', libraryMirror,
               classMirror, methodMirror).children.first.text;
           expect(libraryDocComment == 'foobar', isTrue);
-          
-          temporaryDir.deleteSync(recursive: true);
-        }));
+        })).whenComplete(() => temporaryDir.deleteSync(recursive: true));
     });
   });
 }
diff --git a/pkg/fixnum/lib/src/int32.dart b/pkg/fixnum/lib/src/int32.dart
index 6c8a6f4..84d9bfc 100644
--- a/pkg/fixnum/lib/src/int32.dart
+++ b/pkg/fixnum/lib/src/int32.dart
@@ -138,18 +138,15 @@
    */
   int32.fromInt(int i) : _i = (i & 0x7fffffff) - (i & 0x80000000);
 
-  // Convert an [int] or [intx] to an [int32].  Note that an [int64]
-  // will be truncated.
-  int _convert(other) {
-    if (other == null) {
-      throw new ArgumentError(null);
-    } else if (other is intx) {
-      return other.toInt32()._i;
-    } else if (other is int) {
-      return other;
-    } else {
-      throw new Exception("Can't retrieve 32-bit int from $other");
+  // Returns the [int] representation of the specified value. Throws
+  // [ArgumentError] for non-integer arguments.
+  int _toInt(val) {
+    if (val is int32) {
+      return val._i;
+    } else if (val is int) {
+      return val;
     }
+    throw new ArgumentError(val);
   }
 
   // The +, -, * , &, |, and ^ operaters deal with types as follows:
@@ -170,14 +167,14 @@
     if (other is int64) {
       return this.toInt64() + other;
     }
-    return new int32.fromInt(_i + _convert(other));
+    return new int32.fromInt(_i + _toInt(other));
   }
 
   intx operator -(other) {
     if (other is int64) {
       return this.toInt64() - other;
     }
-    return new int32.fromInt(_i - _convert(other));
+    return new int32.fromInt(_i - _toInt(other));
   }
 
   int32 operator -() => new int32.fromInt(-_i);
@@ -195,20 +192,18 @@
       // Result will be int32
       return (this.toInt64() % other).toInt32();
     }
-    return new int32.fromInt(_i % _convert(other));
+    return new int32.fromInt(_i % _toInt(other));
   }
 
   int32 operator ~/(other) {
     if (other is int64) {
-      // Result will be int32
       return (this.toInt64() ~/ other).toInt32();
     }
-    return new int32.fromInt(_i ~/ _convert(other));
+    return new int32.fromInt(_i ~/ _toInt(other));
   }
 
   int32 remainder(other) {
     if (other is int64) {
-      // Result will be int32
       int64 t = this.toInt64();
       return (t - (t ~/ other) * other).toInt32();
     }
@@ -219,21 +214,21 @@
     if (other is int64) {
       return (this.toInt64() & other).toInt32();
     }
-    return new int32.fromInt(_i & _convert(other));
+    return new int32.fromInt(_i & _toInt(other));
   }
 
   int32 operator |(other) {
     if (other is int64) {
       return (this.toInt64() | other).toInt32();
     }
-    return new int32.fromInt(_i | _convert(other));
+    return new int32.fromInt(_i | _toInt(other));
   }
 
   int32 operator ^(other) {
     if (other is int64) {
       return (this.toInt64() ^ other).toInt32();
     }
-    return new int32.fromInt(_i ^ _convert(other));
+    return new int32.fromInt(_i ^ _toInt(other));
   }
 
   int32 operator ~() => new int32.fromInt(~_i);
@@ -279,48 +274,49 @@
    * given object.  The argument may be an [int] or an [intx].
    */
   bool operator ==(other) {
-    if (other == null) {
-      return false;
-    }
-    if (other is int64) {
+    if (other is int32) {
+      return _i == other._i;
+    } else if (other is int64) {
       return this.toInt64() == other;
+    } else if (other is int) {
+      return _i == other;
     }
-    return _i == _convert(other);
+    return false;
   }
 
   int compareTo(Comparable other) {
     if (other is int64) {
       return this.toInt64().compareTo(other);
     }
-    return _i.compareTo(_convert(other));
+    return _i.compareTo(_toInt(other));
   }
 
   bool operator <(other) {
     if (other is int64) {
       return this.toInt64() < other;
     }
-    return _i < _convert(other);
+    return _i < _toInt(other);
   }
 
   bool operator <=(other) {
     if (other is int64) {
-      return this.toInt64() < other;
+      return this.toInt64() <= other;
     }
-    return _i <= _convert(other);
+    return _i <= _toInt(other);
   }
 
   bool operator >(other) {
     if (other is int64) {
-      return this.toInt64() < other;
+      return this.toInt64() > other;
     }
-    return _i > _convert(other);
+    return _i > _toInt(other);
   }
 
   bool operator >=(other) {
     if (other is int64) {
-      return this.toInt64() < other;
+      return this.toInt64() >= other;
     }
-    return _i >= _convert(other);
+    return _i >= _toInt(other);
   }
 
   bool get isEven => (_i & 0x1) == 0;
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 81607de..a179105 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -240,18 +240,17 @@
     _h = (top >> 12) & _MASK_2;
   }
 
-  int64 _promote(other) {
-    if (other == null) {
-      throw new ArgumentError(null);
-    } else if (other is intx) {
-      other = other.toInt64();
-    } else if (other is int) {
-      other = new int64.fromInt(other);
+  // Returns the [int64] representation of the specified value. Throws
+  // [ArgumentError] for non-integer arguments.
+  int64 _promote(val) {
+    if (val is int64) {
+      return val;
+    } else if (val is int) {
+      return new int64.fromInt(val);
+    } else if (val is int32) {
+      return val.toInt64();
     }
-    if (other is !int64) {
-      throw new Exception("Can't promote $other to int64");
-    }
-    return other;
+    throw new ArgumentError(val);
   }
 
   int64 operator +(other) {
@@ -266,7 +265,6 @@
 
   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);
@@ -286,6 +284,7 @@
 
   int64 operator *(other) {
     int64 o = _promote(other);
+
     // Grab 13-bit chunks.
     int a0 = _l & 0x1fff;
     int a1 = (_l >> 13) | ((_m & 0xf) << 9);
@@ -515,11 +514,18 @@
    * given object.  The argument may be an [int] or an [intx].
    */
   bool operator ==(other) {
-    if (other == null) {
-      return false;
+    int64 o;
+    if (other is int64) {
+      o = other;
+    } else if (other is int) {
+      o = new int64.fromInt(other);
+    } else if (other is int32) {
+      o = other.toInt64();
     }
-    int64 o = _promote(other);
-    return _l == o._l && _m == o._m && _h == o._h;
+    if (o != null) {
+      return _l == o._l && _m == o._m && _h == o._h;
+    }
+    return false;
   }
 
   int compareTo(Comparable other) {
@@ -944,7 +950,7 @@
     _h = b2;
   }
 
-  int64 _divModByShift(int64 a, int bpower, bool negative, bool aIsCopy,
+  static int64 _divModByShift(int64 a, int bpower, bool negative, bool aIsCopy,
       bool aIsNegative, bool computeRemainder) {
     int64 c = a >> bpower;
     if (negative) {
@@ -997,7 +1003,7 @@
     return -1;
   }
 
-  int64 _divMod(int64 a, int64 b, bool computeRemainder) {
+  static int64 _divMod(int64 a, int64 b, bool computeRemainder) {
     if (b.isZero) {
       throw new IntegerDivisionByZeroException();
     }
diff --git a/pkg/fixnum/test/int_32_test.dart b/pkg/fixnum/test/int_32_test.dart
index 77a6b27..7e27d41 100644
--- a/pkg/fixnum/test/int_32_test.dart
+++ b/pkg/fixnum/test/int_32_test.dart
@@ -94,6 +94,9 @@
       expect(new int32.fromInt(17) < new int32.fromInt(18), true);
       expect(new int32.fromInt(17) < new int32.fromInt(17), false);
       expect(new int32.fromInt(17) < new int32.fromInt(16), false);
+      expect(new int32.fromInt(17) < new int64.fromInt(18), true);
+      expect(new int32.fromInt(17) < new int64.fromInt(17), false);
+      expect(new int32.fromInt(17) < new int64.fromInt(16), false);
       expect(int32.MIN_VALUE < int32.MAX_VALUE, true);
       expect(int32.MAX_VALUE < int32.MIN_VALUE, false);
       expect(() => new int32.fromInt(17) < null, throws);
@@ -103,6 +106,9 @@
       expect(new int32.fromInt(17) <= new int32.fromInt(18), true);
       expect(new int32.fromInt(17) <= new int32.fromInt(17), true);
       expect(new int32.fromInt(17) <= new int32.fromInt(16), false);
+      expect(new int32.fromInt(17) <= new int64.fromInt(18), true);
+      expect(new int32.fromInt(17) <= new int64.fromInt(17), true);
+      expect(new int32.fromInt(17) <= new int64.fromInt(16), false);
       expect(int32.MIN_VALUE <= int32.MAX_VALUE, true);
       expect(int32.MAX_VALUE <= int32.MIN_VALUE, false);
       expect(() => new int32.fromInt(17) <= null, throws);
@@ -112,7 +118,11 @@
       expect(new int32.fromInt(17) == new int32.fromInt(18), false);
       expect(new int32.fromInt(17) == new int32.fromInt(17), true);
       expect(new int32.fromInt(17) == new int32.fromInt(16), false);
+      expect(new int32.fromInt(17) == new int64.fromInt(18), false);
+      expect(new int32.fromInt(17) == new int64.fromInt(17), true);
+      expect(new int32.fromInt(17) == new int64.fromInt(16), false);
       expect(int32.MIN_VALUE == int32.MAX_VALUE, false);
+      expect(new int32.fromInt(17) == new Object(), false);
       expect(new int32.fromInt(17) == null, false);
     });
 
@@ -120,6 +130,9 @@
       expect(new int32.fromInt(17) >= new int32.fromInt(18), false);
       expect(new int32.fromInt(17) >= new int32.fromInt(17), true);
       expect(new int32.fromInt(17) >= new int32.fromInt(16), true);
+      expect(new int32.fromInt(17) >= new int64.fromInt(18), false);
+      expect(new int32.fromInt(17) >= new int64.fromInt(17), true);
+      expect(new int32.fromInt(17) >= new int64.fromInt(16), true);
       expect(int32.MIN_VALUE >= int32.MAX_VALUE, false);
       expect(int32.MAX_VALUE >= int32.MIN_VALUE, true);
       expect(() => new int32.fromInt(17) >= null, throws);
@@ -129,6 +142,9 @@
       expect(new int32.fromInt(17) > new int32.fromInt(18), false);
       expect(new int32.fromInt(17) > new int32.fromInt(17), false);
       expect(new int32.fromInt(17) > new int32.fromInt(16), true);
+      expect(new int32.fromInt(17) > new int64.fromInt(18), false);
+      expect(new int32.fromInt(17) > new int64.fromInt(17), false);
+      expect(new int32.fromInt(17) > new int64.fromInt(16), true);
       expect(int32.MIN_VALUE > int32.MAX_VALUE, false);
       expect(int32.MAX_VALUE > int32.MIN_VALUE, true);
       expect(() => new int32.fromInt(17) > null, throws);
diff --git a/pkg/fixnum/test/int_64_test.dart b/pkg/fixnum/test/int_64_test.dart
index fddb409..4ff8e1c 100644
--- a/pkg/fixnum/test/int_64_test.dart
+++ b/pkg/fixnum/test/int_64_test.dart
@@ -159,7 +159,7 @@
       expect(int64.MIN_VALUE ~/ new int64.fromInt(1), int64.MIN_VALUE);
       expect(int64.MIN_VALUE ~/ new int64.fromInt(-1), int64.MIN_VALUE);
       expect(() => new int64.fromInt(17) ~/ int64.ZERO, throws);
-      expect(() => new int64.fromInt(17) ~/ null, throws);
+      expect(() => new int64.fromInt(17) ~/ null, throwsArgumentError);
     });
 
     test("%", () {
@@ -218,7 +218,10 @@
     test("<", () {
       expect(new int64.fromInt(10) < new int64.fromInt(11), true);
       expect(new int64.fromInt(10) < new int64.fromInt(10), false);
-      expect(new int64.fromInt(12) < new int64.fromInt(11), false);
+      expect(new int64.fromInt(10) < new int64.fromInt(9), false);
+      expect(new int64.fromInt(10) < new int32.fromInt(11), true);
+      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(largeNeg < largePos, true);
@@ -233,7 +236,10 @@
     test("<=", () {
       expect(new int64.fromInt(10) <= new int64.fromInt(11), true);
       expect(new int64.fromInt(10) <= new int64.fromInt(10), true);
-      expect(new int64.fromInt(12) <= new int64.fromInt(11), false);
+      expect(new int64.fromInt(10) <= new int64.fromInt(9), false);
+      expect(new int64.fromInt(10) <= new int32.fromInt(11), true);
+      expect(new int64.fromInt(10) <= new int32.fromInt(10), true);
+      expect(new int64.fromInt(10) <= new int64.fromInt(9), false);
       expect(new int64.fromInt(-10) <= new int64.fromInt(-11), false);
       expect(new int64.fromInt(-10) <= new int64.fromInt(-10), true);
       expect(largeNeg <= largePos, true);
@@ -249,20 +255,27 @@
     test("==", () {
       expect(new int64.fromInt(10) == new int64.fromInt(11), false);
       expect(new int64.fromInt(10) == new int64.fromInt(10), true);
-      expect(new int64.fromInt(12) == new int64.fromInt(11), false);
+      expect(new int64.fromInt(10) == new int64.fromInt(9), false);
+      expect(new int64.fromInt(10) == new int32.fromInt(11), false);
+      expect(new int64.fromInt(10) == new int32.fromInt(10), true);
+      expect(new int64.fromInt(10) == new int32.fromInt(9), false);
       expect(new int64.fromInt(-10) == new int64.fromInt(-10), true);
       expect(new int64.fromInt(-10) != new int64.fromInt(-10), false);
       expect(largePos == largePos, true);
       expect(largePos == largePosPlusOne, false);
       expect(largePosPlusOne == largePos, false);
       expect(int64.MIN_VALUE == int64.MAX_VALUE, false);
+      expect(new int64.fromInt(17) == new Object(), false);
       expect(new int64.fromInt(17) == null, false);
     });
 
     test(">=", () {
       expect(new int64.fromInt(10) >= new int64.fromInt(11), false);
       expect(new int64.fromInt(10) >= new int64.fromInt(10), true);
-      expect(new int64.fromInt(12) >= new int64.fromInt(11), true);
+      expect(new int64.fromInt(10) >= new int64.fromInt(9), true);
+      expect(new int64.fromInt(10) >= new int32.fromInt(11), false);
+      expect(new int64.fromInt(10) >= new int32.fromInt(10), true);
+      expect(new int64.fromInt(10) >= new int32.fromInt(9), true);
       expect(new int64.fromInt(-10) >= new int64.fromInt(-11), true);
       expect(new int64.fromInt(-10) >= new int64.fromInt(-10), true);
       expect(largePos >= largeNeg, true);
@@ -278,7 +291,10 @@
     test(">", () {
       expect(new int64.fromInt(10) > new int64.fromInt(11), false);
       expect(new int64.fromInt(10) > new int64.fromInt(10), false);
-      expect(new int64.fromInt(12) > new int64.fromInt(11), true);
+      expect(new int64.fromInt(10) > new int64.fromInt(9), true);
+      expect(new int64.fromInt(10) > new int32.fromInt(11), false);
+      expect(new int64.fromInt(10) > new int32.fromInt(10), false);
+      expect(new int64.fromInt(10) > new int32.fromInt(9), true);
       expect(new int64.fromInt(-10) > new int64.fromInt(-11), true);
       expect(new int64.fromInt(10) > new int64.fromInt(-11), true);
       expect(new int64.fromInt(-10) > new int64.fromInt(11), false);
@@ -305,21 +321,21 @@
       expect(n1 & n2, new int64.fromInt(1168));
       expect(n3 & n2, new int64.fromInt(8708));
       expect(n4 & n5, new int64.fromInt(0x1034) << 32);
-      expect(() => n1 & null, throws);
+      expect(() => n1 & null, throwsArgumentError);
     });
 
     test("|", () {
       expect(n1 | n2, new int64.fromInt(9942));
       expect(n3 | n2, new int64.fromInt(-66));
       expect(n4 | n5, new int64.fromInt(0x9a76) << 32);
-      expect(() => n1 | null, throws);
+      expect(() => n1 | null, throwsArgumentError);
     });
 
     test("^", () {
       expect(n1 ^ n2, new int64.fromInt(8774));
       expect(n3 ^ n2, new int64.fromInt(-8774));
       expect(n4 ^ n5, new int64.fromInt(0x8a42) << 32);
-      expect(() => n1 ^ null, throws);
+      expect(() => n1 ^ null, throwsArgumentError);
     });
 
     test("~", () {
diff --git a/pkg/observe/lib/src/change_notifier.dart b/pkg/observe/lib/src/change_notifier.dart
index 9e54f60..8102ab0 100644
--- a/pkg/observe/lib/src/change_notifier.dart
+++ b/pkg/observe/lib/src/change_notifier.dart
@@ -5,22 +5,8 @@
 part of observe;
 
 /**
- * Interface representing an [Observable] object that performs its own change
+ * Base class implementing [Observable] object that performs its own change
  * notifications, and does not need to be considered by [Observable.dirtyCheck].
- */
-abstract class ChangeNotifier extends Observable {
-  /**
-   * Notify observers of a change.
-   *
-   * For most objects [ChangeNotifierMixin.notifyPropertyChange] is more
-   * convenient, but collections sometimes deliver other types of changes such
-   * as a [ListChangeRecord].
-   */
-  void notifyChange(ChangeRecord record);
-}
-
-/**
- * Base class implementing [ChangeNotifier].
  *
  * When a field, property, or indexable item is changed, a derived class should
  * call [notifyPropertyChange]. See that method for an example.
@@ -28,12 +14,13 @@
 typedef ChangeNotifierBase = Object with ChangeNotifierMixin;
 
 /**
- * Mixin for implementing [ChangeNotifier] objects.
+ * Mixin implementing [Observable] object that performs its own change
+ * notifications, and does not need to be considered by [Observable.dirtyCheck].
  *
  * When a field, property, or indexable item is changed, a derived class should
  * call [notifyPropertyChange]. See that method for an example.
  */
-abstract class ChangeNotifierMixin implements ChangeNotifier {
+abstract class ChangeNotifierMixin implements Observable {
   StreamController _changes;
   List<ChangeRecord> _records;
 
@@ -62,8 +49,7 @@
     var records = _records;
     _records = null;
     if (hasObservers && records != null) {
-      // TODO(jmesserly): make "records" immutable
-      _changes.add(records);
+      _changes.add(new UnmodifiableListView<ChangeRecord>(records));
       return true;
     }
     return false;
@@ -91,14 +77,8 @@
    *           const Symbol('myField'), _myField, value);
    *     }
    */
-  // TODO(jmesserly): should this be == instead of identical, to prevent
-  // spurious loops?
-  notifyPropertyChange(Symbol field, Object oldValue, Object newValue) {
-    if (hasObservers && !identical(oldValue, newValue)) {
-      notifyChange(new PropertyChangeRecord(field));
-    }
-    return newValue;
-  }
+  notifyPropertyChange(Symbol field, Object oldValue, Object newValue)
+      => _notifyPropertyChange(this, field, oldValue, newValue);
 
   void notifyChange(ChangeRecord record) {
     if (!hasObservers) return;
diff --git a/pkg/observe/lib/src/observable.dart b/pkg/observe/lib/src/observable.dart
index 8bccef9..a49f8f1 100644
--- a/pkg/observe/lib/src/observable.dart
+++ b/pkg/observe/lib/src/observable.dart
@@ -14,9 +14,9 @@
  * model-view architectures to notify interested parties of [changes].
  *
  * This object does not require any specific technique to implement
- * observability. However if you implement change notification yourself, you
- * should also implement [ChangeNotifier], so [dirtyCheck] knows to skip the
- * object.
+ * observability. If you mixin [ObservableMixin], [dirtyCheck] will know to
+ * check for changes on the object. You may also implement change notification
+ * yourself, by calling [notifyChange].
  *
  * You can use [ObservableBase] or [ObservableMixin] to implement this.
  */
@@ -47,9 +47,22 @@
   // that subscription. Alternatively, we could consider using something other
   // than Stream to deliver the multicast change records, and provide an
   // Observable->Stream adapter.
+  //
+  // Also: we should be delivering changes to the observer (subscription) based
+  // on the birth order of the observer. This is for compatibility with ES
+  // Harmony as well as predictability for app developers.
   bool deliverChanges();
 
   /**
+   * Notify observers of a change.
+   *
+   * For most objects [ObservableMixin.notifyPropertyChange] is more
+   * convenient, but collections sometimes deliver other types of changes such
+   * as a [ListChangeRecord].
+   */
+  void notifyChange(ChangeRecord record);
+
+  /**
    * Performs dirty checking of objects that inherit from [ObservableMixin].
    * This scans all observed objects using mirrors and determines if any fields
    * have changed. If they have, it delivers the changes for the object.
@@ -76,6 +89,7 @@
   InstanceMirror _mirror;
 
   Map<Symbol, Object> _values;
+  List<ChangeRecord> _records;
 
   Stream<List<ChangeRecord>> get changes {
     if (_changes == null) {
@@ -132,24 +146,64 @@
   bool deliverChanges() {
     if (_values == null || !hasObservers) return false;
 
-    List changes = null;
+    // Start with manually notified records (computed properties, etc),
+    // then scan all fields for additional changes.
+    List records = _records;
+    _records = null;
+
     _values.forEach((name, oldValue) {
       var newValue = _mirror.getField(name).reflectee;
       if (!identical(oldValue, newValue)) {
-        if (changes == null) changes = <PropertyChangeRecord>[];
-        changes.add(new PropertyChangeRecord(name));
+        if (records == null) records = [];
+        records.add(new PropertyChangeRecord(name));
         _values[name] = newValue;
       }
     });
 
-    if (changes == null) return false;
+    if (records == null) return false;
 
-    // TODO(jmesserly): make "changes" immutable
-    _changes.add(changes);
+    _changes.add(new UnmodifiableListView<ChangeRecord>(records));
     return true;
   }
+
+  /**
+   * Notify that the field [name] of this object has been changed.
+   *
+   * The [oldValue] and [newValue] are also recorded. If the two values are
+   * identical, no change will be recorded.
+   *
+   * For convenience this returns [newValue].
+   */
+  notifyPropertyChange(Symbol field, Object oldValue, Object newValue)
+      => _notifyPropertyChange(this, field, oldValue, newValue);
+
+  /**
+   * Notify a change manually. This is *not* required for fields, but can be
+   * used for computed properties. *Note*: unlike [ChangeNotifierMixin] this
+   * will not schedule [deliverChanges]; use [Observable.dirtyCheck] instead.
+   */
+  void notifyChange(ChangeRecord record) {
+    if (!hasObservers) return;
+
+    if (_records == null) _records = [];
+    _records.add(record);
+  }
 }
 
+// TODO(jmesserly): remove the instance method and make this top-level method
+// public instead?
+_notifyPropertyChange(Observable obj, Symbol field, Object oldValue,
+    Object newValue) {
+
+  // TODO(jmesserly): should this be == instead of identical, to prevent
+  // spurious loops?
+  if (obj.hasObservers && !identical(oldValue, newValue)) {
+    obj.notifyChange(new PropertyChangeRecord(field));
+  }
+  return newValue;
+}
+
+
 /**
  * The type of the `@observable` annotation.
  *
diff --git a/pkg/observe/test/observe_test.dart b/pkg/observe/test/observe_test.dart
index db57674..c898e43 100644
--- a/pkg/observe/test/observe_test.dart
+++ b/pkg/observe/test/observe_test.dart
@@ -193,6 +193,49 @@
     }));
     t.value = 42;
   });
+
+  observeTest('cannot modify changes list', () {
+    var t = createModel(123);
+    var records = null;
+    subs.add(t.changes.listen((r) { records = r; }));
+    t.value = 42;
+
+    performMicrotaskCheckpoint();
+    expectChanges(records, _changedValue(1));
+
+    // Verify that mutation operations on the list fail:
+
+    expect(() {
+      records[0] = new PropertyChangeRecord(_VALUE);
+    }, throwsUnsupportedError);
+
+    expect(() { records.clear(); }, throwsUnsupportedError);
+
+    expect(() { records.length = 0; }, throwsUnsupportedError);
+  });
+
+  observeTest('notifyChange', () {
+    var t = createModel(123);
+    var records = [];
+    subs.add(t.changes.listen((r) { records.addAll(r); }));
+    t.notifyChange(new PropertyChangeRecord(_VALUE));
+
+    performMicrotaskCheckpoint();
+    expectChanges(records, _changedValue(1));
+    expect(t.value, 123, reason: 'value did not actually change.');
+  });
+
+  observeTest('notifyPropertyChange', () {
+    var t = createModel(123);
+    var records = null;
+    subs.add(t.changes.listen((r) { records = r; }));
+    expect(t.notifyPropertyChange(_VALUE, t.value, 42), 42,
+        reason: 'notifyPropertyChange returns newValue');
+
+    performMicrotaskCheckpoint();
+    expectChanges(records, _changedValue(1));
+    expect(t.value, 123, reason: 'value did not actually change.');
+  });
 }
 
 _changedValue(len) => new List.filled(len, new PropertyChangeRecord(_VALUE));
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 18f116e..c8d7b4d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -15,6 +15,9 @@
 scheduled_test/test/scheduled_server_test: Pass, Fail, Slow, Crash # Issue 9231, 9582
 scheduled_test/test/scheduled_process_test: Pass, Slow # Issue 9231
 
+[ $runtime == vm ]
+watcher/test/no_subscription_test: Pass, Fail # Issue 12107
+
 [ $compiler == none && $runtime == drt && $mode == debug]
 mdv/test/custom_element_bindings_test: Fail # Issue 11657
 
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index 8fb9e83e..3d10f6d 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -130,7 +130,15 @@
     String reason = null;
     // If _limit is 1 we can only recurse one level into object.
     bool canRecurse = depth == 0 || _limit > 1;
-    if (expected == actual) {
+    bool equal;
+    try {
+      equal = (expected == actual);
+    } catch (e,s) {
+      // TODO(gram): Add a test for this case.
+      reason = '== threw "$e"';
+      return [reason, location];
+    }
+    if (equal) {
       // Do nothing.
     } else if (depth > _limit) {
       reason = 'recursion depth limit exceeded';
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 609c38f..f9a1dcf 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -85,33 +85,6 @@
 }
 
 
-static Dart_Handle IsMethodMirror(Dart_Handle object, bool* is_mirror) {
-  Dart_Handle cls_name = NewString("MethodMirror");
-  Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
-  if (Dart_IsError(type)) {
-    return type;
-  }
-  Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  return Dart_True();  // Indicates success.  Result is in is_mirror.
-}
-
-static Dart_Handle IsVariableMirror(Dart_Handle object, bool* is_mirror) {
-  Dart_Handle cls_name = NewString("VariableMirror");
-  Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
-  if (Dart_IsError(type)) {
-    return type;
-  }
-  Dart_Handle result = Dart_ObjectIsType(object, type, is_mirror);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  return Dart_True();  // Indicates success.  Result is in is_mirror.
-}
-
-
 // TODO(11742): Remove once there are no more users of the Dart_Handle-based
 // VMReferences.
 static Dart_Handle CreateMirrorReference(Dart_Handle handle) {
@@ -124,114 +97,6 @@
 }
 
 
-static Dart_Handle StringFromSymbol(Dart_Handle symbol) {
-  Dart_Handle result = Dart_Invoke(MirrorLib(), NewString("_n"), 1, &symbol);
-  return result;
-}
-
-
-static Dart_Handle UnwrapVMReference(Dart_Handle vm_ref) {
-  // Retrieve the persistent handle from the VMReference
-  intptr_t perm_handle_value = 0;
-  Dart_Handle result =
-      Dart_GetNativeInstanceField(vm_ref, 0, &perm_handle_value);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  Dart_PersistentHandle perm_handle =
-      reinterpret_cast<Dart_PersistentHandle>(perm_handle_value);
-  ASSERT(perm_handle != NULL);
-  Dart_Handle handle = Dart_HandleFromPersistent(perm_handle);
-  ASSERT(handle != NULL);
-  ASSERT(!Dart_IsError(handle));
-  return handle;
-}
-
-static Dart_Handle UnwrapMirror(Dart_Handle mirror);
-
-static Dart_Handle UnwrapObjectMirror(Dart_Handle mirror) {
-  Dart_Handle field_name = NewString("_reference");
-  Dart_Handle vm_ref = Dart_GetField(mirror, field_name);
-  if (Dart_IsError(vm_ref)) {
-    return vm_ref;
-  }
-  return UnwrapVMReference(vm_ref);
-}
-
-
-static Dart_Handle UnwrapMethodMirror(Dart_Handle methodMirror) {
-  Dart_Handle namefield_name = NewString("simpleName");
-  Dart_Handle name_ref = Dart_GetField(methodMirror, namefield_name);
-  if (Dart_IsError(name_ref)) {
-    return name_ref;
-  }
-  Dart_Handle ownerfield_name = NewString("_owner");
-  Dart_Handle owner_mirror = Dart_GetField(methodMirror, ownerfield_name);
-  if (Dart_IsError(owner_mirror)) {
-    return owner_mirror;
-  }
-  Dart_Handle owner = UnwrapMirror(owner_mirror);
-  if (Dart_IsError(owner)) {
-    return owner;
-  }
-  Dart_Handle func = Dart_LookupFunction(owner, StringFromSymbol(name_ref));
-  if (Dart_IsError(func)) {
-    return func;
-  }
-  ASSERT(!Dart_IsNull(func));
-  return func;
-}
-
-static Dart_Handle UnwrapVariableMirror(Dart_Handle variableMirror) {
-  Dart_Handle namefield_name = NewString("simpleName");
-  Dart_Handle name_ref = Dart_GetField(variableMirror, namefield_name);
-  if (Dart_IsError(name_ref)) {
-    return name_ref;
-  }
-  Dart_Handle ownerfield_name = NewString("_owner");
-  Dart_Handle owner_mirror = Dart_GetField(variableMirror, ownerfield_name);
-  ASSERT(!Dart_IsNull(owner_mirror));
-  if (Dart_IsError(owner_mirror)) {
-    return owner_mirror;
-  }
-  Dart_Handle owner = UnwrapMirror(owner_mirror);
-  if (Dart_IsError(owner)) {
-    return owner;
-  }
-  Dart_Handle variable =
-  Dart_LookupVariable(owner, StringFromSymbol(name_ref));
-  if (Dart_IsError(variable)) {
-    return variable;
-  }
-  ASSERT(!Dart_IsNull(variable));
-  return variable;
-}
-
-static Dart_Handle UnwrapMirror(Dart_Handle mirror) {
-  // Caveat Emptor:
-  // only works for ObjectMirrors, VariableMirrors and MethodMirrors
-  // and their subtypes
-  bool is_method_mirror = false;
-  Dart_Handle result = IsMethodMirror(mirror, &is_method_mirror);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  if (is_method_mirror) {
-    return UnwrapMethodMirror(mirror);
-  }
-  bool is_variable_mirror = false;
-  result = IsVariableMirror(mirror, &is_variable_mirror);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  if (is_variable_mirror) {
-    return UnwrapVariableMirror(mirror);
-  }
-  return UnwrapObjectMirror(mirror);
-  // will return nonsense if mirror is not an ObjectMirror
-}
-
-
 static Dart_Handle CreateLazyMirror(Dart_Handle target);
 
 
@@ -492,9 +357,6 @@
 }
 
 
-static Dart_Handle CreateConstructorMap(Dart_Handle owner,
-                                        Dart_Handle owner_mirror);
-
 static Dart_Handle CreateClassMirrorUsingApi(Dart_Handle intf,
                                              Dart_Handle intf_name,
                                              Dart_Handle lib_mirror) {
@@ -519,10 +381,6 @@
   if (Dart_IsError(intf_mirror)) {
     return intf_mirror;
   }
-  Dart_Handle constructor_map = CreateConstructorMap(intf, intf_mirror);
-  if (Dart_IsError(constructor_map)) {
-    return constructor_map;
-  }
   Dart_Handle type_var_map = CreateTypeVariableMap(intf, intf_mirror);
   if (Dart_IsError(type_var_map)) {
     return type_var_map;
@@ -536,7 +394,6 @@
     super_class,
     CreateImplementsList(intf),
     CreateLazyMirror(default_class),
-    constructor_map,
     type_var_map,
   };
   Dart_Handle mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
@@ -590,66 +447,6 @@
 }
 
 
-static Dart_Handle AddConstructors(Dart_Handle map,
-                                   Dart_Handle owner,
-                                   Dart_Handle owner_mirror) {
-  Dart_Handle result;
-  Dart_Handle names = Dart_GetFunctionNames(owner);
-  if (Dart_IsError(names)) {
-    return names;
-  }
-  intptr_t len;
-  result = Dart_ListLength(names, &len);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  for (intptr_t i = 0; i < len; i++) {
-    Dart_Handle func_name = Dart_ListGetAt(names, i);
-    Dart_Handle func = Dart_LookupFunction(owner, func_name);
-    if (Dart_IsError(func)) {
-      return func;
-    }
-    ASSERT(!Dart_IsNull(func));
-
-    bool is_constructor = false;
-    result = Dart_FunctionIsConstructor(func, &is_constructor);
-    if (Dart_IsError(result)) {
-      return result;
-    }
-    if (!is_constructor) {
-      // Skip non-constructors.
-      continue;
-    }
-
-    Dart_Handle func_mirror = CreateMethodMirrorUsingApi(func, owner_mirror);
-    if (Dart_IsError(func_mirror)) {
-      return func_mirror;
-    }
-    result = MapAdd(map, func_name, func_mirror);
-    if (Dart_IsError(result)) {
-      return result;
-    }
-  }
-  return Dart_True();
-}
-
-
-static Dart_Handle CreateConstructorMap(Dart_Handle owner,
-                                        Dart_Handle owner_mirror) {
-  // TODO(turnidge): This should be an immutable map.
-  if (Dart_IsError(owner_mirror)) {
-    return owner_mirror;
-  }
-  Dart_Handle result;
-  Dart_Handle map = MapNew();
-  result = AddConstructors(map, owner, owner_mirror);
-  if (Dart_IsError(result)) {
-    return result;
-  }
-  return map;
-}
-
-
 static Dart_Handle CreateLibraryMirrorUsingApi(Dart_Handle lib) {
   Dart_Handle cls_name = NewString("_LocalLibraryMirrorImpl");
   Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
@@ -1045,6 +842,11 @@
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
   const Class& klass = Class::Handle(ref.GetClassReferent());
 
+  const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate));
+  if (!error.IsNull()) {
+    ThrowInvokeError(error);
+  }
+
   const Array& fields = Array::Handle(klass.fields());
   // Some special types like 'dynamic' have a null fields list, but they should
   // not wind up as the reflectees of ClassMirrors.
@@ -1083,6 +885,41 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(ClassMirror_constructors, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance,
+                               owner_mirror,
+                               arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
+  const Class& klass = Class::Handle(ref.GetClassReferent());
+
+  const Error& error = Error::Handle(klass.EnsureIsFinalized(isolate));
+  if (!error.IsNull()) {
+    ThrowInvokeError(error);
+  }
+
+  const Array& functions = Array::Handle(klass.functions());
+  // Some special types like 'dynamic' have a null functions list, but they
+  // should not wind up as the reflectees of ClassMirrors.
+  ASSERT(!functions.IsNull());
+  const intptr_t num_functions = functions.Length();
+
+  Instance& constructor_mirror = Instance::Handle();
+  const GrowableObjectArray& constructor_mirrors = GrowableObjectArray::Handle(
+      GrowableObjectArray::New(num_functions));
+
+  Function& func = Function::Handle();
+  for (intptr_t i = 0; i < num_functions; i++) {
+    func ^= functions.At(i);
+    if (func.kind() == RawFunction::kConstructor) {
+      constructor_mirror = CreateMethodMirror(func, owner_mirror);
+      constructor_mirrors.Add(constructor_mirror);
+    }
+  }
+
+  return constructor_mirrors.raw();
+}
+
+
 DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance,
                                owner_mirror,
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 97d9262..80d2ea4 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -401,10 +401,8 @@
                         this._superclass,
                         this._superinterfaces,
                         this._defaultFactory,
-                        Map<String, Mirror> constructors,
                         Map<String, Mirror> typeVariables)
       : this._simpleName = _s(simpleName),
-        this.constructors = _convertStringToSymbolMap(constructors),
         this.typeVariables = _convertStringToSymbolMap(typeVariables),
         super(reflectee);
 
@@ -535,7 +533,15 @@
     return _variables;
   }
 
-  Map<Symbol, MethodMirror> constructors;
+  Map<Symbol, MethodMirror> _constructors;
+
+  Map<Symbol, MethodMirror> get constructors {
+    if (_constructors == null) {
+      _constructors = _makeMemberMap(_computeConstructors(_reflectee));
+    }
+    return _constructors;
+  }
+
   Map<Symbol, TypeVariableMirror> typeVariables;
 
   Map<Symbol, TypeMirror> get typeArguments {
@@ -605,6 +611,9 @@
 
   _computeMembers(reflectee)
       native "ClassMirror_members";
+  
+  _computeConstructors(reflectee)
+      native "ClassMirror_constructors";
 
   _invoke(reflectee, memberName, positionalArguments)
       native 'ClassMirror_invoke';
@@ -644,10 +653,10 @@
               new _LazyTypeMirror('dart:core', 'Object'),
               [ new _LazyTypeMirror('dart:core', 'Function') ],
               null,
-              const {},
               const {});
 
   Map<Symbol, Mirror> get members => new Map<Symbol,Mirror>();
+  Map<Symbol, MethodMirror> get constructors => new Map<Symbol,MethodMirror>();
 
   var _returnType;
   TypeMirror get returnType {
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
index 54241c4..dc31e38 100644
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
@@ -116,9 +116,8 @@
   Expect.equals(null, lib_mirror.owner);
   Expect.isFalse(lib_mirror.isPrivate);
   Expect.isTrue(lib_mirror.uri.path.contains('isolate_mirror_local_test.dart'));
-  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
-  // Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
-  //               lib_mirror.toString());
+  Expect.equals("LibraryMirror on 'isolate_mirror_local_test'",
+                lib_mirror.toString());
 
   // Test library invocation by calling function(123).
   Expect.equals(0, global_var);
@@ -317,8 +316,7 @@
   Expect.isTrue(list_intf.isClass);
   Expect.equals(const Symbol('Iterable'),
                 list_intf.superinterfaces[0].simpleName);
-  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
-  // Expect.equals("ClassMirror on 'List'", list_intf.toString());
+  Expect.equals("ClassMirror on 'List'", list_intf.toString());
 
   // Lookup a class from a library and make sure it is sane.
   ClassMirror oom_cls = core_lib.members[const Symbol('OutOfMemoryError')];
@@ -332,9 +330,8 @@
   Expect.equals(const Symbol('dart.core'), oom_cls.owner.simpleName);
   Expect.isTrue(oom_cls.isClass);
   Expect.equals(const Symbol('Error'), oom_cls.superinterfaces[0].simpleName);
-  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
-  // Expect.equals("ClassMirror on 'OutOfMemoryError'",
-  //               oom_cls.toString());
+  Expect.equals("ClassMirror on 'OutOfMemoryError'",
+                oom_cls.toString());
   testDone('testLibrariesMap');
 }
 
@@ -434,21 +431,22 @@
     saw_exception = true;
   }
   Expect.isFalse(saw_exception);
-  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
-  // Expect.equals("InstanceMirror on instance of 'MyClass'",
-  //               mirror.toString());
+  Expect.equals("InstanceMirror on Instance of 'MyClass'",
+                mirror.toString());
 
   ClassMirror cls = mirror.type;
   Expect.isTrue(cls is ClassMirror);
   Expect.equals(const Symbol('MyClass'), cls.simpleName);
   Expect.equals(const Symbol('MySuperClass'), cls.superclass.simpleName);
   Expect.isTrue(cls.defaultFactory == null);
-  Expect.equals(const Symbol('isolate_mirror_local_test'), cls.owner.simpleName);
+  Expect.equals(const Symbol('isolate_mirror_local_test'),
+                cls.owner.simpleName);
   Expect.isTrue(cls.isClass);
   Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName);
-  Expect.throws(() => cls.metadata, (e) => e is MirroredCompilationError, 'Bad metadata');
-  // TODO(ahe): toString() test disabled for now as Symbols are 100% opaque.
-  // Expect.equals("ClassMirror on 'MyClass'", cls.toString());
+  Expect.throws(() => cls.metadata,
+                (e) => e is MirroredCompilationError,
+                'Bad metadata');
+  Expect.equals("ClassMirror on 'MyClass'", cls.toString());
 
   // Invoke mirror.method(1000).
   mirror.invokeAsync(const Symbol('method'), [ 1000 ]).then(
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 5a9716f..f1f15e0 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -17,6 +17,7 @@
 DECLARE_FLAG(bool, trace_sim);
 #endif
 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
+DEFINE_FLAG(bool, use_far_branches, false, "Enable far branches on MIPS");
 DECLARE_FLAG(bool, inline_alloc);
 
 void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) {
@@ -30,24 +31,25 @@
 }
 
 
-void Assembler::Bind(Label* label) {
-  ASSERT(!label->IsBound());
-  int bound_pc = buffer_.Size();
-  while (label->IsLinked()) {
-    const int32_t position = label->Position();
-    const int32_t next = buffer_.Load<int32_t>(position);
-    // Relative destination from an instruction after the branch.
-    const int32_t dest = bound_pc - (position + Instr::kInstrSize);
-    const int32_t encoded = Assembler::EncodeBranchOffset(dest, next);
-    buffer_.Store<int32_t>(position, encoded);
-    label->position_ = Assembler::DecodeBranchOffset(next);
+void Assembler::GetNextPC(Register dest, Register temp) {
+  if (temp != kNoRegister) {
+    mov(temp, RA);
   }
-  label->BindTo(bound_pc);
-  delay_slot_available_ = false;
+  EmitRegImmType(REGIMM, R0, BGEZAL, 1);
+  mov(dest, RA);
+  if (temp != kNoRegister) {
+    mov(RA, temp);
+  }
 }
 
 
-int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t instr) {
+static bool CanEncodeBranchOffset(int32_t offset) {
+  ASSERT(Utils::IsAligned(offset, 4));
+  return Utils::IsInt(18, offset);
+}
+
+
+static int32_t EncodeBranchOffset(int32_t offset, int32_t instr) {
   ASSERT(Utils::IsAligned(offset, 4));
   ASSERT(Utils::IsInt(18, offset));
 
@@ -58,12 +60,287 @@
 }
 
 
-int Assembler::DecodeBranchOffset(int32_t instr) {
+static int DecodeBranchOffset(int32_t instr) {
   // Sign-extend, left-shift by 2.
   return (((instr & kBranchOffsetMask) << 16) >> 14);
 }
 
 
+static int32_t DecodeLoadImmediate(int32_t ori_instr, int32_t lui_instr) {
+  return (((lui_instr & kBranchOffsetMask) << 16) |
+           (ori_instr & kBranchOffsetMask));
+}
+
+
+static int32_t EncodeLoadImmediate(int32_t dest, int32_t instr) {
+  return ((instr & ~kBranchOffsetMask) | (dest & kBranchOffsetMask));
+}
+
+
+class PatchFarJump : public AssemblerFixup {
+ public:
+  PatchFarJump() {}
+
+  void Process(const MemoryRegion& region, int position) {
+    const int32_t high = region.Load<int32_t>(position);
+    const int32_t low = region.Load<int32_t>(position + Instr::kInstrSize);
+    const int32_t offset = DecodeLoadImmediate(low, high);
+    const int32_t dest = region.start() + offset;
+
+    if ((Instr::At(reinterpret_cast<uword>(&high))->OpcodeField() == LUI) &&
+        (Instr::At(reinterpret_cast<uword>(&low))->OpcodeField() == ORI)) {
+      // Change the offset to the absolute value.
+      const int32_t encoded_low =
+          EncodeLoadImmediate(dest & kBranchOffsetMask, low);
+      const int32_t encoded_high =
+          EncodeLoadImmediate(dest >> 16, high);
+
+      region.Store<int32_t>(position, encoded_high);
+      region.Store<int32_t>(position + Instr::kInstrSize, encoded_low);
+      return;
+    }
+    // If the offset loading instructions aren't there, we must have replaced
+    // the far branch with a near one, and so these instructions should be NOPs.
+    ASSERT((high == Instr::kNopInstruction) && (low == Instr::kNopInstruction));
+  }
+};
+
+
+void Assembler::EmitFarJump(int32_t offset, bool link) {
+  const uint16_t low = Utils::Low16Bits(offset);
+  const uint16_t high = Utils::High16Bits(offset);
+  buffer_.EmitFixup(new PatchFarJump());
+  lui(TMP, Immediate(high));
+  ori(TMP, TMP, Immediate(low));
+  if (link) {
+    EmitRType(SPECIAL, TMP, R0, RA, 0, JALR);
+  } else {
+    EmitRType(SPECIAL, TMP, R0, R0, 0, JR);
+  }
+}
+
+
+static Opcode OppositeBranchOpcode(Opcode b) {
+  switch (b) {
+    case BEQ: return BNE;
+    case BNE: return BEQ;
+    case BGTZ: return BLEZ;
+    case BLEZ: return BGTZ;
+    case BEQL: return BNEL;
+    case BNEL: return BEQL;
+    case BGTZL: return BLEZL;
+    case BLEZL: return BGTZL;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  return BNE;
+}
+
+
+void Assembler::EmitFarBranch(Opcode b, Register rs, Register rt,
+                              int32_t offset) {
+  EmitIType(b, rs, rt, 4);
+  nop();
+  EmitFarJump(offset, false);
+}
+
+
+static RtRegImm OppositeBranchNoLink(RtRegImm b) {
+  switch (b) {
+    case BLTZ: return BGEZ;
+    case BGEZ: return BLTZ;
+    case BLTZAL: return BGEZ;
+    case BGEZAL: return BLTZ;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  return BLTZ;
+}
+
+
+void Assembler::EmitFarRegImmBranch(RtRegImm b, Register rs, int32_t offset) {
+  EmitRegImmType(REGIMM, rs, b, 4);
+  nop();
+  EmitFarJump(offset, (b == BLTZAL) || (b == BGEZAL));
+}
+
+
+void Assembler::EmitFarFpuBranch(bool kind, int32_t offset) {
+  const uint32_t b16 = kind ? (1 << 16) : 0;
+  Emit(COP1 << kOpcodeShift | COP1_BC << kCop1SubShift | b16 | 4);
+  nop();
+  EmitFarJump(offset, false);
+}
+
+
+void Assembler::EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
+  if (label->IsBound()) {
+    // Relative destination from an instruction after the branch.
+    const int32_t dest =
+        label->Position() - (buffer_.Size() + Instr::kInstrSize);
+    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+      EmitFarBranch(b, rs, rt, label->Position());
+    } else {
+      const uint16_t dest_off = EncodeBranchOffset(dest, 0);
+      EmitIType(b, rs, rt, dest_off);
+    }
+  } else {
+    const int position = buffer_.Size();
+    if (FLAG_use_far_branches) {
+      const uint32_t dest_off = label->position_;
+      EmitFarBranch(b, rs, rt, dest_off);
+    } else {
+      const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
+      EmitIType(b, rs, rt, dest_off);
+    }
+    label->LinkTo(position);
+  }
+}
+
+
+void Assembler::EmitRegImmBranch(RtRegImm b, Register rs, Label* label) {
+  if (label->IsBound()) {
+    // Relative destination from an instruction after the branch.
+    const int32_t dest =
+        label->Position() - (buffer_.Size() + Instr::kInstrSize);
+    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+      EmitFarRegImmBranch(b, rs, label->Position());
+    } else {
+      const uint16_t dest_off = EncodeBranchOffset(dest, 0);
+      EmitRegImmType(REGIMM, rs, b, dest_off);
+    }
+  } else {
+    const int position = buffer_.Size();
+    if (FLAG_use_far_branches) {
+      const uint32_t dest_off = label->position_;
+      EmitFarRegImmBranch(b, rs, dest_off);
+    } else {
+      const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
+      EmitRegImmType(REGIMM, rs, b, dest_off);
+    }
+    label->LinkTo(position);
+  }
+}
+
+
+void Assembler::EmitFpuBranch(bool kind, Label *label) {
+  const int32_t b16 = kind ? (1 << 16) : 0;  // Bit 16 set for branch on true.
+  if (label->IsBound()) {
+    // Relative destination from an instruction after the branch.
+    const int32_t dest =
+        label->Position() - (buffer_.Size() + Instr::kInstrSize);
+    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+      EmitFarFpuBranch(kind, label->Position());
+    } else {
+      const uint16_t dest_off = EncodeBranchOffset(dest, 0);
+      Emit(COP1 << kOpcodeShift |
+           COP1_BC << kCop1SubShift |
+           b16 |
+           dest_off);
+    }
+  } else {
+    const int position = buffer_.Size();
+    if (FLAG_use_far_branches) {
+      const uint32_t dest_off = label->position_;
+      EmitFarFpuBranch(kind, dest_off);
+    } else {
+      const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
+      Emit(COP1 << kOpcodeShift |
+           COP1_BC << kCop1SubShift |
+           b16 |
+           dest_off);
+    }
+    label->LinkTo(position);
+  }
+}
+
+
+static int32_t FlipBranchInstruction(int32_t instr) {
+  Instr* i = Instr::At(reinterpret_cast<uword>(&instr));
+  if (i->OpcodeField() == REGIMM) {
+    RtRegImm b = OppositeBranchNoLink(i->RegImmFnField());
+    i->SetRegImmFnField(b);
+    return i->InstructionBits();
+  } else if (i->OpcodeField() == COP1) {
+    return instr ^ (1 << 16);
+  }
+  Opcode b = OppositeBranchOpcode(i->OpcodeField());
+  i->SetOpcodeField(b);
+  return i->InstructionBits();
+}
+
+
+void Assembler::Bind(Label* label) {
+  ASSERT(!label->IsBound());
+  int bound_pc = buffer_.Size();
+
+  while (label->IsLinked()) {
+    int32_t position = label->Position();
+    int32_t dest = bound_pc - (position + Instr::kInstrSize);
+
+    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+      // Far branches are enabled and we can't encode the branch offset.
+
+      // Grab the branch instruction. We'll need to flip it later.
+      const int32_t branch = buffer_.Load<int32_t>(position);
+
+      // Grab instructions that load the offset.
+      const int32_t high =
+          buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize);
+      const int32_t low =
+          buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize);
+
+      // Change from relative to the branch to relative to the assembler buffer.
+      dest = buffer_.Size();
+      const int32_t encoded_low =
+          EncodeLoadImmediate(dest & kBranchOffsetMask, low);
+      const int32_t encoded_high =
+          EncodeLoadImmediate(dest >> 16, high);
+
+      // Skip the unconditional far jump if the test fails by flipping the
+      // sense of the branch instruction.
+      buffer_.Store<int32_t>(position, FlipBranchInstruction(branch));
+      buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, encoded_high);
+      buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, encoded_low);
+      label->position_ = DecodeLoadImmediate(low, high);
+    } else if (FLAG_use_far_branches && CanEncodeBranchOffset(dest)) {
+      // We assembled a far branch, but we don't need it. Replace with a near
+      // branch.
+
+      // Grab the link to the next branch.
+      const int32_t high =
+          buffer_.Load<int32_t>(position + 2 * Instr::kInstrSize);
+      const int32_t low =
+          buffer_.Load<int32_t>(position + 3 * Instr::kInstrSize);
+
+      // Grab the original branch instruction.
+      int32_t branch = buffer_.Load<int32_t>(position);
+
+      // Clear out the old (far) branch.
+      for (int i = 0; i < 5; i++) {
+        buffer_.Store<int32_t>(position + i * Instr::kInstrSize,
+            Instr::kNopInstruction);
+      }
+
+      // Calculate the new offset.
+      dest = dest - 4 * Instr::kInstrSize;
+      const int32_t encoded = EncodeBranchOffset(dest, branch);
+      buffer_.Store<int32_t>(position + 4 * Instr::kInstrSize, encoded);
+      label->position_ = DecodeLoadImmediate(low, high);
+    } else {
+      const int32_t next = buffer_.Load<int32_t>(position);
+      const int32_t encoded = EncodeBranchOffset(dest, next);
+      buffer_.Store<int32_t>(position, encoded);
+      label->position_ = DecodeBranchOffset(next);
+    }
+  }
+  label->BindTo(bound_pc);
+  delay_slot_available_ = false;
+}
+
+
 void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) {
   ASSERT(rd != PP);
   if (Address::CanHoldOffset(offset)) {
@@ -231,8 +508,8 @@
   // if the bit is not set. We can't destroy the object.
   nor(TMP1, ZR, object);
   and_(TMP1, value, TMP1);
-  andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
-  beq(TMP1, ZR, no_update);
+  andi(CMPRES1, TMP1, Immediate(kNewObjectAlignmentOffset));
+  beq(CMPRES1, ZR, no_update);
 }
 
 
@@ -245,10 +522,10 @@
   sll(TMP1, value, kObjectAlignmentLog2 - 1);
   and_(TMP1, value, TMP1);
   // And the result with the negated space bit of the object.
-  nor(CMPRES, ZR, object);
-  and_(TMP1, TMP1, CMPRES);
-  andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
-  beq(TMP1, ZR, no_update);
+  nor(CMPRES1, ZR, object);
+  and_(TMP1, TMP1, CMPRES1);
+  andi(CMPRES1, TMP1, Immediate(kNewObjectAlignmentOffset));
+  beq(CMPRES1, ZR, no_update);
 }
 
 
@@ -359,15 +636,13 @@
     sw(PP, Address(SP, 0 * kWordSize));
     addiu(FP, SP, Immediate(1 * kWordSize));
     // Setup pool pointer for this stub.
-    Label next;
-    bal(&next);
-    delay_slot()->mov(TMP1, RA);
+
+    GetNextPC(TMP1);  // TMP1 gets the address of the next instruction.
 
     const intptr_t object_pool_pc_dist =
         Instructions::HeaderSize() - Instructions::object_pool_offset() +
         CodeSize();
 
-    Bind(&next);
     lw(PP, Address(TMP1, -object_pool_pc_dist));
   } else {
     addiu(SP, SP, Immediate(-3 * kWordSize));
@@ -465,20 +740,13 @@
   sw(FP, Address(SP, 1 * kWordSize));
   sw(PP, Address(SP, 0 * kWordSize));
 
-  Label next;
-  // Branch and link to the instruction after the delay slot to get the PC.
-  bal(&next);
-  // RA is the address of the sw instruction below. Save it in T0.
-  delay_slot()->mov(TMP1, RA);
+  GetNextPC(TMP1);  // TMP1 gets the address of the next instruction.
 
   // Calculate the offset of the pool pointer from the PC.
   const intptr_t object_pool_pc_dist =
       Instructions::HeaderSize() - Instructions::object_pool_offset() +
       CodeSize();
 
-  // TMP1 has the address of the next instruction.
-  Bind(&next);
-
   // Save PC in frame for fast identification of corresponding code.
   AddImmediate(TMP1, -offset);
   sw(TMP1, Address(SP, 3 * kWordSize));
@@ -501,11 +769,8 @@
 // allocate. We must also set up the pool pointer for the function.
 void Assembler::EnterOsrFrame(intptr_t extra_size) {
   Comment("EnterOsrFrame");
-  Label next;
-  // Branch and link to the instruction after the delay slot to get the PC.
-  bal(&next);
-  // RA is the address of the sw instruction below. Save it in T0.
-  delay_slot()->mov(TMP, RA);
+
+  GetNextPC(TMP);  // TMP gets the address of the next instruction.
 
   // The runtime system assumes that the code marker address is
   // kEntryPointToPcMarkerOffset bytes from the entry.  Since there is no
@@ -516,9 +781,6 @@
       Instructions::HeaderSize() - Instructions::object_pool_offset() +
       CodeSize();
 
-  // temp has the address of the next instruction.
-  Bind(&next);
-
   // Adjust PC by the offset, and store it in the stack frame.
   AddImmediate(TMP, TMP, offset);
   sw(TMP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 91fa899..d2cb44f 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -22,6 +22,8 @@
 //   The MIPS32® Instruction Set" in short "VolII-A"
 namespace dart {
 
+DECLARE_FLAG(bool, use_far_branches);
+
 // Forward declarations.
 class RuntimeEntry;
 
@@ -854,76 +856,80 @@
   }
 
   void BranchEqual(Register rd, int32_t value, Label* l) {
-    ASSERT(rd != CMPRES);
-    LoadImmediate(CMPRES, value);
-    beq(rd, CMPRES, l);
+    ASSERT(rd != CMPRES2);
+    LoadImmediate(CMPRES2, value);
+    beq(rd, CMPRES2, l);
   }
 
   void BranchEqual(Register rd, const Object& object, Label* l) {
-    ASSERT(rd != CMPRES);
-    LoadObject(CMPRES, object);
-    beq(rd, CMPRES, l);
+    ASSERT(rd != CMPRES2);
+    LoadObject(CMPRES2, object);
+    beq(rd, CMPRES2, l);
   }
 
   void BranchNotEqual(Register rd, int32_t value, Label* l) {
-    ASSERT(rd != CMPRES);
-    LoadImmediate(CMPRES, value);
-    bne(rd, CMPRES, l);
+    ASSERT(rd != CMPRES2);
+    LoadImmediate(CMPRES2, value);
+    bne(rd, CMPRES2, l);
   }
 
   void BranchNotEqual(Register rd, const Object& object, Label* l) {
-    ASSERT(rd != CMPRES);
-    LoadObject(CMPRES, object);
-    bne(rd, CMPRES, l);
+    ASSERT(rd != CMPRES2);
+    LoadObject(CMPRES2, object);
+    bne(rd, CMPRES2, l);
   }
 
   void BranchSignedGreater(Register rd, Register rs, Label* l) {
-    slt(CMPRES, rs, rd);  // CMPRES = rd > rs ? 1 : 0.
-    bne(CMPRES, ZR, l);
+    slt(CMPRES2, rs, rd);  // CMPRES2 = rd > rs ? 1 : 0.
+    bne(CMPRES2, ZR, l);
   }
 
   void BranchSignedGreater(Register rd, int32_t value, Label* l) {
-    LoadImmediate(CMPRES, value);
-    BranchSignedGreater(rd, CMPRES, l);
+    ASSERT(rd != CMPRES2);
+    LoadImmediate(CMPRES2, value);
+    BranchSignedGreater(rd, CMPRES2, l);
   }
 
   void BranchUnsignedGreater(Register rd, Register rs, Label* l) {
-    sltu(CMPRES, rs, rd);
-    bne(CMPRES, ZR, l);
+    sltu(CMPRES2, rs, rd);
+    bne(CMPRES2, ZR, l);
   }
 
   void BranchUnsignedGreater(Register rd, int32_t value, Label* l) {
-    LoadImmediate(CMPRES, value);
-    BranchUnsignedGreater(rd, CMPRES, l);
+    ASSERT(rd != CMPRES2);
+    LoadImmediate(CMPRES2, value);
+    BranchUnsignedGreater(rd, CMPRES2, l);
   }
 
   void BranchSignedGreaterEqual(Register rd, Register rs, Label* l) {
-    slt(CMPRES, rd, rs);  // CMPRES = rd < rs ? 1 : 0.
-    beq(CMPRES, ZR, l);  // If CMPRES = 0, then rd >= rs.
+    slt(CMPRES2, rd, rs);  // CMPRES2 = rd < rs ? 1 : 0.
+    beq(CMPRES2, ZR, l);  // If CMPRES2 = 0, then rd >= rs.
   }
 
   void BranchSignedGreaterEqual(Register rd, int32_t value, Label* l) {
     if (Utils::IsInt(kImmBits, value)) {
-      slti(CMPRES, rd, Immediate(value));
-      beq(CMPRES, ZR, l);
+      slti(CMPRES2, rd, Immediate(value));
+      beq(CMPRES2, ZR, l);
     } else {
-      LoadImmediate(CMPRES, value);
-      BranchSignedGreaterEqual(rd, CMPRES, l);
+      ASSERT(rd != CMPRES2);
+      LoadImmediate(CMPRES2, value);
+      BranchSignedGreaterEqual(rd, CMPRES2, l);
     }
   }
 
   void BranchUnsignedGreaterEqual(Register rd, Register rs, Label* l) {
-    sltu(CMPRES, rd, rs);  // CMPRES = rd < rs ? 1 : 0.
-    beq(CMPRES, ZR, l);
+    sltu(CMPRES2, rd, rs);  // CMPRES2 = rd < rs ? 1 : 0.
+    beq(CMPRES2, ZR, l);
   }
 
   void BranchUnsignedGreaterEqual(Register rd, int32_t value, Label* l) {
     if (Utils::IsUint(kImmBits, value)) {
-      sltiu(CMPRES, rd, Immediate(value));
-      beq(CMPRES, ZR, l);
+      sltiu(CMPRES2, rd, Immediate(value));
+      beq(CMPRES2, ZR, l);
     } else {
-      LoadImmediate(CMPRES, value);
-      BranchUnsignedGreaterEqual(rd, CMPRES, l);
+      ASSERT(rd != CMPRES2);
+      LoadImmediate(CMPRES2, value);
+      BranchUnsignedGreaterEqual(rd, CMPRES2, l);
     }
   }
 
@@ -933,11 +939,12 @@
 
   void BranchSignedLess(Register rd, int32_t value, Label* l) {
     if (Utils::IsInt(kImmBits, value)) {
-      slti(CMPRES, rd, Immediate(value));
-      bne(CMPRES, ZR, l);
+      slti(CMPRES2, rd, Immediate(value));
+      bne(CMPRES2, ZR, l);
     } else {
-      LoadImmediate(CMPRES, value);
-      BranchSignedGreater(CMPRES, rd, l);
+      ASSERT(rd != CMPRES2);
+      LoadImmediate(CMPRES2, value);
+      BranchSignedGreater(CMPRES2, rd, l);
     }
   }
 
@@ -947,11 +954,12 @@
 
   void BranchUnsignedLess(Register rd, int32_t value, Label* l) {
     if (Utils::IsUint(kImmBits, value)) {
-      sltiu(CMPRES, rd, Immediate(value));
-      bne(CMPRES, ZR, l);
+      sltiu(CMPRES2, rd, Immediate(value));
+      bne(CMPRES2, ZR, l);
     } else {
-      LoadImmediate(CMPRES, value);
-      BranchUnsignedGreater(CMPRES, rd, l);
+      ASSERT(rd != CMPRES2);
+      LoadImmediate(CMPRES2, value);
+      BranchUnsignedGreater(CMPRES2, rd, l);
     }
   }
 
@@ -960,8 +968,9 @@
   }
 
   void BranchSignedLessEqual(Register rd, int32_t value, Label* l) {
-    LoadImmediate(CMPRES, value);
-    BranchSignedGreaterEqual(CMPRES, rd, l);
+    ASSERT(rd != CMPRES2);
+    LoadImmediate(CMPRES2, value);
+    BranchSignedGreaterEqual(CMPRES2, rd, l);
   }
 
   void BranchUnsignedLessEqual(Register rd, Register rs, Label* l) {
@@ -969,8 +978,9 @@
   }
 
   void BranchUnsignedLessEqual(Register rd, int32_t value, Label* l) {
-    LoadImmediate(CMPRES, value);
-    BranchUnsignedGreaterEqual(CMPRES, rd, l);
+    ASSERT(rd != CMPRES2);
+    LoadImmediate(CMPRES2, value);
+    BranchUnsignedGreaterEqual(CMPRES2, rd, l);
   }
 
   void Push(Register rt) {
@@ -1029,6 +1039,10 @@
     lwc1(hi, Address(base, offset + kWordSize));
   }
 
+  // dest gets the address of the following instruction. If temp is given,
+  // RA is preserved using it as a temporary.
+  void GetNextPC(Register dest, Register temp = kNoRegister);
+
   void ReserveAlignedFrameSpace(intptr_t frame_space);
 
   // Create a frame for calling into runtime that preserves all volatile
@@ -1182,60 +1196,14 @@
          func << kCop1FnShift);
   }
 
-  void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
-    if (label->IsBound()) {
-      // Relative destination from an instruction after the branch.
-      const int32_t dest =
-          label->Position() - (buffer_.Size() + Instr::kInstrSize);
-      const uint16_t dest_off = EncodeBranchOffset(dest, 0);
-      EmitIType(b, rs, rt, dest_off);
-    } else {
-      const int position = buffer_.Size();
-      const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
-      EmitIType(b, rs, rt, dest_off);
-      label->LinkTo(position);
-    }
-  }
 
-  void EmitRegImmBranch(RtRegImm b, Register rs, Label* label) {
-    if (label->IsBound()) {
-      // Relative destination from an instruction after the branch.
-      const int32_t dest =
-          label->Position() - (buffer_.Size() + Instr::kInstrSize);
-      const uint16_t dest_off = EncodeBranchOffset(dest, 0);
-      EmitRegImmType(REGIMM, rs, b, dest_off);
-    } else {
-      const int position = buffer_.Size();
-      const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
-      EmitRegImmType(REGIMM, rs, b, dest_off);
-      label->LinkTo(position);
-    }
-  }
-
-  void EmitFpuBranch(bool kind, Label *label) {
-    const int32_t b16 = kind ? (1 << 16) : 0;  // Bit 16 set for branch on true.
-    if (label->IsBound()) {
-      // Relative destination from an instruction after the branch.
-      const int32_t dest =
-          label->Position() - (buffer_.Size() + Instr::kInstrSize);
-      const uint16_t dest_off = EncodeBranchOffset(dest, 0);
-      Emit(COP1 << kOpcodeShift |
-           COP1_BC << kCop1SubShift |
-           b16 |
-           dest_off);
-    } else {
-      const int position = buffer_.Size();
-      const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
-      Emit(COP1 << kOpcodeShift |
-           COP1_BC << kCop1SubShift |
-           b16 |
-           dest_off);
-      label->LinkTo(position);
-    }
-  }
-
-  static int32_t EncodeBranchOffset(int32_t offset, int32_t instr);
-  static int DecodeBranchOffset(int32_t instr);
+  void EmitFarJump(int32_t offset, bool link);
+  void EmitFarBranch(Opcode b, Register rs, Register rt, int32_t offset);
+  void EmitFarRegImmBranch(RtRegImm b, Register rs, int32_t offset);
+  void EmitFarFpuBranch(bool kind, int32_t offset);
+  void EmitBranch(Opcode b, Register rs, Register rt, Label* label);
+  void EmitRegImmBranch(RtRegImm b, Register rs, Label* label);
+  void EmitFpuBranch(bool kind, Label *label);
 
   void EmitBranchDelayNop() {
     Emit(Instr::kNopInstruction);  // Branch delay NOP.
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 0e9185a..620c17d 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -53,9 +53,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Addu, assembler) {
-  __ addiu(R2, ZR, Immediate(21));
-  __ addiu(R3, ZR, Immediate(21));
-  __ addu(V0, R2, R3);
+  __ addiu(T2, ZR, Immediate(21));
+  __ addiu(T3, ZR, Immediate(21));
+  __ addu(V0, T2, T3);
   __ jr(RA);
 }
 
@@ -67,9 +67,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Addu_overflow, assembler) {
-  __ LoadImmediate(R2, 0x7fffffff);
-  __ addiu(R3, R0, Immediate(1));
-  __ addu(V0, R2, R3);
+  __ LoadImmediate(T2, 0x7fffffff);
+  __ addiu(T3, R0, Immediate(1));
+  __ addu(V0, T2, T3);
   __ jr(RA);
 }
 
@@ -82,9 +82,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(And, assembler) {
-  __ addiu(R2, ZR, Immediate(42));
-  __ addiu(R3, ZR, Immediate(2));
-  __ and_(V0, R2, R3);
+  __ addiu(T2, ZR, Immediate(42));
+  __ addiu(T3, ZR, Immediate(2));
+  __ and_(V0, T2, T3);
   __ jr(RA);
 }
 
@@ -96,8 +96,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Andi, assembler) {
-  __ addiu(R1, ZR, Immediate(42));
-  __ andi(V0, R1, Immediate(2));
+  __ addiu(T1, ZR, Immediate(42));
+  __ andi(V0, T1, Immediate(2));
   __ jr(RA);
 }
 
@@ -109,8 +109,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Clo, assembler) {
-  __ addiu(R1, ZR, Immediate(-1));
-  __ clo(V0, R1);
+  __ addiu(T1, ZR, Immediate(-1));
+  __ clo(V0, T1);
   __ jr(RA);
 }
 
@@ -122,8 +122,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Clz, assembler) {
-  __ addiu(R1, ZR, Immediate(0x7fff));
-  __ clz(V0, R1);
+  __ addiu(T1, ZR, Immediate(0x7fff));
+  __ clz(V0, T1);
   __ jr(RA);
 }
 
@@ -163,9 +163,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Divu, assembler) {
-  __ addiu(R1, ZR, Immediate(27));
-  __ addiu(R2, ZR, Immediate(9));
-  __ divu(R1, R2);
+  __ addiu(T1, ZR, Immediate(27));
+  __ addiu(T2, ZR, Immediate(9));
+  __ divu(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -178,9 +178,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Div, assembler) {
-  __ addiu(R1, ZR, Immediate(27));
-  __ addiu(R2, ZR, Immediate(9));
-  __ div(R1, R2);
+  __ addiu(T1, ZR, Immediate(27));
+  __ addiu(T2, ZR, Immediate(9));
+  __ div(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -193,9 +193,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Divu_corner, assembler) {
-  __ LoadImmediate(R1, 0x80000000);
-  __ LoadImmediate(R2, 0xffffffff);
-  __ divu(R1, R2);
+  __ LoadImmediate(T1, 0x80000000);
+  __ LoadImmediate(T2, 0xffffffff);
+  __ divu(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -208,9 +208,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Div_corner, assembler) {
-  __ LoadImmediate(R1, 0x80000000);
-  __ LoadImmediate(R2, 0xffffffff);
-  __ div(R1, R2);
+  __ LoadImmediate(T1, 0x80000000);
+  __ LoadImmediate(T2, 0xffffffff);
+  __ div(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -225,8 +225,8 @@
 
 ASSEMBLER_TEST_GENERATE(Lb, assembler) {
   __ addiu(SP, SP, Immediate(-kWordSize * 30));
-  __ LoadImmediate(R1, 0xff);
-  __ sb(R1, Address(SP));
+  __ LoadImmediate(T1, 0xff);
+  __ sb(T1, Address(SP));
   __ lb(V0, Address(SP));
   __ addiu(SP, SP, Immediate(kWordSize * 30));
   __ jr(RA);
@@ -241,8 +241,8 @@
 
 ASSEMBLER_TEST_GENERATE(Lb_offset, assembler) {
   __ addiu(SP, SP, Immediate(-kWordSize * 30));
-  __ LoadImmediate(R1, 0xff);
-  __ sb(R1, Address(SP, 1));
+  __ LoadImmediate(T1, 0xff);
+  __ sb(T1, Address(SP, 1));
   __ lb(V0, Address(SP, 1));
   __ addiu(SP, SP, Immediate(kWordSize * 30));
   __ jr(RA);
@@ -257,8 +257,8 @@
 
 ASSEMBLER_TEST_GENERATE(Lbu, assembler) {
   __ addiu(SP, SP, Immediate(-kWordSize * 30));
-  __ LoadImmediate(R1, 0xff);
-  __ sb(R1, Address(SP));
+  __ LoadImmediate(T1, 0xff);
+  __ sb(T1, Address(SP));
   __ lbu(V0, Address(SP));
   __ addiu(SP, SP, Immediate(kWordSize * 30));
   __ jr(RA);
@@ -273,8 +273,8 @@
 
 ASSEMBLER_TEST_GENERATE(Lh, assembler) {
   __ addiu(SP, SP, Immediate(-kWordSize * 30));
-  __ LoadImmediate(R1, 0xffff);
-  __ sh(R1, Address(SP));
+  __ LoadImmediate(T1, 0xffff);
+  __ sh(T1, Address(SP));
   __ lh(V0, Address(SP));
   __ addiu(SP, SP, Immediate(kWordSize * 30));
   __ jr(RA);
@@ -289,8 +289,8 @@
 
 ASSEMBLER_TEST_GENERATE(Lhu, assembler) {
   __ addiu(SP, SP, Immediate(-kWordSize * 30));
-  __ LoadImmediate(R1, 0xffff);
-  __ sh(R1, Address(SP));
+  __ LoadImmediate(T1, 0xffff);
+  __ sh(T1, Address(SP));
   __ lhu(V0, Address(SP));
   __ addiu(SP, SP, Immediate(kWordSize * 30));
   __ jr(RA);
@@ -305,8 +305,8 @@
 
 ASSEMBLER_TEST_GENERATE(Lw, assembler) {
   __ addiu(SP, SP, Immediate(-kWordSize * 30));
-  __ LoadImmediate(R1, -1);
-  __ sw(R1, Address(SP));
+  __ LoadImmediate(T1, -1);
+  __ sw(T1, Address(SP));
   __ lw(V0, Address(SP));
   __ addiu(SP, SP, Immediate(kWordSize * 30));
   __ jr(RA);
@@ -332,8 +332,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sll, assembler) {
-  __ LoadImmediate(R1, 21);
-  __ sll(V0, R1, 1);
+  __ LoadImmediate(T1, 21);
+  __ sll(V0, T1, 1);
   __ jr(RA);
 }
 
@@ -345,8 +345,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Srl, assembler) {
-  __ LoadImmediate(R1, 84);
-  __ srl(V0, R1, 1);
+  __ LoadImmediate(T1, 84);
+  __ srl(V0, T1, 1);
   __ jr(RA);
 }
 
@@ -358,9 +358,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(LShifting, assembler) {
-  __ LoadImmediate(R1, 1);
-  __ sll(R1, R1, 31);
-  __ srl(V0, R1, 31);
+  __ LoadImmediate(T1, 1);
+  __ sll(T1, T1, 31);
+  __ srl(V0, T1, 31);
   __ jr(RA);
 }
 
@@ -372,9 +372,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(RShifting, assembler) {
-  __ LoadImmediate(R1, 1);
-  __ sll(R1, R1, 31);
-  __ sra(V0, R1, 31);
+  __ LoadImmediate(T1, 1);
+  __ sll(T1, T1, 31);
+  __ sra(V0, T1, 31);
   __ jr(RA);
 }
 
@@ -386,9 +386,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sllv, assembler) {
-  __ LoadImmediate(R1, 21);
-  __ LoadImmediate(R2, 1);
-  __ sllv(V0, R1, R2);
+  __ LoadImmediate(T1, 21);
+  __ LoadImmediate(T2, 1);
+  __ sllv(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -400,9 +400,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Srlv, assembler) {
-  __ LoadImmediate(R1, 84);
-  __ LoadImmediate(R2, 1);
-  __ srlv(V0, R1, R2);
+  __ LoadImmediate(T1, 84);
+  __ LoadImmediate(T2, 1);
+  __ srlv(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -414,10 +414,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(LShiftingV, assembler) {
-  __ LoadImmediate(R1, 1);
-  __ LoadImmediate(R2, 31);
-  __ sllv(R1, R1, R2);
-  __ srlv(V0, R1, R2);
+  __ LoadImmediate(T1, 1);
+  __ LoadImmediate(T2, 31);
+  __ sllv(T1, T1, T2);
+  __ srlv(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -429,10 +429,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(RShiftingV, assembler) {
-  __ LoadImmediate(R1, 1);
-  __ LoadImmediate(R2, 31);
-  __ sllv(R1, R1, R2);
-  __ srav(V0, R1, R2);
+  __ LoadImmediate(T1, 1);
+  __ LoadImmediate(T2, 31);
+  __ sllv(T1, T1, T2);
+  __ srav(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -444,9 +444,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Mult_pos, assembler) {
-  __ LoadImmediate(R1, 6);
-  __ LoadImmediate(R2, 7);
-  __ mult(R1, R2);
+  __ LoadImmediate(T1, 6);
+  __ LoadImmediate(T2, 7);
+  __ mult(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -459,9 +459,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Mult_neg, assembler) {
-  __ LoadImmediate(R1, -6);
-  __ LoadImmediate(R2, 7);
-  __ mult(R1, R2);
+  __ LoadImmediate(T1, -6);
+  __ LoadImmediate(T2, 7);
+  __ mult(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -474,9 +474,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Mult_neg_hi, assembler) {
-  __ LoadImmediate(R1, -6);
-  __ LoadImmediate(R2, 7);
-  __ mult(R1, R2);
+  __ LoadImmediate(T1, -6);
+  __ LoadImmediate(T2, 7);
+  __ mult(T1, T2);
   __ mfhi(V0);
   __ jr(RA);
 }
@@ -489,9 +489,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Multu_lo, assembler) {
-  __ LoadImmediate(R1, 6);
-  __ LoadImmediate(R2, 7);
-  __ multu(R1, R2);
+  __ LoadImmediate(T1, 6);
+  __ LoadImmediate(T2, 7);
+  __ multu(T1, T2);
   __ mflo(V0);
   __ jr(RA);
 }
@@ -504,9 +504,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Multu_hi, assembler) {
-  __ LoadImmediate(R1, 65536);
-  __ LoadImmediate(R2, 65536);
-  __ multu(R1, R2);
+  __ LoadImmediate(T1, 65536);
+  __ LoadImmediate(T2, 65536);
+  __ multu(T1, T2);
   __ mfhi(V0);
   __ jr(RA);
 }
@@ -519,10 +519,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(Madd_neg, assembler) {
-  __ LoadImmediate(R1, -6);
-  __ LoadImmediate(R2, 7);
-  __ mult(R1, R2);
-  __ madd(R1, R2);
+  __ LoadImmediate(T1, -6);
+  __ LoadImmediate(T2, 7);
+  __ mult(T1, T2);
+  __ madd(T1, T2);
   __ mflo(V0);
   __ mfhi(V1);
   __ jr(RA);
@@ -536,9 +536,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Subu, assembler) {
-  __ LoadImmediate(R1, 737);
-  __ LoadImmediate(R2, 695);
-  __ subu(V0, R1, R2);
+  __ LoadImmediate(T1, 737);
+  __ LoadImmediate(T2, 695);
+  __ subu(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -550,9 +550,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Or, assembler) {
-  __ LoadImmediate(R1, 34);
-  __ LoadImmediate(R2, 8);
-  __ or_(V0, R1, R2);
+  __ LoadImmediate(T1, 34);
+  __ LoadImmediate(T2, 8);
+  __ or_(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -564,9 +564,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Nor, assembler) {
-  __ LoadImmediate(R1, -47);
-  __ LoadImmediate(R2, -60);
-  __ nor(V0, R1, R2);
+  __ LoadImmediate(T1, -47);
+  __ LoadImmediate(T2, -60);
+  __ nor(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -578,9 +578,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Xor, assembler) {
-  __ LoadImmediate(R1, 51);
-  __ LoadImmediate(R2, 25);
-  __ xor_(V0, R1, R2);
+  __ LoadImmediate(T1, 51);
+  __ LoadImmediate(T2, 25);
+  __ xor_(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -605,9 +605,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Slt, assembler) {
-  __ LoadImmediate(R1, -1);
-  __ LoadImmediate(R2, 0);
-  __ slt(V0, R1, R2);
+  __ LoadImmediate(T1, -1);
+  __ LoadImmediate(T2, 0);
+  __ slt(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -619,9 +619,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Sltu, assembler) {
-  __ LoadImmediate(R1, -1);
-  __ LoadImmediate(R2, 0);
-  __ sltu(V0, R1, R2);
+  __ LoadImmediate(T1, -1);
+  __ LoadImmediate(T2, 0);
+  __ sltu(V0, T1, T2);
   __ jr(RA);
 }
 
@@ -633,10 +633,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(Movz, assembler) {
-  __ LoadImmediate(R1, 42);
-  __ LoadImmediate(R2, 23);
-  __ slt(R3, R1, R2);
-  __ movz(V0, R1, R3);
+  __ LoadImmediate(T1, 42);
+  __ LoadImmediate(T2, 23);
+  __ slt(T3, T1, T2);
+  __ movz(V0, T1, T3);
   __ jr(RA);
 }
 
@@ -648,10 +648,10 @@
 
 
 ASSEMBLER_TEST_GENERATE(Movn, assembler) {
-  __ LoadImmediate(R1, 42);
-  __ LoadImmediate(R2, 23);
-  __ slt(R3, R2, R1);
-  __ movn(V0, R1, R3);
+  __ LoadImmediate(T1, 42);
+  __ LoadImmediate(T2, 23);
+  __ slt(T3, T2, T1);
+  __ movn(V0, T1, T3);
   __ jr(RA);
 }
 
@@ -677,12 +677,12 @@
 ASSEMBLER_TEST_GENERATE(Beq_backward, assembler) {
   Label l;
 
-  __ LoadImmediate(R1, 0);
-  __ LoadImmediate(R2, 1);
+  __ LoadImmediate(T1, 0);
+  __ LoadImmediate(T2, 1);
   __ Bind(&l);
-  __ addiu(R1, R1, Immediate(1));
-  __ beq(R1, R2, &l);
-  __ ori(V0, R1, Immediate(0));
+  __ addiu(T1, T1, Immediate(1));
+  __ beq(T1, T2, &l);
+  __ ori(V0, T1, Immediate(0));
   __ jr(RA);
 }
 
@@ -696,13 +696,13 @@
 ASSEMBLER_TEST_GENERATE(Beq_backward_delay, assembler) {
   Label l;
 
-  __ LoadImmediate(R1, 0);
-  __ LoadImmediate(R2, 1);
+  __ LoadImmediate(T1, 0);
+  __ LoadImmediate(T2, 1);
   __ Bind(&l);
-  __ addiu(R1, R1, Immediate(1));
-  __ beq(R1, R2, &l);
-  __ delay_slot()->addiu(R1, R1, Immediate(1));
-  __ ori(V0, R1, Immediate(0));
+  __ addiu(T1, T1, Immediate(1));
+  __ beq(T1, T2, &l);
+  __ delay_slot()->addiu(T1, T1, Immediate(1));
+  __ ori(V0, T1, Immediate(0));
   __ jr(RA);
 }
 
@@ -716,11 +716,11 @@
 ASSEMBLER_TEST_GENERATE(Beq_forward_taken, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 1);
-  __ LoadImmediate(R6, 1);
+  __ LoadImmediate(T5, 1);
+  __ LoadImmediate(T6, 1);
 
   __ LoadImmediate(V0, 42);
-  __ beq(R5, R6, &l);
+  __ beq(T5, T6, &l);
   __ LoadImmediate(V0, 0);
   __ Bind(&l);
   __ jr(RA);
@@ -736,11 +736,11 @@
 ASSEMBLER_TEST_GENERATE(Beq_forward_not_taken, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 0);
-  __ LoadImmediate(R6, 1);
+  __ LoadImmediate(T5, 0);
+  __ LoadImmediate(T6, 1);
 
   __ LoadImmediate(V0, 42);
-  __ beq(R5, R6, &l);
+  __ beq(T5, T6, &l);
   __ LoadImmediate(V0, 0);
   __ Bind(&l);
   __ jr(RA);
@@ -756,11 +756,11 @@
 ASSEMBLER_TEST_GENERATE(Beq_forward_taken2, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 1);
-  __ LoadImmediate(R6, 1);
+  __ LoadImmediate(T5, 1);
+  __ LoadImmediate(T6, 1);
 
   __ LoadImmediate(V0, 42);
-  __ beq(R5, R6, &l);
+  __ beq(T5, T6, &l);
   __ nop();
   __ nop();
   __ LoadImmediate(V0, 0);
@@ -778,11 +778,11 @@
 ASSEMBLER_TEST_GENERATE(Beq_forward_taken_delay, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 1);
-  __ LoadImmediate(R6, 1);
+  __ LoadImmediate(T5, 1);
+  __ LoadImmediate(T6, 1);
 
   __ LoadImmediate(V0, 42);
-  __ beq(R5, R6, &l);
+  __ beq(T5, T6, &l);
   __ delay_slot()->ori(V0, V0, Immediate(1));
   __ LoadImmediate(V0, 0);
   __ Bind(&l);
@@ -799,11 +799,11 @@
 ASSEMBLER_TEST_GENERATE(Beq_forward_not_taken_delay, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 0);
-  __ LoadImmediate(R6, 1);
+  __ LoadImmediate(T5, 0);
+  __ LoadImmediate(T6, 1);
 
   __ LoadImmediate(V0, 42);
-  __ beq(R5, R6, &l);
+  __ beq(T5, T6, &l);
   __ delay_slot()->ori(V0, V0, Immediate(1));
   __ addiu(V0, V0, Immediate(1));
   __ Bind(&l);
@@ -820,13 +820,13 @@
 ASSEMBLER_TEST_GENERATE(Beql_backward_delay, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 0);
-  __ LoadImmediate(R6, 1);
+  __ LoadImmediate(T5, 0);
+  __ LoadImmediate(T6, 1);
   __ Bind(&l);
-  __ addiu(R5, R5, Immediate(1));
-  __ beql(R5, R6, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(1));
-  __ ori(V0, R5, Immediate(0));
+  __ addiu(T5, T5, Immediate(1));
+  __ beql(T5, T6, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -840,11 +840,11 @@
 ASSEMBLER_TEST_GENERATE(Bgez, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 3);
+  __ LoadImmediate(T5, 3);
   __ Bind(&l);
-  __ bgez(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(-1));
-  __ ori(V0, R5, Immediate(0));
+  __ bgez(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(-1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -858,11 +858,11 @@
 ASSEMBLER_TEST_GENERATE(Bgezl, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 3);
+  __ LoadImmediate(T5, 3);
   __ Bind(&l);
-  __ bgezl(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(-1));
-  __ ori(V0, R5, Immediate(0));
+  __ bgezl(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(-1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -876,11 +876,11 @@
 ASSEMBLER_TEST_GENERATE(Blez, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, -3);
+  __ LoadImmediate(T5, -3);
   __ Bind(&l);
-  __ blez(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(1));
-  __ ori(V0, R5, Immediate(0));
+  __ blez(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -894,11 +894,11 @@
 ASSEMBLER_TEST_GENERATE(Blezl, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, -3);
+  __ LoadImmediate(T5, -3);
   __ Bind(&l);
-  __ blezl(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(1));
-  __ ori(V0, R5, Immediate(0));
+  __ blezl(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -912,11 +912,11 @@
 ASSEMBLER_TEST_GENERATE(Bgtz, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 3);
+  __ LoadImmediate(T5, 3);
   __ Bind(&l);
-  __ bgtz(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(-1));
-  __ ori(V0, R5, Immediate(0));
+  __ bgtz(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(-1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -930,11 +930,11 @@
 ASSEMBLER_TEST_GENERATE(Bgtzl, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 3);
+  __ LoadImmediate(T5, 3);
   __ Bind(&l);
-  __ bgtzl(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(-1));
-  __ ori(V0, R5, Immediate(0));
+  __ bgtzl(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(-1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -948,11 +948,11 @@
 ASSEMBLER_TEST_GENERATE(Bltz, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, -3);
+  __ LoadImmediate(T5, -3);
   __ Bind(&l);
-  __ bltz(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(1));
-  __ ori(V0, R5, Immediate(0));
+  __ bltz(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -966,11 +966,11 @@
 ASSEMBLER_TEST_GENERATE(Bltzl, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, -3);
+  __ LoadImmediate(T5, -3);
   __ Bind(&l);
-  __ bltzl(R5, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(1));
-  __ ori(V0, R5, Immediate(0));
+  __ bltzl(T5, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -984,11 +984,11 @@
 ASSEMBLER_TEST_GENERATE(Bne, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 3);
+  __ LoadImmediate(T5, 3);
   __ Bind(&l);
-  __ bne(R5, R0, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(-1));
-  __ ori(V0, R5, Immediate(0));
+  __ bne(T5, R0, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(-1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -1002,11 +1002,11 @@
 ASSEMBLER_TEST_GENERATE(Bnel, assembler) {
   Label l;
 
-  __ LoadImmediate(R5, 3);
+  __ LoadImmediate(T5, 3);
   __ Bind(&l);
-  __ bnel(R5, R0, &l);
-  __ delay_slot()->addiu(R5, R5, Immediate(-1));
-  __ ori(V0, R5, Immediate(0));
+  __ bnel(T5, R0, &l);
+  __ delay_slot()->addiu(T5, T5, Immediate(-1));
+  __ ori(V0, T5, Immediate(0));
   __ jr(RA);
 }
 
@@ -1058,8 +1058,8 @@
 
 
 ASSEMBLER_TEST_GENERATE(Jalr_delay, assembler) {
-  __ mov(R2, RA);
-  __ jalr(R2, RA);
+  __ mov(T2, RA);
+  __ jalr(T2, RA);
   __ delay_slot()->ori(V0, ZR, Immediate(42));
 }
 
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 7223916..26d8be4 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -251,6 +251,7 @@
   V(ClassMirror_library, 1)                                                    \
   V(ClassMirror_supertype, 1)                                                  \
   V(ClassMirror_members, 2)                                                    \
+  V(ClassMirror_constructors, 2)                                               \
   V(LibraryMirror_members, 2)                                                  \
   V(ClassMirror_invoke, 4)                                                     \
   V(ClassMirror_invokeGetter, 3)                                               \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index f12c6d0..0134612 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -282,6 +282,21 @@
 }
 
 
+
+void ClassFinalizer::ResolveRedirectingFactory(const Class& cls,
+                                               const Function& factory) {
+  const Function& target = Function::Handle(factory.RedirectionTarget());
+  if (target.IsNull()) {
+    const Type& type = Type::Handle(factory.RedirectionType());
+    if (!type.IsMalformed()) {
+      const GrowableObjectArray& visited_factories =
+          GrowableObjectArray::Handle(GrowableObjectArray::New());
+      ResolveRedirectingFactoryTarget(cls, factory, visited_factories);
+    }
+  }
+}
+
+
 void ClassFinalizer::ResolveRedirectingFactoryTarget(
     const Class& cls,
     const Function& factory,
@@ -385,7 +400,7 @@
     return;
   }
 
-  // Verify that the target is const if the the redirecting factory is const.
+  // Verify that the target is const if the redirecting factory is const.
   if (factory.is_const() && !target.is_const()) {
     const Script& script = Script::Handle(cls.script());
     ReportError(script, factory.token_pos(),
@@ -1159,11 +1174,8 @@
                     function_name.ToCString(),
                     super_class_name.ToCString());
       }
-      if (function.IsRedirectingFactory()) {
-        const GrowableObjectArray& redirecting_factories =
-            GrowableObjectArray::Handle(GrowableObjectArray::New());
-        ResolveRedirectingFactoryTarget(cls, function, redirecting_factories);
-      }
+      // The function may be a still unresolved redirecting factory. Do not yet
+      // try to resolve it in order to avoid cycles in class finalization.
     } else {
       for (int i = 0; i < interfaces.Length(); i++) {
         super_class ^= interfaces.At(i);
@@ -1505,7 +1517,7 @@
     return;
   }
   if (FLAG_trace_class_finalization) {
-    OS::Print("Finalize %s\n", cls.ToCString());
+    OS::Print("Finalize types in %s\n", cls.ToCString());
   }
   if (!IsSuperCycleFree(cls)) {
     const String& name = String::Handle(cls.Name());
@@ -1614,7 +1626,7 @@
   }
   // Top level classes are parsed eagerly so just finalize it.
   if (cls.IsTopLevel()) {
-    ClassFinalizer::FinalizeClass(cls);
+    FinalizeClass(cls);
   }
 }
 
@@ -1624,12 +1636,20 @@
   if (cls.is_finalized()) {
     return;
   }
+  if (FLAG_trace_class_finalization) {
+    OS::Print("Finalize %s\n", cls.ToCString());
+  }
   if (cls.mixin() != Type::null()) {
     // Copy instance methods and fields from the mixin class.
     // This has to happen before the check whether the methods of
     // the class conflict with inherited methods.
     ApplyMixin(cls);
   }
+  // Ensure super class is finalized.
+  const Class& super = Class::Handle(cls.SuperClass());
+  if (!super.IsNull()) {
+    FinalizeClass(super);
+  }
   // Mark as parsed and finalized.
   cls.Finalize();
   // Resolve and finalize all member types.
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 224a961..b82cabf 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -91,6 +91,10 @@
   // needed during bootstrapping where the classes have been preloaded.
   static void VerifyBootstrapClasses();
 
+  // Resolve the type and target of the redirecting factory.
+  static void ResolveRedirectingFactory(const Class& cls,
+                                        const Function& factory);
+
  private:
   static bool IsSuperCycleFree(const Class& cls);
   static bool IsParameterTypeCycleFree(const Class& cls,
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index f439def..c818976 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -289,22 +289,6 @@
 }
 
 
-// Allocate a new implicit static closure.
-// Arg0: local function.
-// Return value: newly allocated closure.
-DEFINE_RUNTIME_ENTRY(AllocateImplicitStaticClosure, 1) {
-  ASSERT(arguments.ArgCount() ==
-         kAllocateImplicitStaticClosureRuntimeEntry.argument_count());
-  ObjectStore* object_store = isolate->object_store();
-  ASSERT(object_store != NULL);
-  const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
-  ASSERT(!function.IsNull());
-  ASSERT(function.IsImplicitStaticClosureFunction());
-  const Context& context = Context::Handle(object_store->empty_context());
-  arguments.SetReturn(Instance::Handle(Closure::New(function, context)));
-}
-
-
 // Allocate a new implicit instance closure.
 // Arg0: local function.
 // Arg1: receiver object.
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 6ec0c13..c3a7ed6 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -19,7 +19,6 @@
 DECLARE_RUNTIME_ENTRY(AllocateArray);
 DECLARE_RUNTIME_ENTRY(AllocateClosure);
 DECLARE_RUNTIME_ENTRY(AllocateImplicitInstanceClosure);
-DECLARE_RUNTIME_ENTRY(AllocateImplicitStaticClosure);
 DECLARE_RUNTIME_ENTRY(AllocateContext);
 DECLARE_RUNTIME_ENTRY(AllocateObject);
 DECLARE_RUNTIME_ENTRY(AllocateObjectWithBoundsCheck);
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 23e90cd..7c2e59b 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -186,8 +186,11 @@
 
 // The code that generates a comparison can be far away from the code that
 // generates the branch that uses the result of that comparison. In this case,
-// CMPRES is used for the result of the comparison.
-const Register CMPRES = T9;
+// CMPRES1 and CMPRES2 are used for the results of the comparison. We need two
+// since TMP is clobbered by a far branch.
+const Register CMPRES1 = T8;
+const Register CMPRES2 = T9;
+const Register CMPRES = CMPRES1;
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
@@ -504,6 +507,12 @@
     return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
   }
 
+  inline void SetOpcodeField(Opcode b) {
+    int32_t instr = InstructionBits();
+    int32_t mask = ((1 << kOpcodeBits) - 1) << kOpcodeShift;
+    SetInstructionBits((b << kOpcodeShift) | (instr & ~mask));
+  }
+
   inline Register RsField() const {
     return static_cast<Register>(Bits(kRsShift, kRsBits));
   }
@@ -553,6 +562,12 @@
     return static_cast<RtRegImm>(Bits(kRtShift, kRtBits));
   }
 
+  inline void SetRegImmFnField(RtRegImm b) {
+    int32_t instr = InstructionBits();
+    int32_t mask = ((1 << kRtBits) - 1) << kRtShift;
+    SetInstructionBits((b << kRtShift) | (instr & ~mask));
+  }
+
   inline bool IsBreakPoint() {
     return (OpcodeField() == SPECIAL) && (FunctionField() == BREAK);
   }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 9e3bbb5..d298335 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2819,9 +2819,14 @@
 
   Instance& new_object = Instance::Handle(isolate);
   if (constructor.IsRedirectingFactory()) {
-    Type& type = Type::Handle(constructor.RedirectionType());
-    cls = type.type_class();
+    ClassFinalizer::ResolveRedirectingFactory(cls, constructor);
+    const Type& type = Type::Handle(constructor.RedirectionType());
     constructor = constructor.RedirectionTarget();
+    if (constructor.IsNull()) {
+      ASSERT(type.IsMalformed());
+      return Api::NewHandle(isolate, type.malformed_error());
+    }
+    cls = type.type_class();
   }
   if (constructor.IsConstructor()) {
     // Create the new object.
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 3f24c50..36822f1 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -4,6 +4,7 @@
 
 #include "vm/dart_entry.h"
 
+#include "vm/class_finalizer.h"
 #include "vm/code_generator.h"
 #include "vm/compiler.h"
 #include "vm/debugger.h"
@@ -161,9 +162,11 @@
 
   Instance& new_object = Instance::Handle();
   if (ultimate_constructor.IsRedirectingFactory()) {
+    ClassFinalizer::ResolveRedirectingFactory(klass, ultimate_constructor);
     Type& type = Type::Handle(ultimate_constructor.RedirectionType());
-    ultimate_klass = type.type_class();
     ultimate_constructor = ultimate_constructor.RedirectionTarget();
+    ASSERT(!ultimate_constructor.IsNull());
+    ultimate_klass = type.type_class();
   }
   if (ultimate_constructor.IsConstructor()) {
     // "Constructors" are really instance initializers. They are passed a newly
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index e97b981..8c5dbd4 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -481,6 +481,10 @@
       Format(instr, "bgezal 'rs, 'dest");
       break;
     }
+    case BLTZAL: {
+      Format(instr, "bltzal 'rs, 'dest");
+      break;
+    }
     case BGEZL: {
       Format(instr, "bgezl 'rs, 'dest");
       break;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 361d323..eb6822b 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -542,7 +542,6 @@
 Definition* EffectGraphVisitor::BuildStoreLocal(
     const LocalVariable& local, Value* value, bool result_is_needed) {
   if (local.is_captured()) {
-    InlineBailout("EffectGraphVisitor::BuildStoreLocal (context)");
     if (result_is_needed) {
       value = Bind(BuildStoreExprTemp(value));
     }
@@ -575,7 +574,6 @@
 
 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
   if (local.is_captured()) {
-    InlineBailout("EffectGraphVisitor::BuildLoadLocal (context)");
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
@@ -594,14 +592,14 @@
 
 
 // Stores current context into the 'variable'
-void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) {
+void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
   Value* context = Bind(new CurrentContextInstr());
   Do(BuildStoreLocal(variable, context, kResultNotNeeded));
 }
 
 
 // Loads context saved in 'context_variable' into the current context.
-void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
+void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
   Value* load_saved_context = Bind(BuildLoadLocal(variable));
   AddInstruction(new StoreContextInstr(load_saved_context));
 }
@@ -823,7 +821,7 @@
   ASSERT(current_context_level >= 0);
   if (owner()->parsed_function()->saved_entry_context_var() != NULL) {
     // CTX on entry was saved, but not linked as context parent.
-    BuildLoadContext(*owner()->parsed_function()->saved_entry_context_var());
+    BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var());
   } else {
     while (current_context_level-- > 0) {
       UnchainContext();
@@ -2138,7 +2136,7 @@
 
   // Save context around the call.
   ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
-  BuildStoreContext(*owner()->parsed_function()->saved_current_context_var());
+  BuildSaveContext(*owner()->parsed_function()->saved_current_context_var());
   return new ClosureCallInstr(node, arguments);
 }
 
@@ -2147,7 +2145,7 @@
   Do(BuildClosureCall(node));
   // Restore context from saved location.
   ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
-  BuildLoadContext(*owner()->parsed_function()->saved_current_context_var());
+  BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var());
 }
 
 
@@ -2155,13 +2153,12 @@
   Value* result = Bind(BuildClosureCall(node));
   // Restore context from temp.
   ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
-  BuildLoadContext(*owner()->parsed_function()->saved_current_context_var());
+  BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var());
   ReturnValue(result);
 }
 
 
 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
-  InlineBailout("EffectGraphVisitor::VisitCloneContextNode (context)");
   Value* context = Bind(new CurrentContextInstr());
   Value* clone = Bind(new CloneContextInstr(node->token_pos(), context));
   AddInstruction(new StoreContextInstr(clone));
@@ -3068,7 +3065,6 @@
 
 
 void EffectGraphVisitor::UnchainContext() {
-  InlineBailout("EffectGraphVisitor::UnchainContext (context)");
   Value* context = Bind(new CurrentContextInstr());
   Value* parent = Bind(
       new LoadFieldInstr(context,
@@ -3087,7 +3083,6 @@
       (scope != NULL) ? scope->num_context_variables() : 0;
   int previous_context_level = owner()->context_level();
   if (num_context_variables > 0) {
-    InlineBailout("EffectGraphVisitor::VisitSequenceNode (context)");
     // The loop local scope declares variables that are captured.
     // Allocate and chain a new context.
     // Allocate context computation (uses current CTX)
@@ -3205,7 +3200,8 @@
   if (is_open()) {
     if (MustSaveRestoreContext(node)) {
       ASSERT(num_context_variables > 0);
-      BuildLoadContext(*owner()->parsed_function()->saved_entry_context_var());
+      BuildRestoreContext(
+          *owner()->parsed_function()->saved_entry_context_var());
     } else if (num_context_variables > 0) {
       UnchainContext();
     }
@@ -3236,7 +3232,7 @@
   // Restores CTX from local variable ':saved_context'.
   AddInstruction(
       new CatchEntryInstr(node->exception_var(), node->stacktrace_var()));
-  BuildLoadContext(node->context_var());
+  BuildRestoreContext(node->context_var());
 
   EffectGraphVisitor for_catch(owner(), temp_index());
   node->VisitChildren(&for_catch);
@@ -3251,7 +3247,7 @@
   owner()->set_try_index(try_handler_index);
 
   // Preserve CTX into local variable '%saved_context'.
-  BuildStoreContext(node->context_var());
+  BuildSaveContext(node->context_var());
 
   EffectGraphVisitor for_try(owner(), temp_index());
   node->try_block()->Visit(&for_try);
@@ -3308,7 +3304,7 @@
       for_finally.AddInstruction(
           new CatchEntryInstr(catch_block->exception_var(),
                               catch_block->stacktrace_var()));
-      for_finally.BuildLoadContext(catch_block->context_var());
+      for_finally.BuildRestoreContext(catch_block->context_var());
 
       finally_block->Visit(&for_finally);
       if (for_finally.is_open()) {
@@ -3478,7 +3474,7 @@
     // thrown not from the current try block but the outer try block if any.
     owner()->set_try_index((try_index - 1));
   }
-  BuildLoadContext(node->context_var());
+  BuildRestoreContext(node->context_var());
 
   JoinEntryInstr* finally_entry =
       new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 771b6d3..4674a2a 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -348,8 +348,8 @@
   void BuildConstructorCall(ConstructorCallNode* node,
                             PushArgumentInstr* alloc_value);
 
-  void BuildStoreContext(const LocalVariable& variable);
-  void BuildLoadContext(const LocalVariable& variable);
+  void BuildSaveContext(const LocalVariable& variable);
+  void BuildRestoreContext(const LocalVariable& variable);
 
   void BuildThrowNode(ThrowNode* node);
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 0aeec79..28497ca 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -993,7 +993,7 @@
     // Invoke noSuchMethod function passing "call" as the original name.
     const int kNumArgsChecked = 1;
     const ICData& ic_data = ICData::ZoneHandle(
-        ICData::New(function, Symbols::Call(), Object::null_array(),
+        ICData::New(function, Symbols::Call(), Object::empty_array(),
                     Isolate::kNoDeoptId, kNumArgsChecked));
     __ LoadObject(R5, ic_data);
     __ LeaveDartFrame();  // The arguments are still on the stack.
@@ -1164,7 +1164,7 @@
                              : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, name, Object::null_array(),
+            ICData::New(function, name, Object::empty_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(R5, ic_data);
         __ LeaveDartFrame();  // The arguments are still on the stack.
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 6db56ad..fb965ed 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1016,7 +1016,7 @@
     // Invoke noSuchMethod function passing "call" as the original name.
     const int kNumArgsChecked = 1;
     const ICData& ic_data = ICData::ZoneHandle(
-        ICData::New(function, Symbols::Call(), Object::null_array(),
+        ICData::New(function, Symbols::Call(), Object::empty_array(),
                     Isolate::kNoDeoptId, kNumArgsChecked));
     __ LoadObject(ECX, ic_data);
     __ LeaveFrame();  // The arguments are still on the stack.
@@ -1169,7 +1169,7 @@
                              : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, name, Object::null_array(),
+            ICData::New(function, name, Object::empty_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(ECX, ic_data);
         __ LeaveFrame();  // The arguments are still on the stack.
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index adbd850..ea29621 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1022,7 +1022,7 @@
     // Invoke noSuchMethod function passing "call" as the original name.
     const int kNumArgsChecked = 1;
     const ICData& ic_data = ICData::ZoneHandle(
-        ICData::New(function, Symbols::Call(), Object::null_array(),
+        ICData::New(function, Symbols::Call(), Object::empty_array(),
                     Isolate::kNoDeoptId, kNumArgsChecked));
     __ LoadObject(S5, ic_data);
     __ LeaveDartFrame();  // The arguments are still on the stack.
@@ -1052,9 +1052,9 @@
   __ Bind(&null_args_loop);
   __ addiu(T2, T2, Immediate(-kWordSize));
   __ addu(T3, T1, T2);
-  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
+  __ LoadImmediate(T5, reinterpret_cast<int32_t>(Object::null()));
   __ bgtz(T2, &null_args_loop);
-  __ delay_slot()->sw(TMP, Address(T3));
+  __ delay_slot()->sw(T5, Address(T3));
   __ Bind(&null_args_loop_exit);
 }
 
@@ -1077,9 +1077,8 @@
   __ lw(T0, Address(SP, 1 * kWordSize));  // Receiver.
   __ lw(T1, Address(SP, 0 * kWordSize));  // Value.
   __ StoreIntoObject(T0, FieldAddress(T0, offset), T1);
-  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
+  __ LoadImmediate(V0, reinterpret_cast<int32_t>(Object::null()));
   __ Ret();
-  __ delay_slot()->mov(V0, TMP);
 }
 
 
@@ -1090,17 +1089,13 @@
       (!is_optimizing() || may_reoptimize())) {
     const Register function_reg = T0;
 
-    Label next;
-    // The pool pointer is not setup before entering the Dart frame.
-    __ mov(TMP1, RA);  // Save RA.
-    __ bal(&next);  // Branch and link to next instruction to get PC in RA.
-    __ delay_slot()->mov(T2, RA);  // Save PC of the following mov.
+    __ GetNextPC(T2, TMP);
+
     // Calculate offset of pool pointer from the PC.
     const intptr_t object_pool_pc_dist =
        Instructions::HeaderSize() - Instructions::object_pool_offset() +
-       assembler()->CodeSize();
-    __ Bind(&next);
-    __ mov(RA, TMP1);  // Restore RA.
+       assembler()->CodeSize() - 1 * Instr::kInstrSize;
+
     // Preserve PP of caller.
     __ mov(T1, PP);
     // Temporarily setup pool pointer for this dart function.
@@ -1213,7 +1208,7 @@
                              : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, name, Object::null_array(),
+            ICData::New(function, name, Object::empty_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(S5, ic_data);
         __ LeaveDartFrame();  // The arguments are still on the stack.
@@ -1486,7 +1481,7 @@
     __ addiu(SP, SP, Immediate(2 * kWordSize));  // Discard constant.
     return;
   }
-  __ CompareObject(CMPRES, TMP1, reg, obj);
+  __ CompareObject(CMPRES1, CMPRES2, reg, obj);
 }
 
 
@@ -1514,8 +1509,8 @@
     __ lw(left, Address(SP, 1 * kWordSize));
     __ addiu(SP, SP, Immediate(2 * kWordSize));
   } else {
-    __ slt(CMPRES, left, right);
-    __ slt(TMP1, right, left);
+    __ slt(CMPRES1, left, right);
+    __ slt(CMPRES2, right, left);
   }
 }
 
@@ -1527,13 +1522,14 @@
   Label check_identity, is_false, fall_through;
   __ TraceSimMsg("SuperEqualityCallPrologue");
   __ lw(result, Address(SP, 0 * kWordSize));  // Load right operand.
-  __ lw(TMP1, Address(SP, 1 * kWordSize));  // Load left operand.
-  __ LoadImmediate(CMPRES, reinterpret_cast<int32_t>(Object::null()));
-  __ beq(result, CMPRES, &check_identity);  // Is right null?
-  __ bne(TMP1, CMPRES, &fall_through);  // If right is non-null, check left.
+  __ lw(CMPRES1, Address(SP, 1 * kWordSize));  // Load left operand.
+  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
+  __ beq(result, TMP, &check_identity);  // Is right null?
+  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
+  __ bne(TMP, CMPRES1, &fall_through);  // If right is non-null, check left.
 
   __ Bind(&check_identity);
-  __ bne(result, TMP1, &is_false);
+  __ bne(result, CMPRES1, &is_false);
   __ LoadObject(result, Bool::True());
   __ Drop(2);
   __ b(skip_call);
@@ -1693,15 +1689,15 @@
 
   assembler()->LoadImmediate(TMP, 1);
   if (true_condition == NE) {
-    assembler()->movf(CMPRES, ZR);
-    assembler()->movt(CMPRES, TMP);
+    assembler()->movf(CMPRES1, ZR);
+    assembler()->movt(CMPRES1, TMP);
   } else {
-    assembler()->movf(CMPRES, TMP);
-    assembler()->movt(CMPRES, ZR);
+    assembler()->movf(CMPRES1, TMP);
+    assembler()->movt(CMPRES1, ZR);
   }
-  assembler()->mov(TMP, ZR);
+  assembler()->mov(CMPRES2, ZR);
 
-  // EmitBranchOnCondition expects ordering to be described by CMPRES, TMP1.
+  // EmitBranchOnCondition expects ordering to be described by CMPRES, CMPRES2.
   branch->EmitBranchOnCondition(this, EQ);
 }
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index c165e50..00784c9 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1010,7 +1010,7 @@
     // Invoke noSuchMethod function passing "call" as the original name.
     const int kNumArgsChecked = 1;
     const ICData& ic_data = ICData::ZoneHandle(
-        ICData::New(function, Symbols::Call(), Object::null_array(),
+        ICData::New(function, Symbols::Call(), Object::empty_array(),
                     Isolate::kNoDeoptId, kNumArgsChecked));
     __ LoadObject(RBX, ic_data);
     __ LeaveFrame();  // The arguments are still on the stack.
@@ -1164,7 +1164,7 @@
                              : function.name());
         const int kNumArgsChecked = 1;
         const ICData& ic_data = ICData::ZoneHandle(
-            ICData::New(function, name, Object::null_array(),
+            ICData::New(function, name, Object::empty_array(),
                         Isolate::kNoDeoptId, kNumArgsChecked));
         __ LoadObject(RBX, ic_data);
         __ LeaveFrame();  // The arguments are still on the stack.
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index b22eda0..229f7fc 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -668,11 +668,30 @@
                      &CompilerStats::graphinliner_subst_timer,
                      Isolate::Current());
 
-    // Plug result in the caller graph.
+    // For closure calls: Store context value.
     FlowGraph* callee_graph = call_data->callee_graph;
+    TargetEntryInstr* callee_entry =
+        callee_graph->graph_entry()->normal_entry();
+    ClosureCallInstr* closure_call = call_data->call->AsClosureCall();
+    if (closure_call != NULL) {
+      // TODO(fschneider): Avoid setting the context, if not needed.
+      Definition* closure =
+          closure_call->PushArgumentAt(0)->value()->definition();
+      LoadFieldInstr* context =
+          new LoadFieldInstr(new Value(closure),
+                             Closure::context_offset(),
+                             Type::ZoneHandle());
+      context->set_ssa_temp_index(caller_graph()->alloc_ssa_temp_index());
+      context->InsertAfter(callee_entry);
+      StoreContextInstr* set_context =
+          new StoreContextInstr(new Value(context));
+      set_context->InsertAfter(context);
+    }
+
+    // Plug result in the caller graph.
     InlineExitCollector* exit_collector = call_data->exit_collector;
     exit_collector->PrepareGraphs(callee_graph);
-    exit_collector->ReplaceCall(callee_graph->graph_entry()->normal_entry());
+    exit_collector->ReplaceCall(callee_entry);
 
     // Replace each stub with the actual argument or the caller's constant.
     // Nulls denote optional parameters for which no actual was given.
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 7861810..170f5a4 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -133,7 +133,7 @@
     ICData& ic_data = ICData::ZoneHandle(ICData::New(
         flow_graph_->parsed_function().function(),
         call->function_name(),
-        Object::null_array(),  // Dummy argument descriptor.
+        Object::empty_array(),  // Dummy argument descriptor.
         call->deopt_id(),
         class_ids.length()));
     ic_data.AddReceiverCheck(class_ids[0], function);
@@ -155,7 +155,7 @@
   const ICData& new_ic_data = ICData::ZoneHandle(ICData::New(
       Function::Handle(ic_data.function()),
       String::Handle(ic_data.target_name()),
-      Object::null_array(),  // Dummy argument descriptor.
+      Object::empty_array(),  // Dummy argument descriptor.
       ic_data.deopt_id(),
       ic_data.num_args_tested()));
 
@@ -617,6 +617,16 @@
 }
 
 
+// Returns false if the ICData contains anything other than the 4 combinations
+// of Double and Smi for the receiver and argument classes.
+static bool HasTwoDoubleOrSmi(const ICData& ic_data) {
+  GrowableArray<intptr_t> class_ids(2);
+  class_ids.Add(kSmiCid);
+  class_ids.Add(kDoubleCid);
+  return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids);
+}
+
+
 static bool HasOnlyOneDouble(const ICData& ic_data) {
   return (ic_data.NumberOfChecks() == 1)
       && ic_data.HasReceiverClassId(kDoubleCid);
@@ -1912,32 +1922,23 @@
 
       // ByteArray setters.
       case MethodRecognizer::kByteArrayBaseSetInt8:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataInt8ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetUint8:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataUint8ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetInt16:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataInt16ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetUint16:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataUint16ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetInt32:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataInt32ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetUint32:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataUint32ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetFloat32:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataFloat32ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetFloat64:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataFloat64ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid);
       case MethodRecognizer::kByteArrayBaseSetFloat32x4:
-        return BuildByteArrayViewStore(
-            call, class_ids[0], kTypedDataFloat32x4ArrayCid);
+        return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid);
       default:
         // Unsupported method.
         return false;
@@ -2263,13 +2264,17 @@
 }
 
 
-bool FlowGraphOptimizer::BuildByteArrayViewStore(
-    InstanceCallInstr* call,
-    intptr_t receiver_cid,
-    intptr_t view_cid) {
+bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call,
+                                                 intptr_t view_cid) {
   if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) {
     return false;
   }
+  ASSERT(call->HasICData());
+  Function& target = Function::Handle();
+  GrowableArray<intptr_t> class_ids;
+  call->ic_data()->GetCheckAt(0, &class_ids, &target);
+  const intptr_t receiver_cid = class_ids[0];
+
   Definition* array = call->ArgumentAt(0);
   PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array);
   ICData& value_check = ICData::ZoneHandle();
@@ -2282,12 +2287,12 @@
     case kTypedDataInt16ArrayCid:
     case kTypedDataUint16ArrayCid: {
       // Check that value is always smi.
-      value_check = ICData::New(Function::Handle(),
-                                Object::null_string(),
-                                Object::null_array(),
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
                                 Isolate::kNoDeoptId,
                                 1);
-      value_check.AddReceiverCheck(kSmiCid, Function::Handle());
+      value_check.AddReceiverCheck(kSmiCid, target);
       break;
     }
     case kTypedDataInt32ArrayCid:
@@ -2296,33 +2301,33 @@
       // smis first. If we ever deoptimized here, we require to unbox the value
       // before storing to handle the mint case, too.
       if (call->ic_data()->deopt_reason() == kDeoptUnknown) {
-        value_check = ICData::New(Function::Handle(),
-                                  Object::null_string(),
-                                  Object::null_array(),  // Dummy args. descr.
+        value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                  call->function_name(),
+                                  Object::empty_array(),  // Dummy args. descr.
                                   Isolate::kNoDeoptId,
                                   1);
-        value_check.AddReceiverCheck(kSmiCid, Function::Handle());
+        value_check.AddReceiverCheck(kSmiCid, target);
       }
       break;
     case kTypedDataFloat32ArrayCid:
     case kTypedDataFloat64ArrayCid: {
       // Check that value is always double.
-      value_check = ICData::New(Function::Handle(),
-                                Object::null_string(),
-                                Object::null_array(),  // Dummy args. descr.
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
                                 Isolate::kNoDeoptId,
                                 1);
-      value_check.AddReceiverCheck(kDoubleCid, Function::Handle());
+      value_check.AddReceiverCheck(kDoubleCid, target);
       break;
     }
     case kTypedDataFloat32x4ArrayCid: {
       // Check that value is always Float32x4.
-      value_check = ICData::New(Function::Handle(),
-                                Object::null_string(),
-                                Object::null_array(),  // Dummy args. descr.
+      value_check = ICData::New(flow_graph_->parsed_function().function(),
+                                call->function_name(),
+                                Object::empty_array(),  // Dummy args. descr.
                                 Isolate::kNoDeoptId,
                                 1);
-      value_check.AddReceiverCheck(kFloat32x4Cid, Function::Handle());
+      value_check.AddReceiverCheck(kFloat32x4Cid, target);
       break;
     }
     default:
@@ -2744,36 +2749,57 @@
 }
 
 
+static bool SmiFitsInDouble() { return kSmiBits < 53; }
+
+
+void FlowGraphOptimizer::HandleComparison(ComparisonInstr* comp,
+                                          const ICData& ic_data,
+                                          Instruction* current_instruction) {
+  ASSERT(ic_data.num_args_tested() == 2);
+  ASSERT(comp->operation_cid() == kIllegalCid);
+  Instruction* instr = current_iterator()->Current();
+  if (HasOnlyTwoSmis(ic_data)) {
+    InsertBefore(instr,
+                 new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
+                 instr->env(),
+                 Definition::kEffect);
+    InsertBefore(instr,
+                 new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
+                 instr->env(),
+                 Definition::kEffect);
+    comp->set_operation_cid(kSmiCid);
+  } else if (HasTwoMintOrSmi(ic_data) &&
+             FlowGraphCompiler::SupportsUnboxedMints()) {
+    comp->set_operation_cid(kMintCid);
+  } else if (HasTwoDoubleOrSmi(ic_data)) {
+    // Use double comparison.
+    if (SmiFitsInDouble()) {
+      comp->set_operation_cid(kDoubleCid);
+    } else {
+      if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
+        // We cannot use double comparison on two Smi-s.
+        ASSERT(comp->operation_cid() == kIllegalCid);
+      } else {
+        InsertBefore(instr,
+                     new CheckEitherNonSmiInstr(comp->left()->Copy(),
+                                                comp->right()->Copy(),
+                                                comp->deopt_id()),
+                     instr->env(),
+                     Definition::kEffect);
+        comp->set_operation_cid(kDoubleCid);
+      }
+    }
+  } else {
+    ASSERT(comp->operation_cid() == kIllegalCid);
+  }
+}
+
+
 void FlowGraphOptimizer::HandleRelationalOp(RelationalOpInstr* comp) {
   if (!comp->HasICData() || (comp->ic_data()->NumberOfChecks() == 0)) {
     return;
   }
-  const ICData& ic_data = *comp->ic_data();
-  Instruction* instr = current_iterator()->Current();
-  if (ic_data.NumberOfChecks() == 1) {
-    ASSERT(ic_data.HasOneTarget());
-    if (HasOnlyTwoSmis(ic_data)) {
-      InsertBefore(instr,
-                   new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
-                   instr->env(),
-                   Definition::kEffect);
-      InsertBefore(instr,
-                   new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
-                   instr->env(),
-                   Definition::kEffect);
-      comp->set_operands_class_id(kSmiCid);
-    } else if (ShouldSpecializeForDouble(ic_data)) {
-      comp->set_operands_class_id(kDoubleCid);
-    } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
-               FlowGraphCompiler::SupportsUnboxedMints()) {
-      comp->set_operands_class_id(kMintCid);
-    } else {
-      ASSERT(comp->operands_class_id() == kIllegalCid);
-    }
-  } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
-             FlowGraphCompiler::SupportsUnboxedMints()) {
-    comp->set_operands_class_id(kMintCid);
-  }
+  HandleComparison(comp, *comp->ic_data(), current_iterator()->Current());
 }
 
 
@@ -2857,37 +2883,10 @@
     return;
   }
 
-  ASSERT(comp->ic_data()->num_args_tested() == 2);
-  if (comp->ic_data()->NumberOfChecks() == 1) {
-    GrowableArray<intptr_t> class_ids;
-    Function& target = Function::Handle();
-    comp->ic_data()->GetCheckAt(0, &class_ids, &target);
-    // TODO(srdjan): allow for mixed mode int/double comparison.
+  const ICData& ic_data = *comp->ic_data();
+  HandleComparison(comp, ic_data, current_instruction);
 
-    if ((class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
-      InsertBefore(current_instruction,
-                   new CheckSmiInstr(comp->left()->Copy(), comp->deopt_id()),
-                   current_instruction->env(),
-                   Definition::kEffect);
-      InsertBefore(current_instruction,
-                   new CheckSmiInstr(comp->right()->Copy(), comp->deopt_id()),
-                   current_instruction->env(),
-                   Definition::kEffect);
-      comp->set_receiver_class_id(kSmiCid);
-    } else if ((class_ids[0] == kDoubleCid) && (class_ids[1] == kDoubleCid)) {
-      comp->set_receiver_class_id(kDoubleCid);
-    } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
-               FlowGraphCompiler::SupportsUnboxedMints()) {
-      comp->set_receiver_class_id(kMintCid);
-    } else {
-      ASSERT(comp->receiver_class_id() == kIllegalCid);
-    }
-  } else if (HasTwoMintOrSmi(*comp->ic_data()) &&
-             FlowGraphCompiler::SupportsUnboxedMints()) {
-    comp->set_receiver_class_id(kMintCid);
-  }
-
-  if (comp->receiver_class_id() != kIllegalCid) {
+  if (comp->operation_cid() != kIllegalCid) {
     // Done.
     return;
   }
@@ -2899,7 +2898,7 @@
   GrowableArray<intptr_t> smi_or_null(2);
   smi_or_null.Add(kSmiCid);
   smi_or_null.Add(kNullCid);
-  if (ICDataHasOnlyReceiverArgumentClassIds(*comp->ic_data(),
+  if (ICDataHasOnlyReceiverArgumentClassIds(ic_data,
                                             smi_or_null,
                                             smi_or_null)) {
     const ICData& unary_checks_0 =
@@ -2917,7 +2916,7 @@
                   comp->deopt_id(),
                   current_instruction->env(),
                   current_instruction);
-    comp->set_receiver_class_id(kSmiCid);
+    comp->set_operation_cid(kSmiCid);
   }
 }
 
@@ -3237,7 +3236,7 @@
 void RangeAnalysis::ConstrainValueAfterBranch(Definition* defn, Value* use) {
   BranchInstr* branch = use->instruction()->AsBranch();
   RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp();
-  if ((rel_op != NULL) && (rel_op->operands_class_id() == kSmiCid)) {
+  if ((rel_op != NULL) && (rel_op->operation_cid() == kSmiCid)) {
     // Found comparison of two smis. Constrain defn at true and false
     // successors using the other operand as a boundary.
     Definition* boundary;
@@ -5880,7 +5879,7 @@
     // Fold x == x, and x != x to true/false for numbers and checked strict
     // comparisons.
     if (instr->IsCheckedStrictEqual() ||
-        RawObject::IsIntegerClassId(instr->receiver_class_id())) {
+        RawObject::IsIntegerClassId(instr->operation_cid())) {
       return SetValue(instr,
                       (instr->kind() == Token::kEQ)
                         ? Bool::True()
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 1f18c51..ced6e0f 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -105,7 +105,6 @@
                               intptr_t receiver_cid,
                               intptr_t view_cid);
   bool BuildByteArrayViewStore(InstanceCallInstr* call,
-                               intptr_t receiver_cid,
                                intptr_t view_cid);
   void PrepareByteArrayViewOp(InstanceCallInstr* call,
                               intptr_t receiver_cid,
@@ -172,6 +171,10 @@
   void ReplaceWithMathCFunction(InstanceCallInstr* call,
                                 MethodRecognizer::Kind recognized_kind);
 
+  void HandleComparison(ComparisonInstr* comp,
+                        const ICData& ic_data,
+                        Instruction* current_instruction);
+
   void HandleRelationalOp(RelationalOpInstr* comp);
 
   // Visit an equality compare.  The current instruction can be the
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 04775f3..dc9768c 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -124,7 +124,9 @@
 // A list of core function that should always be inlined.
 #define INLINE_WHITE_LIST(V)                                                   \
   V(ListIterator, moveNext, ListIteratorMoveNext, 203118278)                   \
-  V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 810824939)
+  V(_GrowableObjectArray, get:iterator, GrowableArrayIterator, 810824939)      \
+  V(_GrowableObjectArray, forEach, GrowableArrayForEach, 619038738)
+
 
 // Class that recognizes the name and owner of a function and returns the
 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -2697,15 +2699,6 @@
 
 class ComparisonInstr : public TemplateDefinition<2> {
  public:
-  ComparisonInstr(intptr_t token_pos,
-                  Token::Kind kind,
-                  Value* left,
-                  Value* right)
-      : token_pos_(token_pos), kind_(kind) {
-    SetInputAt(0, left);
-    SetInputAt(1, right);
-  }
-
   Value* left() const { return inputs_[0]; }
   Value* right() const { return inputs_[1]; }
 
@@ -2721,9 +2714,27 @@
     deopt_id_ = deopt_id;
   }
 
+  // Operation class id is computed from collected ICData.
+  void set_operation_cid(intptr_t value) { operation_cid_ = value; }
+  intptr_t operation_cid() const { return operation_cid_; }
+
  protected:
+  ComparisonInstr(intptr_t token_pos,
+                  Token::Kind kind,
+                  Value* left,
+                  Value* right)
+      : token_pos_(token_pos), kind_(kind), operation_cid_(kIllegalCid) {
+    SetInputAt(0, left);
+    SetInputAt(1, right);
+  }
+
   intptr_t token_pos_;
   Token::Kind kind_;
+
+ private:
+  intptr_t operation_cid_;  // Set by optimizer.
+
+  DISALLOW_COPY_AND_ASSIGN(ComparisonInstr);
 };
 
 
@@ -2840,8 +2851,7 @@
                        const Array& ic_data_array)
       : ComparisonInstr(token_pos, kind, left, right),
         ic_data_(GetICData(ic_data_array)),
-        unary_ic_data_(NULL),
-        receiver_class_id_(kIllegalCid) {
+        unary_ic_data_(NULL) {
     ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
     if (HasICData()) {
       unary_ic_data_ = &ICData::ZoneHandle(ic_data_->AsUnaryClassChecks());
@@ -2863,14 +2873,10 @@
     }
   }
 
-  // Receiver class id is computed from collected ICData.
-  void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; }
-  intptr_t receiver_class_id() const { return receiver_class_id_; }
-
   bool IsInlinedNumericComparison() const {
-    return (receiver_class_id() == kDoubleCid)
-        || (receiver_class_id() == kMintCid)
-        || (receiver_class_id() == kSmiCid);
+    return (operation_cid() == kDoubleCid)
+        || (operation_cid() == kMintCid)
+        || (operation_cid() == kSmiCid);
   }
 
   bool IsCheckedStrictEqual() const;
@@ -2890,8 +2896,8 @@
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT((idx == 0) || (idx == 1));
-    if (receiver_class_id() == kDoubleCid) return kUnboxedDouble;
-    if (receiver_class_id() == kMintCid) return kUnboxedMint;
+    if (operation_cid() == kDoubleCid) return kUnboxedDouble;
+    if (operation_cid() == kMintCid) return kUnboxedMint;
     return kTagged;
   }
 
@@ -2908,7 +2914,6 @@
  private:
   const ICData* ic_data_;
   ICData* unary_ic_data_;
-  intptr_t receiver_class_id_;  // Set by optimizer.
 
   DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr);
 };
@@ -2922,8 +2927,7 @@
                     Value* right,
                     const Array& ic_data_array)
       : ComparisonInstr(token_pos, kind, left, right),
-        ic_data_(GetICData(ic_data_array)),
-        operands_class_id_(kIllegalCid) {
+        ic_data_(GetICData(ic_data_array)) {
     ASSERT(Token::IsRelationalOperator(kind));
   }
 
@@ -2937,18 +2941,10 @@
   }
   void set_ic_data(const ICData* value) { ic_data_ = value; }
 
-  // TODO(srdjan): instead of class-id pass an enum that can differentiate
-  // between boxed and unboxed doubles and integers.
-  void set_operands_class_id(intptr_t value) {
-    operands_class_id_ = value;
-  }
-
-  intptr_t operands_class_id() const { return operands_class_id_; }
-
   bool IsInlinedNumericComparison() const {
-    return (operands_class_id() == kDoubleCid)
-        || (operands_class_id() == kMintCid)
-        || (operands_class_id() == kSmiCid);
+    return (operation_cid() == kDoubleCid)
+        || (operation_cid() == kMintCid)
+        || (operation_cid() == kSmiCid);
   }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -2967,8 +2963,8 @@
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT((idx == 0) || (idx == 1));
-    if (operands_class_id() == kDoubleCid) return kUnboxedDouble;
-    if (operands_class_id() == kMintCid) return kUnboxedMint;
+    if (operation_cid() == kDoubleCid) return kUnboxedDouble;
+    if (operation_cid() == kMintCid) return kUnboxedMint;
     return kTagged;
   }
 
@@ -2980,7 +2976,6 @@
 
  private:
   const ICData* ic_data_;
-  intptr_t operands_class_id_;  // class id of both operands.
 
   DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr);
 };
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 1ce7473..dcf9143 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -283,7 +283,7 @@
 
 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 1;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -293,7 +293,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -302,7 +302,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -746,15 +746,15 @@
 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
   BranchInstr* kNoBranch = NULL;
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
@@ -786,16 +786,16 @@
 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                           BranchInstr* branch) {
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     // Deoptimizes if both arguments not Smi.
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
@@ -832,7 +832,7 @@
 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 2;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -843,14 +843,14 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RequiresFpuRegister());
     summary->set_in(1, Location::RequiresFpuRegister());
     summary->set_out(Location::RequiresRegister());
     return summary;
-  } else if (operands_class_id() == kSmiCid) {
+  } else if (operation_cid() == kSmiCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RegisterOrConstant(left()));
@@ -873,15 +873,15 @@
 
 
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
@@ -950,15 +950,15 @@
 
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 73abb15..fef3d76 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -230,7 +230,7 @@
 
 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 1;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -240,7 +240,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -249,7 +249,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -794,15 +794,15 @@
 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
   BranchInstr* kNoBranch = NULL;
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
@@ -833,16 +833,16 @@
 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                           BranchInstr* branch) {
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     // Deoptimizes if both arguments not Smi.
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
@@ -878,7 +878,7 @@
 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 2;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -889,14 +889,14 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RequiresFpuRegister());
     summary->set_in(1, Location::RequiresFpuRegister());
     summary->set_out(Location::RequiresRegister());
     return summary;
-  } else if (operands_class_id() == kSmiCid) {
+  } else if (operation_cid() == kSmiCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RegisterOrConstant(left()));
@@ -919,15 +919,15 @@
 
 
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
@@ -996,15 +996,15 @@
 
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
@@ -4625,7 +4625,7 @@
   if (!(comparison->IsStrictCompare() &&
         !comparison->AsStrictCompare()->needs_number_check()) &&
       !(comparison->IsEqualityCompare() &&
-        (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) {
+        (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) {
     return false;
   }
 
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 2bbe357..85bf725 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -94,9 +94,9 @@
     const intptr_t fp_sp_dist =
         (kFirstLocalSlotFromFp + 1 - compiler->StackSize()) * kWordSize;
     ASSERT(fp_sp_dist <= 0);
-    __ subu(TMP1, SP, FP);
+    __ subu(CMPRES1, SP, FP);
 
-    __ BranchEqual(TMP1, fp_sp_dist, &stack_ok);
+    __ BranchEqual(CMPRES1, fp_sp_dist, &stack_ok);
     __ break_(0);
 
     __ Bind(&stack_ok);
@@ -272,7 +272,7 @@
 
 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 1;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -282,7 +282,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -291,7 +291,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -359,9 +359,9 @@
   Label check_identity;
   __ lw(A1, Address(SP, 1 * kWordSize));
   __ lw(A0, Address(SP, 0 * kWordSize));
-  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
-  __ beq(A1, TMP, &check_identity);
-  __ beq(A0, TMP, &check_identity);
+  __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
+  __ beq(A1, CMPRES1, &check_identity);
+  __ beq(A0, CMPRES1, &check_identity);
 
   ICData& equality_ic_data = ICData::ZoneHandle();
   if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
@@ -446,11 +446,11 @@
   if (value_is_smi == NULL) {
     __ LoadImmediate(value_cid_reg, kSmiCid);
   }
-  __ andi(TMP1, value_reg, Immediate(kSmiTagMask));
+  __ andi(CMPRES1, value_reg, Immediate(kSmiTagMask));
   if (value_is_smi == NULL) {
-    __ beq(TMP1, ZR, &done);
+    __ beq(CMPRES1, ZR, &done);
   } else {
-    __ beq(TMP1, ZR, value_is_smi);
+    __ beq(CMPRES1, ZR, value_is_smi);
   }
   __ LoadClassId(value_cid_reg, value_reg);
   __ Bind(&done);
@@ -472,16 +472,16 @@
 }
 
 
-// Branches on condition c assuming comparison results in CMPRES and TMP1.
+// Branches on condition c assuming comparison results in CMPRES and CMPRES2.
 static void EmitBranchAfterCompare(
     FlowGraphCompiler* compiler, Condition c, Label* is_true) {
   switch (c) {
-    case EQ: __ beq(CMPRES, TMP1, is_true); break;
-    case NE: __ bne(CMPRES, TMP1, is_true); break;
-    case GT: __ bne(TMP1, ZR, is_true); break;
-    case GE: __ beq(CMPRES, ZR, is_true); break;
-    case LT: __ bne(CMPRES, ZR, is_true); break;
-    case LE: __ beq(TMP1, ZR, is_true); break;
+    case EQ: __ beq(CMPRES1, CMPRES2, is_true); break;
+    case NE: __ bne(CMPRES1, CMPRES2, is_true); break;
+    case GT: __ bne(CMPRES2, ZR, is_true); break;
+    case GE: __ beq(CMPRES1, ZR, is_true); break;
+    case LT: __ bne(CMPRES1, ZR, is_true); break;
+    case LE: __ beq(CMPRES2, ZR, is_true); break;
     default:
       UNREACHABLE();
       break;
@@ -532,8 +532,8 @@
     if (target.Owner() == object_store->object_class()) {
       // Object.== is same as ===.
       __ Drop(2);
-      __ slt(CMPRES, left, right);
-      __ slt(TMP1, right, left);
+      __ slt(CMPRES1, left, right);
+      __ slt(CMPRES2, right, left);
       if (branch != NULL) {
         branch->EmitBranchOnCondition(compiler, cond);
       } else {
@@ -557,8 +557,8 @@
       if (branch == NULL) {
         if (kind == Token::kNE) {
           Label is_true;
-          __ CompareObject(CMPRES, TMP1, V0, Bool::True());
-          __ beq(CMPRES, TMP1, &is_true);
+          __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
+          __ beq(CMPRES, CMPRES2, &is_true);
           __ LoadObject(V0, Bool::True());
           __ b(&done);
           __ Bind(&is_true);
@@ -568,7 +568,7 @@
         if (branch->is_checked()) {
           EmitAssertBoolean(V0, token_pos, deopt_id, locs, compiler);
         }
-        __ CompareObject(CMPRES, TMP1, V0, Bool::True());
+        __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
         branch->EmitBranchOnCondition(compiler, cond);
       }
     }
@@ -600,9 +600,9 @@
   __ beq(CMPRES, ZR, deopt);
   // 'left' is not Smi.
   Label identity_compare;
-  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
-  __ beq(right, TMP, &identity_compare);
-  __ beq(left, TMP, &identity_compare);
+  __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
+  __ beq(right, CMPRES1, &identity_compare);
+  __ beq(left, CMPRES1, &identity_compare);
 
   __ LoadClassId(temp, left);
   const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
@@ -615,7 +615,7 @@
     }
   }
   __ Bind(&identity_compare);
-  __ subu(CMPRES, left, right);
+  __ subu(CMPRES1, left, right);
   if (branch == NULL) {
     Label done, is_equal;
     Register result = locs.out().reg();
@@ -631,7 +631,7 @@
 
   } else {
     Condition cond = TokenKindToSmiCondition(kind);
-    __ mov(TMP, ZR);
+    __ mov(CMPRES2, ZR);
     branch->EmitBranchOnCondition(compiler, cond);
   }
 }
@@ -654,15 +654,15 @@
   Label done, identity_compare, non_null_compare;
   __ TraceSimMsg("EmitGenericEqualityCompare");
   __ Comment("EmitGenericEqualityCompare");
-  __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
-  __ beq(right, TMP, &identity_compare);
-  __ bne(left, TMP, &non_null_compare);
+  __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null()));
+  __ beq(right, CMPRES1, &identity_compare);
+  __ bne(left, CMPRES1, &non_null_compare);
 
   // Comparison with NULL is "===".
   __ Bind(&identity_compare);
   Condition cond = TokenKindToSmiCondition(kind);
-  __ slt(CMPRES, left, right);
-  __ slt(TMP1, right, left);
+  __ slt(CMPRES1, left, right);
+  __ slt(CMPRES2, right, left);
   if (branch != NULL) {
     branch->EmitBranchOnCondition(compiler, cond);
   } else {
@@ -715,13 +715,13 @@
   Condition true_condition = TokenKindToSmiCondition(kind);
 
   if (left.IsConstant()) {
-    __ CompareObject(CMPRES, TMP1, right.reg(), left.constant());
+    __ CompareObject(CMPRES1, CMPRES2, right.reg(), left.constant());
     true_condition = FlipCondition(true_condition);
   } else if (right.IsConstant()) {
-    __ CompareObject(CMPRES, TMP1, left.reg(), right.constant());
+    __ CompareObject(CMPRES1, CMPRES2, left.reg(), right.constant());
   } else {
-    __ slt(CMPRES, left.reg(), right.reg());
-    __ slt(TMP1, right.reg(), left.reg());
+    __ slt(CMPRES1, left.reg(), right.reg());
+    __ slt(CMPRES2, right.reg(), left.reg());
   }
 
   if (branch != NULL) {
@@ -794,15 +794,15 @@
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
   BranchInstr* kNoBranch = NULL;
   __ Comment("EqualityCompareInstr");
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
@@ -838,16 +838,16 @@
   __ TraceSimMsg("EqualityCompareInstr");
   __ Comment("EqualityCompareInstr:BranchCode");
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     // Deoptimizes if both arguments not Smi.
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
@@ -878,7 +878,7 @@
     EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler);
   }
   Condition branch_condition = (kind() == Token::kNE) ? NE : EQ;
-  __ CompareObject(CMPRES, TMP1, V0, Bool::True());
+  __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
   branch->EmitBranchOnCondition(compiler, branch_condition);
 }
 
@@ -886,7 +886,7 @@
 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     const intptr_t kNumTemps = 2;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -897,14 +897,14 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RequiresFpuRegister());
     summary->set_in(1, Location::RequiresFpuRegister());
     summary->set_out(Location::RequiresRegister());
     return summary;
-  } else if (operands_class_id() == kSmiCid) {
+  } else if (operation_cid() == kSmiCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RegisterOrConstant(left()));
@@ -928,15 +928,15 @@
 
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ TraceSimMsg("RelationalOpInstr");
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
@@ -1005,20 +1005,20 @@
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
   __ TraceSimMsg("RelationalOpInstr");
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kMintCid) {
+  if (operation_cid() == kMintCid) {
     EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
   EmitNativeCode(compiler);
-  __ CompareObject(CMPRES, TMP1, V0, Bool::True());
+  __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True());
   branch->EmitBranchOnCondition(compiler, EQ);
 }
 
@@ -1631,8 +1631,8 @@
 
       LoadValueCid(compiler, value_cid_reg, value_reg);
 
-      __ lw(TMP1, field_cid_operand);
-      __ beq(value_cid_reg, TMP1, &ok);
+      __ lw(CMPRES1, field_cid_operand);
+      __ beq(value_cid_reg, CMPRES1, &ok);
       __ lw(TMP1, field_nullability_operand);
       __ subu(CMPRES, value_cid_reg, TMP1);
     } else if (value_cid == kNullCid) {
@@ -1648,8 +1648,8 @@
     }
     __ beq(CMPRES, ZR, &ok);
 
-    __ lw(TMP1, field_cid_operand);
-    __ BranchNotEqual(TMP1, kIllegalCid, fail);
+    __ lw(CMPRES1, field_cid_operand);
+    __ BranchNotEqual(CMPRES1, kIllegalCid, fail);
 
     if (value_cid == kDynamicCid) {
       __ sw(value_cid_reg, field_cid_operand);
@@ -1704,8 +1704,8 @@
     ASSERT(!compiler->is_optimizing());
     __ Bind(fail);
 
-    __ lw(TMP1, FieldAddress(field_reg, Field::guarded_cid_offset()));
-    __ BranchEqual(TMP1, kDynamicCid, &ok);
+    __ lw(CMPRES1, FieldAddress(field_reg, Field::guarded_cid_offset()));
+    __ BranchEqual(CMPRES1, kDynamicCid, &ok);
 
     __ addiu(SP, SP, Immediate(-2 * kWordSize));
     __ sw(field_reg, Address(SP, 1 * kWordSize));
@@ -2144,20 +2144,14 @@
   __ sw(kStackTraceObjectReg,
         Address(FP, stacktrace_var().index() * kWordSize));
 
-  Label next;
-  __ mov(TMP, RA);  // Save return adress.
-  // Restore the pool pointer.
-  __ bal(&next);  // Branch and link to next instruction to get PC in RA.
-  __ delay_slot()->mov(CMPRES, RA);  // Save PC of the following mov.
+  __ GetNextPC(CMPRES, TMP);
 
   // Calculate offset of pool pointer from the PC.
   const intptr_t object_pool_pc_dist =
      Instructions::HeaderSize() - Instructions::object_pool_offset() +
-     compiler->assembler()->CodeSize();
+     compiler->assembler()->CodeSize() - 1 * Instr::kInstrSize;
 
-  __ Bind(&next);
-  __ mov(RA, TMP);  // Restore return address.
-  __ lw(PP, Address(CMPRES, -object_pool_pc_dist));
+  __ LoadFromOffset(PP, CMPRES, -object_pool_pc_dist);
 }
 
 
@@ -2215,8 +2209,8 @@
 
   __ LoadImmediate(TMP1, Isolate::Current()->stack_limit_address());
 
-  __ lw(TMP1, Address(TMP1));
-  __ BranchUnsignedLessEqual(SP, TMP1, slow_path->entry_label());
+  __ lw(CMPRES1, Address(TMP1));
+  __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label());
   if (compiler->CanOSRFunction() && in_loop()) {
     Register temp = locs()->temp(0).reg();
     // In unoptimized code check the usage counter to trigger OSR at loop
@@ -2266,8 +2260,8 @@
       if (!is_truncating) {
         // Check for overflow (preserve left).
         __ sll(TMP1, left, value);
-        __ sra(TMP1, TMP1, value);
-        __ bne(TMP1, left, deopt);  // Overflow.
+        __ sra(CMPRES1, TMP1, value);
+        __ bne(CMPRES1, left, deopt);  // Overflow.
       }
       // Shift for result now we know there is no overflow.
       __ sll(result, left, value);
@@ -2334,15 +2328,15 @@
           right, reinterpret_cast<int32_t>(Smi::New(Smi::kBits)), deopt);
     }
     // Left is not a constant.
-    // Check if count too large for handling it inlined.
-    __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
-    // Overflow test (preserve left, right, and TMP);
     Register temp = locs.temp(0).reg();
-    __ sllv(temp, left, TMP);
-    __ srav(temp, temp, TMP);
-    __ bne(temp, left, deopt);  // Overflow.
+    // Check if count too large for handling it inlined.
+    __ sra(temp, right, kSmiTagSize);  // SmiUntag right into temp.
+    // Overflow test (preserve left, right, and temp);
+    __ sllv(CMPRES1, left, temp);
+    __ srav(CMPRES1, CMPRES1, temp);
+    __ bne(CMPRES1, left, deopt);  // Overflow.
     // Shift for result now we know there is no overflow.
-    __ sllv(result, left, TMP);
+    __ sllv(result, left, temp);
   }
 }
 
@@ -2433,16 +2427,16 @@
           }
         } else {
           if (value == 2) {
-            __ sra(TMP1, left, 31);  // TMP1 = sign of left.
+            __ sra(CMPRES2, left, 31);  // CMPRES2 = sign of left.
             __ sll(result, left, 1);
           } else {
             __ LoadImmediate(TMP1, value);
             __ mult(left, TMP1);
             __ mflo(result);
-            __ mfhi(TMP1);
+            __ mfhi(CMPRES2);
           }
           __ sra(CMPRES, result, 31);
-          __ bne(TMP1, CMPRES, deopt);
+          __ bne(CMPRES1, CMPRES2, deopt);
         }
         break;
       }
@@ -2569,9 +2563,9 @@
       __ mult(TMP, right);
       __ mflo(result);
       if (deopt != NULL) {
-        __ mfhi(TMP1);
-        __ sra(CMPRES, result, 31);
-        __ bne(TMP1, CMPRES, deopt);
+        __ mfhi(CMPRES2);
+        __ sra(CMPRES1, result, 31);
+        __ bne(CMPRES1, CMPRES2, deopt);
       }
       break;
     }
@@ -2605,23 +2599,24 @@
       break;
     }
     case Token::kSHR: {
+      Register temp = locs()->temp(0).reg();
       if (CanDeoptimize()) {
         __ bltz(right, deopt);
       }
-      __ sra(TMP, right, kSmiTagSize);  // SmiUntag right into TMP.
+      __ sra(temp, right, kSmiTagSize);  // SmiUntag right into temp.
       // sra operation masks the count to 5 bits.
       const intptr_t kCountLimit = 0x1F;
       Range* right_range = this->right()->definition()->range();
       if ((right_range == NULL) ||
           !right_range->IsWithin(RangeBoundary::kMinusInfinity, kCountLimit)) {
         Label ok;
-        __ BranchSignedLessEqual(TMP, kCountLimit, &ok);
-        __ LoadImmediate(TMP, kCountLimit);
+        __ BranchSignedLessEqual(temp, kCountLimit, &ok);
+        __ LoadImmediate(temp, kCountLimit);
         __ Bind(&ok);
       }
-      Register temp = locs()->temp(0).reg();
-      __ sra(temp, left, kSmiTagSize);  // SmiUntag left into temp.
-      __ srav(result, temp, TMP);
+
+      __ sra(CMPRES1, left, kSmiTagSize);  // SmiUntag left into CMPRES1.
+      __ srav(result, CMPRES1, temp);
       __ SmiTag(result);
       break;
     }
@@ -2776,8 +2771,8 @@
 
     __ andi(CMPRES, value, Immediate(kSmiTagMask));
     __ beq(CMPRES, ZR, &is_smi);
-    __ LoadClassId(TMP, value);
-    __ BranchNotEqual(TMP, kDoubleCid, deopt);
+    __ LoadClassId(CMPRES1, value);
+    __ BranchNotEqual(CMPRES1, kDoubleCid, deopt);
     __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
     __ b(&done);
     __ Bind(&is_smi);
@@ -3469,8 +3464,8 @@
   Register value = locs()->in(0).reg();
   Label* deopt = compiler->AddDeoptStub(deopt_id(),
                                         kDeoptCheckSmi);
-  __ andi(TMP1, value, Immediate(kSmiTagMask));
-  __ bne(TMP1, ZR, deopt);
+  __ andi(CMPRES1, value, Immediate(kSmiTagMask));
+  __ bne(CMPRES1, ZR, deopt);
 }
 
 
@@ -3737,10 +3732,10 @@
   Register result = locs()->out().reg();
   Label load_true, done;
   if (kind() == Token::kEQ_STRICT) {
-    __ beq(CMPRES, TMP1, &load_true);
+    __ beq(CMPRES1, CMPRES2, &load_true);
   } else {
     ASSERT(kind() == Token::kNE_STRICT);
-    __ bne(CMPRES, TMP1, &load_true);
+    __ bne(CMPRES1, CMPRES2, &load_true);
   }
   __ LoadObject(result, Bool::False());
   __ b(&done);
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 8fd3bf2..3ab4d0f 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -169,7 +169,7 @@
   if (!(comparison->IsStrictCompare() &&
         !comparison->AsStrictCompare()->needs_number_check()) &&
       !(comparison->IsEqualityCompare() &&
-        (comparison->AsEqualityCompare()->receiver_class_id() == kSmiCid))) {
+        (comparison->AsEqualityCompare()->operation_cid() == kSmiCid))) {
     return false;
   }
 
@@ -396,7 +396,7 @@
 
 LocationSummary* EqualityCompareInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     const intptr_t kNumTemps =  0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -405,7 +405,7 @@
     locs->set_out(Location::RequiresRegister());
     return locs;
   }
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     const intptr_t kNumTemps = 0;
     LocationSummary* locs =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
@@ -841,12 +841,12 @@
 void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE));
   BranchInstr* kNoBranch = NULL;
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     // Deoptimizes if both arguments not Smi.
     EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
     EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
     return;
@@ -878,12 +878,12 @@
 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                           BranchInstr* branch) {
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
-  if (receiver_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     // Deoptimizes if both arguments not Smi.
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (receiver_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
@@ -920,14 +920,14 @@
 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 2;
   const intptr_t kNumTemps = 0;
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RequiresFpuRegister());
     summary->set_in(1, Location::RequiresFpuRegister());
     summary->set_out(Location::RequiresRegister());
     return summary;
-  } else if (operands_class_id() == kSmiCid) {
+  } else if (operation_cid() == kSmiCid) {
     LocationSummary* summary =
         new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
     summary->set_in(0, Location::RegisterOrConstant(left()));
@@ -950,11 +950,11 @@
 
 
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
     return;
   }
@@ -1024,11 +1024,11 @@
 
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
-  if (operands_class_id() == kSmiCid) {
+  if (operation_cid() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
-  if (operands_class_id() == kDoubleCid) {
+  if (operation_cid() == kDoubleCid) {
     EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
     return;
   }
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 8f75d2e..61c0a82 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -213,8 +213,8 @@
 
     // Check if it's dynamic.
     // For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
-    __ LoadClassId(TMP, T1);
-    __ BranchNotEqual(TMP, kTypeArgumentsCid, &fall_through);
+    __ LoadClassId(CMPRES1, T1);
+    __ BranchNotEqual(CMPRES1, kTypeArgumentsCid, &fall_through);
 
     // Get type at index 0.
     __ lw(T0, FieldAddress(T1, TypeArguments::type_at_offset(0)));
@@ -424,8 +424,8 @@
   // Check that data is an ObjectArray.
   __ andi(CMPRES, T1, Immediate(kSmiTagMask));
   __ beq(CMPRES, ZR, &fall_through);  // Data is Smi.
-  __ LoadClassId(TMP, T1);
-  __ BranchNotEqual(TMP, kArrayCid, &fall_through);
+  __ LoadClassId(CMPRES1, T1);
+  __ BranchNotEqual(CMPRES1, kArrayCid, &fall_through);
   __ lw(T0, Address(SP, 1 * kWordSize));  // Growable array.
   __ StoreIntoObject(T0,
                      FieldAddress(T0, GrowableObjectArray::data_offset()),
@@ -865,8 +865,8 @@
   // Check for overflow by shifting left and shifting back arithmetically.
   // If the result is different from the original, there was overflow.
   __ sllv(TMP, T1, T0);
-  __ srav(TMP, TMP, T0);
-  __ bne(TMP, T1, &overflow);
+  __ srav(CMPRES1, TMP, T0);
+  __ bne(CMPRES1, T1, &overflow);
 
   // No overflow, result in V0.
   __ Ret();
@@ -920,8 +920,8 @@
   __ delay_slot()->sra(res_hi, reg, 31);
 
   __ Bind(&not_smi);
-  __ LoadClassId(TMP, reg);
-  __ BranchNotEqual(TMP, kMintCid, not_smi_or_mint);
+  __ LoadClassId(CMPRES1, reg);
+  __ BranchNotEqual(CMPRES1, kMintCid, not_smi_or_mint);
 
   // Mint.
   __ lw(res_lo, FieldAddress(reg, Mint::value_offset()));
@@ -1061,16 +1061,16 @@
   // Note that an instance of Mint or Bigint never contains a value that can be
   // represented by Smi.
 
-  __ LoadClassId(TMP, T0);
-  __ BranchEqual(TMP, kDoubleCid, &fall_through);
+  __ LoadClassId(CMPRES1, T0);
+  __ BranchEqual(CMPRES1, kDoubleCid, &fall_through);
   __ LoadObject(V0, Bool::False());  // Smi == Mint -> false.
   __ Ret();
 
   __ Bind(&receiver_not_smi);
   // T1:: receiver.
 
-  __ LoadClassId(TMP, T1);
-  __ BranchNotEqual(TMP, kMintCid, &fall_through);
+  __ LoadClassId(CMPRES1, T1);
+  __ BranchNotEqual(CMPRES1, kMintCid, &fall_through);
   // Receiver is Mint, return false if right is Smi.
   __ andi(CMPRES, T0, Immediate(kSmiTagMask));
   __ bne(CMPRES, ZR, &fall_through);
@@ -1128,8 +1128,8 @@
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ andi(CMPRES, T0, Immediate(kSmiTagMask));
   __ beq(CMPRES, ZR, is_smi);
-  __ LoadClassId(TMP, T0);
-  __ BranchNotEqual(TMP, kDoubleCid, not_double_smi);
+  __ LoadClassId(CMPRES1, T0);
+  __ BranchNotEqual(CMPRES1, kDoubleCid, not_double_smi);
   // Fall through with Double in T0.
 }
 
@@ -1518,8 +1518,8 @@
   __ lw(T2, FieldAddress(T0, String::length_offset()));  // Range check.
   // Runtime throws exception.
   __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
-  __ LoadClassId(TMP1, T0);  // Class ID check.
-  __ BranchNotEqual(TMP1, kOneByteStringCid, &try_two_byte_string);
+  __ LoadClassId(CMPRES1, T0);  // Class ID check.
+  __ BranchNotEqual(CMPRES1, kOneByteStringCid, &try_two_byte_string);
 
   // Grab byte and return.
   __ SmiUntag(T1);
@@ -1529,7 +1529,7 @@
   __ delay_slot()->SmiTag(V0);
 
   __ Bind(&try_two_byte_string);
-  __ BranchNotEqual(TMP1, kTwoByteStringCid, &fall_through);
+  __ BranchNotEqual(CMPRES1, kTwoByteStringCid, &fall_through);
   ASSERT(kSmiTagShift == 1);
   __ addu(T2, T0, T1);
   __ lhu(V0, FieldAddress(T2, OneByteString::data_offset()));
@@ -1593,25 +1593,25 @@
   // T5: ch.
   __ addiu(T3, T3, Immediate(1));
   __ addu(V0, V0, T5);
-  __ sll(TMP, V0, 10);
-  __ addu(V0, V0, TMP);
-  __ srl(TMP, V0, 6);
+  __ sll(T6, V0, 10);
+  __ addu(V0, V0, T6);
+  __ srl(T6, V0, 6);
   __ bne(T3, T4, &loop);
-  __ delay_slot()->xor_(V0, V0, TMP);
+  __ delay_slot()->xor_(V0, V0, T6);
 
   // Finalize.
   // hash_ += hash_ << 3;
   // hash_ ^= hash_ >> 11;
   // hash_ += hash_ << 15;
-  __ sll(TMP, V0, 3);
-  __ addu(V0, V0, TMP);
-  __ srl(TMP, V0, 11);
-  __ xor_(V0, V0, TMP);
-  __ sll(TMP, V0, 15);
-  __ addu(V0, V0, TMP);
+  __ sll(T6, V0, 3);
+  __ addu(V0, V0, T6);
+  __ srl(T6, V0, 11);
+  __ xor_(V0, V0, T6);
+  __ sll(T6, V0, 15);
+  __ addu(V0, V0, T6);
   // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
-  __ LoadImmediate(TMP, (static_cast<intptr_t>(1) << String::kHashBits) - 1);
-  __ and_(V0, V0, TMP);
+  __ LoadImmediate(T6, (static_cast<intptr_t>(1) << String::kHashBits) - 1);
+  __ and_(V0, V0, T6);
   __ Bind(&done);
 
   __ LoadImmediate(T2, 1);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b0bfbe8..dae6510 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1739,6 +1739,7 @@
   if (super.IsNull()) {
     offset = sizeof(RawObject);
   } else {
+    ASSERT(super.is_finalized() || super.is_prefinalized());
     type_args_field_offset = super.type_arguments_field_offset();
     offset = super.next_field_offset();
     ASSERT(offset > 0);
@@ -1747,7 +1748,9 @@
     ASSERT(num_native_fields() == 0);
     set_num_native_fields(super.num_native_fields());
   }
-  // If the super class is parameterized, use the same type_arguments field.
+  // If the super class is parameterized, use the same type_arguments field,
+  // otherwise, if this class is the first in the super chain to be
+  // parameterized, introduce a new type_arguments field.
   if (type_args_field_offset == kNoTypeArguments) {
     const TypeArguments& type_params = TypeArguments::Handle(type_parameters());
     if (!type_params.IsNull()) {
@@ -8864,16 +8867,19 @@
 
 
 void ICData::set_function(const Function& value) const {
+  ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->function_, value.raw());
 }
 
 
 void ICData::set_target_name(const String& value) const {
+  ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->target_name_, value.raw());
 }
 
 
 void ICData::set_arguments_descriptor(const Array& value) const {
+  ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->args_descriptor_, value.raw());
 }
 
@@ -8888,6 +8894,7 @@
 
 
 void ICData::set_ic_data(const Array& value) const {
+  ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->ic_data_, value.raw());
 }
 
@@ -8918,6 +8925,7 @@
 
 
 void ICData::WriteSentinel(const Array& data) const {
+  ASSERT(!data.IsNull());
   for (intptr_t i = 1; i <= TestEntryLength(); i++) {
     data.SetAt(data.Length() - i, smi_illegal_cid());
   }
@@ -8950,6 +8958,7 @@
 
 // Used for unoptimized static calls when no class-ids are checked.
 void ICData::AddTarget(const Function& target) const {
+  ASSERT(!target.IsNull());
   if (num_args_tested() > 0) {
     // Create a fake cid entry, so that we can store the target.
     GrowableArray<intptr_t> class_ids(num_args_tested());
@@ -8978,6 +8987,7 @@
 
 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
                       const Function& target) const {
+  ASSERT(!target.IsNull());
   DEBUG_ASSERT(!HasCheck(class_ids));
   ASSERT(num_args_tested() > 1);  // Otherwise use 'AddReceiverCheck'.
   ASSERT(class_ids.length() == num_args_tested());
@@ -9033,6 +9043,7 @@
   class_ids.Add(receiver_class_id);
   ASSERT(!HasCheck(class_ids));
 #endif  // DEBUG
+  ASSERT(!target.IsNull());
   ASSERT(num_args_tested() == 1);  // Otherwise use 'AddCheck'.
   ASSERT(receiver_class_id != kIllegalCid);
 
@@ -9269,6 +9280,9 @@
                        const Array& arguments_descriptor,
                        intptr_t deopt_id,
                        intptr_t num_args_tested) {
+  ASSERT(!function.IsNull());
+  ASSERT(!target_name.IsNull());
+  ASSERT(!arguments_descriptor.IsNull());
   ASSERT(Object::icdata_class() != Class::null());
   ASSERT(num_args_tested >= 0);
   ICData& result = ICData::Handle();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 04581ae..a02cee2 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3322,6 +3322,7 @@
   void GetCheckAt(intptr_t index,
                   GrowableArray<intptr_t>* class_ids,
                   Function* target) const;
+  // Only for 'num_args_checked == 1'.
   void GetOneClassCheckAt(intptr_t index,
                           intptr_t* class_id,
                           Function* target) const;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 71eb3f2..11bd5e7 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -9526,6 +9526,7 @@
                                     InvocationMirror::kConstructor,
                                     InvocationMirror::kMethod);
     } else if (constructor.IsRedirectingFactory()) {
+      ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
       Type& redirect_type = Type::Handle(constructor.RedirectionType());
       if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) {
         // The type arguments of the redirection type are instantiated from the
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index d93753a..c30e25e 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1489,6 +1489,13 @@
       DoBranch(instr, rs_val >= 0, false);
       break;
     }
+    case BLTZAL: {
+      int32_t rs_val = get_register(instr->RsField());
+      // Return address is one after the delay slot.
+      set_register(RA, pc_ + (2*Instr::kInstrSize));
+      DoBranch(instr, rs_val < 0, false);
+      break;
+    }
     case BGEZL: {
       // Format(instr, "bgezl 'rs, 'dest");
       int32_t rs_val = get_register(instr->RsField());
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index d71bed8..bf9b5e4 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -976,8 +976,9 @@
 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
                                               const Class& cls) {
   // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized =
-      cls.type_arguments_field_offset() != Class::kNoTypeArguments;
+  const bool is_cls_parameterized = cls.HasTypeArguments();
+  ASSERT(!cls.HasTypeArguments() ||
+         (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
   // kInlineInstanceSize is a constant used as a threshold for determining
   // when the object initialization should be done as a loop or as
   // straight line code.
@@ -1143,8 +1144,7 @@
 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
                                                 const Function& func) {
   ASSERT(func.IsClosureFunction());
-  const bool is_implicit_static_closure =
-      func.IsImplicitStaticClosureFunction();
+  ASSERT(!func.IsImplicitStaticClosureFunction());
   const bool is_implicit_instance_closure =
       func.IsImplicitInstanceClosureFunction();
   const Class& cls = Class::ZoneHandle(func.signature_class());
@@ -1199,14 +1199,7 @@
     __ str(R0, Address(R2, Closure::function_offset()));
 
     // Setup the context for this closure.
-    if (is_implicit_static_closure) {
-      ObjectStore* object_store = Isolate::Current()->object_store();
-      ASSERT(object_store != NULL);
-      const Context& empty_context =
-          Context::ZoneHandle(object_store->empty_context());
-      __ LoadObject(R0, empty_context);
-      __ str(R0, Address(R2, Closure::context_offset()));
-    } else if (is_implicit_instance_closure) {
+    if (is_implicit_instance_closure) {
       // Initialize the new context capturing the receiver.
       const Class& context_class = Class::ZoneHandle(Object::context_class());
       // Set the tags.
@@ -1255,27 +1248,23 @@
   __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
   __ Push(R0);  // Setup space on stack for return value.
   __ PushObject(func);
-  if (is_implicit_static_closure) {
-    __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
-  } else {
-    if (is_implicit_instance_closure) {
-      __ ldr(R1, Address(FP, kReceiverFPOffset));
-      __ Push(R1);  // Receiver.
-    }
-    // R0: raw null.
-    if (has_type_arguments) {
-      __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
-    }
-    __ Push(R0);  // Push type arguments of closure to be allocated or null.
+  if (is_implicit_instance_closure) {
+    __ ldr(R1, Address(FP, kReceiverFPOffset));
+    __ Push(R1);  // Receiver.
+  }
+  // R0: raw null.
+  if (has_type_arguments) {
+    __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
+  }
+  __ Push(R0);  // Push type arguments of closure to be allocated or null.
 
-    if (is_implicit_instance_closure) {
-      __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
-      __ Drop(2);  // Pop arguments (type arguments of object and receiver).
-    } else {
-      ASSERT(func.IsNonImplicitClosureFunction());
-      __ CallRuntime(kAllocateClosureRuntimeEntry);
-      __ Drop(1);  // Pop argument (type arguments of object).
-    }
+  if (is_implicit_instance_closure) {
+    __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
+    __ Drop(2);  // Pop arguments (type arguments of object and receiver).
+  } else {
+    ASSERT(func.IsNonImplicitClosureFunction());
+    __ CallRuntime(kAllocateClosureRuntimeEntry);
+    __ Drop(1);  // Pop argument (type arguments of object).
   }
   __ Drop(1);  // Pop function object.
   __ Pop(R0);
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 926816e..6dd0a85 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1023,8 +1023,9 @@
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized =
-      cls.type_arguments_field_offset() != Class::kNoTypeArguments;
+  const bool is_cls_parameterized = cls.HasTypeArguments();
+  ASSERT(!cls.HasTypeArguments() ||
+         (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
   // kInlineInstanceSize is a constant used as a threshold for determining
   // when the object initialization should be done as a loop or as
   // straight line code.
@@ -1195,8 +1196,7 @@
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   ASSERT(func.IsClosureFunction());
-  const bool is_implicit_static_closure =
-      func.IsImplicitStaticClosureFunction();
+  ASSERT(!func.IsImplicitStaticClosureFunction());
   const bool is_implicit_instance_closure =
       func.IsImplicitInstanceClosureFunction();
   const Class& cls = Class::ZoneHandle(func.signature_class());
@@ -1246,14 +1246,7 @@
     __ movl(Address(EAX, Closure::function_offset()), EDX);
 
     // Setup the context for this closure.
-    if (is_implicit_static_closure) {
-      ObjectStore* object_store = Isolate::Current()->object_store();
-      ASSERT(object_store != NULL);
-      const Context& empty_context =
-          Context::ZoneHandle(object_store->empty_context());
-      __ LoadObject(EDX, empty_context);
-      __ movl(Address(EAX, Closure::context_offset()), EDX);
-    } else if (is_implicit_instance_closure) {
+    if (is_implicit_instance_closure) {
       // Initialize the new context capturing the receiver.
       const Class& context_class = Class::ZoneHandle(Object::context_class());
       // Set the tags.
@@ -1305,26 +1298,22 @@
   __ EnterStubFrame();
   __ pushl(raw_null);  // Setup space on stack for return value.
   __ PushObject(func);
-  if (is_implicit_static_closure) {
-    __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
+  if (is_implicit_instance_closure) {
+    __ pushl(EAX);  // Receiver.
+  }
+  if (has_type_arguments) {
+    __ pushl(ECX);  // Push type arguments of closure to be allocated.
   } else {
-    if (is_implicit_instance_closure) {
-      __ pushl(EAX);  // Receiver.
-    }
-    if (has_type_arguments) {
-      __ pushl(ECX);  // Push type arguments of closure to be allocated.
-    } else {
-      __ pushl(raw_null);  // Push null type arguments.
-    }
-    if (is_implicit_instance_closure) {
-      __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
-      __ popl(EAX);  // Pop argument (type arguments of object).
-      __ popl(EAX);  // Pop receiver.
-    } else {
-      ASSERT(func.IsNonImplicitClosureFunction());
-      __ CallRuntime(kAllocateClosureRuntimeEntry);
-      __ popl(EAX);  // Pop argument (type arguments of object).
-    }
+    __ pushl(raw_null);  // Push null type arguments.
+  }
+  if (is_implicit_instance_closure) {
+    __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
+    __ popl(EAX);  // Pop argument (type arguments of object).
+    __ popl(EAX);  // Pop receiver.
+  } else {
+    ASSERT(func.IsNonImplicitClosureFunction());
+    __ CallRuntime(kAllocateClosureRuntimeEntry);
+    __ popl(EAX);  // Pop argument (type arguments of object).
   }
   __ popl(EAX);  // Pop function object.
   __ popl(EAX);
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 5644aa4..115bd84 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -300,12 +300,12 @@
   __ delay_slot()->addiu(T2, V0,
                          Immediate(Array::data_offset() - kHeapObjectTag));
   __ Bind(&loop);
-  __ lw(TMP, Address(T1));
+  __ lw(T3, Address(T1));
   __ addiu(A1, A1, Immediate(-Smi::RawValue(1)));
   __ addiu(T1, T1, Immediate(-kWordSize));
   __ addiu(T2, T2, Immediate(kWordSize));
   __ bgez(A1, &loop);
-  __ delay_slot()->sw(TMP, Address(T2, -kWordSize));
+  __ delay_slot()->sw(T3, Address(T2, -kWordSize));
   __ Bind(&loop_exit);
 }
 
@@ -589,8 +589,8 @@
     // T0: points to new space object.
     // T2: potential next object start.
     // T3: array size.
-    __ lw(TMP1, Address(T0, Scavenger::end_offset()));
-    __ BranchUnsignedGreaterEqual(T2, TMP1, &slow_case);
+    __ lw(CMPRES1, Address(T0, Scavenger::end_offset()));
+    __ BranchUnsignedGreaterEqual(T2, CMPRES1, &slow_case);
 
     // Successfully allocated the object(s), now update top to point to
     // next object start and initialize the object.
@@ -953,11 +953,11 @@
     // T2: object size.
     // T3: potential next object start.
     __ LoadImmediate(TMP1, heap->EndAddress());
-    __ lw(TMP1, Address(TMP1, 0));
+    __ lw(CMPRES1, Address(TMP1, 0));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
     } else {
-      __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case);
+      __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
     }
 
     // Successfully allocated the object, now update top to point to
@@ -1012,9 +1012,9 @@
     __ sll(T1, T1, 2);
     __ Bind(&loop);
     __ addiu(T1, T1, Immediate(-kWordSize));
-    __ addu(TMP1, T3, T1);
+    __ addu(T4, T3, T1);
     __ bgtz(T1, &loop);
-    __ delay_slot()->sw(T7, Address(TMP1));
+    __ delay_slot()->sw(T7, Address(T4));
     __ Bind(&loop_exit);
 
     // Done allocating and initializing the context.
@@ -1126,8 +1126,9 @@
                                               const Class& cls) {
   __ TraceSimMsg("AllocationStubForClass");
   // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized =
-      cls.type_arguments_field_offset() != Class::kNoTypeArguments;
+  const bool is_cls_parameterized = cls.HasTypeArguments();
+  ASSERT(!cls.HasTypeArguments() ||
+         (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
   // kInlineInstanceSize is a constant used as a threshold for determining
   // when the object initialization should be done as a loop or as
   // straight line code.
@@ -1161,11 +1162,11 @@
     // T2: potential new object start.
     // T3: potential next object start.
     __ LoadImmediate(TMP1, heap->EndAddress());
-    __ lw(TMP1, Address(TMP1));
+    __ lw(CMPRES1, Address(TMP1));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
     } else {
-      __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case);
+      __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
     }
 
     // Successfully allocated the object(s), now update top to point to
@@ -1300,8 +1301,7 @@
 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
                                                 const Function& func) {
   ASSERT(func.IsClosureFunction());
-  const bool is_implicit_static_closure =
-      func.IsImplicitStaticClosureFunction();
+  ASSERT(!func.IsImplicitStaticClosureFunction());
   const bool is_implicit_instance_closure =
       func.IsImplicitInstanceClosureFunction();
   const Class& cls = Class::ZoneHandle(func.signature_class());
@@ -1329,11 +1329,11 @@
     // T3: address of top of heap.
     // T4: potential new context object (only if is_implicit_closure).
     __ LoadImmediate(TMP1, heap->EndAddress());
-    __ lw(TMP1, Address(TMP1));
+    __ lw(CMPRES1, Address(TMP1));
     if (FLAG_use_slow_path) {
       __ b(&slow_case);
     } else {
-      __ BranchUnsignedGreaterEqual(T3, TMP1, &slow_case);
+      __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case);
     }
 
     // Successfully allocated the object, now update top to point to
@@ -1356,14 +1356,7 @@
     __ sw(T0, Address(T2, Closure::function_offset()));
 
     // Setup the context for this closure.
-    if (is_implicit_static_closure) {
-      ObjectStore* object_store = Isolate::Current()->object_store();
-      ASSERT(object_store != NULL);
-      const Context& empty_context =
-          Context::ZoneHandle(object_store->empty_context());
-      __ LoadObject(T0, empty_context);
-      __ sw(T0, Address(T0, Closure::context_offset()));
-    } else if (is_implicit_instance_closure) {
+    if (is_implicit_instance_closure) {
       // Initialize the new context capturing the receiver.
       const Class& context_class = Class::ZoneHandle(Object::context_class());
       // Set the tags.
@@ -1409,40 +1402,31 @@
     __ Bind(&slow_case);
   }
 
-  // If it's an implicit static closure we need 2 stack slots. Otherwise,
   // If it's an implicit instance closure we need 4 stack slots, o/w only 3.
-  int num_slots = 2;
-  if (!is_implicit_static_closure) {
-    num_slots = is_implicit_instance_closure ? 4 : 3;
-  }
+  intptr_t num_slots = is_implicit_instance_closure ? 4 : 3;
   __ addiu(SP, SP, Immediate(-num_slots * kWordSize));
   // Setup space on stack for return value.
   __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null()));
   __ sw(T7, Address(SP, (num_slots - 1) * kWordSize));
   __ LoadObject(TMP1, func);
   __ sw(TMP1, Address(SP, (num_slots - 2) * kWordSize));
-  if (is_implicit_static_closure) {
-    __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
+  __ mov(T2, T7);
+  if (is_implicit_instance_closure) {
+    __ lw(T1, Address(FP, kReceiverFPOffset));
+    __ sw(T1, Address(SP, (num_slots - 3) * kWordSize));  // Receiver.
+  }
+  if (has_type_arguments) {
+    __ lw(T2, Address(FP, kTypeArgumentsFPOffset));
+  }
+  __ sw(T2, Address(SP, 0 * kWordSize));
+
+  if (is_implicit_instance_closure) {
+    __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
     __ TraceSimMsg("AllocationStubForClosure return");
   } else {
-    __ mov(T2, T7);
-    if (is_implicit_instance_closure) {
-      __ lw(T1, Address(FP, kReceiverFPOffset));
-      __ sw(T1, Address(SP, (num_slots - 3) * kWordSize));  // Receiver.
-    }
-    if (has_type_arguments) {
-      __ lw(T2, Address(FP, kTypeArgumentsFPOffset));
-    }
-    __ sw(T2, Address(SP, 0 * kWordSize));
-
-    if (is_implicit_instance_closure) {
-      __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
-      __ TraceSimMsg("AllocationStubForClosure return");
-    } else {
-      ASSERT(func.IsNonImplicitClosureFunction());
-      __ CallRuntime(kAllocateClosureRuntimeEntry);
-      __ TraceSimMsg("AllocationStubForClosure return");
-    }
+    ASSERT(func.IsNonImplicitClosureFunction());
+    __ CallRuntime(kAllocateClosureRuntimeEntry);
+    __ TraceSimMsg("AllocationStubForClosure return");
   }
   __ lw(V0, Address(SP, (num_slots - 1) * kWordSize));  // Pop function object.
   __ addiu(SP, SP, Immediate(num_slots * kWordSize));
@@ -1688,9 +1672,9 @@
   // NoSuchMethod or closure.
   // Mark IC call that it may be a closure call that does not collect
   // type feedback.
-  __ LoadImmediate(TMP1, 1);
+  __ LoadImmediate(T6, 1);
   __ Branch(&StubCode::InstanceFunctionLookupLabel());
-  __ delay_slot()->sb(TMP1, FieldAddress(S5, ICData::is_closure_call_offset()));
+  __ delay_slot()->sb(T6, FieldAddress(S5, ICData::is_closure_call_offset()));
 
   __ Bind(&found);
   // T0: Pointer to an IC data check group.
@@ -1718,8 +1702,8 @@
   __ Bind(&get_class_id_as_smi);
   Label not_smi;
   // Test if Smi -> load Smi class for comparison.
-  __ andi(TMP1, T3, Immediate(kSmiTagMask));
-  __ bne(TMP1, ZR, &not_smi);
+  __ andi(CMPRES1, T3, Immediate(kSmiTagMask));
+  __ bne(CMPRES1, ZR, &not_smi);
   __ jr(RA);
   __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
 
@@ -1854,8 +1838,8 @@
   // Get function and call it, if possible.
   __ lw(T3, Address(T0, target_offset));
   __ lw(T4, FieldAddress(T3, Function::code_offset()));
-  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
-  __ bne(T4, TMP, &target_is_compiled);
+  __ LoadImmediate(CMPRES1, reinterpret_cast<intptr_t>(Object::null()));
+  __ bne(T4, CMPRES1, &target_is_compiled);
 
   __ EnterStubFrame();
   // Preserve target function and IC data object.
@@ -1954,12 +1938,12 @@
   __ LeaveStubFrame();
 
   // Find out which dispatch stub to call.
-  __ lw(TMP1, FieldAddress(S5, ICData::num_args_tested_offset()));
+  __ lw(T1, FieldAddress(S5, ICData::num_args_tested_offset()));
 
   Label one_arg, two_args, three_args;
-  __ BranchEqual(TMP1, 1, &one_arg);
-  __ BranchEqual(TMP1, 2, &two_args);
-  __ BranchEqual(TMP1, 3, &three_args);
+  __ BranchEqual(T1, 1, &one_arg);
+  __ BranchEqual(T1, 2, &two_args);
+  __ BranchEqual(T1, 3, &three_args);
   __ Stop("Unsupported number of arguments tested.");
 
   __ Bind(&one_arg);
@@ -2121,8 +2105,8 @@
   static const intptr_t kNumArgsTested = 2;
 #if defined(DEBUG)
   { Label ok;
-    __ lw(TMP1, FieldAddress(T0, ICData::num_args_tested_offset()));
-    __ BranchEqual(TMP1, kNumArgsTested, &ok);
+    __ lw(CMPRES1, FieldAddress(T0, ICData::num_args_tested_offset()));
+    __ BranchEqual(CMPRES1, kNumArgsTested, &ok);
     __ Stop("Incorrect ICData for equality");
     __ Bind(&ok);
   }
@@ -2319,8 +2303,8 @@
   __ Bind(&reference_compare);
   __ subu(CMPRES, left, right);
   __ Bind(&done);
-  // A branch or test after this comparison will check CMPRES == TMP1.
-  __ mov(TMP1, ZR);
+  // A branch or test after this comparison will check CMPRES1 == CMPRES2.
+  __ mov(CMPRES2, ZR);
 }
 
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index e74e83f..c12b959 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1005,8 +1005,9 @@
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized =
-      cls.type_arguments_field_offset() != Class::kNoTypeArguments;
+  const bool is_cls_parameterized = cls.HasTypeArguments();
+  ASSERT(!cls.HasTypeArguments() ||
+         (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
   // kInlineInstanceSize is a constant used as a threshold for determining
   // when the object initialization should be done as a loop or as
   // straight line code.
@@ -1178,8 +1179,7 @@
   const Immediate& raw_null =
       Immediate(reinterpret_cast<intptr_t>(Object::null()));
   ASSERT(func.IsClosureFunction());
-  const bool is_implicit_static_closure =
-      func.IsImplicitStaticClosureFunction();
+  ASSERT(!func.IsImplicitStaticClosureFunction());
   const bool is_implicit_instance_closure =
       func.IsImplicitInstanceClosureFunction();
   const Class& cls = Class::ZoneHandle(func.signature_class());
@@ -1232,14 +1232,7 @@
     __ movq(Address(RAX, Closure::function_offset()), R10);
 
     // Setup the context for this closure.
-    if (is_implicit_static_closure) {
-      ObjectStore* object_store = Isolate::Current()->object_store();
-      ASSERT(object_store != NULL);
-      const Context& empty_context =
-          Context::ZoneHandle(object_store->empty_context());
-      __ LoadObject(R10, empty_context);
-      __ movq(Address(RAX, Closure::context_offset()), R10);
-    } else if (is_implicit_instance_closure) {
+    if (is_implicit_instance_closure) {
       // Initialize the new context capturing the receiver.
 
       const Class& context_class = Class::ZoneHandle(Object::context_class());
@@ -1291,26 +1284,22 @@
   __ EnterStubFrame();
   __ pushq(raw_null);  // Setup space on stack for the return value.
   __ PushObject(func);
-  if (is_implicit_static_closure) {
-    __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry);
+  if (is_implicit_instance_closure) {
+    __ pushq(RAX);  // Receiver.
+  }
+  if (has_type_arguments) {
+    __ pushq(RCX);  // Push type arguments of closure to be allocated.
   } else {
-    if (is_implicit_instance_closure) {
-      __ pushq(RAX);  // Receiver.
-    }
-    if (has_type_arguments) {
-      __ pushq(RCX);  // Push type arguments of closure to be allocated.
-    } else {
-      __ pushq(raw_null);  // Push null type arguments.
-    }
-    if (is_implicit_instance_closure) {
-      __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
-      __ popq(RAX);  // Pop type arguments.
-      __ popq(RAX);  // Pop receiver.
-    } else {
-      ASSERT(func.IsNonImplicitClosureFunction());
-      __ CallRuntime(kAllocateClosureRuntimeEntry);
-      __ popq(RAX);  // Pop type arguments.
-    }
+    __ pushq(raw_null);  // Push null type arguments.
+  }
+  if (is_implicit_instance_closure) {
+    __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
+    __ popq(RAX);  // Pop type arguments.
+    __ popq(RAX);  // Pop receiver.
+  } else {
+    ASSERT(func.IsNonImplicitClosureFunction());
+    __ CallRuntime(kAllocateClosureRuntimeEntry);
+    __ popq(RAX);  // Pop type arguments.
   }
   __ popq(RAX);  // Pop the function object.
   __ popq(RAX);  // Pop the result.
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index e78ada2..9f24fc6 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -177,7 +177,9 @@
         if (node != null) {
           cancel("$exception", node: node);
         } else {
-          reportDiagnostic(null, "$exception", api.Diagnostic.ERROR);
+          reportError(
+              null,
+              leg.MessageKind.GENERIC, {'text': 'Error: $exception'});
           throw new leg.CompilerCancelledException("$exception");
         }
       }
@@ -219,24 +221,32 @@
       }
       if (!allowInternalLibraryAccess) {
         if (node != null && importingLibrary != null) {
-          reportDiagnostic(spanFromNode(node),
-              'Error: Internal library $resolvedUri is not accessible from '
-              '${importingLibrary.canonicalUri}.',
-              api.Diagnostic.ERROR);
+          reportError(
+              node,
+              leg.MessageKind.GENERIC,
+              {'text':
+                  'Error: Internal library $resolvedUri is not accessible from '
+                  '${importingLibrary.canonicalUri}.'});
         } else {
-          reportDiagnostic(null,
-              'Error: Internal library $resolvedUri is not accessible.',
-              api.Diagnostic.ERROR);
+          reportError(
+              null,
+              leg.MessageKind.GENERIC,
+              {'text':
+                  'Error: Internal library $resolvedUri is not accessible.'});
         }
-        //path = null;
       }
     }
     if (path == null) {
       if (node != null) {
-        reportError(node, 'library not found ${resolvedUri}');
+        reportFatalError(
+            node,
+            leg.MessageKind.GENERIC,
+            {'text': 'Error: Library not found ${resolvedUri}.'});
       } else {
-        reportDiagnostic(null, 'library not found ${resolvedUri}',
-                         api.Diagnostic.ERROR);
+        reportFatalError(
+            null,
+            leg.MessageKind.GENERIC,
+            {'text': 'Error: Library not found ${resolvedUri}.'});
       }
       return null;
     }
@@ -257,16 +267,8 @@
 
   Uri translatePackageUri(Uri uri, tree.Node node) {
     if (packageRoot == null) {
-      if (node != null) {
-        reportErrorCode(node,
-            leg.MessageKind.PACKAGE_ROOT_NOT_SET,
-            {'uri': uri});
-      } else {
-        reportDiagnostic(null,
-            leg.MessageKind.PACKAGE_ROOT_NOT_SET.error({'uri': uri}).toString(),
-            api.Diagnostic.ERROR);
-      }
-      throw new leg.CompilerCancelledException("Package root not set.");
+      reportFatalError(
+          node, leg.MessageKind.PACKAGE_ROOT_NOT_SET, {'uri': uri});
     }
     return packageRoot.resolve(uri.path);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index 610114e..baaef0b 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -176,9 +176,8 @@
       Node node = element.parseNode(compiler);
       if (pendingVariables.contains(element)) {
         if (isConst) {
-          MessageKind kind = MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS;
-          compiler.reportError(node,
-                               new CompileTimeConstantError(kind));
+          compiler.reportFatalError(
+              node, MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS);
         } else {
           lazyStatics.add(element);
           return null;
@@ -200,12 +199,11 @@
             && element.isField()) {
           DartType elementType = element.computeType(compiler);
           DartType constantType = value.computeType(compiler);
-          if (elementType.isMalformed || constantType.isMalformed ||
-              !constantSystem.isSubtype(compiler, constantType, elementType)) {
+          if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
             if (isConst) {
-              compiler.reportError(node, new CompileTimeConstantError(
-                  MessageKind.NOT_ASSIGNABLE,
-                  {'fromType': constantType, 'toType': elementType}));
+              compiler.reportFatalError(
+                  node, MessageKind.NOT_ASSIGNABLE.error,
+                  {'fromType': constantType, 'toType': elementType});
             } else {
               // If the field can be lazily initialized, we will throw
               // the exception at runtime.
@@ -396,8 +394,8 @@
       LiteralMapEntry entry = link.head;
       Constant key = evaluateConstant(entry.key);
       if (!key.isString() || entry.key.asStringNode() == null) {
-        MessageKind kind = MessageKind.KEY_NOT_A_STRING_LITERAL;
-        compiler.reportError(entry.key, new ResolutionError(kind));
+        compiler.reportFatalError(
+            entry.key, MessageKind.KEY_NOT_A_STRING_LITERAL);
       }
       StringConstant keyConstant = key;
       if (!map.containsKey(key)) keys.add(key);
@@ -669,9 +667,9 @@
                                                  compileConstant,
                                                  compiler);
     if (!succeeded) {
-      MessageKind kind = MessageKind.INVALID_ARGUMENTS;
-      compiler.reportError(node,
-          new CompileTimeConstantError(kind, {'methodName': target.name}));
+      compiler.reportFatalError(
+          node,
+          MessageKind.INVALID_ARGUMENTS.error, {'methodName': target.name});
     }
     return compiledArguments;
   }
@@ -721,8 +719,8 @@
   error(Node node) {
     // TODO(floitsch): get the list of constants that are currently compiled
     // and present some kind of stack-trace.
-    MessageKind kind = MessageKind.NOT_A_COMPILE_TIME_CONSTANT;
-    compiler.reportError(node, new CompileTimeConstantError(kind));
+    compiler.reportFatalError(
+        node, MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
   }
 
   Constant signalNotCompileTimeConstant(Node node) {
@@ -746,8 +744,7 @@
 
   error(Node node) {
     // Just fail without reporting it anywhere.
-    throw new CompileTimeConstantError(
-        MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
+    throw new CompileTimeConstantError(MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
   }
 }
 
@@ -792,11 +789,10 @@
       DartType constantType = constant.computeType(compiler);
       // TODO(ngeoffray): Handle type parameters.
       if (elementType.element.isTypeVariable()) return;
-      if (elementType.isMalformed || constantType.isMalformed ||
-          !constantSystem.isSubtype(compiler, constantType, elementType)) {
-        compiler.reportError(node, new CompileTimeConstantError(
-            MessageKind.NOT_ASSIGNABLE,
-            {'fromType': elementType, 'toType': constantType}));
+      if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
+        compiler.reportFatalError(
+            node, MessageKind.NOT_ASSIGNABLE.error,
+            {'fromType': elementType, 'toType': constantType});
       }
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 47e44e7..86f5db8 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -397,7 +397,7 @@
     } on SpannableAssertionFailure catch (ex) {
       if (!hasCrashed) {
         SourceSpan span = spanFromSpannable(ex.node);
-        reportDiagnostic(span, ex.message, api.Diagnostic.ERROR);
+        reportError(ex.node, MessageKind.GENERIC, {'text': ex.message});
         pleaseReportCrash();
       }
       hasCrashed = true;
@@ -582,7 +582,7 @@
   void internalError(String message,
                      {Node node, Token token, HInstruction instruction,
                       Element element}) {
-    cancel('Internal error: $message',
+    cancel('Internal Error: $message',
            node: node, token: token,
            instruction: instruction, element: element);
   }
@@ -608,23 +608,24 @@
                HInstruction instruction, Element element}) {
     assembledCode = null; // Compilation failed. Make sure that we
                           // don't return a bogus result.
-    SourceSpan span = null;
+    Spannable spannable = null;
     if (node != null) {
-      span = spanFromNode(node);
+      spannable = node;
     } else if (token != null) {
-      span = spanFromTokens(token, token);
+      spannable = token;
     } else if (instruction != null) {
-      span = spanFromHInstruction(instruction);
+      spannable = instruction;
     } else if (element != null) {
-      span = spanFromElement(element);
+      spannable = element;
     } else {
       throw 'No error location for error: $reason';
     }
-    reportDiagnostic(span, reason, api.Diagnostic.ERROR);
+    reportError(spannable, MessageKind.GENERIC, {'text': reason});
     throw new CompilerCancelledException(reason);
   }
 
   SourceSpan spanFromSpannable(Spannable node, [Uri uri]) {
+    if (node == null) return null;
     if (node == CURRENT_ELEMENT_SPANNABLE) {
       node = currentElement;
     }
@@ -644,14 +645,6 @@
     }
   }
 
-  void reportFatalError(String reason, Element element,
-                        {Node node, Token token, HInstruction instruction}) {
-    withCurrentElement(element, () {
-      cancel(reason, node: node, token: token, instruction: instruction,
-             element: element);
-    });
-  }
-
   void log(message) {
     reportDiagnostic(null, message, api.Diagnostic.VERBOSE_INFO);
   }
@@ -698,7 +691,7 @@
         library.addToScope(dynamicClass, this);
       });
     }
-    if (uri == new Uri(scheme: 'dart', path: 'dart:mirrors')) {
+    if (uri == new Uri(scheme: 'dart', path: 'mirrors')) {
       mirrorSystemClass =
           findRequiredElement(library, const SourceString('MirrorSystem'));
     } else if (uri == new Uri(scheme: 'dart', path: '_collection-dev')) {
@@ -875,22 +868,33 @@
       if (main == null) {
         if (!analyzeOnly) {
           // Allow analyze only of libraries with no main.
-          reportFatalError('Could not find $MAIN', mainApp);
+          reportFatalError(
+              mainApp,
+              MessageKind.GENERIC,
+              {'text': 'Error: Could not find "${MAIN.slowToString()}".'});
         } else if (!analyzeAll) {
           reportFatalError(
-              "Could not find $MAIN. "
-              "No source will be analyzed. "
-              "Use '--analyze-all' to analyze all code in the library.",
-              mainApp);
+              mainApp,
+              MessageKind.GENERIC,
+              {'text': 'Error: Could not find "${MAIN.slowToString()}". '
+                  'No source will be analyzed. '
+                  'Use "--analyze-all" to analyze all code in the library.'});
         }
       } else {
         if (!main.isFunction()) {
-          reportFatalError('main is not a function', main);
+          reportFatalError(
+              main,
+              MessageKind.GENERIC,
+              {'text': 'Error: "${MAIN.slowToString()}" is not a function.'});
         }
         FunctionElement mainMethod = main;
         FunctionSignature parameters = mainMethod.computeSignature(this);
         parameters.forEachParameter((Element parameter) {
-          reportFatalError('main cannot have parameters', parameter);
+          reportError(
+              parameter,
+              MessageKind.GENERIC,
+              {'text':
+                  'Error: "${MAIN.slowToString()}" cannot have parameters.'});
         });
       }
 
@@ -1136,24 +1140,25 @@
     }
     SourceSpan span = spanFromNode(node);
 
-    reportDiagnostic(span, 'Warning: $message', api.Diagnostic.WARNING);
+    reportDiagnostic(span, '$message', api.Diagnostic.WARNING);
   }
 
-  // TODO(ahe): Remove this method.
-  reportError(Node node, var message) {
-    SourceSpan span = spanFromNode(node);
-    reportDiagnostic(span, 'Error: $message', api.Diagnostic.ERROR);
-    throw new CompilerCancelledException(message.toString());
-  }
-
-  // TODO(ahe): Rename to reportError when that method has been removed.
-  void reportErrorCode(Spannable node, MessageKind errorCode,
-                       [Map arguments = const {}]) {
+  void reportError(Spannable node,
+                   MessageKind errorCode,
+                   [Map arguments = const {}]) {
     reportMessage(spanFromSpannable(node),
                   errorCode.error(arguments),
                   api.Diagnostic.ERROR);
   }
 
+  void reportFatalError(Spannable node, MessageKind errorCode,
+                        [Map arguments = const {}]) {
+    reportError(node, errorCode, arguments);
+    // TODO(ahe): Make this only abort the current method.
+    throw new CompilerCancelledException(
+        'Error: Cannot continue due to previous error.');
+  }
+
   // TODO(ahe): Rename to reportWarning when that method has been removed.
   void reportWarningCode(Spannable node, MessageKind errorCode,
                          [Map arguments = const {}]) {
@@ -1177,9 +1182,8 @@
   }
 
   void reportInternalError(Spannable node, String message) {
-    reportMessage(spanFromSpannable(node),
-                  MessageKind.GENERIC.error({'text': message}),
-                  api.Diagnostic.ERROR);
+    reportError(
+        node, MessageKind.GENERIC, {'text': 'Internal Error: $message'});
   }
 
   void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 4b41ae4..55812c0 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -5,10 +5,8 @@
 library dart2js.cmdline;
 
 import 'dart:async';
-import 'dart:collection' show Queue, LinkedHashMap;
 import 'dart:io';
 import 'dart:math' as math;
-import 'dart:utf';
 
 import '../compiler.dart' as api;
 import 'source_file.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 517573f..c789d11 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -20,14 +20,10 @@
          VoidElementX;
 import 'js_backend/js_backend.dart' as js_backend;
 import 'native_handler.dart' as native;
-import 'scanner/scanner_implementation.dart';
 import 'scanner/scannerlib.dart';
 import 'ssa/ssa.dart';
-import 'string_validator.dart';
-import 'source_file.dart';
 import 'tree/tree.dart';
 import 'universe/universe.dart';
-import 'util/characters.dart';
 import 'util/util.dart';
 import '../compiler.dart' as api;
 import 'patch_parser.dart';
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 d816a0b..c7c7ec2 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -310,7 +310,7 @@
     if (element.getLibrary().isPlatformLibrary && !element.isTopLevel()) {
       return;
     }
-    if (element == compiler.types.dynamicType.element) {
+    if (element == compiler.dynamicClass) {
       internalError(
           'Should never make element placeholder for dynamic type element',
           node: node);
@@ -365,7 +365,7 @@
 
   visitNewExpression(NewExpression node) {
     Send send = node.send;
-    InterfaceType type = treeElements.getType(node);
+    DartType type = treeElements.getType(node);
     assert(type != null);
     Element constructor = treeElements[send];
     assert(constructor != null);
@@ -481,7 +481,7 @@
       // Corner case: dart:core type with a prefix.
       // Most probably there are some additional problems with
       // coreLibPrefix.topLevels.
-      if (!identical(type.element, compiler.types.dynamicType.element)) {
+      if (!type.treatAsDynamic) {
         makeTypePlaceholder(node.typeName, type);
       } else {
         if (!isDynamicType(node)) makeUnresolvedPlaceholder(node.typeName);
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index 2d3ea94..a3e0821 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -81,43 +81,46 @@
   Member lookupMember(SourceString name, {bool isSetter: false}) => null;
 
   /**
-   * A type is malformed if it is itself a malformed type or contains a
-   * malformed type.
+   * If this type is malformed or a generic type created with the wrong number
+   * of type arguments then [userProvidedBadType] holds the bad type provided
+   * by the user. 
    */
-  bool get isMalformed => false;
-
+  DartType get userProvidedBadType => null;
+  
+  /// Returns [:true:] if this type contains an ambiguous type.
+  bool get containsAmbiguousTypes {
+    return !forEachAmbiguousType((_) => false);
+  }
+  
   /**
-   * Calls [f] with each [MalformedType] within this type.
+   * Calls [f] with each [AmbiguousType] within this type.
    *
    * If [f] returns [: false :], the traversal stops prematurely.
    *
-   * [forEachMalformedType] returns [: false :] if the traversal was stopped
+   * [forEachAmbiguousType] returns [: false :] if the traversal was stopped
    * prematurely.
    */
-  bool forEachMalformedType(bool f(MalformedType type)) => true;
+  bool forEachAmbiguousType(bool f(AmbiguousType type)) => true;
 
-  /**
-   * Is [: true :] if this type has no explict type arguments.
-   */
+  /// Is [: true :] if this type has no explict type arguments.
   bool get isRaw => true;
 
+  /// Returns the raw version of this type.
   DartType asRaw() => this;
 
-  /**
-   * Is [: true :] if this type is the dynamic type.
-   */
+  /// Is [: true :] if this type should be treated as the dynamic type.
+  bool get treatAsDynamic => false;
+
+  /// Is [: true :] if this type is the dynamic type.
   bool get isDynamic => false;
 
-  /**
-   * Is [: true :] if this type is the void type.
-   */
+  /// Is [: true :] if this type is the void type.
   bool get isVoid => false;
 
-  /**
-   * Returns an occurrence of a type variable within this type, if any.
-   */
+  /// Returns an occurrence of a type variable within this type, if any.
   TypeVariableType get typeVariableOccurrence => null;
 
+  /// Applies [f] to each occurence of a [TypeVariableType] within this type. 
   void forEachTypeVariable(f(TypeVariableType variable)) {}
 
   TypeVariableType _findTypeVariableOccurrence(Link<DartType> types) {
@@ -130,9 +133,7 @@
     return null;
   }
 
-  /**
-   * Is [: true :] if this type contains any type variables.
-   */
+  /// Is [: true :] if this type contains any type variables.
   bool get containsTypeVariables => typeVariableOccurrence != null;
 
   accept(DartTypeVisitor visitor, var argument);
@@ -334,9 +335,8 @@
     return this;
   }
 
-  bool get isMalformed => true;
-
-  bool forEachMalformedType(bool f(MalformedType type)) => f(this);
+  // Malformed types are treated as dynamic.
+  bool get treatAsDynamic => true;
 
   DartType unalias(Compiler compiler) => this;
 
@@ -364,20 +364,18 @@
   }
 }
 
-bool hasMalformed(Link<DartType> types) {
-  for (DartType typeArgument in types) {
-    if (typeArgument.isMalformed) {
-      return true;
-    }
-  }
-  return false;
+class AmbiguousType extends MalformedType {
+  AmbiguousType(ErroneousElement element, 
+                [Link<DartType> typeArguments = null]) 
+      : super(element, null, typeArguments);
+
+  bool forEachAmbiguousType(bool f(AmbiguousType type)) => f(this);
 }
 
 abstract class GenericType extends DartType {
   final Link<DartType> typeArguments;
-  final bool isMalformed;
 
-  GenericType(Link<DartType> this.typeArguments, bool this.isMalformed);
+  GenericType(Link<DartType> this.typeArguments);
 
   TypeDeclarationElement get element;
 
@@ -403,9 +401,9 @@
     return this;
   }
 
-  bool forEachMalformedType(bool f(MalformedType type)) {
+  bool forEachAmbiguousType(bool f(AmbiguousType type)) {
     for (DartType typeArgument in typeArguments) {
-      if (!typeArgument.forEachMalformedType(f)) {
+      if (!typeArgument.forEachAmbiguousType(f)) {
         return false;
       }
     }
@@ -465,7 +463,7 @@
 
   InterfaceType(this.element,
                 [Link<DartType> typeArguments = const Link<DartType>()])
-      : super(typeArguments, hasMalformed(typeArguments)) {
+      : super(typeArguments) {
     assert(invariant(element, element.isDeclaration));
     assert(invariant(element, element.thisType == null ||
         typeArguments.slowLength() == element.typeVariables.slowLength(),
@@ -473,10 +471,10 @@
                        'Provided type arguments: $typeArguments.'));
   }
 
-  InterfaceType.userProvidedBadType(this.element,
-                                    [Link<DartType> typeArguments =
-                                        const Link<DartType>()])
-      : super(typeArguments, true);
+  InterfaceType.forUserProvidedBadType(this.element,
+                                       [Link<DartType> typeArguments =
+                                           const Link<DartType>()])
+      : super(typeArguments);
 
   TypeKind get kind => TypeKind.INTERFACE;
 
@@ -575,6 +573,43 @@
   }
 }
 
+/**
+ * Special subclass of [InterfaceType] used for generic interface types created
+ * with the wrong number of type arguments.
+ * 
+ * The type uses [:dynamic:] for all it s type arguments.
+ */
+class BadInterfaceType extends InterfaceType {
+  final InterfaceType userProvidedBadType;
+
+  BadInterfaceType(ClassElement element,
+                   InterfaceType this.userProvidedBadType)
+      : super(element, element.rawType.typeArguments);
+
+  String toString() {
+    return userProvidedBadType.toString();
+  }
+}
+
+
+/**
+ * Special subclass of [TypedefType] used for generic typedef types created
+ * with the wrong number of type arguments.
+ * 
+ * The type uses [:dynamic:] for all it s type arguments.
+ */
+class BadTypedefType extends TypedefType {
+  final TypedefType userProvidedBadType;
+
+  BadTypedefType(TypedefElement element,
+                 TypedefType this.userProvidedBadType)
+      : super(element, element.rawType.typeArguments);
+
+  String toString() {
+    return userProvidedBadType.toString();
+  }
+}
+
 class FunctionType extends DartType {
   final Element element;
   final DartType returnType;
@@ -591,38 +626,13 @@
    * [namedParameters].
    */
   final Link<DartType> namedParameterTypes;
-  final bool isMalformed;
 
-  factory FunctionType(Element element,
-                       DartType returnType,
-                       Link<DartType> parameterTypes,
-                       Link<DartType> optionalParameterTypes,
-                       Link<SourceString> namedParameters,
-                       Link<DartType> namedParameterTypes) {
-    // Compute [isMalformed] eagerly since it is faster than a lazy computation
-    // and since [isMalformed] most likely will be accessed in [Types.isSubtype]
-    // anyway.
-    bool isMalformed = returnType != null &&
-                       returnType.isMalformed ||
-                       hasMalformed(parameterTypes) ||
-                       hasMalformed(optionalParameterTypes) ||
-                       hasMalformed(namedParameterTypes);
-    return new FunctionType.internal(element,
-                                     returnType,
-                                     parameterTypes,
-                                     optionalParameterTypes,
-                                     namedParameters,
-                                     namedParameterTypes,
-                                     isMalformed);
-  }
-
-  FunctionType.internal(Element this.element,
-                        DartType this.returnType,
-                        Link<DartType> this.parameterTypes,
-                        Link<DartType> this.optionalParameterTypes,
-                        Link<SourceString> this.namedParameters,
-                        Link<DartType> this.namedParameterTypes,
-                        bool this.isMalformed) {
+  FunctionType(Element this.element,
+               DartType this.returnType,
+               Link<DartType> this.parameterTypes,
+               Link<DartType> this.optionalParameterTypes,
+               Link<SourceString> this.namedParameters,
+               Link<DartType> this.namedParameterTypes) {
     assert(invariant(element, element.isDeclaration));
     // Assert that optional and named parameters are not used at the same time.
     assert(optionalParameterTypes.isEmpty || namedParameterTypes.isEmpty);
@@ -676,22 +686,22 @@
     return this;
   }
 
-  bool forEachMalformedType(bool f(MalformedType type)) {
-    if (!returnType.forEachMalformedType(f)) {
+  bool forEachAmbiguousType(bool f(AmbiguousType type)) {
+    if (!returnType.forEachAmbiguousType(f)) {
       return false;
     }
     for (DartType parameterType in parameterTypes) {
-      if (!parameterType.forEachMalformedType(f)) {
+      if (!parameterType.forEachAmbiguousType(f)) {
         return false;
       }
     }
     for (DartType parameterType in optionalParameterTypes) {
-      if (!parameterType.forEachMalformedType(f)) {
+      if (!parameterType.forEachAmbiguousType(f)) {
         return false;
       }
     }
     for (DartType parameterType in namedParameterTypes) {
-      if (!parameterType.forEachMalformedType(f)) {
+      if (!parameterType.forEachAmbiguousType(f)) {
         return false;
       }
     }
@@ -805,16 +815,16 @@
   // match, like for [InterfaceType].
   TypedefType(this.element,
               [Link<DartType> typeArguments = const Link<DartType>()])
-      : super(typeArguments, hasMalformed(typeArguments));
+      : super(typeArguments);
 
   TypedefType _createType(Link<DartType> newTypeArguments) {
     return new TypedefType(element, newTypeArguments);
   }
 
-  TypedefType.userProvidedBadType(this.element,
-                                  [Link<DartType> typeArguments =
-                                      const Link<DartType>()])
-      : super(typeArguments, true);
+  TypedefType.forUserProvidedBadType(this.element,
+                                     [Link<DartType> typeArguments =
+                                         const Link<DartType>()])
+      : super(typeArguments);
 
   TypeKind get kind => TypeKind.TYPEDEF;
 
@@ -846,6 +856,8 @@
 
   SourceString get name => const SourceString('dynamic');
 
+  bool get treatAsDynamic => true;
+
   bool get isDynamic => true;
 
   accept(DartTypeVisitor visitor, var argument) {
@@ -976,10 +988,8 @@
 
   bool isSubtype(DartType t, DartType s) {
     if (identical(t, s) ||
-        identical(t, dynamicType) ||
-        identical(s, dynamicType) ||
-        t.isMalformed ||
-        s.isMalformed ||
+        t.treatAsDynamic || 
+        s.treatAsDynamic || 
         identical(s.element, compiler.objectClass) ||
         identical(t.element, compiler.nullClass)) {
       return true;
@@ -1229,14 +1239,15 @@
   }
 
   /**
-   * Combine error messages in a malformed type to a single message string.
+   * Combine error messages in a type containing ambiguous types to a single 
+   * message string.
    */
-  static String fetchReasonsFromMalformedType(DartType type) {
+  static String fetchReasonsFromAmbiguousType(DartType type) {
     // TODO(johnniwinther): Figure out how to produce good error message in face
     // of multiple errors, and how to ensure non-localized error messages.
     var reasons = new List<String>();
-    type.forEachMalformedType((MalformedType malformedType) {
-      ErroneousElement error = malformedType.element;
+    type.forEachAmbiguousType((AmbiguousType ambiguousType) {
+      ErroneousElement error = ambiguousType.element;
       Message message = error.messageKind.message(error.messageArguments);
       reasons.add(message.toString());
       return true;
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index b20faed..7745460 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -208,7 +208,7 @@
           SourceString actualName =
               new SourceString(deferredLibrary.getLibraryOrScriptName());
           if (expectedName != actualName) {
-            compiler.reportErrorCode(
+            compiler.reportError(
                 metadata,
                 MessageKind.DEFERRED_LIBRARY_NAME_MISMATCH,
                 { 'expectedName': expectedName.slowToString(),
diff --git a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
index ff9595f..67d3792 100644
--- a/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/diagnostic_listener.dart
@@ -9,7 +9,6 @@
   void cancel(String reason, {node, token, instruction, element});
   // TODO(karlklose): rename log to something like reportInfo.
   void log(message);
-  // TODO(karlklose): add reportWarning and reportError to this interface.
 
   void internalErrorOnElement(Element element, String message);
   void internalError(String message,
@@ -20,8 +19,7 @@
 
   void reportMessage(SourceSpan span, Diagnostic message, api.Diagnostic kind);
 
-  // TODO(ahe): Rename to reportError when that method has been removed.
-  void reportErrorCode(Spannable node, MessageKind errorCode, [Map arguments]);
+  void reportError(Spannable node, MessageKind errorCode, [Map arguments]);
 
   void reportInfo(Spannable node, MessageKind errorCode, [Map arguments]);
 
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 7703b26..6413fc1 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -5,7 +5,6 @@
 library elements;
 
 
-import 'modelx.dart';
 import '../tree/tree.dart';
 import '../util/util.dart';
 import '../resolution/resolution.dart';
@@ -14,6 +13,7 @@
                                  DartType,
                                  TypeVariableType,
                                  TypedefType,
+                                 DualKind,
                                  MessageKind,
                                  DiagnosticListener,
                                  Script,
@@ -579,7 +579,7 @@
 }
 
 abstract class AmbiguousElement extends Element {
-  MessageKind get messageKind;
+  DualKind get messageKind;
   Map get messageArguments;
   Element get existingElement;
   Element get newElement;
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index c2791c8..57b7c7b 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -17,6 +17,7 @@
                                  DartType,
                                  TypeVariableType,
                                  TypedefType,
+                                 DualKind,
                                  MessageKind,
                                  DiagnosticListener,
                                  Script,
@@ -320,13 +321,11 @@
   get type => unsupported();
   get cachedNode => unsupported();
   get functionSignature => unsupported();
-  get patch => unsupported();
-  get origin => unsupported();
+  get patch => null;
+  get origin => this;
   get defaultImplementation => unsupported();
 
   bool get isRedirectingFactory => unsupported();
-  bool get isPatched => unsupported();
-  bool get isPatch => unsupported();
 
   setPatch(patch) => unsupported();
   computeSignature(compiler) => unsupported();
@@ -362,7 +361,7 @@
   /**
    * The message to report on resolving this element.
    */
-  final MessageKind messageKind;
+  final DualKind messageKind;
 
   /**
    * The message arguments to report on resolving this element.
@@ -435,8 +434,8 @@
     } else {
       Element existing = contents.putIfAbsent(name, () => element);
       if (!identical(existing, element)) {
-        listener.reportErrorCode(element,
-            MessageKind.DUPLICATE_DEFINITION, {'name': name});
+        listener.reportError(
+            element, MessageKind.DUPLICATE_DEFINITION, {'name': name});
         listener.reportMessage(
             listener.spanFromSpannable(existing),
             MessageKind.EXISTING_DEFINITION.error({'name': name}),
@@ -539,7 +538,7 @@
       return;
     }
     if (!localMembers.isEmpty) {
-      listener.reportErrorCode(tag, MessageKind.BEFORE_TOP_LEVEL);
+      listener.reportError(tag, MessageKind.BEFORE_TOP_LEVEL);
       return;
     }
     if (partTag != null) {
@@ -1377,7 +1376,7 @@
   bool isInstanceMember() => true;
 
   FunctionType computeType(Compiler compiler) {
-    compiler.reportFatalError('Internal error: $this.computeType', this);
+    compiler.internalErrorOnElement(this, '$this.computeType.');
   }
 
   Node parseNode(DiagnosticListener listener) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
index 2b43548..99b1dae 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
@@ -33,7 +33,6 @@
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
-    assert(!node.typeExpression.isMalformed);
     // No additional arguments needed.
   }
 }
@@ -45,7 +44,6 @@
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
     DartType type = node.typeExpression;
-    assert(!type.isMalformed);
     String additionalArgument = codegen.backend.namer.operatorIsType(type);
     arguments.add(js.string(additionalArgument));
   }
@@ -107,19 +105,21 @@
   }
 }
 
-class MalformedCheckedModeHelper extends CheckedModeHelper {
-  const MalformedCheckedModeHelper(SourceString name) : super(name);
+class AmbiguousTypeCheckedModeHelper extends CheckedModeHelper {
+  const AmbiguousTypeCheckedModeHelper(SourceString name) : super(name);
 
   void generateAdditionalArguments(SsaCodeGenerator codegen,
                                    HTypeConversion node,
                                    List<jsAst.Expression> arguments) {
     DartType type = node.typeExpression;
-    assert(type.isMalformed);
-    String reasons = Types.fetchReasonsFromMalformedType(type);
-    arguments.add(js.string('$type'));
-    // TODO(johnniwinther): Handle escaping correctly.
-    arguments.add(js.string(reasons));
+    assert(type.containsAmbiguousTypes);
+    String reasons = Types.fetchReasonsFromAmbiguousType(type);
+
+    arguments.add(js.string(quote('$type')));
+    arguments.add(js.string(quote(reasons)));
   }
+
+  String quote(String string) => string.replaceAll('"', r'\"');
 }
 
 /*
@@ -853,11 +853,11 @@
       // We also need the native variant of the check (for DOM types).
       helper = getNativeCheckedModeHelper(type, typeCast: false);
       if (helper != null) world.addToWorkList(helper.getElement(compiler));
-      if (type.isMalformed) {
+      if (type.containsAmbiguousTypes) {
         enqueueInResolution(getThrowMalformedSubtypeError(), elements);
         return;
       }
-    } else if (type.isMalformed) {
+    } else if (type.containsAmbiguousTypes) {
       registerThrowRuntimeError(elements);
       return;
     }
@@ -1120,14 +1120,14 @@
     Element element = type.element;
     bool nativeCheck = nativeCheckOnly ||
         emitter.nativeEmitter.requiresNativeIsCheck(element);
-    if (type.isMalformed) {
+    if (type.containsAmbiguousTypes) {
       // Check for malformed types first, because the type may be a list type
       // with a malformed argument type.
       if (nativeCheckOnly) return null;
       return typeCast
-          ? const MalformedCheckedModeHelper(
+          ? const AmbiguousTypeCheckedModeHelper(
               const SourceString('malformedTypeCast'))
-          : const MalformedCheckedModeHelper(
+          : const AmbiguousTypeCheckedModeHelper(
               const SourceString('malformedTypeCheck'));
     } else if (type == compiler.types.voidType) {
       assert(!typeCast); // Cannot cast to void.
@@ -1255,10 +1255,6 @@
     return compiler.findHelper(const SourceString('throwRuntimeError'));
   }
 
-  Element getMalformedTypeCheck() {
-    return compiler.findHelper(const SourceString('malformedTypeCheck'));
-  }
-
   Element getThrowMalformedSubtypeError() {
     return compiler.findHelper(
         const SourceString('throwMalformedSubtypeError'));
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index b408354..2ee81e7 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -221,12 +221,10 @@
     checkedClasses = new Set<ClassElement>();
     checkedFunctionTypes = new Set<FunctionType>();
     compiler.codegenWorld.isChecks.forEach((DartType t) {
-      if (!t.isMalformed) {
-        if (t is InterfaceType) {
-          checkedClasses.add(t.element);
-        } else if (t is FunctionType) {
-          checkedFunctionTypes.add(t);
-        }
+      if (t is InterfaceType) {
+        checkedClasses.add(t.element);
+      } else if (t is FunctionType) {
+        checkedFunctionTypes.add(t);
       }
     });
   }
@@ -1649,7 +1647,7 @@
     DartType type = field.computeType(compiler).unalias(compiler);
     if (type.element.isTypeVariable() ||
         (type is FunctionType && type.containsTypeVariables) ||
-        type.element == compiler.dynamicClass ||
+        type.treatAsDynamic ||
         type.element == compiler.objectClass) {
       // TODO(ngeoffray): Support type checks on type parameters.
       return false;
@@ -1794,7 +1792,7 @@
               // Only the native classes can have renaming accessors.
               assert(classIsNative);
             }
-      
+
             int getterCode = 0;
             if (needsGetter) {
               if (field.isInstanceMember()) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index 9ddf1a5..92a4898 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -240,7 +240,7 @@
       case 'SETTER_PREFIX': return setterPrefix;
       case 'CALL_CATCH_ALL': return callCatchAllName;
       default:
-        compiler.reportErrorCode(
+        compiler.reportError(
             node, MessageKind.GENERIC,
             {'text': 'Error: Namer has no name for "$name".'});
         return 'BROKEN';
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 3f21597..4c72122 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -631,7 +631,7 @@
     addProperty(namer.functionTypeTag(), name);
     if (type.returnType.isVoid) {
       addProperty(namer.functionTypeVoidReturnTag(), js('true'));
-    } else if (!type.returnType.isDynamic) {
+    } else if (!type.returnType.treatAsDynamic) {
       addProperty(namer.functionTypeReturnTypeTag(), visit(type.returnType));
     }
     if (!type.parameterTypes.isEmpty) {
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart
index 0e70958..0bcd1a5 100644
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart
@@ -255,7 +255,9 @@
      */
     int checkTag(int value, LibraryTag tag) {
       if (tagState > value) {
-        compiler.reportError(tag, 'out of order');
+        compiler.reportFatalError(
+            tag,
+            MessageKind.GENERIC, {'text': 'Error: Out of order.'});
         return tagState;
       }
       return TagState.NEXT[value];
@@ -397,8 +399,11 @@
 
     if (!loadedLibrary.hasLibraryName()) {
       compiler.withCurrentElement(library, () {
-        compiler.reportError(tag == null ? null : tag.uri,
-            'no library name found in ${loadedLibrary.canonicalUri}');
+        compiler.reportFatalError(
+            tag == null ? null : tag.uri,
+            MessageKind.GENERIC,
+            {'text':
+             'Error: No library name found in ${loadedLibrary.canonicalUri}.'});
       });
     }
   }
@@ -505,7 +510,9 @@
           compiler.reportWarning(new Identifier(e.position()),
           'duplicated definition');
         });
-        compiler.reportError(import.prefix, 'duplicate definition');
+        compiler.reportFatalError(
+            import.prefix,
+            MessageKind.GENERIC, {'text': 'Error: Duplicate definition.'});
       }
       PrefixElement prefixElement = e;
       importedLibrary.forEachExport((Element element) {
@@ -519,8 +526,9 @@
             'duplicated import');
           });
           compiler.withCurrentElement(element, () {
-            compiler.reportError(new Identifier(element.position()),
-            'duplicated import');
+            compiler.reportFatalError(
+                element,
+                MessageKind.GENERIC, {'text': 'Error: Duplicated import.'});
           });
         }
       });
@@ -675,15 +683,15 @@
     Element existingElement = exportScope[name];
     if (existingElement != null) {
       if (existingElement.isErroneous()) {
-        compiler.reportErrorCode(element, MessageKind.DUPLICATE_EXPORT,
-                                 {'name': name});
+        compiler.reportError(element, MessageKind.DUPLICATE_EXPORT,
+                             {'name': name});
         element = existingElement;
       } else if (existingElement.getLibrary() != library) {
         // Declared elements hide exported elements.
-        compiler.reportErrorCode(existingElement, MessageKind.DUPLICATE_EXPORT,
-                                 {'name': name});
-        compiler.reportErrorCode(element, MessageKind.DUPLICATE_EXPORT,
-                                 {'name': name});
+        compiler.reportError(existingElement, MessageKind.DUPLICATE_EXPORT,
+                             {'name': name});
+        compiler.reportError(element, MessageKind.DUPLICATE_EXPORT,
+                             {'name': name});
         element = exportScope[name] = new ErroneousElementX(
             MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
       }
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
index d86c626..a00716e 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart
@@ -1084,7 +1084,8 @@
 
   bool get isObject => mirrors.compiler.objectClass == _type.element;
 
-  bool get isDynamic => mirrors.compiler.dynamicClass == _type.element;
+  // TODO(johnniwinther): How to show malformed types?
+  bool get isDynamic => _type.isDynamic;
 
   ClassMirror get originalDeclaration
       => new Dart2JsClassMirror(mirrors, _type.element);
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
index ebfa797..d6b2553 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart
@@ -4,8 +4,6 @@
 
 library mirrors;
 
-import 'dart:async';
-
 /**
  * The main interface for the whole mirror system.
  */
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index 49975b8..ed7fb1f 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -816,7 +816,7 @@
       lookup(name), locationNodeOrElement) {
     if (typeString == '=Object') return SpecialType.JsObject;
     if (typeString == 'dynamic') {
-      return  compiler.dynamicClass.computeType(compiler);
+      return  compiler.types.dynamicType;
     }
     DartType type = lookup(typeString);
     if (type != null) return type;
diff --git a/sdk/lib/_internal/compiler/implementation/patch_parser.dart b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
index b356d78..5827a3d 100644
--- a/sdk/lib/_internal/compiler/implementation/patch_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/patch_parser.dart
@@ -116,7 +116,6 @@
 
 import "tree/tree.dart" as tree;
 import "dart2jslib.dart" as leg;  // CompilerTask, Compiler.
-import "apiimpl.dart";
 import "../compiler.dart" as api;
 import "scanner/scannerlib.dart";  // Scanner, Parsers, Listeners
 import "elements/elements.dart";
@@ -394,20 +393,15 @@
                    Element origin,
                    Element patch) {
   if (origin == null) {
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_NON_EXISTING.error({'name': patch.name}),
-        api.Diagnostic.ERROR);
+    listener.reportError(
+        patch, leg.MessageKind.PATCH_NON_EXISTING, {'name': patch.name});
     return;
   }
   if (!(origin.isClass() ||
         origin.isConstructor() ||
         origin.isFunction() ||
         origin.isAbstractField())) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NONPATCHABLE.error(),
-        api.Diagnostic.ERROR);
+    listener.reportError(origin, leg.MessageKind.PATCH_NONPATCHABLE);
     return;
   }
   if (patch.isClass()) {
@@ -421,10 +415,7 @@
   } else if(patch.isFunction()) {
     tryPatchFunction(listener, origin, patch);
   } else {
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_NONPATCHABLE.error(),
-        api.Diagnostic.ERROR);
+    listener.reportError(patch, leg.MessageKind.PATCH_NONPATCHABLE);
   }
 }
 
@@ -432,14 +423,10 @@
                     Element origin,
                     ClassElement patch) {
   if (!origin.isClass()) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NON_CLASS.error({'className': patch.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_CLASS.error({'className': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin, leg.MessageKind.PATCH_NON_CLASS, {'className': patch.name});
+    listener.reportInfo(
+        patch, leg.MessageKind.PATCH_POINT_TO_CLASS, {'className': patch.name});
     return;
   }
   patchClass(listener, origin, patch);
@@ -461,26 +448,20 @@
                      Element origin,
                      FunctionElement patch) {
   if (!origin.isAbstractField()) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NON_GETTER.error({'name': origin.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_GETTER.error({'getterName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin, leg.MessageKind.PATCH_NON_GETTER, {'name': origin.name});
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_GETTER, {'getterName': patch.name});
     return;
   }
   AbstractFieldElement originField = origin;
   if (originField.getter == null) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NO_GETTER.error({'getterName': patch.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_GETTER.error({'getterName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin, leg.MessageKind.PATCH_NO_GETTER, {'getterName': patch.name});
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_GETTER, {'getterName': patch.name});
     return;
   }
   patchFunction(listener, originField.getter, patch);
@@ -490,26 +471,20 @@
                      Element origin,
                      FunctionElement patch) {
   if (!origin.isAbstractField()) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NON_SETTER.error({'name': origin.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_SETTER.error({'setterName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin, leg.MessageKind.PATCH_NON_SETTER, {'name': origin.name});
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_SETTER, {'setterName': patch.name});
     return;
   }
   AbstractFieldElement originField = origin;
   if (originField.setter == null) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NO_SETTER.error({'setterName': patch.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_SETTER.error({'setterName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin, leg.MessageKind.PATCH_NO_SETTER, {'setterName': patch.name});
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_SETTER, {'setterName': patch.name});
     return;
   }
   patchFunction(listener, originField.setter, patch);
@@ -519,16 +494,13 @@
                           Element origin,
                           FunctionElement patch) {
   if (!origin.isConstructor()) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NON_CONSTRUCTOR.error(
-            {'constructorName': patch.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_CONSTRUCTOR.error(
-            {'constructorName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin,
+        leg.MessageKind.PATCH_NON_CONSTRUCTOR, {'constructorName': patch.name});
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
+        {'constructorName': patch.name});
     return;
   }
   patchFunction(listener, origin, patch);
@@ -538,15 +510,12 @@
                        Element origin,
                        FunctionElement patch) {
   if (!origin.isFunction()) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NON_FUNCTION.error({'functionName': patch.name}),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_FUNCTION.error(
-            {'functionName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(
+        origin,
+        leg.MessageKind.PATCH_NON_FUNCTION, {'functionName': patch.name});
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_FUNCTION, {'functionName': patch.name});
     return;
   }
   patchFunction(listener, origin, patch);
@@ -556,15 +525,10 @@
                     FunctionElement origin,
                     FunctionElement patch) {
   if (!origin.modifiers.isExternal()) {
-    listener.reportMessage(
-        listener.spanFromSpannable(origin),
-        leg.MessageKind.PATCH_NON_EXTERNAL.error(),
-        api.Diagnostic.ERROR);
-    listener.reportMessage(
-        listener.spanFromSpannable(patch),
-        leg.MessageKind.PATCH_POINT_TO_FUNCTION.error(
-            {'functionName': patch.name}),
-        api.Diagnostic.INFO);
+    listener.reportError(origin, leg.MessageKind.PATCH_NON_EXTERNAL);
+    listener.reportInfo(
+        patch,
+        leg.MessageKind.PATCH_POINT_TO_FUNCTION, {'functionName': patch.name});
     return;
   }
   if (origin.isPatched) {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 3ae9aa1..cea260d 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -227,7 +227,7 @@
       String patchParameterText =
           patchParameter.parseNode(compiler).toString();
       if (originParameterText != patchParameterText) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             originParameter.parseNode(compiler),
             MessageKind.PATCH_PARAMETER_MISMATCH,
             {'methodName': origin.name,
@@ -242,7 +242,7 @@
       DartType originParameterType = originParameter.computeType(compiler);
       DartType patchParameterType = patchParameter.computeType(compiler);
       if (originParameterType != patchParameterType) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             originParameter.parseNode(compiler),
             MessageKind.PATCH_PARAMETER_TYPE_MISMATCH,
             {'methodName': origin.name,
@@ -482,7 +482,7 @@
     compiler.withCurrentElement(cls, () => measure(() {
       if (cls.supertypeLoadState == STATE_DONE) return;
       if (cls.supertypeLoadState == STATE_STARTED) {
-        compiler.reportErrorCode(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
+        compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY,
                                  {'className': cls.name});
         cls.supertypeLoadState = STATE_DONE;
         cls.allSupertypes = const Link<DartType>().prepend(
@@ -593,7 +593,7 @@
     int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
     if (illegalFlags != 0) {
       Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
-      compiler.reportErrorCode(
+      compiler.reportError(
           modifiers,
           MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
           {'modifiers': illegalModifiers});
@@ -607,7 +607,7 @@
 
     // Check that we're not trying to use Object as a mixin.
     if (mixin.superclass == null) {
-      compiler.reportErrorCode(mixinApplication,
+      compiler.reportError(mixinApplication,
                                MessageKind.ILLEGAL_MIXIN_OBJECT);
       // Avoid reporting additional errors for the Object class.
       return;
@@ -615,14 +615,14 @@
 
     // Check that the mixed in class has Object as its superclass.
     if (!mixin.superclass.isObject(compiler)) {
-      compiler.reportErrorCode(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
+      compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
     }
 
     // Check that the mixed in class doesn't have any constructors and
     // make sure we aren't mixing in methods that use 'super'.
     mixin.forEachLocalMember((Element member) {
       if (member.isGenerativeConstructor() && !member.isSynthesized) {
-        compiler.reportErrorCode(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
+        compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
       } else {
         // Get the resolution tree and check that the resolved member
         // doesn't use 'super'. This is the part of the 'super' mixin
@@ -642,14 +642,14 @@
     if (resolutionTree == null) return;
     Set<Node> superUses = resolutionTree.superUses;
     if (superUses.isEmpty) return;
-    compiler.reportErrorCode(mixinApplication,
-                             MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
-                             {'className': mixin.name});
+    compiler.reportError(mixinApplication,
+                         MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
+                         {'className': mixin.name});
     // Show the user the problematic uses of 'super' in the mixin.
     for (Node use in superUses) {
-      CompilationError error = MessageKind.ILLEGAL_MIXIN_SUPER_USE.error();
-      compiler.reportMessage(compiler.spanFromNode(use),
-                             error, Diagnostic.INFO);
+      compiler.reportInfo(
+          use,
+          MessageKind.ILLEGAL_MIXIN_SUPER_USE);
     }
   }
 
@@ -665,7 +665,7 @@
 
         // Check modifiers.
         if (member.isFunction() && member.modifiers.isFinal()) {
-          compiler.reportErrorCode(
+          compiler.reportError(
               member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
         }
         if (member.isConstructor()) {
@@ -675,7 +675,7 @@
           if (mismatchedFlagsBits != 0) {
             final mismatchedFlags =
                 new Modifiers.withFlags(null, mismatchedFlagsBits);
-            compiler.reportErrorCode(
+            compiler.reportError(
                 member,
                 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
                 {'modifiers': mismatchedFlags});
@@ -713,11 +713,11 @@
     if (!identical(getterFlags, setterFlags)) {
       final mismatchedFlags =
         new Modifiers.withFlags(null, getterFlags ^ setterFlags);
-      compiler.reportErrorCode(
+      compiler.reportError(
           field.getter,
           MessageKind.GETTER_MISMATCH,
           {'modifiers': mismatchedFlags});
-      compiler.reportErrorCode(
+      compiler.reportError(
           field.setter,
           MessageKind.SETTER_MISMATCH,
           {'modifiers': mismatchedFlags});
@@ -807,19 +807,19 @@
           errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
         }
       }
-      compiler.reportErrorCode(
+      compiler.reportError(
           errorNode, messageKind, {'operatorName': function.name});
     }
     if (signature.optionalParameterCount != 0) {
       Node errorNode =
           node.parameters.nodes.skip(signature.requiredParameterCount).head;
       if (signature.optionalParametersAreNamed) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             errorNode,
             MessageKind.OPERATOR_NAMED_PARAMETERS,
             {'operatorName': function.name});
       } else {
-        compiler.reportErrorCode(
+        compiler.reportError(
             errorNode,
             MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
             {'operatorName': function.name});
@@ -831,7 +831,7 @@
                          MessageKind errorMessage,
                          Element contextElement,
                          MessageKind contextMessage) {
-    compiler.reportErrorCode(
+    compiler.reportError(
         errorneousElement,
         errorMessage,
         {'memberName': contextElement.name,
@@ -969,8 +969,8 @@
   }
 
   error(Node node, MessageKind kind, [arguments = const {}]) {
-    ResolutionError message = new ResolutionError(kind, arguments);
-    compiler.reportError(node, message);
+    // TODO(ahe): Make non-fatal.
+    compiler.reportFatalError(node, kind, arguments);
   }
 }
 
@@ -1001,13 +1001,10 @@
   reportDuplicateInitializerError(Element field, Node init, Node existing) {
     visitor.compiler.reportError(
         init,
-        new ResolutionError(MessageKind.DUPLICATE_INITIALIZER,
-                            {'fieldName': field.name}));
-    visitor.compiler.reportMessage(
-        visitor.compiler.spanFromNode(existing),
-        new ResolutionError(MessageKind.ALREADY_INITIALIZED,
-                            {'fieldName': field.name}),
-        Diagnostic.INFO);
+        MessageKind.DUPLICATE_INITIALIZER, {'fieldName': field.name});
+    visitor.compiler.reportInfo(
+        existing,
+        MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name});
   }
 
   void checkForDuplicateInitializers(Element field, Node init) {
@@ -1034,7 +1031,7 @@
     if (isFieldInitializer(init)) {
       target = constructor.getEnclosingClass().lookupLocalMember(name);
       if (target == null) {
-        error(selector, MessageKind.CANNOT_RESOLVE, {'name': name});
+        error(selector, MessageKind.CANNOT_RESOLVE.error, {'name': name});
       } else if (target.kind != ElementKind.FIELD) {
         error(selector, MessageKind.NOT_A_FIELD, {'fieldName': name});
       } else if (!target.isInstanceMember()) {
@@ -1154,17 +1151,17 @@
       MessageKind kind = isImplicitSuperCall
           ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
           : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
-      visitor.compiler.reportErrorCode(
+      visitor.compiler.reportError(
           diagnosticNode, kind, {'constructorName': fullConstructorName});
     } else {
       if (!call.applies(lookedupConstructor, visitor.compiler)) {
         MessageKind kind = isImplicitSuperCall
                            ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
                            : MessageKind.NO_MATCHING_CONSTRUCTOR;
-        visitor.compiler.reportErrorCode(diagnosticNode, kind);
+        visitor.compiler.reportError(diagnosticNode, kind);
       } else if (caller.modifiers.isConst()
                  && !lookedupConstructor.modifiers.isConst()) {
-        visitor.compiler.reportErrorCode(
+        visitor.compiler.reportError(
             diagnosticNode, MessageKind.CONST_CALLS_NON_CONST);
       }
     }
@@ -1269,8 +1266,11 @@
   R visit(Node node) => (node == null) ? null : node.accept(this);
 
   void error(Node node, MessageKind kind, [Map arguments = const {}]) {
-    ResolutionError message  = new ResolutionError(kind, arguments);
-    compiler.reportError(node, message);
+    compiler.reportFatalError(node, kind, arguments);
+  }
+
+  void dualError(Node node, DualKind kind, [Map arguments = const {}]) {
+    error(node, kind.error, arguments);
   }
 
   void warning(Node node, MessageKind kind, [Map arguments = const {}]) {
@@ -1278,6 +1278,10 @@
     compiler.reportWarning(node, message);
   }
 
+  void dualWarning(Node node, DualKind kind, [Map arguments = const {}]) {
+    warning(node, kind.warning, arguments);
+  }
+
   void cancel(Node node, String message) {
     compiler.cancel(message, node: node);
   }
@@ -1423,21 +1427,9 @@
     }
   }
 
-  // TODO(johnniwinther): Change  [onFailure] and [whenResolved] to use boolean
-  // flags instead of closures.
-  DartType resolveTypeAnnotation(
-      MappingVisitor visitor,
-      TypeAnnotation node,
-      {onFailure(Node node, MessageKind kind, [Map arguments])}) {
-    if (onFailure == null) {
-      onFailure = (n, k, [arguments]) {};
-    }
-    return resolveTypeAnnotationInContext(visitor, node, onFailure);
-  }
-
-  DartType resolveTypeAnnotationInContext(MappingVisitor visitor,
-                                          TypeAnnotation node,
-                                          onFailure) {
+  DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node,
+                                 {bool malformedIsError: false,
+                                  bool ambiguousIsError: false}) {
     Identifier typeName;
     SourceString prefixName;
     Send send = node.typeName.asSend();
@@ -1452,25 +1444,32 @@
     Element element = resolveTypeName(visitor.scope, prefixName, typeName);
     DartType type;
 
-    DartType reportFailureAndCreateType(MessageKind messageKind,
-                                        Map messageArguments) {
-      onFailure(node, messageKind, messageArguments);
+    DartType reportFailureAndCreateType(DualKind messageKind,
+                                        Map messageArguments,
+                                        {DartType userProvidedBadType,
+                                         bool isError: false,
+                                         bool isAmbiguous: false}) {
+      if (isError) {
+        visitor.error(node, messageKind.error, messageArguments);
+      } else {
+        visitor.warning(node, messageKind.warning, messageArguments);
+      }
       var erroneousElement = new ErroneousElementX(
-          messageKind, messageArguments, typeName.source,
+          messageKind.error, messageArguments, typeName.source,
           visitor.enclosingElement);
       var arguments = new LinkBuilder<DartType>();
-      resolveTypeArguments(
-          visitor, node, null,
-          onFailure, arguments);
-      return new MalformedType(erroneousElement, null, arguments.toLink());
+      resolveTypeArguments(visitor, node, null, arguments);
+      return isAmbiguous
+          ? new AmbiguousType(erroneousElement, arguments.toLink())
+          : new MalformedType(erroneousElement,
+              userProvidedBadType, arguments.toLink());
     }
 
     DartType checkNoTypeArguments(DartType type) {
       var arguments = new LinkBuilder<DartType>();
-      bool hashTypeArgumentMismatch = resolveTypeArguments(
-          visitor, node, const Link<DartType>(),
-          onFailure, arguments);
-      if (hashTypeArgumentMismatch) {
+      bool hasTypeArgumentMismatch = resolveTypeArguments(
+          visitor, node, const Link<DartType>(), arguments);
+      if (hasTypeArgumentMismatch) {
         type = new MalformedType(
             new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
                 {'type': node}, typeName.source, visitor.enclosingElement),
@@ -1481,33 +1480,33 @@
 
     if (element == null) {
       type = reportFailureAndCreateType(
-          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName});
+          MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName},
+          isError: malformedIsError);
     } else if (element.isAmbiguous()) {
       AmbiguousElement ambiguous = element;
       type = reportFailureAndCreateType(
-          ambiguous.messageKind, ambiguous.messageArguments);
+          ambiguous.messageKind, ambiguous.messageArguments,
+          isError: ambiguousIsError, isAmbiguous: true);
       ambiguous.diagnose(visitor.mapping.currentElement, compiler);
     } else if (!element.impliesType()) {
       type = reportFailureAndCreateType(
-          MessageKind.NOT_A_TYPE, {'node': node.typeName});
+          MessageKind.NOT_A_TYPE, {'node': node.typeName},
+          isError: malformedIsError);
     } else {
       if (identical(element, compiler.types.voidType.element) ||
-          identical(element, compiler.types.dynamicType.element)) {
+          identical(element, compiler.dynamicClass)) {
         type = checkNoTypeArguments(element.computeType(compiler));
       } else if (element.isClass()) {
         ClassElement cls = element;
         compiler.resolver._ensureClassWillBeResolved(cls);
         element.computeType(compiler);
         var arguments = new LinkBuilder<DartType>();
-        bool hashTypeArgumentMismatch = resolveTypeArguments(
-            visitor, node, cls.typeVariables,
-            onFailure, arguments);
-        if (hashTypeArgumentMismatch) {
-          type = new MalformedType(
-              new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-                  {'type': node}, typeName.source, visitor.enclosingElement),
-              new InterfaceType.userProvidedBadType(cls.declaration,
-                                                    arguments.toLink()));
+        bool hasTypeArgumentMismatch = resolveTypeArguments(
+            visitor, node, cls.typeVariables, arguments);
+        if (hasTypeArgumentMismatch) {
+          type = new BadInterfaceType(cls.declaration,
+              new InterfaceType.forUserProvidedBadType(cls.declaration,
+                                                       arguments.toLink()));
         } else {
           if (arguments.isEmpty) {
             type = cls.rawType;
@@ -1520,14 +1519,12 @@
         // TODO(ahe): Should be [ensureResolved].
         compiler.resolveTypedef(typdef);
         var arguments = new LinkBuilder<DartType>();
-        bool hashTypeArgumentMismatch = resolveTypeArguments(
-            visitor, node, typdef.typeVariables,
-            onFailure, arguments);
-        if (hashTypeArgumentMismatch) {
-          type = new MalformedType(
-              new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-                  {'type': node}, typeName.source, visitor.enclosingElement),
-              new TypedefType.userProvidedBadType(typdef, arguments.toLink()));
+        bool hasTypeArgumentMismatch = resolveTypeArguments(
+            visitor, node, typdef.typeVariables, arguments);
+        if (hasTypeArgumentMismatch) {
+          type = new BadTypedefType(typdef,
+              new TypedefType.forUserProvidedBadType(typdef, 
+                                                     arguments.toLink()));
         } else {
           if (arguments.isEmpty) {
             type = typdef.rawType;
@@ -1545,15 +1542,11 @@
             !isInFactoryConstructor &&
             Elements.isInStaticContext(visitor.enclosingElement)) {
           compiler.backend.registerThrowRuntimeError(visitor.mapping);
-          compiler.reportWarning(node,
-              MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message(
-                  {'typeVariableName': node}));
-          type = new MalformedType(
-              new ErroneousElementX(
-                  MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-                  {'typeVariableName': node},
-                  typeName.source, visitor.enclosingElement),
-                  element.computeType(compiler));
+          type = reportFailureAndCreateType(
+              MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
+              {'typeVariableName': node},
+              userProvidedBadType: element.computeType(compiler),
+              isError: malformedIsError);
         } else {
           type = element.computeType(compiler);
         }
@@ -1577,8 +1570,8 @@
       MappingVisitor visitor,
       TypeAnnotation node,
       Link<DartType> typeVariables,
-      onFailure,
-      LinkBuilder<DartType> arguments) {
+      LinkBuilder<DartType> arguments,
+      {bool ambiguousIsError: false}) {
     if (node.typeArguments == null) {
       return false;
     }
@@ -1587,19 +1580,20 @@
          !typeArguments.isEmpty;
          typeArguments = typeArguments.tail) {
       if (typeVariables != null && typeVariables.isEmpty) {
-        onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
+        visitor.warning(
+            typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
         typeArgumentCountMismatch = true;
       }
-      DartType argType = resolveTypeAnnotationInContext(visitor,
-                                                        typeArguments.head,
-                                                        onFailure);
+      DartType argType = resolveTypeAnnotation(visitor, typeArguments.head,
+          ambiguousIsError: ambiguousIsError);
       arguments.addLast(argType);
       if (typeVariables != null && !typeVariables.isEmpty) {
         typeVariables = typeVariables.tail;
       }
     }
     if (typeVariables != null && !typeVariables.isEmpty) {
-      onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
+      visitor.warning(node.typeArguments,
+                      MessageKind.MISSING_TYPE_ARGUMENT.warning);
       typeArgumentCountMismatch = true;
     }
     return typeArgumentCountMismatch;
@@ -1655,7 +1649,6 @@
   Scope scope;
   ClassElement currentClass;
   ExpressionStatement currentExpressionStatement;
-  bool typeRequired = false;
   bool sendIsMemberAccess = false;
   StatementScope statementScope;
   int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
@@ -1714,17 +1707,17 @@
     Element result = scope.lookup(name);
     if (!Elements.isUnresolved(result)) {
       if (!inInstanceContext && result.isInstanceMember()) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name});
         return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE,
                                      {'name': name},
                                      name, enclosingElement);
       } else if (result.isAmbiguous()) {
         AmbiguousElement ambiguous = result;
-        compiler.reportErrorCode(
-            node, ambiguous.messageKind, ambiguous.messageArguments);
+        compiler.reportError(
+            node, ambiguous.messageKind.error, ambiguous.messageArguments);
         ambiguous.diagnose(enclosingElement, compiler);
-        return new ErroneousElementX(ambiguous.messageKind,
+        return new ErroneousElementX(ambiguous.messageKind.error,
                                      ambiguous.messageArguments,
                                      name, enclosingElement);
       }
@@ -1766,11 +1759,11 @@
 
   ErroneousElement warnAndCreateErroneousElement(Node node,
                                                  SourceString name,
-                                                 MessageKind kind,
+                                                 DualKind kind,
                                                  [Map arguments = const {}]) {
-    ResolutionWarning warning = new ResolutionWarning(kind, arguments);
+    ResolutionWarning warning = new ResolutionWarning(kind.warning, arguments);
     compiler.reportWarning(node, warning);
-    return new ErroneousElementX(kind, arguments, name, enclosingElement);
+    return new ErroneousElementX(kind.error, arguments, name, enclosingElement);
   }
 
   Element visitIdentifier(Identifier node) {
@@ -1789,9 +1782,9 @@
       Element element = lookup(node, node.source);
       if (element == null) {
         if (!inInstanceContext) {
-          element = warnAndCreateErroneousElement(node, node.source,
-                                                  MessageKind.CANNOT_RESOLVE,
-                                                  {'name': node});
+          element = warnAndCreateErroneousElement(
+              node, node.source, MessageKind.CANNOT_RESOLVE,
+              {'name': node});
           compiler.backend.registerThrowNoSuchMethod(mapping);
         }
       } else if (element.isErroneous()) {
@@ -1829,7 +1822,7 @@
     if (doAddToScope) {
       Element existing = scope.add(element);
       if (existing != element) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             node, MessageKind.DUPLICATE_DEFINITION, {'name': node});
         compiler.reportMessage(
             compiler.spanFromSpannable(existing),
@@ -1875,7 +1868,7 @@
     Element enclosingElement = function.enclosingElement;
     if (node.modifiers.isStatic() &&
         enclosingElement.kind != ElementKind.CLASS) {
-      compiler.reportErrorCode(node, MessageKind.ILLEGAL_STATIC);
+      compiler.reportError(node, MessageKind.ILLEGAL_STATIC);
     }
 
     scope = new MethodScope(scope, function);
@@ -2110,7 +2103,7 @@
         // TODO(karlklose): this should be reported by the caller of
         // [resolveSend] to select better warning messages for getters and
         // setters.
-        MessageKind kind = (target == null)
+        DualKind kind = (target == null)
             ? MessageKind.MEMBER_NOT_FOUND
             : MessageKind.MEMBER_NOT_STATIC;
         return warnAndCreateErroneousElement(node, name, kind,
@@ -2212,7 +2205,7 @@
       if (namedArgument != null) {
         SourceString source = namedArgument.name.source;
         if (seenNamedArguments.containsKey(source)) {
-          compiler.reportErrorCode(
+          compiler.reportError(
               argument,
               MessageKind.DUPLICATE_DEFINITION,
               {'name': source});
@@ -2274,13 +2267,13 @@
       String operatorString = node.selector.asOperator().source.stringValue;
       if (operatorString == 'is') {
         DartType type =
-            resolveTypeRequired(node.typeAnnotationFromIsCheckOrCast);
+            resolveTypeExpression(node.typeAnnotationFromIsCheckOrCast);
         if (type != null) {
           compiler.enqueuer.resolution.registerIsCheck(type, mapping);
         }
         resolvedArguments = true;
       } else if (operatorString == 'as') {
-        DartType type = resolveTypeRequired(node.arguments.head);
+        DartType type = resolveTypeExpression(node.arguments.head);
         if (type != null) {
           compiler.enqueuer.resolution.registerAsCheck(type, mapping);
         }
@@ -2339,7 +2332,7 @@
     compiler.backend.registerThrowNoSuchMethod(mapping);
     // TODO(karlklose): we can be more precise about the reason of the
     // mismatch.
-    warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS,
+    warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS.warning,
             {'methodName': target.name});
   }
 
@@ -2507,9 +2500,9 @@
   void handleRedirectingFactoryBody(Return node) {
     final isSymbolConstructor = enclosingElement == compiler.symbolConstructor;
     if (!enclosingElement.isFactoryConstructor()) {
-      compiler.reportErrorCode(
+      compiler.reportError(
           node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY);
-      compiler.reportErrorCode(
+      compiler.reportHint(
           enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD);
     }
     FunctionElement redirectionTarget = resolveRedirectingFactory(node);
@@ -2533,7 +2526,7 @@
         .subst(type.typeArguments, targetClass.typeVariables);
     FunctionType constructorType = constructor.computeType(compiler);
     if (!compiler.types.isSubtype(targetType, constructorType)) {
-      warning(node, MessageKind.NOT_ASSIGNABLE,
+      warning(node, MessageKind.NOT_ASSIGNABLE.warning,
               {'fromType': targetType, 'toType': constructorType});
     }
 
@@ -2625,7 +2618,7 @@
     ClassElement cls = constructor.getEnclosingClass();
     InterfaceType type = mapping.getType(node);
     if (node.isConst() && type.containsTypeVariables) {
-      compiler.reportErrorCode(node.send.selector,
+      compiler.reportError(node.send.selector,
                                MessageKind.TYPE_VARIABLE_IN_CONSTANT);
     }
     world.registerInstantiatedType(type, mapping);
@@ -2643,7 +2636,7 @@
             argumentNode, mapping, isConst: true);
         if (!name.isString()) {
           DartType type = name.computeType(compiler);
-          compiler.reportErrorCode(argumentNode, MessageKind.STRING_EXPECTED,
+          compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED,
                                    {'type': type});
         } else {
           StringConstant stringConstant = name;
@@ -2666,12 +2659,12 @@
   bool validateSymbol(Node node, String name) {
     if (name.isEmpty) return true;
     if (name.startsWith('_')) {
-      compiler.reportErrorCode(node, MessageKind.PRIVATE_IDENTIFIER,
+      compiler.reportError(node, MessageKind.PRIVATE_IDENTIFIER,
                                {'value': name});
       return false;
     }
     if (!symbolValidationPattern.hasMatch(name)) {
-      compiler.reportErrorCode(node, MessageKind.INVALID_SYMBOL,
+      compiler.reportError(node, MessageKind.INVALID_SYMBOL,
                                {'value': name});
       return false;
     }
@@ -2692,23 +2685,17 @@
     return node.accept(new ConstructorResolver(compiler, this));
   }
 
-  DartType resolveTypeRequired(TypeAnnotation node) {
-    bool old = typeRequired;
-    typeRequired = true;
-    DartType result = resolveTypeAnnotation(node);
-    typeRequired = old;
-    return result;
+  DartType resolveTypeExpression(TypeAnnotation node) {
+    return resolveTypeAnnotation(node, isTypeExpression: true);
   }
 
-  DartType resolveTypeAnnotation(TypeAnnotation node) {
-    Function report = typeRequired ? error : warning;
+  DartType resolveTypeAnnotation(TypeAnnotation node,
+                                 {bool isTypeExpression: false}) {
     DartType type = typeResolver.resolveTypeAnnotation(
-        this, node, onFailure: report);
+        this, node, ambiguousIsError: isTypeExpression);
     if (type == null) return null;
     if (inCheckContext) {
       compiler.enqueuer.resolution.registerIsCheck(type, mapping);
-    }
-    if (typeRequired || inCheckContext) {
       compiler.backend.registerRequiredType(type, enclosingElement);
     }
     return type;
@@ -2725,19 +2712,20 @@
     if (arguments != null) {
       Link<Node> nodes = arguments.nodes;
       if (nodes.isEmpty) {
-        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
+        // The syntax [: <>[] :] is not allowed.
+        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
       } else {
-        typeArgument = resolveTypeRequired(nodes.head);
+        typeArgument = resolveTypeExpression(nodes.head);
         for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-          error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-          resolveTypeRequired(nodes.head);
+          warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+          resolveTypeAnnotation(nodes.head);
         }
       }
     }
     DartType listType;
     if (typeArgument != null) {
       if (node.isConst() && typeArgument.containsTypeVariables) {
-        compiler.reportErrorCode(arguments.nodes.head,
+        compiler.reportError(arguments.nodes.head,
             MessageKind.TYPE_VARIABLE_IN_CONSTANT);
       }
       listType = new InterfaceType(compiler.listClass,
@@ -2748,6 +2736,7 @@
     }
     mapping.setType(node, listType);
     world.registerInstantiatedType(listType, mapping);
+    compiler.backend.registerRequiredType(listType, enclosingElement);
     visit(node.elements);
   }
 
@@ -2853,28 +2842,28 @@
       loopVariable = mapping[send];
       Identifier identifier = send.selector.asIdentifier();
       if (identifier == null) {
-        compiler.reportErrorCode(send.selector, MessageKind.INVALID_FOR_IN);
+        compiler.reportError(send.selector, MessageKind.INVALID_FOR_IN);
       } else {
         loopVariableSelector = new Selector.setter(identifier.source, library);
       }
       if (send.receiver != null) {
-        compiler.reportErrorCode(send.receiver, MessageKind.INVALID_FOR_IN);
+        compiler.reportError(send.receiver, MessageKind.INVALID_FOR_IN);
       }
     } else if (variableDefinitions != null) {
       Link<Node> nodes = variableDefinitions.definitions.nodes;
       if (!nodes.tail.isEmpty) {
-        compiler.reportErrorCode(nodes.tail.head, MessageKind.INVALID_FOR_IN);
+        compiler.reportError(nodes.tail.head, MessageKind.INVALID_FOR_IN);
       }
       Node first = nodes.head;
       Identifier identifier = first.asIdentifier();
       if (identifier == null) {
-        compiler.reportErrorCode(first, MessageKind.INVALID_FOR_IN);
+        compiler.reportError(first, MessageKind.INVALID_FOR_IN);
       } else {
         loopVariableSelector = new Selector.setter(identifier.source, library);
         loopVariable = mapping[identifier];
       }
     } else {
-      compiler.reportErrorCode(declaration, MessageKind.INVALID_FOR_IN);
+      compiler.reportError(declaration, MessageKind.INVALID_FOR_IN);
     }
     if (loopVariableSelector != null) {
       mapping.setSelector(declaration, loopVariableSelector);
@@ -2929,17 +2918,18 @@
     if (arguments != null) {
       Link<Node> nodes = arguments.nodes;
       if (nodes.isEmpty) {
-        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
+        // The syntax [: <>{} :] is not allowed.
+        error(arguments, MessageKind.MISSING_TYPE_ARGUMENT.error);
       } else {
-        keyTypeArgument = resolveTypeRequired(nodes.head);
+        keyTypeArgument = resolveTypeExpression(nodes.head);
         nodes = nodes.tail;
         if (nodes.isEmpty) {
-          error(arguments, MessageKind.MISSING_TYPE_ARGUMENT);
+          warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT.warning);
         } else {
-          valueTypeArgument = resolveTypeRequired(nodes.head);
+          valueTypeArgument = resolveTypeExpression(nodes.head);
           for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) {
-            error(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
-            resolveTypeRequired(nodes.head);
+            warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT.warning);
+            resolveTypeAnnotation(nodes.head);
           }
         }
       }
@@ -2953,7 +2943,7 @@
       mapType = compiler.mapClass.rawType;
     }
     if (node.isConst() && mapType.containsTypeVariables) {
-      compiler.reportErrorCode(arguments,
+      compiler.reportError(arguments,
           MessageKind.TYPE_VARIABLE_IN_CONSTANT);
     }
     mapping.setType(node, mapType);
@@ -2961,6 +2951,7 @@
     if (node.isConst()) {
       compiler.backend.registerConstantMap(mapping);
     }
+    compiler.backend.registerRequiredType(mapType, enclosingElement);
     node.visitChildren(this);
   }
 
@@ -2988,17 +2979,22 @@
         LabelElement existingElement = continueLabels[labelName];
         if (existingElement != null) {
           // It's an error if the same label occurs twice in the same switch.
-          warning(label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName});
-          error(existingElement.label, MessageKind.EXISTING_LABEL,
-                {'labelName': labelName});
+          compiler.reportError(
+              label,
+              MessageKind.DUPLICATE_LABEL.error, {'labelName': labelName});
+          compiler.reportInfo(
+              existingElement.label,
+              MessageKind.EXISTING_LABEL, {'labelName': labelName});
         } else {
           // It's only a warning if it shadows another label.
           existingElement = statementScope.lookupLabel(labelName);
           if (existingElement != null) {
-            warning(label, MessageKind.DUPLICATE_LABEL,
-                    {'labelName': labelName});
-            warning(existingElement.label,
-                    MessageKind.EXISTING_LABEL, {'labelName': labelName});
+            compiler.reportWarningCode(
+                label,
+                MessageKind.DUPLICATE_LABEL.warning, {'labelName': labelName});
+            compiler.reportInfo(
+                existingElement.label,
+                MessageKind.EXISTING_LABEL, {'labelName': labelName});
           }
         }
 
@@ -3101,10 +3097,7 @@
     }
 
     Scope blockScope = new BlockScope(scope);
-    var wasTypeRequired = typeRequired;
-    typeRequired = true;
     doInCheckContext(() => visitIn(node.type, blockScope));
-    typeRequired = wasTypeRequired;
     visitIn(node.formals, blockScope);
     var oldInCatchBlock = inCatchBlock;
     inCatchBlock = true;
@@ -3162,7 +3155,7 @@
       TypeVariableElement variableElement = typeVariable.element;
       if (typeNode.bound != null) {
         DartType boundType = typeResolver.resolveTypeAnnotation(
-            this, typeNode.bound, onFailure: warning);
+            this, typeNode.bound);
         variableElement.bound = boundType;
 
         void checkTypeVariableBound() {
@@ -3294,11 +3287,13 @@
       Element superMember =
           element.superclass.localLookup(const SourceString(''));
       if (superMember == null || !superMember.isGenerativeConstructor()) {
-        MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
+        DualKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR;
         Map arguments = {'constructorName': const SourceString('')};
-        compiler.reportErrorCode(node, kind, arguments);
+        // TODO(ahe): Why is this a compile-time error? Or if it is an error,
+        // why do we bother to registerThrowNoSuchMethod below?
+        compiler.reportError(node, kind.error, arguments);
         superMember = new ErroneousElementX(
-            kind, arguments, const SourceString(''), element);
+            kind.error, arguments, const SourceString(''), element);
         compiler.backend.registerThrowNoSuchMethod(mapping);
       }
       FunctionElement constructor =
@@ -3410,7 +3405,7 @@
     while (current != null && current.isMixinApplication) {
       MixinApplicationElement currentMixinApplication = current;
       if (currentMixinApplication == mixinApplication) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             mixinApplication, MessageKind.ILLEGAL_MIXIN_CYCLE,
             {'mixinName1': current.name, 'mixinName2': previous.name});
         // We have found a cycle in the mixin chain. Return null as
@@ -3432,7 +3427,7 @@
 
   DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
     DartType supertype = typeResolver.resolveTypeAnnotation(
-        this, superclass, onFailure: error);
+        this, superclass, malformedIsError: true);
     if (supertype != null) {
       if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) {
         // Error has already been reported.
@@ -3454,7 +3449,7 @@
     if (interfaces == null) return result;
     for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) {
       DartType interfaceType = typeResolver.resolveTypeAnnotation(
-          this, link.head, onFailure: error);
+          this, link.head, malformedIsError: true);
       if (interfaceType != null) {
         if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) {
           // Error has already been reported.
@@ -3464,17 +3459,17 @@
           error(typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED);
         } else {
           if (interfaceType == element.supertype) {
-            compiler.reportErrorCode(
+            compiler.reportError(
                 superclass,
                 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
                 {'type': interfaceType});
-            compiler.reportErrorCode(
+            compiler.reportError(
                 link.head,
                 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
                 {'type': interfaceType});
           }
           if (result.contains(interfaceType)) {
-            compiler.reportErrorCode(
+            compiler.reportError(
                 link.head,
                 MessageKind.DUPLICATE_IMPLEMENTS,
                 {'type': interfaceType});
@@ -3570,7 +3565,7 @@
       !identical(lib, compiler.coreLibrary) &&
       !identical(lib, compiler.jsHelperLibrary) &&
       !identical(lib, compiler.interceptorsLibrary) &&
-      (identical(type.element, compiler.dynamicClass) ||
+      (identical(type, compiler.types.dynamicType) ||
        identical(type.element, compiler.boolClass) ||
        identical(type.element, compiler.numClass) ||
        identical(type.element, compiler.intClass) ||
@@ -3632,14 +3627,14 @@
   void visitIdentifier(Identifier node) {
     Element element = context.lookup(node.source);
     if (element == null) {
-      error(node, MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node});
+      error(node, MessageKind.CANNOT_RESOLVE_TYPE.error, {'typeName': node});
     } else if (!element.impliesType()) {
-      error(node, MessageKind.NOT_A_TYPE, {'node': node});
+      error(node, MessageKind.NOT_A_TYPE.error, {'node': node});
     } else {
       if (element.isClass()) {
         loadSupertype(element, node);
       } else {
-        compiler.reportErrorCode(node, MessageKind.CLASS_NAME_EXPECTED);
+        compiler.reportError(node, MessageKind.CLASS_NAME_EXPECTED);
       }
     }
   }
@@ -3659,7 +3654,7 @@
     Identifier selector = node.selector.asIdentifier();
     var e = prefixElement.lookupLocalMember(selector.source);
     if (e == null || !e.impliesType()) {
-      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE,
+      error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE.error,
             {'typeName': node.selector});
       return;
     }
@@ -3860,7 +3855,7 @@
     int requiredParameterCount = 0;
     if (formalParameters == null) {
       if (!element.isGetter()) {
-        compiler.reportErrorCode(element, MessageKind.MISSING_FORMALS);
+        compiler.reportError(element, MessageKind.MISSING_FORMALS);
       }
     } else {
       if (element.isGetter()) {
@@ -3870,7 +3865,7 @@
           if (compiler.rejectDeprecatedFeatures &&
               // TODO(ahe): Remove isPlatformLibrary check.
               !element.getLibrary().isPlatformLibrary) {
-            compiler.reportErrorCode(formalParameters,
+            compiler.reportError(formalParameters,
                                      MessageKind.EXTRA_FORMALS);
           } else {
             compiler.onDeprecatedFeature(formalParameters, 'getter parameters');
@@ -3899,13 +3894,13 @@
                                visitor.optionalParameterCount != 0)) {
       // If there are no formal parameters, we already reported an error above.
       if (formalParameters != null) {
-        compiler.reportErrorCode(formalParameters,
+        compiler.reportError(formalParameters,
                                  MessageKind.ILLEGAL_SETTER_FORMALS);
       }
     }
     if (element.isGetter() && (requiredParameterCount != 0
                                || visitor.optionalParameterCount != 0)) {
-      compiler.reportErrorCode(formalParameters, MessageKind.EXTRA_FORMALS);
+      compiler.reportError(formalParameters, MessageKind.EXTRA_FORMALS);
     }
     return new FunctionSignatureX(parameters,
                                   visitor.optionalParameters,
@@ -3941,7 +3936,7 @@
   }
 
   failOrReturnErroneousElement(Element enclosing, Node diagnosticNode,
-                               SourceString targetName, MessageKind kind,
+                               SourceString targetName, DualKind kind,
                                Map arguments) {
     if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
       compiler.backend.registerThrowNoSuchMethod(resolver.mapping);
@@ -3949,11 +3944,13 @@
       compiler.backend.registerThrowRuntimeError(resolver.mapping);
     }
     if (inConstContext) {
-      error(diagnosticNode, kind, arguments);
+      error(diagnosticNode, kind.error, arguments);
     } else {
-      ResolutionWarning warning  = new ResolutionWarning(kind, arguments);
+      ResolutionWarning warning  =
+          new ResolutionWarning(kind.warning, arguments);
       compiler.reportWarning(diagnosticNode, warning);
-      return new ErroneousElementX(kind, arguments, targetName, enclosing);
+      return new ErroneousElementX(
+          kind.error, arguments, targetName, enclosing);
     }
   }
 
@@ -4012,7 +4009,7 @@
     }
     if (type == null) {
       if (Elements.isUnresolved(e)) {
-        type = compiler.dynamicClass.computeType(compiler);
+        type = compiler.types.dynamicType;
       } else {
         type = e.getEnclosingClass().computeType(compiler).asRaw();
       }
@@ -4023,7 +4020,8 @@
 
   visitTypeAnnotation(TypeAnnotation node) {
     assert(invariant(node, type == null));
-    type = resolver.resolveTypeRequired(node);
+    type = resolver.resolveTypeExpression(node);
+    compiler.backend.registerRequiredType(type, resolver.enclosingElement);
     return resolver.mapping[node];
   }
 
@@ -4041,12 +4039,13 @@
       PrefixElement prefix = e;
       e = prefix.lookupLocalMember(name.source);
       if (e == null) {
-        return failOrReturnErroneousElement(resolver.enclosingElement, name,
-                                            name.source,
-                                            MessageKind.CANNOT_RESOLVE,
-                                            {'name': name});
+        return failOrReturnErroneousElement(
+            resolver.enclosingElement, name,
+            name.source,
+            MessageKind.CANNOT_RESOLVE,
+            {'name': name});
       } else if (!identical(e.kind, ElementKind.CLASS)) {
-        error(node, MessageKind.NOT_A_TYPE, {'node': name});
+        error(node, MessageKind.NOT_A_TYPE.error, {'node': name});
       }
     } else {
       internalError(node.receiver, 'unexpected element $e');
@@ -4072,7 +4071,7 @@
             {'typeVariableName': name});
     } else if (!identical(e.kind, ElementKind.CLASS)
         && !identical(e.kind, ElementKind.PREFIX)) {
-      error(node, MessageKind.NOT_A_TYPE, {'node': name});
+      error(node, MessageKind.NOT_A_TYPE.error, {'node': name});
     }
     return e;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart
index 81f9fec..9cb1736 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/class_element_parser.dart
@@ -104,7 +104,7 @@
       return Elements.constructOperatorName(operator.source, isUnary);
     } else {
       if (receiver == null || receiver.source != enclosingElement.name) {
-        listener.reportErrorCode(send.receiver,
+        listener.reportError(send.receiver,
                                  MessageKind.INVALID_CONSTRUCTOR_NAME,
                                  {'name': enclosingElement.name});
       }
@@ -142,7 +142,7 @@
     Identifier singleIdentifierName = method.name.asIdentifier();
     if (singleIdentifierName != null && singleIdentifierName.source == name) {
       if (name != enclosingElement.name) {
-        listener.reportErrorCode(singleIdentifierName,
+        listener.reportError(singleIdentifierName,
                                  MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
                                  {'name': enclosingElement.name});
       }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart b/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
index f9a175f..9ca5b8a 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/scannerlib.dart
@@ -22,8 +22,6 @@
 import '../tree/tree.dart';
 import '../util/characters.dart';
 import '../util/util.dart';
-// TODO(ahe): Rename prefix to 'api' when VM bug is fixed.
-import '../../compiler.dart' as api_s;
 
 part 'class_element_parser.dart';
 part 'keyword.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/source_file.dart b/sdk/lib/_internal/compiler/implementation/source_file.dart
index ca6d614..3e7d2b8 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file.dart
@@ -6,8 +6,6 @@
 
 import 'dart:math';
 
-import 'colors.dart' as colors;
-
 /**
  * Represents a file of source code.
  */
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
index e4d3ce1..8895637 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/bailout.dart
@@ -141,7 +141,7 @@
     Element source = instruction.sourceElement;
     if (source != null) {
       DartType sourceType = source.computeType(compiler);
-      if (!sourceType.isMalformed && !sourceType.isDynamic &&
+      if (!sourceType.treatAsDynamic &&
           sourceType.kind == TypeKind.INTERFACE) {
         TypeMask sourceMask = new TypeMask.subtype(sourceType);
         TypeMask speculatedMask = speculativeType.computeMask(compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 9e84207..151efbd 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1444,7 +1444,7 @@
 
       Element target = constructor.targetConstructor.implementation;
       Selector.addForwardingElementArgumentsToList(
-          constructor, 
+          constructor,
           arguments,
           target,
           compileArgument,
@@ -1761,7 +1761,7 @@
                                    int kind) {
     if (type == null) return original;
     type = type.unalias(compiler);
-    if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) {
+    if (type.kind == TypeKind.INTERFACE && !type.isRaw) {
      HType subtype = new HType.subtype(type, compiler);
      HInstruction representations = buildTypeArgumentRepresentations(type);
      add(representations);
@@ -2770,12 +2770,12 @@
     bool isNot = node.isIsNotCheck;
     DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
     type = type.unalias(compiler);
-    if (type.isMalformed) {
-      String reasons = Types.fetchReasonsFromMalformedType(type);
+    if (type.containsAmbiguousTypes) {
+      String reasons = Types.fetchReasonsFromAmbiguousType(type);
       if (compiler.enableTypeAssertions) {
         generateMalformedSubtypeError(node, expression, type, reasons);
       } else {
-        generateRuntimeError(node, '$type is malformed: $reasons');
+        generateRuntimeError(node, '$type is ambiguous: $reasons');
       }
     } else {
       HInstruction instruction = buildIsNode(node, type, expression);
@@ -3028,7 +3028,7 @@
     Node argument;
     switch (arguments.length) {
     case 0:
-      compiler.reportErrorCode(
+      compiler.reportError(
           node, MessageKind.GENERIC,
           {'text': 'Error: Expected one argument to JS_GET_NAME.'});
       return;
@@ -3037,7 +3037,7 @@
       break;
     default:
       for (int i = 1; i < arguments.length; i++) {
-        compiler.reportErrorCode(
+        compiler.reportError(
             arguments[i], MessageKind.GENERIC,
             {'text': 'Error: Extra argument to JS_GET_NAME.'});
       }
@@ -3045,7 +3045,7 @@
     }
     LiteralString string = argument.asLiteralString();
     if (string == null) {
-      compiler.reportErrorCode(
+      compiler.reportError(
           argument, MessageKind.GENERIC,
           {'text': 'Error: Expected a literal string.'});
     }
@@ -3415,10 +3415,7 @@
    * Invariant: [argument] must not be malformed in checked mode.
    */
   HInstruction analyzeTypeArgument(DartType argument) {
-    assert(invariant(currentElement,
-                     !compiler.enableTypeAssertions || !argument.isMalformed,
-                     message: '$argument is malformed in checked mode'));
-    if (argument == compiler.types.dynamicType || argument.isMalformed) {
+    if (argument.treatAsDynamic) {
       // Represent [dynamic] as [null].
       return graph.addConstantNull(compiler);
     }
@@ -3474,9 +3471,6 @@
    */
   handleNewSend(NewExpression node, InterfaceType type) {
     Send send = node.send;
-    assert(invariant(send,
-                     !compiler.enableTypeAssertions || !type.isMalformed,
-                     message: '$type is malformed in checked mode'));
     bool isListConstructor = false;
     computeType(element) {
       Element originalElement = elements[send];
@@ -3768,7 +3762,7 @@
     }
     if (Elements.isErroneousElement(element)) {
       ErroneousElement error = element;
-      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) {
+      if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR.error) {
         generateThrowNoSuchMethod(node.send,
                                   getTargetName(error, 'constructor'),
                                   argumentNodes: node.send.arguments);
@@ -3788,8 +3782,8 @@
       }
     } else {
       DartType type = elements.getType(node);
-      if (compiler.enableTypeAssertions && type.isMalformed) {
-        String reasons = Types.fetchReasonsFromMalformedType(type);
+      if (compiler.enableTypeAssertions && type.containsAmbiguousTypes) {
+        String reasons = Types.fetchReasonsFromAmbiguousType(type);
         // TODO(johnniwinther): Change to resemble type errors from bounds check
         // on type arguments.
         generateRuntimeError(node, '$type is malformed: $reasons');
@@ -4467,16 +4461,18 @@
           if (firstConstantType == null) {
             firstConstantType = constant.computeType(compiler);
             if (nonPrimitiveTypeOverridesEquals(constant)) {
-              compiler.reportError(match.expression,
-                  MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS.error());
+              compiler.reportFatalError(
+                  match.expression,
+                  MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS);
               failure = true;
             }
           } else {
             DartType constantType =
                 constant.computeType(compiler);
             if (constantType != firstConstantType) {
-              compiler.reportError(match.expression,
-                  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL.error());
+              compiler.reportFatalError(
+                  match.expression,
+                  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL);
               failure = true;
             }
           }
@@ -4925,18 +4921,11 @@
           if (type == null) {
             compiler.internalError('On with no type', node: catchBlock.type);
           }
-          if (type.isMalformed) {
-            // TODO(johnniwinther): Handle malformed types in [HIs] instead.
-            HInstruction condition =
-                graph.addConstantBool(true, compiler);
-            stack.add(condition);
-          } else {
-            // TODO(karlkose): support type arguments here.
-            HInstruction condition = new HIs(type,
-                                             <HInstruction>[unwrappedException],
-                                             HIs.RAW_CHECK);
-            push(condition);
-          }
+          // TODO(karlkose): support type arguments here.
+          HInstruction condition = new HIs(type,
+                                           <HInstruction>[unwrappedException],
+                                           HIs.RAW_CHECK);
+          push(condition);
         } else {
           VariableDefinitions declaration = catchBlock.formals.nodes.head;
           HInstruction condition = null;
@@ -4969,8 +4958,8 @@
           // malformed.
           if (catchBlock.onKeyword != null) {
             DartType type = elements.getType(catchBlock.type);
-            if (type != null && type.isMalformed) {
-              String reasons = Types.fetchReasonsFromMalformedType(type);
+            if (type != null && type.containsAmbiguousTypes) {
+              String reasons = Types.fetchReasonsFromAmbiguousType(type);
               generateMalformedSubtypeError(node,
                   unwrappedException, type, reasons);
               pop();
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
index 29780bf..3e072dc 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen.dart
@@ -2217,8 +2217,6 @@
   }
 
   void checkType(HInstruction input, DartType type, {bool negative: false}) {
-    assert(invariant(input, !type.isMalformed,
-                     message: 'Attempt to check malformed type $type'));
     Element element = type.element;
     if (element == backend.jsArrayClass) {
       checkArray(input, negative ? '!==': '===');
@@ -2349,8 +2347,7 @@
       ClassElement objectClass = compiler.objectClass;
       Element element = type.element;
 
-      if (identical(element, objectClass) ||
-          identical(element, compiler.dynamicClass)) {
+      if (identical(element, objectClass) || type.treatAsDynamic) {
         // The constant folder also does this optimization, but we make
         // it safe by assuming it may have not run.
         push(newLiteralBool(!negative), node);
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index be46135..38e9e4f 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1116,12 +1116,13 @@
     // instructions with generics. It has the generic type context
     // available.
     assert(type.kind != TypeKind.TYPE_VARIABLE);
-    assert(type.isRaw
-           || type.isMalformed
-           || type.kind == TypeKind.FUNCTION);
-    if (identical(type.element, compiler.dynamicClass)) return this;
+    assert(type.isRaw || type.kind == TypeKind.FUNCTION);
+    if (type.containsAmbiguousTypes) {
+      return new HTypeConversion(type, kind, HType.UNKNOWN, this);
+    }
+    if (type.treatAsDynamic) return this;
     if (identical(type.element, compiler.objectClass)) return this;
-    if (type.isMalformed || type.kind != TypeKind.INTERFACE) {
+    if (type.kind != TypeKind.INTERFACE) {
       return new HTypeConversion(type, kind, HType.UNKNOWN, this);
     } else if (kind == HTypeConversion.BOOLEAN_CONVERSION_CHECK) {
       // Boolean conversion checks work on non-nullable booleans.
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index 44ef282..2b01077 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -540,7 +540,7 @@
       return node;
     }
 
-    if (element == compiler.objectClass || element == compiler.dynamicClass) {
+    if (element == compiler.objectClass || type.treatAsDynamic) {
       return graph.addConstantBool(true, compiler);
     }
 
@@ -581,7 +581,7 @@
     // the notion of generics in the backend. For example, [:this:] in
     // a class [:A<T>:], is currently always considered to have the
     // raw type.
-    } else if (!RuntimeTypes.hasTypeArguments(type) && !type.isMalformed) {
+    } else if (!RuntimeTypes.hasTypeArguments(type)) {
       TypeMask expressionMask = expressionType.computeMask(compiler);
       TypeMask typeMask = new TypeMask.nonNullSubtype(type);
       if (expressionMask.union(typeMask, compiler) == typeMask) {
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
index c62f67e..60014f2 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa.dart
@@ -19,7 +19,6 @@
 import '../types/types.dart';
 import '../universe/universe.dart';
 import '../util/util.dart';
-import '../util/characters.dart';
 
 import '../scanner/scannerlib.dart'
     show PartialFunctionElement, Token, PLUS_TOKEN;
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index fd8d660..659737c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -129,7 +129,7 @@
       return HType.NULL;
     } else if (type.element == compiler.nullClass) {
       return HType.NULL;
-    } else if (type.isDynamic) {
+    } else if (type.treatAsDynamic) {
       return HType.UNKNOWN;
     } else if (compiler.world.hasAnySubtype(type.element)) {
       return new HType.nonNullSubtype(type, compiler);
diff --git a/sdk/lib/_internal/compiler/implementation/string_validator.dart b/sdk/lib/_internal/compiler/implementation/string_validator.dart
index ef294bd..77154b2 100644
--- a/sdk/lib/_internal/compiler/implementation/string_validator.dart
+++ b/sdk/lib/_internal/compiler/implementation/string_validator.dart
@@ -10,7 +10,6 @@
 
 import "dart2jslib.dart";
 import "tree/tree.dart";
-import "elements/elements.dart";
 import "util/characters.dart";
 import "scanner/scannerlib.dart" show Token;
 
diff --git a/sdk/lib/_internal/compiler/implementation/tree/tree.dart b/sdk/lib/_internal/compiler/implementation/tree/tree.dart
index 3faa36c..cc1ceb0 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/tree.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/tree.dart
@@ -4,7 +4,6 @@
 
 library tree;
 
-import 'dart:math';
 import 'dart:collection';
 
 import '../scanner/scannerlib.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 5249a6e..d9f7c5bc 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -237,7 +237,7 @@
    */
   bool checkAssignable(Node node, DartType from, DartType to) {
     if (!types.isAssignable(from, to)) {
-      reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE,
+      reportTypeWarning(node, MessageKind.NOT_ASSIGNABLE.warning,
                         {'fromType': from, 'toType': to});
       return false;
     }
@@ -340,7 +340,7 @@
     DartType previous = expectedReturnType;
     expectedReturnType = returnType;
     StatementType bodyType = analyze(node.body);
-    if (returnType != types.voidType && returnType != types.dynamicType
+    if (returnType != types.voidType && !returnType.treatAsDynamic
         && bodyType != StatementType.RETURNING) {
       MessageKind kind;
       if (bodyType == StatementType.MAYBE_RETURNING) {
@@ -394,7 +394,7 @@
 
   ElementAccess lookupMember(Node node, DartType type, SourceString name,
                              MemberKind memberKind) {
-    if (identical(type, types.dynamicType)) {
+    if (type.treatAsDynamic) {
       return const DynamicAccess();
     }
     Member member = type.lookupMember(name,
@@ -413,7 +413,7 @@
             {'className': type.name, 'memberName': name});
         break;
       case MemberKind.GETTER:
-        reportTypeWarning(node, MessageKind.MEMBER_NOT_FOUND,
+        reportTypeWarning(node, MessageKind.MEMBER_NOT_FOUND.warning,
             {'className': type.name, 'memberName': name});
         break;
       case MemberKind.SETTER:
@@ -552,9 +552,7 @@
       }
       // e.foo() for some expression e.
       DartType receiverType = analyze(node.receiver);
-      if (receiverType.isDynamic ||
-          receiverType.isMalformed ||
-          receiverType.isVoid) {
+      if (receiverType.treatAsDynamic || receiverType.isVoid) {
         return const DynamicAccess();
       }
       TypeKind receiverKind = receiverType.kind;
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 1c05b77..57b7904 100644
--- a/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/concrete_types_inferrer.dart
@@ -403,7 +403,7 @@
     Types types = inferrer.compiler.types;
     bool paramMatches(ConcreteType concrete, VariableElement parameter) {
       DartType parameterType = parameter.variables.type;
-      if (parameterType.isDynamic || parameterType.isRaw) {
+      if (parameterType.treatAsDynamic || parameterType.isRaw) {
         return true;
       }
       for (BaseType baseType in concrete.baseTypes) {
@@ -1221,7 +1221,7 @@
     for (final type in typesReturned) {
       if (type == native.SpecialType.JsObject) {
         registerDynamic();
-      } else if (type.isDynamic) {
+      } else if (type.treatAsDynamic) {
         registerDynamic();
       } else {
         ClassElement element = type.element;
diff --git a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
index 1164c64..b9a50a2 100644
--- a/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/flat_type_mask.dart
@@ -41,7 +41,7 @@
 
   FlatTypeMask.internal(DartType base, this.flags)
       : this.base = transformBase(base) {
-    assert(base == null || !(isExact && base.isDynamic));
+    assert(base == null || !(isExact && base.treatAsDynamic));
   }
 
   // TODO(kasperl): We temporarily transform the base to be the raw
@@ -54,7 +54,6 @@
       assert(base.kind == TypeKind.INTERFACE);
       return null;
     } else {
-      assert(!base.isMalformed);
       return base.asRaw();
     }
   }
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
index 2c127ad..12389ee 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
@@ -84,8 +84,7 @@
   TypeMask narrowType(TypeMask type,
                       DartType annotation,
                       {bool isNullable: true}) {
-    if (annotation.isDynamic) return type;
-    if (annotation.isMalformed) return type;
+    if (annotation.treatAsDynamic) return type;
     if (annotation.isVoid) return nullType;
     if (annotation.element == compiler.objectClass) return type;
     TypeMask otherType;
@@ -869,7 +868,7 @@
     Node exception = node.exception;
     if (exception != null) {
       DartType type = elements.getType(node.type);
-      T mask = type == null
+      T mask = type == null || type.treatAsDynamic
           ? types.dynamicType
           : types.nonNullSubtype(type.asRaw());
       locals.update(elements[exception], mask, 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 62a9225..5bae1d7 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -95,7 +95,7 @@
       callers[caller]--;
     }
   }
-  
+
   void addAssignment(Node node, TypeMask mask) {
     assignments[node] = mask;
   }
@@ -997,7 +997,7 @@
     if (isNativeElement(element) && element.isField()) {
       if (type == null) {
         InterfaceType rawType = element.computeType(compiler).asRaw();
-        info.type = type = rawType.isDynamic
+        info.type = type = rawType.treatAsDynamic
             ? types.dynamicType
             : new TypeMask.subtype(rawType);
       }
diff --git a/sdk/lib/_internal/compiler/implementation/types/types.dart b/sdk/lib/_internal/compiler/implementation/types/types.dart
index 6db7670..538b44e 100644
--- a/sdk/lib/_internal/compiler/implementation/types/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/types.dart
@@ -7,7 +7,6 @@
 import 'dart:collection' show Queue, IterableBase;
 
 import '../dart2jslib.dart' hide Selector, TypedSelector;
-import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../tree/tree.dart';
 import '../elements/elements.dart';
 import '../native_handler.dart' as native;
diff --git a/sdk/lib/_internal/compiler/implementation/universe/universe.dart b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
index 5f76676..5658fe1 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/universe.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/universe.dart
@@ -4,14 +4,12 @@
 
 library universe;
 
-import '../closure.dart';
 import '../elements/elements.dart';
 import '../dart2jslib.dart';
 import '../dart_types.dart';
 import '../types/types.dart';
 import '../tree/tree.dart';
 import '../util/util.dart';
-import '../js/js.dart' as js;
 
 part 'function_set.dart';
 part 'side_effects.dart';
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index b7442dd..7950a31 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -4,457 +4,622 @@
 
 part of dart2js;
 
+/**
+ * The messages in this file should meet the following guide lines:
+ *
+ * 1. The message should start with exactly one of "Error", "Internal error",
+ * "Warning", "Info", or "Hint" followed by a colon. It is crucial to users to
+ * be able to locate errors in the midst of warnings, but we are operating
+ * under the assumption that these messages will eventually be translated to
+ * other languages than English, and that it is therefor not possible to
+ * automatically apply these prefixes.
+ *
+ * 2. After the colon, one space and a complete sentence starting with an
+ * uppercase letter, and ending with a period.
+ *
+ * 3. Reserved words and embedded identifiers should be in quotes (double
+ * quotes), so prefer single quotes for the complete message. For example,
+ * 'Error: The class "#{className}" cannot use "super".' Notice that the word
+ * "class" in the preceding message is not quoted as it refers to the concept
+ * "class", not the reserved word. On the other hand, "super" refers to the
+ * reserved word. Do not quote "null" and numeric literals.
+ *
+ * 4. Do not try to compose messages, as it can make translating them hard.
+ *
+ * 5. Try to keep the error messages short, but informative.
+ *
+ * 6. Use simple words and terminology, assume the reader of the message does
+ * not have an advanced degree in math, and that English is not the reader's
+ * native language. Do not assume any formal computer science training. For
+ * example, do not use Latin abbreviations (prefer "that is" over "i.e.", and
+ * "for example" over "e.g."). Also avoid phrases such as "if and only if" and
+ * "iff", that level of precision is unnecessary.
+ *
+ * 7. Do not use contractions, for example, prefer "cannot" over "can't". This
+ * is again to benefit readers to whom English is not their first language.
+ *
+ * 8. Use common terminology, preferably from the Dart Language
+ * Specification. This increases the user's chance of finding a good
+ * explanation on the web.
+ *
+ * 9. Do not try to be cute or funny. It is extremely frustrating to work on a
+ * product that crashes with a "tongue-in-cheek" message, especially if you did
+ * not want to use this product to begin with with.
+ *
+ * 10. Do not lie, that is, do not write error messages containing phrases like
+ * "cannot happen".  If the user ever saw this message, it would be a
+ * lie. Prefer messages like: 'Internal error: This function should not be
+ * called when "x" is null.'.
+ */
 class MessageKind {
   final String template;
   const MessageKind(this.template);
 
-  static const GENERIC = const MessageKind('#{text}');
+  /// Do not use this. It is here for legacy and debugging. It violates item 4
+  /// above.
+  static const MessageKind GENERIC = const MessageKind('#{text}');
 
-  static const NOT_ASSIGNABLE = const MessageKind(
-      '#{fromType} is not assignable to #{toType}');
-  static const VOID_EXPRESSION = const MessageKind(
-      'expression does not yield a value');
-  static const VOID_VARIABLE = const MessageKind(
-      'variable cannot be of type void');
-  static const RETURN_VALUE_IN_VOID = const MessageKind(
-      'cannot return value from void function');
-  static const RETURN_NOTHING = const MessageKind(
-      'value of type #{returnType} expected');
-  static const MISSING_ARGUMENT = const MessageKind(
-      'missing argument of type #{argumentType}');
-  static const ADDITIONAL_ARGUMENT = const MessageKind(
-      'additional argument');
-  static const NAMED_ARGUMENT_NOT_FOUND = const MessageKind(
-      "no named argument '#{argumentName}' found on method");
-  static const MEMBER_NOT_FOUND = const MessageKind(
-      'no member named #{memberName} in class #{className}');
-  static const METHOD_NOT_FOUND = const MessageKind(
-      'no method named #{memberName} in class #{className}');
-  static const OPERATOR_NOT_FOUND = const MessageKind(
-      'no operator #{memberName} in class #{className}');
-  static const PROPERTY_NOT_FOUND = const MessageKind(
-      'no property named #{memberName} in class #{className}');
-  static const NOT_CALLABLE = const MessageKind(
-      "'#{elementName}' is not callable");
-  static const MEMBER_NOT_STATIC = const MessageKind(
-      '#{className}.#{memberName} is not static');
-  static const NO_INSTANCE_AVAILABLE = const MessageKind(
-      '#{name} is only available in instance methods');
-  static const PRIVATE_ACCESS = const MessageKind(
-      "'#{name}' is declared private within library #{libraryName} and "
-      "is therefore not accessible.");
+  static const DualKind NOT_ASSIGNABLE = const DualKind(
+      error: const MessageKind(
+          'Error: "#{fromType}" is not assignable to "#{toType}".'),
+      warning: const MessageKind(
+          'Warning: "#{fromType}" is not assignable to "#{toType}".'));
 
-  static const THIS_IS_THE_METHOD = const MessageKind(
-      "This is the method declaration.");
+  static const MessageKind VOID_EXPRESSION = const MessageKind(
+      'Warning: Expression does not yield a value.');
 
-  static const UNREACHABLE_CODE = const MessageKind(
-      'unreachable code');
-  static const MISSING_RETURN = const MessageKind(
-      'missing return');
-  static const MAYBE_MISSING_RETURN = const MessageKind(
-      'not all paths lead to a return or throw statement');
+  static const MessageKind VOID_VARIABLE = const MessageKind(
+      'Warning: Variable cannot be of type void.');
 
-  static const CANNOT_RESOLVE = const MessageKind(
-      'cannot resolve #{name}');
-  static const CANNOT_RESOLVE_CONSTRUCTOR = const MessageKind(
-      'cannot resolve constructor #{constructorName}');
-  static const CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
-      'cannot resolve constructor #{constructorName} for implicit super call');
-  static const INVALID_UNNAMED_CONSTRUCTOR_NAME = const MessageKind(
-      'Error: Unnamed constructor name must be #{name}.');
-  static const INVALID_CONSTRUCTOR_NAME = const MessageKind(
-      'Error: Constructor name must start with #{name}.');
-  static const CANNOT_RESOLVE_TYPE = const MessageKind(
-      'cannot resolve type #{typeName}');
-  static const DUPLICATE_DEFINITION = const MessageKind(
-      "Error: Duplicate definition of '#{name}'.");
-  static const EXISTING_DEFINITION = const MessageKind(
-      "Info: Existing definition of '#{name}'.");
-  static const DUPLICATE_IMPORT = const MessageKind(
-      'duplicate import of #{name}');
-  static const DUPLICATE_EXPORT = const MessageKind(
-      'duplicate export of #{name}');
-  static const NOT_A_TYPE = const MessageKind(
-      '#{node} is not a type');
-  static const NOT_A_PREFIX = const MessageKind(
-      '#{node} is not a prefix');
-  static const NO_SUPER_IN_OBJECT = const MessageKind(
-      "'Object' does not have a superclass");
-  static const CANNOT_FIND_CONSTRUCTOR = const MessageKind(
-      'cannot find constructor #{constructorName}');
-  static const CYCLIC_CLASS_HIERARCHY = const MessageKind(
-      '#{className} creates a cycle in the class hierarchy');
-  static const INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
-      'field initializer expected');
-  static const NO_SUPER_IN_STATIC = const MessageKind(
-      "'super' is only available in instance methods");
-  static const DUPLICATE_INITIALIZER = const MessageKind(
-      'field #{fieldName} is initialized more than once');
-  static const ALREADY_INITIALIZED = const MessageKind(
-      '#{fieldName} was already initialized here');
-  static const INIT_STATIC_FIELD = const MessageKind(
-      'cannot initialize static field #{fieldName}');
-  static const NOT_A_FIELD = const MessageKind(
-      '#{fieldName} is not a field');
-  static const CONSTRUCTOR_CALL_EXPECTED = const MessageKind(
-      "only call to 'this' or 'super' constructor allowed");
-  static const INVALID_FOR_IN = const MessageKind(
-      'invalid for-in variable declaration.');
-  static const INVALID_INITIALIZER = const MessageKind(
-      'invalid initializer');
-  static const FUNCTION_WITH_INITIALIZER = const MessageKind(
-      'only constructors can have initializers');
-  static const REDIRECTING_CONSTRUCTOR_CYCLE = const MessageKind(
-      'cyclic constructor redirection');
-  static const REDIRECTING_CONSTRUCTOR_HAS_BODY = const MessageKind(
-      'redirecting constructor cannot have a body');
-  static const REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER = const MessageKind(
-      'redirecting constructor cannot have other initializers');
-  static const SUPER_INITIALIZER_IN_OBJECT = const MessageKind(
-      "'Object' cannot have a super initializer");
-  static const DUPLICATE_SUPER_INITIALIZER = const MessageKind(
-      'cannot have more than one super initializer');
-  static const INVALID_ARGUMENTS = const MessageKind(
-      "arguments do not match the expected parameters of #{methodName}");
-  static const NO_MATCHING_CONSTRUCTOR = const MessageKind(
-      "super call arguments and constructor parameters don't match");
-  static const NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT = const MessageKind(
-      "implicit super call arguments and constructor parameters don't match");
-  static const CONST_CALLS_NON_CONST = const MessageKind(
-      "const constructor cannot call a non-const constructor");
-  static const INITIALIZING_FORMAL_NOT_ALLOWED = const MessageKind(
-      'an initializing formal parameter is only allowed in '
-      'non-redirecting generative constructors');
-  static const INVALID_PARAMETER = const MessageKind(
-      "cannot resolve parameter");
-  static const NOT_INSTANCE_FIELD = const MessageKind(
-      '#{fieldName} is not an instance field');
-  static const NO_CATCH_NOR_FINALLY = const MessageKind(
-      "expected 'catch' or 'finally'");
-  static const EMPTY_CATCH_DECLARATION = const MessageKind(
-      'expected an identifier in catch declaration');
-  static const EXTRA_CATCH_DECLARATION = const MessageKind(
-      'extra parameter in catch declaration');
-  static const PARAMETER_WITH_TYPE_IN_CATCH = const MessageKind(
-      'cannot use type annotations in catch');
-  static const PARAMETER_WITH_MODIFIER_IN_CATCH = const MessageKind(
-      'cannot use modifiers in catch');
-  static const OPTIONAL_PARAMETER_IN_CATCH = const MessageKind(
-      'cannot use optional parameters in catch');
-  static const THROW_WITHOUT_EXPRESSION = const MessageKind(
-      'cannot use re-throw outside of catch block (expression expected after '
-      '"throw")');
-  static const UNBOUND_LABEL = const MessageKind(
-      'cannot resolve label #{labelName}');
-  static const NO_BREAK_TARGET = const MessageKind(
-      'break statement not inside switch or loop');
-  static const NO_CONTINUE_TARGET = const MessageKind(
-      'continue statement not inside loop');
-  static const EXISTING_LABEL = const MessageKind(
-      'original declaration of duplicate label #{labelName}');
-  static const DUPLICATE_LABEL = const MessageKind(
-      'duplicate declaration of label #{labelName}');
-  static const UNUSED_LABEL = const MessageKind(
-      'unused label #{labelName}');
-  static const INVALID_CONTINUE = const MessageKind(
-      'target of continue is not a loop or switch case');
-  static const INVALID_BREAK = const MessageKind(
-      'target of break is not a statement');
+  static const MessageKind RETURN_VALUE_IN_VOID = const MessageKind(
+      'Warning: Cannot return value from void function.');
 
-  static const TYPE_VARIABLE_AS_CONSTRUCTOR = const MessageKind(
-      'cannot use type variable as constructor');
-  static const DUPLICATE_TYPE_VARIABLE_NAME = const MessageKind(
-      'type variable #{typeVariableName} already declared');
-  static const TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const MessageKind(
-      'cannot refer to type variable #{typeVariableName} '
-      'within a static member');
-  static const TYPE_VARIABLE_IN_CONSTANT = const MessageKind(
-      'Error: cannot refer to type variable in constant');
+  static const MessageKind RETURN_NOTHING = const MessageKind(
+      'Warning: Value of type "#{returnType}" expected.');
 
-  static const INVALID_USE_OF_SUPER = const MessageKind(
-      'super not allowed here');
-  static const INVALID_CASE_DEFAULT = const MessageKind(
-      'default only allowed on last case of a switch');
+  static const MessageKind MISSING_ARGUMENT = const MessageKind(
+      'Warning: Missing argument of type "#{argumentType}".');
 
-  static const SWITCH_CASE_TYPES_NOT_EQUAL = const MessageKind(
-      "case expressions don't all have the same type.");
-  static const SWITCH_CASE_VALUE_OVERRIDES_EQUALS = const MessageKind(
-      "case expression value overrides 'operator=='.");
-  static const SWITCH_INVALID = const MessageKind(
-      "switch cases contain invalid expressions.");
+  static const MessageKind ADDITIONAL_ARGUMENT = const MessageKind(
+      'Warning: Additional argument.');
 
-  static const INVALID_ARGUMENT_AFTER_NAMED = const MessageKind(
-      'non-named argument after named argument');
+  static const MessageKind NAMED_ARGUMENT_NOT_FOUND = const MessageKind(
+      'Warning: No named argument "#{argumentName}" found on method.');
 
-  static const NOT_A_COMPILE_TIME_CONSTANT = const MessageKind(
-      'not a compile-time constant');
-  static const CYCLIC_COMPILE_TIME_CONSTANTS = const MessageKind(
-      'cycle in the compile-time constant computation');
-  static const CONSTRUCTOR_IS_NOT_CONST = const MessageKind(
-      'constructor is not a const constructor');
+  static const DualKind MEMBER_NOT_FOUND = const DualKind(
+      error: const MessageKind(
+          'Error: No member named "#{memberName}" in class "#{className}".'),
+      warning: const MessageKind(
+          'Warning: No member named "#{memberName}" in class "#{className}".'));
 
-  static const KEY_NOT_A_STRING_LITERAL = const MessageKind(
-      'map-literal key not a string literal');
+  static const MessageKind METHOD_NOT_FOUND = const MessageKind(
+      'Warning: No method named "#{memberName}" in class "#{className}".');
 
-  static const NO_SUCH_LIBRARY_MEMBER = const MessageKind(
-      '#{libraryName} has no member named #{memberName}');
+  static const MessageKind OPERATOR_NOT_FOUND = const MessageKind(
+      'Warning: No operator "#{memberName}" in class "#{className}".');
 
-  static const CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
-      "cannot instantiate typedef '#{typedefName}'");
+  static const MessageKind PROPERTY_NOT_FOUND = const MessageKind(
+      'Warning: No property named "#{memberName}" in class "#{className}".');
 
-  static const CANNOT_INSTANTIATE_TYPE_VARIABLE = const MessageKind(
-      "cannot instantiate type variable '#{typeVariableName}'");
+  static const MessageKind NOT_CALLABLE = const MessageKind(
+      'Warning: "#{elementName}" is not callable.');
 
-  static const NO_DEFAULT_CLASS = const MessageKind(
-      "no default class on enclosing interface '#{interfaceName}'");
+  static const DualKind MEMBER_NOT_STATIC = const DualKind(
+      error: const MessageKind(
+          'Error: "#{className}.#{memberName}" is not static.'),
+      warning: const MessageKind(
+          'Warning: "#{className}.#{memberName}" is not static.'));
 
-  static const CYCLIC_TYPE_VARIABLE = const MessageKind(
-      "type variable #{typeVariableName} is a supertype of itself");
+  static const MessageKind NO_INSTANCE_AVAILABLE = const MessageKind(
+      'Error: "#{name}" is only available in instance methods.');
 
-  static const CLASS_NAME_EXPECTED = const MessageKind(
-      "class name expected");
+  static const MessageKind PRIVATE_ACCESS = const MessageKind(
+      'Warning: "#{name}" is declared private within library '
+      '"#{libraryName}".');
 
-  static const INTERFACE_TYPE_EXPECTED = const MessageKind(
-      "interface type expected");
+  static const MessageKind THIS_IS_THE_METHOD = const MessageKind(
+      'Info: This is the method declaration.');
 
-  static const CANNOT_EXTEND = const MessageKind(
-      "#{type} cannot be extended");
+  static const MessageKind UNREACHABLE_CODE = const MessageKind(
+      'Warning: Unreachable code.');
 
-  static const CANNOT_IMPLEMENT = const MessageKind(
-      "#{type} cannot be implemented");
+  static const MessageKind MISSING_RETURN = const MessageKind(
+      'Warning: Missing return.');
 
-  static const DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
-      "Error: #{type} can not be both extended and implemented.");
+  static const MessageKind MAYBE_MISSING_RETURN = const MessageKind(
+      'Warning: Not all paths lead to a return or throw statement.');
 
-  static const DUPLICATE_IMPLEMENTS = const MessageKind(
-      "Error: #{type} must not occur more than once "
-      "in the implements clause.");
+  static const DualKind CANNOT_RESOLVE = const DualKind(
+      error: const MessageKind('Error: Cannot resolve "#{name}".'),
+      warning: const MessageKind('Warning: Cannot resolve "#{name}".'));
 
-  static const ILLEGAL_SUPER_SEND = const MessageKind(
-      "#{name} cannot be called on super");
+  static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR = const MessageKind(
+      'Error: Cannot resolve constructor "#{constructorName}".');
 
-  static const NO_SUCH_SUPER_MEMBER = const MessageKind(
-      "Cannot resolve #{memberName} in a superclass of #{className}");
+  static const MessageKind CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT =
+      const MessageKind(
+          'Error: cannot resolve constructor "#{constructorName}" for implicit'
+          'super call.');
 
-  static const ADDITIONAL_TYPE_ARGUMENT = const MessageKind(
-      "additional type argument");
+  static const MessageKind INVALID_UNNAMED_CONSTRUCTOR_NAME = const MessageKind(
+      'Error: Unnamed constructor name must be "#{name}".');
 
-  static const MISSING_TYPE_ARGUMENT = const MessageKind(
-      "missing type argument");
+  static const MessageKind INVALID_CONSTRUCTOR_NAME = const MessageKind(
+      'Error: Constructor name must start with "#{name}".');
+
+  static const DualKind CANNOT_RESOLVE_TYPE = const DualKind(
+      error: const MessageKind('Error: Cannot resolve type "#{typeName}".'),
+      warning: const MessageKind(
+          'Warning: Cannot resolve type "#{typeName}".'));
+
+  static const MessageKind DUPLICATE_DEFINITION = const MessageKind(
+      'Error: Duplicate definition of "#{name}".');
+
+  static const MessageKind EXISTING_DEFINITION = const MessageKind(
+      'Info: Existing definition of "#{name}".');
+
+  static const DualKind DUPLICATE_IMPORT = const DualKind(
+      error: const MessageKind('Error: Duplicate import of "#{name}".'),
+      warning: const MessageKind('Warning: Duplicate import of "#{name}".'));
+
+  static const MessageKind DUPLICATE_EXPORT = const MessageKind(
+      'Error: Duplicate export of "#{name}".');
+
+  static const DualKind NOT_A_TYPE = const DualKind(
+      error: const MessageKind('Error: "#{node}" is not a type.'),
+      warning: const MessageKind('Warning: "#{node}" is not a type.'));
+
+  static const MessageKind NOT_A_PREFIX = const MessageKind(
+      'Error: "#{node}" is not a prefix.');
+
+  static const DualKind CANNOT_FIND_CONSTRUCTOR = const DualKind(
+      error: const MessageKind(
+          'Error: Cannot find constructor "#{constructorName}".'),
+      warning: const MessageKind(
+          'Warning: Cannot find constructor "#{constructorName}".'));
+
+  static const MessageKind CYCLIC_CLASS_HIERARCHY = const MessageKind(
+      'Error: "#{className}" creates a cycle in the class hierarchy.');
+
+  static const MessageKind INVALID_RECEIVER_IN_INITIALIZER = const MessageKind(
+      'Error: Field initializer expected.');
+
+  static const MessageKind NO_SUPER_IN_STATIC = const MessageKind(
+      'Error: "super" is only available in instance methods.');
+
+  static const MessageKind DUPLICATE_INITIALIZER = const MessageKind(
+      'Error: Field "#{fieldName}" is initialized more than once.');
+
+  static const MessageKind ALREADY_INITIALIZED = const MessageKind(
+      'Info: "#{fieldName}" was already initialized here.');
+
+  static const MessageKind INIT_STATIC_FIELD = const MessageKind(
+      'Error: Cannot initialize static field "#{fieldName}".');
+
+  static const MessageKind NOT_A_FIELD = const MessageKind(
+      'Error: "#{fieldName}" is not a field.');
+
+  static const MessageKind CONSTRUCTOR_CALL_EXPECTED = const MessageKind(
+      'Error: only call to "this" or "super" constructor allowed.');
+
+  static const MessageKind INVALID_FOR_IN = const MessageKind(
+      'Error: Invalid for-in variable declaration.');
+
+  static const MessageKind INVALID_INITIALIZER = const MessageKind(
+      'Error: Invalid initializer.');
+
+  static const MessageKind FUNCTION_WITH_INITIALIZER = const MessageKind(
+      'Error: Only constructors can have initializers.');
+
+  static const MessageKind REDIRECTING_CONSTRUCTOR_CYCLE = const MessageKind(
+      'Error: Cyclic constructor redirection.');
+
+  static const MessageKind REDIRECTING_CONSTRUCTOR_HAS_BODY = const MessageKind(
+      'Error: Redirecting constructor cannot have a body.');
+
+  static const MessageKind REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER =
+      const MessageKind(
+          'Error: Redirecting constructor cannot have other initializers.');
+
+  static const MessageKind SUPER_INITIALIZER_IN_OBJECT = const MessageKind(
+      'Error: "Object" cannot have a super initializer.');
+
+  static const MessageKind DUPLICATE_SUPER_INITIALIZER = const MessageKind(
+      'Error: Cannot have more than one super initializer.');
+
+  static const DualKind INVALID_ARGUMENTS = const DualKind(
+      error: const MessageKind(
+          'Error: Arguments do not match the expected parameters of '
+          '"#{methodName}".'),
+      warning: const MessageKind(
+          'Warning: Arguments do not match the expected parameters of '
+          '"#{methodName}".'));
+
+  static const MessageKind NO_MATCHING_CONSTRUCTOR = const MessageKind(
+      'Error: "super" call arguments and constructor parameters do not match.');
+
+  static const MessageKind NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT =
+      const MessageKind(
+          'Error: Implicit "super" call arguments and constructor parameters '
+          'do not match.');
+
+  static const MessageKind CONST_CALLS_NON_CONST = const MessageKind(
+      'Error: "const" constructor cannot call a non-const constructor.');
+
+  static const MessageKind INITIALIZING_FORMAL_NOT_ALLOWED = const MessageKind(
+      'Error: Initializing formal parameter only allowed in generative '
+      'constructor.');
+
+  static const MessageKind INVALID_PARAMETER = const MessageKind(
+      'Error: Cannot resolve parameter.');
+
+  static const MessageKind NOT_INSTANCE_FIELD = const MessageKind(
+      'Error: "#{fieldName}" is not an instance field.');
+
+  static const MessageKind NO_CATCH_NOR_FINALLY = const MessageKind(
+      'Error: Expected "catch" or "finally".');
+
+  static const MessageKind EMPTY_CATCH_DECLARATION = const MessageKind(
+      'Error: Expected an identifier in catch declaration.');
+
+  static const MessageKind EXTRA_CATCH_DECLARATION = const MessageKind(
+      'Error: Extra parameter in catch declaration.');
+
+  static const MessageKind PARAMETER_WITH_TYPE_IN_CATCH = const MessageKind(
+      'Error: Cannot use type annotations in catch.');
+
+  static const MessageKind PARAMETER_WITH_MODIFIER_IN_CATCH = const MessageKind(
+      'Error: Cannot use modifiers in catch.');
+
+  static const MessageKind OPTIONAL_PARAMETER_IN_CATCH = const MessageKind(
+      'Error: Cannot use optional parameters in catch.');
+
+  static const MessageKind THROW_WITHOUT_EXPRESSION = const MessageKind(
+      'Error: Cannot use re-throw outside of catch block '
+      '(expression expected after "throw").');
+
+  static const MessageKind UNBOUND_LABEL = const MessageKind(
+      'Error: Cannot resolve label "#{labelName}".');
+
+  static const MessageKind NO_BREAK_TARGET = const MessageKind(
+      'Error: "break" statement not inside switch or loop.');
+
+  static const MessageKind NO_CONTINUE_TARGET = const MessageKind(
+      'Error: "continue" statement not inside loop.');
+
+  static const MessageKind EXISTING_LABEL = const MessageKind(
+      'Info: Original declaration of duplicate label "#{labelName}".');
+
+  static const DualKind DUPLICATE_LABEL = const DualKind(
+      error: const MessageKind(
+          'Error: Duplicate declaration of label "#{labelName}".'),
+      warning: const MessageKind(
+          'Warning: Duplicate declaration of label "#{labelName}".'));
+
+  static const MessageKind UNUSED_LABEL = const MessageKind(
+      'Warning: Unused label "#{labelName}".');
+
+  static const MessageKind INVALID_CONTINUE = const MessageKind(
+      'Error: Target of continue is not a loop or switch case.');
+
+  static const MessageKind INVALID_BREAK = const MessageKind(
+      'Error: Target of break is not a statement.');
+
+  static const MessageKind DUPLICATE_TYPE_VARIABLE_NAME = const MessageKind(
+      'Error: Type variable "#{typeVariableName}" already declared.');
+
+  static const DualKind TYPE_VARIABLE_WITHIN_STATIC_MEMBER = const DualKind(
+      error: const MessageKind(
+          'Error: Cannot refer to type variable "#{typeVariableName}" '
+          'within a static member.'),
+      warning: const MessageKind(
+          'Warning: Cannot refer to type variable "#{typeVariableName}" '
+          'within a static member.'));
+
+  static const MessageKind TYPE_VARIABLE_IN_CONSTANT = const MessageKind(
+      'Error: Cannot refer to type variable in constant.');
+
+  static const MessageKind INVALID_USE_OF_SUPER = const MessageKind(
+      'Error: "super" not allowed here.');
+
+  static const MessageKind INVALID_CASE_DEFAULT = const MessageKind(
+      'Error: "default" only allowed on last case of a switch.');
+
+  static const MessageKind SWITCH_CASE_TYPES_NOT_EQUAL = const MessageKind(
+      'Error: "case" expressions do not all have the same type.');
+
+  static const MessageKind SWITCH_CASE_VALUE_OVERRIDES_EQUALS =
+      const MessageKind(
+          'Error: "case" expression value overrides "operator==".');
+
+  static const MessageKind INVALID_ARGUMENT_AFTER_NAMED = const MessageKind(
+      'Error: Unnamed argument after named argument.');
+
+  static const MessageKind NOT_A_COMPILE_TIME_CONSTANT = const MessageKind(
+      'Error: Not a compile-time constant.');
+
+  static const MessageKind CYCLIC_COMPILE_TIME_CONSTANTS = const MessageKind(
+      'Error: Cycle in the compile-time constant computation.');
+
+  static const MessageKind CONSTRUCTOR_IS_NOT_CONST = const MessageKind(
+      'Error: Constructor is not a "const" constructor.');
+
+  static const MessageKind KEY_NOT_A_STRING_LITERAL = const MessageKind(
+      'Error: Map-literal key not a string literal.');
+
+  static const DualKind NO_SUCH_LIBRARY_MEMBER = const DualKind(
+      error: const MessageKind(
+          'Error: "#{libraryName}" has no member named "#{memberName}".'),
+      warning: const MessageKind(
+          'Warning: "#{libraryName}" has no member named "#{memberName}".'));
+
+  static const MessageKind CANNOT_INSTANTIATE_TYPEDEF = const MessageKind(
+      'Error: Cannot instantiate typedef "#{typedefName}".');
+
+  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 MessageKind CLASS_NAME_EXPECTED = const MessageKind(
+      'Error: Class name expected.');
+
+  static const MessageKind CANNOT_EXTEND = const MessageKind(
+      'Error: "#{type}" cannot be extended.');
+
+  static const MessageKind CANNOT_IMPLEMENT = const MessageKind(
+      'Error: "#{type}" cannot be implemented.');
+
+  static const MessageKind DUPLICATE_EXTENDS_IMPLEMENTS = const MessageKind(
+      'Error: "#{type}" can not be both extended and implemented.');
+
+  static const MessageKind DUPLICATE_IMPLEMENTS = const MessageKind(
+      'Error: "#{type}" must not occur more than once '
+      'in the implements clause.');
+
+  static const MessageKind ILLEGAL_SUPER_SEND = const MessageKind(
+      'Error: "#{name}" cannot be called on super.');
+
+  static const DualKind NO_SUCH_SUPER_MEMBER = const DualKind(
+      error: const MessageKind(
+          'Error: Cannot resolve "#{memberName}" in a superclass of '
+          '"#{className}".'),
+      warning: const MessageKind(
+          'Warning: Cannot resolve "#{memberName}" in a superclass of '
+          '"#{className}".'));
+
+  static const DualKind ADDITIONAL_TYPE_ARGUMENT = const DualKind(
+      error: const MessageKind('Error: Additional type argument.'),
+      warning: const MessageKind('Warning: Additional type argument.'));
+
+  static const DualKind MISSING_TYPE_ARGUMENT = const DualKind(
+      error: const MessageKind('Error: Missing type argument.'),
+      warning: const MessageKind('Warning: Missing type argument.'));
 
   // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or MISSING_TYPE_ARGUMENT
   // instead.
-  static const TYPE_ARGUMENT_COUNT_MISMATCH = const MessageKind(
-      "incorrect number of type arguments on #{type}");
+  static const MessageKind TYPE_ARGUMENT_COUNT_MISMATCH = const MessageKind(
+      'Error: Incorrect number of type arguments on "#{type}".');
 
-  static const MISSING_ARGUMENTS_TO_ASSERT = const MessageKind(
-      "missing arguments to assert");
+  static const MessageKind GETTER_MISMATCH = const MessageKind(
+      'Error: Setter disagrees on: "#{modifiers}".');
 
-  static const GETTER_MISMATCH = const MessageKind(
-      "Error: setter disagrees on: #{modifiers}.");
+  static const MessageKind SETTER_MISMATCH = const MessageKind(
+      'Error: Getter disagrees on: "#{modifiers}".');
 
-  static const SETTER_MISMATCH = const MessageKind(
-      "Error: getter disagrees on: #{modifiers}.");
+  static const MessageKind ILLEGAL_SETTER_FORMALS = const MessageKind(
+      'Error: A setter must have exactly one argument.');
 
-  static const ILLEGAL_SETTER_FORMALS = const MessageKind(
-      "Error: a setter must have exactly one argument.");
+  static const MessageKind NO_STATIC_OVERRIDE = const MessageKind(
+      'Error: Static member cannot override instance member "#{memberName}" of '
+      '"#{className}".');
 
-  static const NO_STATIC_OVERRIDE = const MessageKind(
-      "Error: static member cannot override instance member '#{memberName}' of "
-      "'#{className}'.");
+  static const MessageKind NO_STATIC_OVERRIDE_CONT = const MessageKind(
+      'Info: This is the instance member that cannot be overridden '
+      'by a static member.');
 
-  static const NO_STATIC_OVERRIDE_CONT = const MessageKind(
-      "Info: this is the instance member that cannot be overridden "
-      "by a static member.");
+  static const MessageKind CANNOT_OVERRIDE_FIELD_WITH_METHOD =
+      const MessageKind(
+          'Error: Method cannot override field "#{memberName}" of '
+          '"#{className}".');
 
-  static const CANNOT_OVERRIDE_FIELD_WITH_METHOD = const MessageKind(
-      "Error: method cannot override field '#{memberName}' of '#{className}'.");
+  static const MessageKind CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT =
+      const MessageKind(
+          'Info: This is the field that cannot be overridden by a method.');
 
-  static const CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT = const MessageKind(
-      "Info: this is the field that cannot be overridden by a method.");
+  static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_FIELD =
+      const MessageKind(
+          'Error: Field cannot override method "#{memberName}" of '
+          '"#{className}".');
 
-  static const CANNOT_OVERRIDE_METHOD_WITH_FIELD = const MessageKind(
-      "Error: field cannot override method '#{memberName}' of '#{className}'.");
+  static const MessageKind CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT =
+      const MessageKind(
+          'Info: This is the method that cannot be overridden by a field.');
 
-  static const CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT = const MessageKind(
-      "Info: this is the method that cannot be overridden by a field.");
+  static const MessageKind BAD_ARITY_OVERRIDE = const MessageKind(
+      'Error: Cannot override method "#{memberName}" in "#{className}"; '
+      'the parameters do not match.');
 
-  static const BAD_ARITY_OVERRIDE = const MessageKind(
-      "Error: cannot override method '#{memberName}' in '#{className}'; "
-      "the parameters do not match.");
+  static const MessageKind BAD_ARITY_OVERRIDE_CONT = const MessageKind(
+      'Info: This is the method whose parameters do not match.');
 
-  static const BAD_ARITY_OVERRIDE_CONT = const MessageKind(
-      "Info: this is the method whose parameters do not match.");
+  static const MessageKind MISSING_FORMALS = const MessageKind(
+      'Error: Formal parameters are missing.');
 
-  static const MISSING_FORMALS = const MessageKind(
-      "Error: Formal parameters are missing.");
+  static const MessageKind EXTRA_FORMALS = const MessageKind(
+      'Error: Formal parameters are not allowed here.');
 
-  static const EXTRA_FORMALS = const MessageKind(
-      "Error: Formal parameters are not allowed here.");
+  static const MessageKind UNARY_OPERATOR_BAD_ARITY = const MessageKind(
+      'Error: Operator "#{operatorName}" must have no parameters.');
 
-  static const UNARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator #{operatorName} must have no parameters.");
+  static const MessageKind MINUS_OPERATOR_BAD_ARITY = const MessageKind(
+      'Error: Operator "-" must have 0 or 1 parameters.');
 
-  static const MINUS_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator - must have 0 or 1 parameters.");
+  static const MessageKind BINARY_OPERATOR_BAD_ARITY = const MessageKind(
+      'Error: Operator "#{operatorName}" must have exactly 1 parameter.');
 
-  static const BINARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator #{operatorName} must have exactly 1 parameter.");
+  static const MessageKind TERNARY_OPERATOR_BAD_ARITY = const MessageKind(
+      'Error: Operator "#{operatorName}" must have exactly 2 parameters.');
 
-  static const TERNARY_OPERATOR_BAD_ARITY = const MessageKind(
-      "Error: Operator #{operatorName} must have exactly 2 parameters.");
+  static const MessageKind OPERATOR_OPTIONAL_PARAMETERS = const MessageKind(
+      'Error: Operator "#{operatorName}" cannot have optional parameters.');
 
-  static const OPERATOR_OPTIONAL_PARAMETERS = const MessageKind(
-      "Error: Operator #{operatorName} cannot have optional parameters.");
-
-  static const OPERATOR_NAMED_PARAMETERS = const MessageKind(
-      "Error: Operator #{operatorName} cannot have named parameters.");
+  static const MessageKind OPERATOR_NAMED_PARAMETERS = const MessageKind(
+      'Error: Operator "#{operatorName}" cannot have named parameters.');
 
   // TODO(ahe): This message is hard to localize.  This is acceptable,
   // as it will be removed when we ship Dart version 1.0.
-  static const DEPRECATED_FEATURE_WARNING = const MessageKind(
-      "Warning: deprecated language feature, #{featureName}, "
-      "will be removed in a future Dart milestone.");
+  static const MessageKind DEPRECATED_FEATURE_WARNING = const MessageKind(
+      'Warning: Deprecated language feature, #{featureName}, '
+      'will be removed in a future Dart milestone.');
 
   // TODO(ahe): This message is hard to localize.  This is acceptable,
   // as it will be removed when we ship Dart version 1.0.
-  static const DEPRECATED_FEATURE_ERROR = const MessageKind(
-      "Error: #{featureName} are not legal "
-      "due to option --reject-deprecated-language-features.");
+  static const MessageKind DEPRECATED_FEATURE_ERROR = const MessageKind(
+      'Error: #{featureName} are not legal '
+      'due to option --reject-deprecated-language-features.');
 
-  static const CONSTRUCTOR_WITH_RETURN_TYPE = const MessageKind(
-      "Error: cannot have return type for constructor.");
+  static const MessageKind CONSTRUCTOR_WITH_RETURN_TYPE = const MessageKind(
+      'Error: Cannot have return type for constructor.');
 
-  static const ILLEGAL_FINAL_METHOD_MODIFIER = const MessageKind(
-      "Error: cannot have final modifier on method.");
+  static const MessageKind ILLEGAL_FINAL_METHOD_MODIFIER = const MessageKind(
+      'Error: Cannot have final modifier on method.');
 
-  static const ILLEGAL_CONSTRUCTOR_MODIFIERS = const MessageKind(
-      "Error: illegal constructor modifiers: #{modifiers}.");
+  static const MessageKind ILLEGAL_CONSTRUCTOR_MODIFIERS = const MessageKind(
+      'Error: Illegal constructor modifiers: "#{modifiers}".');
 
-  static const ILLEGAL_MIXIN_APPLICATION_MODIFIERS = const MessageKind(
-      "Error: illegal mixin application modifiers: #{modifiers}.");
+  static const MessageKind ILLEGAL_MIXIN_APPLICATION_MODIFIERS =
+      const MessageKind(
+          'Error: Illegal mixin application modifiers: "#{modifiers}".');
 
-  static const ILLEGAL_MIXIN_SUPERCLASS = const MessageKind(
-      "Error: class used as mixin must have Object as superclass.");
+  static const MessageKind ILLEGAL_MIXIN_SUPERCLASS = const MessageKind(
+      'Error: Class used as mixin must have Object as superclass.');
 
-  static const ILLEGAL_MIXIN_OBJECT = const MessageKind(
-      "Error: cannot use Object as mixin.");
+  static const MessageKind ILLEGAL_MIXIN_OBJECT = const MessageKind(
+      'Error: Cannot use Object as mixin.');
 
-  static const ILLEGAL_MIXIN_CONSTRUCTOR = const MessageKind(
-      "Error: class used as mixin cannot have non-factory constructor.");
+  static const MessageKind ILLEGAL_MIXIN_CONSTRUCTOR = const MessageKind(
+      'Error: Class used as mixin cannot have non-factory constructor.');
 
-  static const ILLEGAL_MIXIN_CYCLE = const MessageKind(
-      "Error: class used as mixin introduces mixin cycle: "
-      "#{mixinName1} <-> #{mixinName2}.");
+  static const MessageKind ILLEGAL_MIXIN_CYCLE = const MessageKind(
+      'Error: Class used as mixin introduces mixin cycle: '
+      '"#{mixinName1}" <-> "#{mixinName2}".');
 
-  static const ILLEGAL_MIXIN_WITH_SUPER = const MessageKind(
-      "Error: cannot use class #{className} as a mixin because it uses super.");
+  static const MessageKind ILLEGAL_MIXIN_WITH_SUPER = const MessageKind(
+      'Error: Cannot use class "#{className}" as a mixin because it uses '
+      '"super".');
 
-  static const ILLEGAL_MIXIN_SUPER_USE = const MessageKind(
-      "Use of super in class used as mixin.");
+  static const MessageKind ILLEGAL_MIXIN_SUPER_USE = const MessageKind(
+      'Info: Use of "super" in class used as mixin.');
 
-  static const PARAMETER_NAME_EXPECTED = const MessageKind(
-      "Error: parameter name expected.");
+  static const MessageKind PARAMETER_NAME_EXPECTED = const MessageKind(
+      'Error: parameter name expected.');
 
-  static const CANNOT_RESOLVE_GETTER = const MessageKind(
-      'cannot resolve getter.');
+  static const DualKind CANNOT_RESOLVE_GETTER = const DualKind(
+      error: const MessageKind('Error: Cannot resolve getter.'),
+      warning: const MessageKind('Warning: Cannot resolve getter.'));
 
-  static const CANNOT_RESOLVE_SETTER = const MessageKind(
-      'cannot resolve setter.');
+  static const DualKind CANNOT_RESOLVE_SETTER = const DualKind(
+      error: const MessageKind('Error: Cannot resolve setter.'),
+      warning: const MessageKind('Warning: Cannot resolve setter.'));
 
-  static const CANNOT_RESOLVE_INDEX = const MessageKind(
-      'cannot resolve [] member.');
+  static const MessageKind VOID_NOT_ALLOWED = const MessageKind(
+      'Error: Type "void" is only allowed in a return type.');
 
-  static const VOID_NOT_ALLOWED = const MessageKind(
-      'type void is only allowed in a return type.');
+  static const MessageKind BEFORE_TOP_LEVEL = const MessageKind(
+      'Error: Part header must come before top-level definitions.');
 
-  static const BEFORE_TOP_LEVEL = const MessageKind(
-      'Error: part header must come before top-level definitions.');
+  static const MessageKind LIBRARY_NAME_MISMATCH = const MessageKind(
+      'Warning: Expected part of library name "#{libraryName}".');
 
-  static const LIBRARY_NAME_MISMATCH = const MessageKind(
-      'Warning: expected part of library name "#{libraryName}".');
-
-  static const MISSING_PART_OF_TAG = const MessageKind(
+  static const MessageKind MISSING_PART_OF_TAG = const MessageKind(
       'Note: This file has no part-of tag, but it is being used as a part.');
 
-  static const DUPLICATED_PART_OF = const MessageKind(
-      'Error: duplicated part-of directive.');
+  static const MessageKind DUPLICATED_PART_OF = const MessageKind(
+      'Error: Duplicated part-of directive.');
 
-  static const ILLEGAL_DIRECTIVE = const MessageKind(
-      'Error: directive not allowed here.');
+  static const MessageKind ILLEGAL_DIRECTIVE = const MessageKind(
+      'Error: Directive not allowed here.');
 
-  static const DUPLICATED_LIBRARY_NAME = const MessageKind(
-      'Warning: duplicated library name "#{libraryName}".');
+  static const MessageKind DUPLICATED_LIBRARY_NAME = const MessageKind(
+      'Warning: Duplicated library name "#{libraryName}".');
 
-  static const INVALID_SOURCE_FILE_LOCATION = const MessageKind('''
+  // This is used as an exception.
+  static const MessageKind INVALID_SOURCE_FILE_LOCATION = const MessageKind('''
 Invalid offset (#{offset}) in source map.
 File: #{fileName}
 Length: #{length}''');
 
-  static const TOP_LEVEL_VARIABLE_DECLARED_STATIC = const MessageKind(
-      "Top-level variable cannot be declared static.");
+  static const MessageKind TOP_LEVEL_VARIABLE_DECLARED_STATIC =
+      const MessageKind(
+          'Error: Top-level variable cannot be declared static.');
 
-  static const WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT = const MessageKind(
-      "Wrong number of arguments to assert. Should be 1, but given "
-      "#{argumentCount}.");
+  static const MessageKind WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT =
+      const MessageKind(
+          'Error: Wrong number of arguments to assert. Should be 1, but given '
+          '#{argumentCount}.');
 
-  static const ASSERT_IS_GIVEN_NAMED_ARGUMENTS = const MessageKind(
-      "assert takes no named arguments, but given #{argumentCount}.");
+  static const MessageKind ASSERT_IS_GIVEN_NAMED_ARGUMENTS = const MessageKind(
+      'Error: "assert" takes no named arguments, but given #{argumentCount}.');
 
-  static const FACTORY_REDIRECTION_IN_NON_FACTORY = const MessageKind(
-      "Error: Factory redirection only allowed in factories.");
+  static const MessageKind FACTORY_REDIRECTION_IN_NON_FACTORY =
+      const MessageKind(
+          'Error: Factory redirection only allowed in factories.');
 
-  static const MISSING_FACTORY_KEYWORD = const MessageKind(
-      "Did you forget a factory keyword here?");
+  static const MessageKind MISSING_FACTORY_KEYWORD = const MessageKind(
+      'Hint: Did you forget a factory keyword here?');
 
-  static const DEFERRED_LIBRARY_NAME_MISMATCH = const MessageKind(
-      'Error: Library name mismatch "#{expectedName}" != "#{actualName}".');
+  static const MessageKind DEFERRED_LIBRARY_NAME_MISMATCH =
+      const MessageKind(
+          'Error: Library name mismatch "#{expectedName}" != "#{actualName}".');
 
-  static const ILLEGAL_STATIC = const MessageKind(
-      "Error: Modifier static is only allowed on functions declared in"
-      " a class.");
+  static const MessageKind ILLEGAL_STATIC = const MessageKind(
+      'Error: Modifier static is only allowed on functions declared in '
+      'a class.');
 
-  static const STATIC_FUNCTION_BLOAT = const MessageKind(
+  static const MessageKind STATIC_FUNCTION_BLOAT = const MessageKind(
       'Hint: Using "#{class}.#{name}" may result in larger output.');
 
-  static const NON_CONST_BLOAT = const MessageKind('''
+  static const MessageKind NON_CONST_BLOAT = const MessageKind('''
 Hint: Using "new #{name}" may result in larger output.
 Use "const #{name}" if possible.''');
 
-  static const STRING_EXPECTED = const MessageKind(
+  static const MessageKind STRING_EXPECTED = const MessageKind(
       'Error: Expected a "String", but got an instance of "#{type}".');
 
-  static const PRIVATE_IDENTIFIER = const MessageKind(
+  static const MessageKind PRIVATE_IDENTIFIER = const MessageKind(
       'Error: "#{value}" is not a valid Symbol name because it starts with '
       '"_".');
 
-  static const INVALID_SYMBOL = const MessageKind('''
+  static const MessageKind INVALID_SYMBOL = const MessageKind('''
 Error: "#{value}" is not a valid Symbol name because is not:
  * an empty String,
  * a user defined operator,
  * a qualified non-private identifier optionally followed by "=", or
- * a qualified non-private identifier followed by "." and a user-defined operator.''');
+ * a qualified non-private identifier followed by "." and a user-defined '''
+'operator.');
 
-  static const AMBIGUOUS_REEXPORT = const MessageKind(
+  static const MessageKind AMBIGUOUS_REEXPORT = const MessageKind(
       'Info: "#{element}" is (re)exported by multiple libraries.');
 
-  static const AMBIGUOUS_LOCATION = const MessageKind(
+  static const MessageKind AMBIGUOUS_LOCATION = const MessageKind(
       'Info: "#{element}" is defined here.');
 
-  static const IMPORTED_HERE = const MessageKind(
+  static const MessageKind IMPORTED_HERE = const MessageKind(
       'Info: "#{element}" is imported here.');
 
-  static const OVERRIDE_EQUALS_NOT_HASH_CODE = const MessageKind(
+  static const MessageKind OVERRIDE_EQUALS_NOT_HASH_CODE = const MessageKind(
       'Hint: The class "#{class}" overrides "operator==", '
       'but not "get hashCode".');
-  
-  static const PACKAGE_ROOT_NOT_SET = const MessageKind(
-      "Error: Cannot resolve '#{uri}'. Package root has not been set.");
 
-  static const COMPILER_CRASHED = const MessageKind(
-      "Error: The compiler crashed when compiling this element.");
+  static const MessageKind PACKAGE_ROOT_NOT_SET = const MessageKind(
+      'Error: Cannot resolve "#{uri}". Package root has not been set.');
 
-  static const PLEASE_REPORT_THE_CRASH = const MessageKind('''
+  static const MessageKind COMPILER_CRASHED = const MessageKind(
+      'Error: The compiler crashed when compiling this element.');
+
+  static const MessageKind PLEASE_REPORT_THE_CRASH = const MessageKind('''
 The compiler is broken.
 
 When compiling the above element, the compiler crashed. It is not
@@ -479,84 +644,88 @@
   // Patch errors start.
   //////////////////////////////////////////////////////////////////////////////
 
-  static const PATCH_RETURN_TYPE_MISMATCH = const MessageKind(
-      "Patch return type '#{patchReturnType}' doesn't match "
-      "'#{originReturnType}' on origin method '#{methodName}'.");
+  static const MessageKind PATCH_RETURN_TYPE_MISMATCH = const MessageKind(
+      'Error: Patch return type "#{patchReturnType}" does not match '
+      '"#{originReturnType}" on origin method "#{methodName}".');
 
-  static const PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH = const MessageKind(
-      "Required parameter count of patch method (#{patchParameterCount}) "
-      "doesn't match parameter count on origin method '#{methodName}' "
-      "(#{originParameterCount}).");
+  static const MessageKind PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH =
+      const MessageKind(
+          'Error: Required parameter count of patch method '
+          '(#{patchParameterCount}) does not match parameter count on origin '
+          'method "#{methodName}" (#{originParameterCount}).');
 
-  static const PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH = const MessageKind(
-      "Optional parameter count of patch method (#{patchParameterCount}) "
-      "doesn't match parameter count on origin method '#{methodName}' "
-      "(#{originParameterCount}).");
+  static const MessageKind PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH =
+      const MessageKind(
+          'Error: Optional parameter count of patch method '
+          '(#{patchParameterCount}) does not match parameter count on origin '
+          'method "#{methodName}" (#{originParameterCount}).');
 
-  static const PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH = const MessageKind(
-      "Optional parameters of origin and patch method '#{methodName}' must "
-      "both be either named or positional.");
+  static const MessageKind PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH =
+      const MessageKind(
+          'Error: Optional parameters of origin and patch method '
+          '"#{methodName}" must both be either named or positional.');
 
-  static const PATCH_PARAMETER_MISMATCH = const MessageKind(
-      "Patch method parameter '#{patchParameter}' doesn't match "
-      "'#{originParameter}' on origin method #{methodName}.");
+  static const MessageKind PATCH_PARAMETER_MISMATCH = const MessageKind(
+      'Error: Patch method parameter "#{patchParameter}" does not match '
+      '"#{originParameter}" on origin method "#{methodName}".');
 
-  static const PATCH_PARAMETER_TYPE_MISMATCH = const MessageKind(
-      "Patch method parameter '#{parameterName}' type #{patchParameterType} "
-      "doesn't match #{originParameterType} on origin method #{methodName}.");
+  static const MessageKind PATCH_PARAMETER_TYPE_MISMATCH = const MessageKind(
+      'Error: Patch method parameter "#{parameterName}" type '
+      '"#{patchParameterType}" does not match "#{originParameterType}" on '
+      'origin method "#{methodName}".');
 
-  static const PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION = const MessageKind(
-      "External method without an implementation.");
+  static const MessageKind PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION =
+      const MessageKind('Error: External method without an implementation.');
 
-  static const PATCH_POINT_TO_FUNCTION = const MessageKind(
-      "Info: This is the function patch '#{functionName}'.");
+  static const MessageKind PATCH_POINT_TO_FUNCTION = const MessageKind(
+      'Info: This is the function patch "#{functionName}".');
 
-  static const PATCH_POINT_TO_CLASS = const MessageKind(
-      "Info: This is the class patch '#{className}'.");
+  static const MessageKind PATCH_POINT_TO_CLASS = const MessageKind(
+      'Info: This is the class patch "#{className}".');
 
-  static const PATCH_POINT_TO_GETTER = const MessageKind(
-      "Info: This is the getter patch '#{getterName}'.");
+  static const MessageKind PATCH_POINT_TO_GETTER = const MessageKind(
+      'Info: This is the getter patch "#{getterName}".');
 
-  static const PATCH_POINT_TO_SETTER = const MessageKind(
-      "Info: This is the setter patch '#{setterName}'.");
+  static const MessageKind PATCH_POINT_TO_SETTER = const MessageKind(
+      'Info: This is the setter patch "#{setterName}".');
 
-  static const PATCH_POINT_TO_CONSTRUCTOR = const MessageKind(
-      "Info: This is the constructor patch '#{constructorName}'.");
+  static const MessageKind PATCH_POINT_TO_CONSTRUCTOR = const MessageKind(
+      'Info: This is the constructor patch "#{constructorName}".');
 
-  static const PATCH_POINT_TO_PARAMETER = const MessageKind(
-      "Info: This is the patch parameter '#{parameterName}'.");
+  static const MessageKind PATCH_POINT_TO_PARAMETER = const MessageKind(
+      'Info: This is the patch parameter "#{parameterName}".');
 
-  static const PATCH_NON_EXISTING = const MessageKind(
-      "Error: Origin does not exist for patch '#{name}'.");
+  static const MessageKind PATCH_NON_EXISTING = const MessageKind(
+      'Error: Origin does not exist for patch "#{name}".');
 
-  static const PATCH_NONPATCHABLE = const MessageKind(
-      "Error: Only classes and functions can be patched.");
+  static const MessageKind PATCH_NONPATCHABLE = const MessageKind(
+      'Error: Only classes and functions can be patched.');
 
-  static const PATCH_NON_EXTERNAL = const MessageKind(
-      "Error: Only external functions can be patched.");
+  static const MessageKind PATCH_NON_EXTERNAL = const MessageKind(
+      'Error: Only external functions can be patched.');
 
-  static const PATCH_NON_CLASS = const MessageKind(
-      "Error: Patching non-class with class patch '#{className}'.");
+  static const MessageKind PATCH_NON_CLASS = const MessageKind(
+      'Error: Patching non-class with class patch "#{className}".');
 
-  static const PATCH_NON_GETTER = const MessageKind(
-      "Error: Cannot patch non-getter '#{name}' with getter patch.");
+  static const MessageKind PATCH_NON_GETTER = const MessageKind(
+      'Error: Cannot patch non-getter "#{name}" with getter patch.');
 
-  static const PATCH_NO_GETTER = const MessageKind(
-      "Error: No getter found for getter patch '#{getterName}'.");
+  static const MessageKind PATCH_NO_GETTER = const MessageKind(
+      'Error: No getter found for getter patch "#{getterName}".');
 
-  static const PATCH_NON_SETTER = const MessageKind(
-      "Error: Cannot patch non-setter '#{name}' with setter patch.");
+  static const MessageKind PATCH_NON_SETTER = const MessageKind(
+      'Error: Cannot patch non-setter "#{name}" with setter patch.');
 
-  static const PATCH_NO_SETTER = const MessageKind(
-      "Error: No setter found for setter patch '#{setterName}'.");
+  static const MessageKind PATCH_NO_SETTER = const MessageKind(
+      'Error: No setter found for setter patch "#{setterName}".');
 
-  static const PATCH_NON_CONSTRUCTOR = const MessageKind(
-      "Error: Cannot patch non-constructor with constructor patch "
-      "'#{constructorName}'.");
+  static const MessageKind PATCH_NON_CONSTRUCTOR = const MessageKind(
+      'Error: Cannot patch non-constructor with constructor patch '
+      '"#{constructorName}".');
 
-  static const PATCH_NON_FUNCTION = const MessageKind(
-      "Error: Cannot patch non-function with function patch "
-      "'#{functionName}'.");
+  static const MessageKind PATCH_NON_FUNCTION = const MessageKind(
+      'Error: Cannot patch non-function with function patch '
+      '"#{functionName}".');
 
   //////////////////////////////////////////////////////////////////////////////
   // Patch errors end.
@@ -573,6 +742,13 @@
   }
 }
 
+class DualKind {
+  final MessageKind error;
+  final MessageKind warning;
+
+  const DualKind({this.error, this.warning});
+}
+
 class Message {
   final kind;
   final Map arguments;
@@ -591,7 +767,7 @@
       });
       assert(invariant(
           CURRENT_ELEMENT_SPANNABLE,
-          !message.contains(new RegExp(r"#\{.+\}")),
+          !message.contains(new RegExp(r'#\{.+\}')),
           message: 'Missing arguments in error message: "$message"'));
     }
     return message;
@@ -629,11 +805,6 @@
     : super(kind, arguments);
 }
 
-class ResolutionError extends Diagnostic {
-  ResolutionError(MessageKind kind, [Map arguments = const {}])
-      : super(kind, arguments);
-}
-
 class ResolutionWarning extends Diagnostic {
   ResolutionWarning(MessageKind kind, [Map arguments = const {}])
     : super(kind, arguments);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index a4f487c..6bd9e6c 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -24393,14 +24393,6 @@
   @DocsEditable()
   final int screenY;
 
-  @DomName('Window.scrollX')
-  @DocsEditable()
-  final int scrollX;
-
-  @DomName('Window.scrollY')
-  @DocsEditable()
-  final int scrollY;
-
   @DomName('Window.scrollbars')
   @DocsEditable()
   final BarProp scrollbars;
@@ -24966,6 +24958,11 @@
   void moveTo(Point p) {
     $dom_moveTo(p.x, p.y);
   }
+
+  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int', 
+      '#.scrollX', this) : document.documentElement.scrollLeft;
+  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int', 
+      '#.scrollY', this) : document.documentElement.scrollTop;
 }
 
 /**
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 516c416..d667804 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -26320,6 +26320,7 @@
   void moveTo(Point p) {
     $dom_moveTo(p.x, p.y);
   }
+
 }
 
 /**
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 2e9b652..d69839e 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -29,7 +29,7 @@
 }
 
 
-class _StdinEventSink {
+class _StdinEventSink implements EventSink<String> {
   Function add;
   Function addError;
   Function close;
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index c054b1e..dd837445 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -668,7 +668,8 @@
 
 
 class _WebSocketImpl extends Stream implements WebSocket {
-  final StreamController _controller = new StreamController(sync: true);
+  StreamController _controller;
+  StreamSubscription _subscription;
   StreamSink _sink;
 
   final Socket _socket;
@@ -763,7 +764,7 @@
     _readyState = WebSocket.OPEN;
 
     var transformer = new _WebSocketProtocolTransformer(_serverSide);
-    _socket.transform(transformer).listen(
+    _subscription = _socket.transform(transformer).listen(
         (data) {
           if (data is _WebSocketPing) {
             if (!_writeClosed) _consumer.add(new _WebSocketPong(data.payload));
@@ -798,6 +799,11 @@
           _controller.close();
         },
         cancelOnError: true);
+    _subscription.pause();
+    _controller = new StreamController(sync: true,
+                                       onListen: _subscription.resume,
+                                       onPause: _subscription.pause,
+                                       onResume: _subscription.resume);
   }
 
   StreamSubscription listen(void onData(message),
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index fd91660..5353755 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -162,6 +162,16 @@
    * A mirror on the root library for this isolate.
    */
   LibraryMirror get rootLibrary;
+
+  /**
+   * Returns true if this mirror is equal to [other].
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind 
+   * and
+   * (2) the isolate being reflected by this mirror is the same
+   * isolate being reflected by [other].
+   */
+  bool operator == (other);
 }
 
 /**
@@ -275,8 +285,10 @@
    * class of *o* (otherwise).
    * If the invocation returns a result *r*, this method returns
    * the result of calling [reflect](*r*).
+   * If the invocation causes a compilation error
+   * this method throws a [MirroredCompilationError].
    * If the invocation throws an exception *e* (that it does not catch)
-   * the the result is a [MirrorError] wrapping *e*.
+   * this method throws *e*.
    */
   /*
    * TODO(turnidge): Handle ambiguous names.
@@ -300,8 +312,10 @@
    * class of *o* (otherwise).
    * If the invocation returns a result *r*, this method returns
    * the result of calling [reflect](*r*).
+   * If the invocation causes a compilation error
+   * this method throws a [MirroredCompilationError].
    * If the invocation throws an exception *e* (that it does not catch)
-   * the the result is a [MirrorError] wrapping *e*.
+   * this method throws *e*.
    */
   /* TODO(turnidge): Handle ambiguous names.*/
   InstanceMirror getField(Symbol fieldName);
@@ -321,8 +335,10 @@
    * class of *o* (otherwise).
    * If the invocation returns a result *r*, this method returns
    * the result of calling [reflect]([value]).
+   * If the invocation causes a compilation error
+   * this method throws a [MirroredCompilationError].
    * If the invocation throws an exception *e* (that it does not catch)
-   * the the result is a [MirrorError] wrapping *e*.
+   * this method throws *e*.
    */
   /* TODO(turnidge): Handle ambiguous names.*/
   InstanceMirror setField(Symbol fieldName, Object value);
@@ -454,6 +470,20 @@
   get reflectee;
 
   /**
+   * Returns true if this mirror is equal to [other].
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind
+   * and
+   * (2) either 
+   * (a) [hasReflectee] is true and so is
+   * [:identical(reflectee, other.reflectee):] 
+   * or
+   * (b) the remote objects reflected by this mirror and
+   * by [other] are identical.
+   */
+  bool operator == (other);
+
+  /**
    * Perform [invocation] on [reflectee].
    * Equivalent to
    *
@@ -494,8 +524,10 @@
    *  *f(a1, ..., an, k1: v1, ..., km: vm)*
    * If the invocation returns a result *r*, this method returns
    * the result of calling [reflect](*r*).
+   * If the invocation causes a compilation error
+   * this method throws a [MirrorError].
    * If the invocation throws an exception *e* (that it does not catch)
-   * the the result is a [MirrorError] wrapping *e*.
+   * this method throws *e*.
    */
   InstanceMirror apply(List positionalArguments,
                        [Map<Symbol, dynamic> namedArguments]);
@@ -598,6 +630,19 @@
    * declarations in this library.
    */
   Map<Symbol, VariableMirror> get variables;
+
+  /**
+   * Returns true if this mirror is equal to [other].
+   *
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind
+   * and
+   * (2)  The library being reflected by this mirror
+   * and the library being reflected by [other]
+   * are
+   * the same library in the same isolate.
+   */
+   bool operator == (other);
 }
 
 /**
@@ -726,9 +771,11 @@
    * In either case:
    * If the expression evaluates to a result *r*, this method returns
    * the result of calling [reflect](*r*).
-   * If evaluating the expression throws an exception *e* (that it does not
-   * catch)
-   * the the result is a [MirrorError] wrapping *e*.
+   * If evaluating the expression causes a compilation error
+   * this method throws a [MirroredCompilationError].
+   * If evaluating the expression throws an exception *e* 
+   * (that it does not catch)
+   * this method throws *e*.
    */
   InstanceMirror newInstance(Symbol constructorName,
                              List positionalArguments,
@@ -788,6 +835,16 @@
    * class/interface changes.
    */
   ClassMirror get defaultFactory;
+
+  /**
+   * Returns true if this mirror is equal to [other].
+   *
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind
+   * and
+   * (2) This mirror and [other] reflect the same class.
+   */
+   bool operator == (other);
 }
 
 /**
@@ -822,6 +879,17 @@
    * A mirror on the type that is the upper bound of this type variable.
    */
   TypeMirror get upperBound;
+
+  /**
+   * Returns true if this mirror is equal to [other].
+   *
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind
+   * and
+   * (2)  [:simpleName == other.simpleName:] and
+   * [:owner == other.owner:].
+   */
+   bool operator == (other);
 }
 
 /**
@@ -923,6 +991,17 @@
    * Is the reflectee a factory constructor?
    */
   bool get isFactoryConstructor;
+
+  /**
+   * Returns true if this mirror is equal to [other].
+   *
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind
+   * and
+   * (2) [:simpleName == other.simpleName:] and
+   * [:owner == other.owner:].
+   */
+   bool operator == (other);
 }
 
 /**
@@ -946,6 +1025,17 @@
    * Is the reflectee a final variable?
    */
   bool get isFinal;
+
+  /**
+   * Returns true if this mirror is equal to [other].
+   *
+   * The equality holds if and only if 
+   * (1) [other] is a mirror of the same kind
+   * and
+   * (2)  [:simpleName == other.simpleName:] and
+   * [:owner == other.owner:].
+   */
+   bool operator == (other);
 }
 
 /**
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 4924b6d..7b828a5 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -97,7 +97,6 @@
 Language/03_Overview/1_Scoping_A02_t05: Fail # Inherited from dart2js
 Language/03_Overview/1_Scoping_A02_t06: Fail # inherited from dart2js
 Language/03_Overview/1_Scoping_A02_t07: Fail # inherited from dart2js
-Language/03_Overview/2_Privacy_A01_t06: Fail # New import syntax
 Language/05_Variables/05_Variables_A01_t04: Fail # http://dartbug.com/5519
 Language/05_Variables/05_Variables_A01_t05: Fail # http://dartbug.com/5519
 Language/05_Variables/05_Variables_A01_t08: Fail # http://dartbug.com/5519
@@ -269,12 +268,6 @@
 Language/11_Expressions/30_Identifier_Reference_A05_t01: Fail # Inherited from dart2js
 Language/11_Expressions/30_Identifier_Reference_A05_t12: Fail # Inherited from dart2js
 Language/11_Expressions/30_Identifier_Reference_A08_t02: Fail # Inhertited from VM.
-Language/11_Expressions/31_Type_Test_A04_t01: Fail # Inherited from dart2js
-Language/11_Expressions/32_Type_Cast_A03_t01: Fail # Inherited from dart2js
-Language/11_Expressions/32_Type_Cast_A03_t02: Fail # Inherited from dart2js
-Language/11_Expressions/32_Type_Cast_A05_t01: Fail # Inherited from dart2js
-Language/11_Expressions/32_Type_Cast_A05_t02: Fail # Inherited from dart2js
-Language/11_Expressions/32_Type_Cast_A05_t04: Fail # Inherited from dart2js
 Language/12_Statements/03_Variable_Declaration_A04_t01: Fail # http://dartbug.com/5519
 Language/12_Statements/03_Variable_Declaration_A04_t02: Fail # Inherited from dart2js
 Language/12_Statements/03_Variable_Declaration_A04_t03: Fail # Inherited from dart2js
@@ -307,7 +300,6 @@
 Language/13_Libraries_and_Scripts/5_URIs_A01_t21: Fail # Inherited from dart2js
 Language/13_Libraries_and_Scripts/5_URIs_A01_t24: Fail # Inherited from dart2js
 Language/13_Libraries_and_Scripts/5_URIs_A01_t25: Fail # Inherited from dart2js
-Language/14_Types/2_Dynamic_Type_System_A02_t01: Fail # inherited from VM
 Language/14_Types/3_Type_Declarations/1_Typedef_A06_t01: Fail # http://dartbug.com/5519
 Language/14_Types/3_Type_Declarations/1_Typedef_A06_t02: Fail # http://dartbug.com/5519
 Language/14_Types/3_Type_Declarations/1_Typedef_A06_t03: Fail # http://dartbug.com/5519
@@ -373,6 +365,25 @@
 LibTest/core/String/indexOf_A01_t02: Fail # Issue 427
 LibTest/core/String/lastIndexOf_A01_t02: Fail # Issue 427
 
+Language/11_Expressions/31_Type_Test_A05_t01: Fail # co19 issue 463
+Language/11_Expressions/31_Type_Test_A05_t02: Fail # co19 issue 463
+Language/11_Expressions/31_Type_Test_A05_t03: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A04_t01: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A04_t02: Fail # co19 issue 463
+
+Language/11_Expressions/11_Instance_Creation/1_New_A05_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/1_New_A05_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/1_New_A05_t03: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/2_Const_A07_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/2_Const_A07_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/2_Const_A07_t03: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A03_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A03_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t03: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t04: Fail # co19 issue 466
+
 [ $compiler == dart2dart && $minified ]
 Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 396
 Language/11_Expressions/17_Getter_Invocation_A02_t01: Fail, OK # co19 issue 396
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index ff61442..e7c7f0d 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -56,13 +56,9 @@
 Language/11_Expressions/30_Identifier_Reference_A04_t09: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/30_Identifier_Reference_A05_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/30_Identifier_Reference_A05_t12: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/31_Type_Test_A04_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/32_Type_Cast_A02_t03: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/32_Type_Cast_A03_t01: Fail # TODO(ahe): Please triage this failure.
 Language/11_Expressions/32_Type_Cast_A03_t02: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/32_Type_Cast_A05_t01: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/32_Type_Cast_A05_t02: Fail # TODO(ahe): Please triage this failure.
-Language/11_Expressions/32_Type_Cast_A05_t04: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/02_Expression_Statements_A01_t08: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/03_Variable_Declaration_A04_t02: Fail # TODO(ahe): Please triage this failure.
 Language/12_Statements/03_Variable_Declaration_A04_t03: Fail # TODO(ahe): Please triage this failure.
@@ -255,7 +251,6 @@
 LibTest/core/AssertionError/failedAssertion_A01_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/AssertionError/line_A01_t02: Fail # co19 issue 479
 LibTest/core/AssertionError/url_A01_t01: Fail # TODO(ahe): Please triage this failure.
-LibTest/core/Match/str_A01_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/Set/intersection_A03_t01: Fail # co19 issue 480
 LibTest/core/TypeError/column_A01_t01: Fail # TODO(ahe): Please triage this failure.
 LibTest/core/TypeError/dstName_A01_t01: Fail # TODO(ahe): Please triage this failure.
@@ -271,12 +266,6 @@
 Language/11_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: Fail, OK # co19 issue 405
 Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t03: Fail, OK # co19 issue 405
 Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t02: Fail, OK # co19 issue 405
-Language/11_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t06: Fail, OK # co19 issue 405
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t02: Fail, OK # co19 issue 405
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t01: Fail, OK # co19 issue 405
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t03: Fail, OK # co19 issue 405
-Language/11_Expressions/15_Method_Invocation/4_Super_Invocation_A04_t04: Fail, OK # co19 issue 405
-Language/11_Expressions/17_Getter_Invocation_A02_t02: Fail, OK # co19 issue 405
 Language/11_Expressions/18_Assignment_A05_t04: Fail, OK # co19 issue 405
 Language/11_Expressions/18_Assignment_A08_t04: Fail, OK # co19 issue 405
 
@@ -546,6 +535,38 @@
 LibTest/core/FallThroughError/toString_A01_t01: Fail # FallThroughError is no longer const. Issue 459
 LibTest/core/FallThroughError/FallThroughError_A01_t01: Fail # FallThroughError is no longer const. Issue 459
 
+Language/09_Generics/09_Generics_A05_t01: Fail # co19 issue 463
+Language/11_Expressions/31_Type_Test_A04_t01: Fail # co19 issue 463
+Language/11_Expressions/31_Type_Test_A05_t01: Fail # co19 issue 463
+Language/11_Expressions/31_Type_Test_A05_t02: Fail # co19 issue 463
+Language/11_Expressions/31_Type_Test_A05_t03: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A03_t01: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A03_t02: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A04_t01: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A04_t02: Fail # co19 issue 463
+
+Language/11_Expressions/11_Instance_Creation/1_New_A05_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/1_New_A05_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/1_New_A05_t03: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/2_Const_A07_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/2_Const_A07_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation/2_Const_A07_t03: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A03_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A03_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t01: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t02: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t03: Fail # co19 issue 466
+Language/11_Expressions/11_Instance_Creation_A04_t04: Fail # co19 issue 466
+
+[ $compiler == dart2js && $checked ]
+
+Language/03_Overview/1_Scoping_A02_t30: Fail # co19 issue 463
+Language/09_Generics/09_Generics_A05_t02: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A05_t01: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A05_t02: Fail # co19 issue 463
+Language/11_Expressions/32_Type_Cast_A05_t04: Fail # co19 issue 463
+Language/14_Types/8_Parameterized_Types_A02_t01: Fail # co19 issue 463
+
 [ $compiler == dart2js && $unchecked ]
 LibTest/core/List/setRange_A05_t01: Fail # setRange throws StateError if there aren't enough elements in the iterable. Issue 402
 
@@ -555,15 +576,7 @@
 LibTest/core/Set/intersection_A01_t01: Fail # issue 390
 LibTest/core/Set/intersection_A01_t02: Fail # issue 390
 LibTest/core/Set/intersection_A01_t03: Fail # issue 390
-LibTest/core/List/List.from_A01_t01: fail # Issue 400
 LibTest/core/List/every_A01_t01: fail # Issue 400
-LibTest/collection/Queue/Queue.from_A01_t01: Fail # Issue 400
-LibTest/collection/Queue/Queue.from_A01_t02: Fail # Issue 400
-
-LibTest/async/Completer/completeError_A03_t02: Fail # No AsyncError anymore. Issue 407
-LibTest/async/Completer/complete_A02_t02: Fail # No AsyncError anymore. Issue 407
-LibTest/async/Future/catchError_A01_t01: Fail # No AsyncError anymore. Issue 407
-LibTest/async/Future/catchError_A01_t02: Fail # No AsyncError anymore. Issue 407
 
 
 # Issues with co19 test suite in browsers.
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 34e52c7..6ab9867 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -53,7 +53,7 @@
     (String code, List errors, List warnings) {
       Expect.isNull(code);
       Expect.equals(1, errors.length);
-      Expect.equals('Could not find main', errors[0].toString());
+      Expect.equals('Error: Could not find "main".', errors[0].toString());
       Expect.isTrue(warnings.isEmpty);
     });
 
@@ -72,7 +72,8 @@
     (String code, List errors, List warnings) {
       Expect.isNull(code);
       Expect.equals(1, errors.length);
-      Expect.isTrue(errors[0].toString().startsWith('Could not find main'));
+      Expect.isTrue(
+          errors[0].toString().startsWith('Error: Could not find "main".'));
       Expect.isTrue(warnings.isEmpty);
     });
 
@@ -91,7 +92,8 @@
     (String code, List errors, List warnings) {
       Expect.isNull(code);
       Expect.equals(1, errors.length);
-      Expect.isTrue(errors[0].toString().startsWith('Could not find main'));
+      Expect.isTrue(
+          errors[0].toString().startsWith('Error: Could not find "main".'));
       Expect.isTrue(warnings.isEmpty);
     });
 
@@ -104,7 +106,8 @@
       Expect.isNull(code);
       Expect.isTrue(errors.isEmpty);
       Expect.equals(1, warnings.length);
-      Expect.equals('Warning: cannot resolve type Foo', warnings[0].toString());
+      Expect.equals(
+          'Warning: Cannot resolve type "Foo".', warnings[0].toString());
     });
 
   runCompiler(
@@ -124,7 +127,8 @@
     (String code, List errors, List warnings) {
       Expect.isNull(code);
       Expect.isTrue(errors.isEmpty);
-      Expect.equals('Warning: cannot resolve type Foo', warnings[0].toString());
+      Expect.equals(
+          'Warning: Cannot resolve type "Foo".', warnings[0].toString());
     });
 
   runCompiler(
@@ -135,7 +139,8 @@
       Expect.isNull(code);
       Expect.isTrue(errors.isEmpty);
       Expect.equals(1, warnings.length);
-      Expect.equals('Warning: cannot resolve type Foo', warnings[0].toString());
+      Expect.equals(
+          'Warning: Cannot resolve type "Foo".', warnings[0].toString());
     });
 
   runCompiler(
diff --git a/tests/compiler/dart2js/compiler_test.dart b/tests/compiler/dart2js/compiler_test.dart
index e9ba024..83902ad 100644
--- a/tests/compiler/dart2js/compiler_test.dart
+++ b/tests/compiler/dart2js/compiler_test.dart
@@ -25,9 +25,11 @@
     super.reportWarning(node, message);
   }
 
-  void reportError(Node node, var message) {
-    if (onError != null) onError(this, node, message);
-    super.reportError(node, message);
+  void reportError(Spannable node,
+                   MessageKind errorCode,
+                   [Map arguments = const {}]) {
+    if (onError != null) onError(this, node, errorCode.error(arguments));
+    super.reportError(node, errorCode, arguments);
   }
 }
 
@@ -38,7 +40,8 @@
   ResolverVisitor visitor = compiler.resolverVisitor();
   compiler.parseScript('NoSuchPrefix.NoSuchType foo() {}');
   FunctionElement foo = compiler.mainApp.find(buildSourceString('foo'));
-  compiler.setOnWarning((c, n, m) => Expect.equals(foo, compiler.currentElement));
+  compiler.setOnWarning(
+      (c, n, m) => Expect.equals(foo, compiler.currentElement));
   foo.computeType(compiler);
   Expect.equals(1, compiler.warnings.length);
 }
diff --git a/tests/compiler/dart2js/deprecated_features_test.dart b/tests/compiler/dart2js/deprecated_features_test.dart
index f43b6ad..ab679c3 100644
--- a/tests/compiler/dart2js/deprecated_features_test.dart
+++ b/tests/compiler/dart2js/deprecated_features_test.dart
@@ -64,7 +64,7 @@
 
 deprecatedMessage(feature) {
   return
-    "warning: Warning: deprecated language feature, $feature"
+    "warning: Warning: Deprecated language feature, $feature"
     ", will be removed in a future Dart milestone.";
 }
 
diff --git a/tests/compiler/dart2js/diagnose_ambiguous_test.dart b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
index 39f9d8f..70d2fb4 100644
--- a/tests/compiler/dart2js/diagnose_ambiguous_test.dart
+++ b/tests/compiler/dart2js/diagnose_ambiguous_test.dart
@@ -48,9 +48,9 @@
       'memory:main.dart:23:46:Info: "class(Fisk)" is imported here.:info',
       'memory:main.dart:23:46:Info: "function(fisk)" is imported here.:info',
       'memory:main.dart:23:46:Info: "function(hest)" is imported here.:info',
-      'memory:main.dart:59:63:Warning: duplicate import of Fisk:warning',
-      'memory:main.dart:76:80:duplicate import of fisk:error',
-      'memory:main.dart:86:90:duplicate import of hest:error'
+      'memory:main.dart:59:63:Warning: Duplicate import of "Fisk".:warning',
+      'memory:main.dart:76:80:Error: Duplicate import of "fisk".:error',
+      'memory:main.dart:86:90:Error: Duplicate import of "hest".:error'
   ];
   Expect.listEquals(expected, diagnostics);
   Expect.isTrue(compiler.compilationFailed);
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 750dc2e..950a7e5 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -30,7 +30,7 @@
 
 
 class WarningMessage {
-  Node node;
+  Spannable node;
   Message message;
   WarningMessage(this.node, this.message);
 
@@ -281,6 +281,7 @@
     Uri uri = new Uri(scheme: "dart", path: name);
     var script = new Script(uri, new MockFile(source));
     var library = new LibraryElementX(script);
+    library.libraryTag = new LibraryName(null, null, null);
     parseScript(source, library);
     library.setExports(library.localScope.values.toList());
     registerSource(uri, source);
@@ -295,15 +296,18 @@
         'Warning: $message', api.Diagnostic.WARNING);
   }
 
-  void reportError(Node node, var message) {
-    if (message is String && message.startsWith("no library name found in")) {
-      // TODO(ahe): Fix the MockCompiler to not have this problem.
-      return;
-    }
-    if (message is! Message) message = message.message;
+  void reportError(Spannable node,
+                   MessageKind errorCode,
+                   [Map arguments = const {}]) {
+    Message message = errorCode.message(arguments);
     errors.add(new WarningMessage(node, message));
-    reportDiagnostic(spanFromNode(node),
-        'Error: $message', api.Diagnostic.ERROR);
+    reportDiagnostic(spanFromSpannable(node), '$message', api.Diagnostic.ERROR);
+  }
+
+  void reportFatalError(Spannable node,
+                        MessageKind errorCode,
+                        [Map arguments = const {}]) {
+    reportError(node, errorCode, arguments);
   }
 
   void reportMessage(SourceSpan span, var message, api.Diagnostic kind) {
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 6bdb104..62c106d 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -1,72 +1,72 @@
-// 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 the compiler can handle imports when package root has not been set.

-

-library dart2js.test.package_root;

-

-import 'package:expect/expect.dart';

-import 'memory_source_file_helper.dart';

-

-import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'

-       show NullSink;

-

-import '../../../sdk/lib/_internal/compiler/compiler.dart'

-       show DiagnosticHandler, Diagnostic;

-

-import 'dart:async';

-

-import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';

-import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart';

-

-const MEMORY_SOURCE_FILES = const {

-  'main.dart': '''

-

-import 'package:foo/foo.dart';

-

-main() {}

-''',

-};

-

-void runCompiler(Uri main) {

-  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));

-  Uri libraryRoot = script.resolve('../../../sdk/');

-

-  MemorySourceFileProvider.MEMORY_SOURCE_FILES = MEMORY_SOURCE_FILES;

-  var provider = new MemorySourceFileProvider();

-  var handler = new FormattingDiagnosticHandler(provider);

-  var errors = [];

-  

-  void diagnosticHandler(Uri uri, int begin, int end, String message,

-                         Diagnostic kind) {

-    if (kind == Diagnostic.ERROR) {

-      errors.add(message);

-    }

-    handler(uri, begin, end, message, kind);

-  }

-  

-  

-  EventSink<String> outputProvider(String name, String extension) {

-    if (name != '') throw 'Attempt to output file "$name.$extension"';

-    return new NullSink('$name.$extension');

-  }

-

-  Compiler compiler = new Compiler(provider.readStringFromUri,

-                                   outputProvider,

-                                   diagnosticHandler,

-                                   libraryRoot,

-                                   null,

-                                   []);

-  

-  compiler.run(main);

-  Expect.equals(1, errors.length);

-  Expect.equals("Error: Cannot resolve 'package:foo/foo.dart'. "

-                "Package root has not been set.", 

-                errors[0]);

-}

-

-void main() {

-  runCompiler(Uri.parse('memory:main.dart'));

-  runCompiler(Uri.parse('package:foo/foo.dart'));

-}

+// 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 the compiler can handle imports when package root has not been set.
+
+library dart2js.test.package_root;
+
+import 'package:expect/expect.dart';
+import 'memory_source_file_helper.dart';
+
+import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'
+       show NullSink;
+
+import '../../../sdk/lib/_internal/compiler/compiler.dart'
+       show DiagnosticHandler, Diagnostic;
+
+import 'dart:async';
+
+import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors.dart';
+import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart';
+
+const MEMORY_SOURCE_FILES = const {
+  'main.dart': '''
+
+import 'package:foo/foo.dart';
+
+main() {}
+''',
+};
+
+void runCompiler(Uri main) {
+  Uri script = currentDirectory.resolve(nativeToUriPath(Platform.script));
+  Uri libraryRoot = script.resolve('../../../sdk/');
+
+  MemorySourceFileProvider.MEMORY_SOURCE_FILES = MEMORY_SOURCE_FILES;
+  var provider = new MemorySourceFileProvider();
+  var handler = new FormattingDiagnosticHandler(provider);
+  var errors = [];
+
+  void diagnosticHandler(Uri uri, int begin, int end, String message,
+                         Diagnostic kind) {
+    if (kind == Diagnostic.ERROR) {
+      errors.add(message);
+    }
+    handler(uri, begin, end, message, kind);
+  }
+
+
+  EventSink<String> outputProvider(String name, String extension) {
+    if (name != '') throw 'Attempt to output file "$name.$extension"';
+    return new NullSink('$name.$extension');
+  }
+
+  Compiler compiler = new Compiler(provider.readStringFromUri,
+                                   outputProvider,
+                                   diagnosticHandler,
+                                   libraryRoot,
+                                   null,
+                                   []);
+
+  compiler.run(main);
+  Expect.equals(1, errors.length);
+  Expect.equals('Error: Cannot resolve "package:foo/foo.dart". '
+                'Package root has not been set.',
+                errors[0]);
+}
+
+void main() {
+  runCompiler(Uri.parse('memory:main.dart'));
+  runCompiler(Uri.parse('package:foo/foo.dart'));
+}
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index cb7ccab..7463d7e 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -386,8 +386,8 @@
   Expect.isTrue(
       compiler.errors[0].message.kind ==
           MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
-  Expect.equals('External method without an implementation.',
-                compiler.errors[0].message.toString());
+  Expect.stringEquals('Error: External method without an implementation.',
+                      compiler.errors[0].message.toString());
 }
 
 testExternalWithoutImplementationMember() {
@@ -417,8 +417,8 @@
   Expect.isTrue(
       compiler.errors[0].message.kind ==
           MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
-  Expect.equals('External method without an implementation.',
-                compiler.errors[0].message.toString());
+  Expect.stringEquals('Error: External method without an implementation.',
+                      compiler.errors[0].message.toString());
 }
 
 testIsSubclass() {
@@ -721,7 +721,9 @@
 void testAnalyzeAllInjectedMembers() {
   void expect(String patchText, [expectedWarnings]) {
     if (expectedWarnings == null) expectedWarnings = [];
-    if (expectedWarnings is! List) expectedWarnings = [expectedWarnings];
+    if (expectedWarnings is! List) {
+      expectedWarnings = <MessageKind>[expectedWarnings];
+    }
 
     var compiler = applyPatch('', patchText,
                               analyzeAll: true, analyzeOnly: true);
@@ -730,14 +732,14 @@
     compareWarningKinds(patchText, expectedWarnings, compiler.warnings);
   }
 
-  expect('String s = 0;', MessageKind.NOT_ASSIGNABLE);
-  expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE);
+  expect('String s = 0;', MessageKind.NOT_ASSIGNABLE.warning);
+  expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE.warning);
   expect('''
          class Class {
            String s = 0;
          }
          ''',
-         MessageKind.NOT_ASSIGNABLE);
+         MessageKind.NOT_ASSIGNABLE.warning);
   expect('''
          class Class {
            void method() {
@@ -745,7 +747,7 @@
            }
          }
          ''',
-         MessageKind.NOT_ASSIGNABLE);
+         MessageKind.NOT_ASSIGNABLE.warning);
 }
 
 void testTypecheckPatchedMembers() {
@@ -760,7 +762,7 @@
   compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')];
   compiler.runCompiler(null);
   compareWarningKinds(patchText,
-      [MessageKind.NOT_ASSIGNABLE], compiler.warnings);
+      [MessageKind.NOT_ASSIGNABLE.warning], compiler.warnings);
 }
 
 main() {
diff --git a/tests/compiler/dart2js/private_test.dart b/tests/compiler/dart2js/private_test.dart
index 3390c9f..c8918a7 100644
--- a/tests/compiler/dart2js/private_test.dart
+++ b/tests/compiler/dart2js/private_test.dart
@@ -74,21 +74,22 @@
 
 void main() {
   // Read from private variable.
-  analyze('var value = _privateVariable;', MessageKind.CANNOT_RESOLVE);
+  analyze('var value = _privateVariable;', MessageKind.CANNOT_RESOLVE.warning);
   // Write to private variable.
-  analyze('_privateVariable = 0;', MessageKind.CANNOT_RESOLVE);
+  analyze('_privateVariable = 0;', MessageKind.CANNOT_RESOLVE.warning);
   // Access private function.
-  analyze('var value = _privateFunction;', MessageKind.CANNOT_RESOLVE);
+  analyze('var value = _privateFunction;', MessageKind.CANNOT_RESOLVE.warning);
   // Call private function.
-  analyze('_privateFunction();', MessageKind.CANNOT_RESOLVE);
+  analyze('_privateFunction();', MessageKind.CANNOT_RESOLVE.warning);
 
   // Call unnamed (public) constructor on private class.
-  analyze('new _PrivateClass();', MessageKind.CANNOT_RESOLVE);
+  analyze('new _PrivateClass();', MessageKind.CANNOT_RESOLVE.warning);
   // Call public constructor on private class.
-  analyze('new _PrivateClass.publicConstructor();', MessageKind.CANNOT_RESOLVE);
+  analyze('new _PrivateClass.publicConstructor();',
+          MessageKind.CANNOT_RESOLVE.warning);
   // Call private constructor on private class.
   analyze('new _PrivateClass._privateConstructor();',
-      MessageKind.CANNOT_RESOLVE);
+      MessageKind.CANNOT_RESOLVE.warning);
   // Call public getter of private type.
   analyze('var value = publicClass.private;');
   // Read from private field on private class.
@@ -129,7 +130,7 @@
   analyze('publicClass = new PublicClass.publicConstructor();');
   // Call private constructor on public class.
   analyze('publicClass = new PublicClass._privateConstructor();',
-      MessageKind.CANNOT_FIND_CONSTRUCTOR);
+      MessageKind.CANNOT_FIND_CONSTRUCTOR.warning);
   // Read from private field on public class.
   analyze('var value = publicClass._privateField;',
       MessageKind.PRIVATE_ACCESS);
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index c8fc25c..5398829 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -145,17 +145,17 @@
   compiler.parseScript('class Foo<T, U> {}');
   compiler.resolveStatement('Foo<notype, int> x;');
   Expect.equals(1, compiler.warnings.length);
-  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
+  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE.warning,
                 compiler.warnings[0].message.kind);
   Expect.equals(0, compiler.errors.length);
 
   compiler = new MockCompiler();
   compiler.parseScript('class Foo<T, U> {}');
   compiler.resolveStatement('var x = new Foo<notype, int>();');
-  Expect.equals(0, compiler.warnings.length);
-  Expect.equals(1, compiler.errors.length);
-  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE,
-                compiler.errors[0].message.kind);
+  Expect.equals(1, compiler.warnings.length);
+  Expect.equals(0, compiler.errors.length);
+  Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE.warning,
+                compiler.warnings[0].message.kind);
 
   compiler = new MockCompiler();
   compiler.parseScript('class Foo<T> {'
@@ -434,7 +434,8 @@
   Node warningNode = compiler.warnings[0].node;
 
   Expect.equals(
-      new Message(MessageKind.CANNOT_RESOLVE_TYPE,  {'typeName': 'Foo'}),
+      new Message(
+          MessageKind.CANNOT_RESOLVE_TYPE.warning,  {'typeName': 'Foo'}),
       compiler.warnings[0].message);
   VariableDefinitions definition = compiler.parsedTree;
   Expect.equals(warningNode, definition.type);
@@ -460,7 +461,7 @@
   // ClassResolverVisitor, and once from ClassSupertypeResolver. We
   // should only the get the error once.
   Expect.equals(2, compiler.errors.length);
-  var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE,
+  var cannotResolveBar = new Message(MessageKind.CANNOT_RESOLVE_TYPE.error,
                                      {'typeName': 'Bar'});
   Expect.equals(cannotResolveBar, compiler.errors[0].message);
   Expect.equals(cannotResolveBar, compiler.errors[1].message);
@@ -486,7 +487,7 @@
   compiler.resolveStatement("Foo bar;");
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
-      new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'var'}),
+      new Message(MessageKind.CANNOT_RESOLVE_TYPE.warning, {'typeName': 'var'}),
       compiler.errors[0].message);
   compiler.clearErrors();
 }
@@ -497,7 +498,7 @@
   compiler.resolveStatement("Foo bar;");
   Expect.equals(1, compiler.errors.length);
   Expect.equals(
-      new Message(MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': 'bar'}),
+      new Message(MessageKind.CANNOT_RESOLVE_TYPE.warning, {'typeName': 'bar'}),
       compiler.errors[0].message);
   compiler.clearErrors();
 
@@ -639,7 +640,7 @@
   Expect.equals(2, compiler.errors.length);
   Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY,
                 compiler.errors[0].message.kind);
-  Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR,
+  Expect.equals(MessageKind.CANNOT_FIND_CONSTRUCTOR.error,
                 compiler.errors[1].message.kind);
 
   compiler = new MockCompiler();
@@ -730,7 +731,7 @@
               }""";
   resolveConstructor(script, "A a = new A();", "A", "", 0,
                      expectedWarnings: [],
-                     expectedErrors: [MessageKind.CANNOT_RESOLVE]);
+                     expectedErrors: [MessageKind.CANNOT_RESOLVE.error]);
 
   script = """class A {
                 int foo;
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 8b311ce..f0f61fd 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -19,6 +19,9 @@
 
 import '../../../sdk/lib/_internal/compiler/implementation/dart_types.dart';
 
+final MessageKind NOT_ASSIGNABLE = MessageKind.NOT_ASSIGNABLE.warning;
+final MessageKind MEMBER_NOT_FOUND = MessageKind.MEMBER_NOT_FOUND.warning;
+
 DartType voidType;
 DartType intType;
 DartType boolType;
@@ -66,10 +69,11 @@
 
 testReturn() {
   analyzeTopLevel("void foo() { return 3; }", MessageKind.RETURN_VALUE_IN_VOID);
-  analyzeTopLevel("int bar() { return 'hest'; }", MessageKind.NOT_ASSIGNABLE);
+  analyzeTopLevel("int bar() { return 'hest'; }",
+                  NOT_ASSIGNABLE);
   analyzeTopLevel("void baz() { var x; return x; }");
   analyzeTopLevel(returnWithType("int", "'string'"),
-                  MessageKind.NOT_ASSIGNABLE);
+                  NOT_ASSIGNABLE);
   analyzeTopLevel(returnWithType("", "'string'"));
   analyzeTopLevel(returnWithType("Object", "'string'"));
   analyzeTopLevel(returnWithType("String", "'string'"));
@@ -85,35 +89,35 @@
 testFor() {
   analyze("for (var x;true;x = x + 1) {}");
   analyze("for (var x;null;x = x + 1) {}");
-  analyze("for (var x;0;x = x + 1) {}", MessageKind.NOT_ASSIGNABLE);
-  analyze("for (var x;'';x = x + 1) {}", MessageKind.NOT_ASSIGNABLE);
+  analyze("for (var x;0;x = x + 1) {}", NOT_ASSIGNABLE);
+  analyze("for (var x;'';x = x + 1) {}", NOT_ASSIGNABLE);
 
    analyze("for (;true;) {}");
    analyze("for (;null;) {}");
-   analyze("for (;0;) {}", MessageKind.NOT_ASSIGNABLE);
-   analyze("for (;'';) {}", MessageKind.NOT_ASSIGNABLE);
+   analyze("for (;0;) {}", NOT_ASSIGNABLE);
+   analyze("for (;'';) {}", NOT_ASSIGNABLE);
 
   // Foreach tests
 //  TODO(karlklose): for each is not yet implemented.
 //  analyze("{ List<String> strings = ['1','2','3']; " +
 //          "for (String s in strings) {} }");
 //  analyze("{ List<int> ints = [1,2,3]; for (String s in ints) {} }",
-//          MessageKind.NOT_ASSIGNABLE);
+//          NOT_ASSIGNABLE);
 //  analyze("for (String s in true) {}", MessageKind.METHOD_NOT_FOUND);
 }
 
 testWhile() {
   analyze("while (true) {}");
   analyze("while (null) {}");
-  analyze("while (0) {}", MessageKind.NOT_ASSIGNABLE);
-  analyze("while ('') {}", MessageKind.NOT_ASSIGNABLE);
+  analyze("while (0) {}", NOT_ASSIGNABLE);
+  analyze("while ('') {}", NOT_ASSIGNABLE);
 
   analyze("do {} while (true);");
   analyze("do {} while (null);");
-  analyze("do {} while (0);", MessageKind.NOT_ASSIGNABLE);
-  analyze("do {} while ('');", MessageKind.NOT_ASSIGNABLE);
-  analyze("do { int i = 0.5; } while (true);", MessageKind.NOT_ASSIGNABLE);
-  analyze("do { int i = 0.5; } while (null);", MessageKind.NOT_ASSIGNABLE);
+  analyze("do {} while (0);", NOT_ASSIGNABLE);
+  analyze("do {} while ('');", NOT_ASSIGNABLE);
+  analyze("do { int i = 0.5; } while (true);", NOT_ASSIGNABLE);
+  analyze("do { int i = 0.5; } while (null);", NOT_ASSIGNABLE);
 }
 
 testTry() {
@@ -121,25 +125,25 @@
   analyze("try {} catch (e) { int i = e;} finally {}");
   analyze("try {} catch (e, s) { int i = e; StackTrace j = s; } finally {}");
   analyze("try {} on String catch (e) {} finally {}");
-  analyze("try { int i = ''; } finally {}", MessageKind.NOT_ASSIGNABLE);
-  analyze("try {} finally { int i = ''; }", MessageKind.NOT_ASSIGNABLE);
+  analyze("try { int i = ''; } finally {}", NOT_ASSIGNABLE);
+  analyze("try {} finally { int i = ''; }", NOT_ASSIGNABLE);
   analyze("try {} on String catch (e) { int i = e; } finally {}",
-      MessageKind.NOT_ASSIGNABLE);
+      NOT_ASSIGNABLE);
   analyze("try {} catch (e, s) { int i = e; int j = s; } finally {}",
-      MessageKind.NOT_ASSIGNABLE);
+      NOT_ASSIGNABLE);
   analyze("try {} on String catch (e, s) { int i = e; int j = s; } finally {}",
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 }
 
 
 testSwitch() {
   analyze("switch (0) { case 1: break; case 2: break; }");
   analyze("switch (0) { case 1: int i = ''; break; case 2: break; }",
-      MessageKind.NOT_ASSIGNABLE);
+      NOT_ASSIGNABLE);
   analyze("switch (0) { case '': break; case 2: break; }",
-      MessageKind.NOT_ASSIGNABLE);
+      NOT_ASSIGNABLE);
   analyze("switch ('') { case 1: break; case 2: break; }",
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 }
 
 testOperators() {
@@ -149,18 +153,18 @@
     analyze("{ var i = 1 ${op} 2; }");
     analyze("{ var i = 1; i ${op}= 2; }");
     analyze("{ int i; var j = (i = true) ${op} 2; }",
-            [MessageKind.NOT_ASSIGNABLE, MessageKind.OPERATOR_NOT_FOUND]);
+            [NOT_ASSIGNABLE, MessageKind.OPERATOR_NOT_FOUND]);
     analyze("{ int i; var j = 1 ${op} (i = true); }",
-            [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+            [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
   }
   for (final op in ['-', '~']) {
     analyze("{ var i = ${op}1; }");
     analyze("{ int i; var j = ${op}(i = true); }",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.OPERATOR_NOT_FOUND]);
+        [NOT_ASSIGNABLE, MessageKind.OPERATOR_NOT_FOUND]);
   }
   for (final op in ['++', '--']) {
     analyze("{ int i = 1; int j = i${op}; }");
-    analyze("{ int i = 1; bool j = i${op}; }", MessageKind.NOT_ASSIGNABLE);
+    analyze("{ int i = 1; bool j = i${op}; }", NOT_ASSIGNABLE);
     analyze("{ bool b = true; bool j = b${op}; }",
         MessageKind.OPERATOR_NOT_FOUND);
     analyze("{ bool b = true; int j = ${op}b; }",
@@ -168,25 +172,25 @@
   }
   for (final op in ['||', '&&']) {
     analyze("{ bool b = (true ${op} false); }");
-    analyze("{ int b = true ${op} false; }", MessageKind.NOT_ASSIGNABLE);
-    analyze("{ bool b = (1 ${op} false); }", MessageKind.NOT_ASSIGNABLE);
-    analyze("{ bool b = (true ${op} 2); }", MessageKind.NOT_ASSIGNABLE);
+    analyze("{ int b = true ${op} false; }", NOT_ASSIGNABLE);
+    analyze("{ bool b = (1 ${op} false); }", NOT_ASSIGNABLE);
+    analyze("{ bool b = (true ${op} 2); }", NOT_ASSIGNABLE);
   }
   for (final op in ['>', '<', '<=', '>=']) {
     analyze("{ bool b = 1 ${op} 2; }");
-    analyze("{ int i = 1 ${op} 2; }", MessageKind.NOT_ASSIGNABLE);
+    analyze("{ int i = 1 ${op} 2; }", NOT_ASSIGNABLE);
     analyze("{ int i; bool b = (i = true) ${op} 2; }",
-            [MessageKind.NOT_ASSIGNABLE, MessageKind.OPERATOR_NOT_FOUND]);
+            [NOT_ASSIGNABLE, MessageKind.OPERATOR_NOT_FOUND]);
     analyze("{ int i; bool b = 1 ${op} (i = true); }",
-            [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+            [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
   }
   for (final op in ['==', '!=']) {
     analyze("{ bool b = 1 ${op} 2; }");
-    analyze("{ int i = 1 ${op} 2; }", MessageKind.NOT_ASSIGNABLE);
+    analyze("{ int i = 1 ${op} 2; }", NOT_ASSIGNABLE);
     analyze("{ int i; bool b = (i = true) ${op} 2; }",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
     analyze("{ int i; bool b = 1 ${op} (i = true); }",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   }
 }
 
@@ -221,13 +225,13 @@
   analyze("new C1('string');");
   analyze("new C2(42);");
   analyze("new C2('string');",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
   analyze("new C3(42);");
   analyze("new C3('string');",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
   analyze("new C3.named(42);");
   analyze("new C3.named('string');",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
 }
 
 void testMethodInvocationArgumentCount() {
@@ -349,20 +353,20 @@
 
   check("int k = c.intNoArgumentMethod();");
   check("ClassWithMethods x = c.intNoArgumentMethod();",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
-  check("int k = c.intOneArgumentMethod(c);", MessageKind.NOT_ASSIGNABLE);
+  check("int k = c.intOneArgumentMethod(c);", NOT_ASSIGNABLE);
   check("ClassWithMethods x = c.intOneArgumentMethod(1);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check("int k = c.intOneArgumentMethod('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check("int k = c.intOneArgumentMethod(i);");
 
   check("int k = c.intTwoArgumentMethod(1, 'string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check("int k = c.intTwoArgumentMethod(i, j);");
   check("ClassWithMethods x = c.intTwoArgumentMethod(i, j);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
   check("c.functionField();");
   check("d.functionField();");
@@ -379,25 +383,25 @@
 
 
   check("c.intOneArgumentOneOptionalMethod('');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check("c.intOneArgumentOneOptionalMethod('', '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
-  check("c.intTwoOptionalMethod('');", MessageKind.NOT_ASSIGNABLE);
+  check("c.intTwoOptionalMethod('');", NOT_ASSIGNABLE);
   check("c.intTwoOptionalMethod('', '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   check("c.intOneArgumentOneNamedMethod('');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check("c.intOneArgumentOneNamedMethod('', b: '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
-  check("c.intTwoNamedMethod(a: '');", MessageKind.NOT_ASSIGNABLE);
-  check("c.intTwoNamedMethod(b: '');", MessageKind.NOT_ASSIGNABLE);
+  check("c.intTwoNamedMethod(a: '');", NOT_ASSIGNABLE);
+  check("c.intTwoNamedMethod(b: '');", NOT_ASSIGNABLE);
   check("c.intTwoNamedMethod(a: '', b: '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
   check("c.intTwoNamedMethod(b: '', a: '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   // Invocation of dynamic variable.
   check("e();");
@@ -406,10 +410,10 @@
 
   // Invocation on local method.
   check("localMethod();", MessageKind.MISSING_ARGUMENT);
-  check("localMethod(1);", MessageKind.NOT_ASSIGNABLE);
+  check("localMethod(1);", NOT_ASSIGNABLE);
   check("localMethod('string');");
   check("int k = localMethod('string');");
-  check("String k = localMethod('string');", MessageKind.NOT_ASSIGNABLE);
+  check("String k = localMethod('string');", NOT_ASSIGNABLE);
 
   // Invocation on parenthesized expressions.
   check("(e)();");
@@ -423,21 +427,21 @@
   check("(foo){}();", MessageKind.MISSING_ARGUMENT);
   check("(foo){}(1);");
   check("(foo){}('string');");
-  check("(int foo){}('string');", MessageKind.NOT_ASSIGNABLE);
+  check("(int foo){}('string');", NOT_ASSIGNABLE);
   check("(String foo){}('string');");
   check("int k = int bar(String foo){ return 0; }('string');");
   check("int k = String bar(String foo){ return foo; }('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
   // Static invocations.
   check("ClassWithMethods.staticMethod();",
         MessageKind.MISSING_ARGUMENT);
   check("ClassWithMethods.staticMethod(1);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check("ClassWithMethods.staticMethod('string');");
   check("int k = ClassWithMethods.staticMethod('string');");
   check("String k = ClassWithMethods.staticMethod('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
   // Invocation on dynamic variable.
   check("e.foo();");
@@ -449,7 +453,7 @@
   check("foo(1);");
   check("foo('string');");
   check("foo(a: 'string');");
-  check("foo(a: localMethod(1));", MessageKind.NOT_ASSIGNABLE);
+  check("foo(a: localMethod(1));", NOT_ASSIGNABLE);
 }
 
 testMethodInvocationsInClass() {
@@ -500,20 +504,20 @@
 
   check(c, "int k = intNoArgumentMethod();");
   check(c, "ClassWithMethods x = intNoArgumentMethod();",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
-  check(c, "int k = intOneArgumentMethod('');", MessageKind.NOT_ASSIGNABLE);
+  check(c, "int k = intOneArgumentMethod('');", NOT_ASSIGNABLE);
   check(c, "ClassWithMethods x = intOneArgumentMethod(1);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(c, "int k = intOneArgumentMethod('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(c, "int k = intOneArgumentMethod(i);");
 
   check(c, "int k = intTwoArgumentMethod(1, 'string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(c, "int k = intTwoArgumentMethod(i, j);");
   check(c, "ClassWithMethods x = intTwoArgumentMethod(i, j);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
   check(c, "functionField();");
   check(d, "functionField();");
@@ -530,25 +534,25 @@
 
 
   check(c, "intOneArgumentOneOptionalMethod('');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(c, "intOneArgumentOneOptionalMethod('', '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
-  check(c, "intTwoOptionalMethod('');", MessageKind.NOT_ASSIGNABLE);
+  check(c, "intTwoOptionalMethod('');", NOT_ASSIGNABLE);
   check(c, "intTwoOptionalMethod('', '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   check(c, "intOneArgumentOneNamedMethod('');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(c, "intOneArgumentOneNamedMethod('', b: '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
-  check(c, "intTwoNamedMethod(a: '');", MessageKind.NOT_ASSIGNABLE);
-  check(c, "intTwoNamedMethod(b: '');", MessageKind.NOT_ASSIGNABLE);
+  check(c, "intTwoNamedMethod(a: '');", NOT_ASSIGNABLE);
+  check(c, "intTwoNamedMethod(b: '');", NOT_ASSIGNABLE);
   check(c, "intTwoNamedMethod(a: '', b: '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
   check(c, "intTwoNamedMethod(b: '', a: '');",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   // Invocation of dynamic variable.
   check(c, "e();");
@@ -557,46 +561,46 @@
 
   // Invocation on local method.
   check(c, "localMethod();", MessageKind.MISSING_ARGUMENT);
-  check(c, "localMethod(1);", MessageKind.NOT_ASSIGNABLE);
+  check(c, "localMethod(1);", NOT_ASSIGNABLE);
   check(c, "localMethod('string');");
   check(c, "int k = localMethod('string');");
-  check(c, "String k = localMethod('string');", MessageKind.NOT_ASSIGNABLE);
+  check(c, "String k = localMethod('string');", NOT_ASSIGNABLE);
 
   // Invocation on parenthesized expressions.
   check(c, "(e)();");
   check(c, "(e)(1);");
   check(c, "(e)('string');");
-  check(c, "(foo)();", MessageKind.MEMBER_NOT_FOUND);
-  check(c, "(foo)(1);", MessageKind.MEMBER_NOT_FOUND);
-  check(c, "(foo)('string');", MessageKind.MEMBER_NOT_FOUND);
+  check(c, "(foo)();", MEMBER_NOT_FOUND);
+  check(c, "(foo)(1);", MEMBER_NOT_FOUND);
+  check(c, "(foo)('string');", MEMBER_NOT_FOUND);
 
   // Invocations on function expressions.
   check(c, "(foo){}();", MessageKind.MISSING_ARGUMENT);
   check(c, "(foo){}(1);");
   check(c, "(foo){}('string');");
-  check(c, "(int foo){}('string');", MessageKind.NOT_ASSIGNABLE);
+  check(c, "(int foo){}('string');", NOT_ASSIGNABLE);
   check(c, "(String foo){}('string');");
   check(c, "int k = int bar(String foo){ return 0; }('string');");
   check(c, "int k = String bar(String foo){ return foo; }('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
   // Static invocations.
   check(c, "staticMethod();",
         MessageKind.MISSING_ARGUMENT);
   check(c, "staticMethod(1);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(c, "staticMethod('string');");
   check(c, "int k = staticMethod('string');");
   check(c, "String k = staticMethod('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(d, "staticMethod();",
         MessageKind.MISSING_ARGUMENT);
   check(d, "staticMethod(1);",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
   check(d, "staticMethod('string');");
   check(d, "int k = staticMethod('string');");
   check(d, "String k = staticMethod('string');",
-        MessageKind.NOT_ASSIGNABLE);
+        NOT_ASSIGNABLE);
 
   // Invocation on dynamic variable.
   check(c, "e.foo();");
@@ -609,7 +613,7 @@
   check(c, "foo('string');", MessageKind.METHOD_NOT_FOUND);
   check(c, "foo(a: 'string');", MessageKind.METHOD_NOT_FOUND);
   check(c, "foo(a: localMethod(1));",
-      [MessageKind.METHOD_NOT_FOUND, MessageKind.NOT_ASSIGNABLE]);
+      [MessageKind.METHOD_NOT_FOUND, NOT_ASSIGNABLE]);
 }
 
 /** Tests analysis of returns (not required by the specification). */
@@ -655,7 +659,7 @@
 testNewExpression() {
   compiler.parseScript("class A {}");
   analyze("A a = new A();");
-  analyze("int i = new A();", MessageKind.NOT_ASSIGNABLE);
+  analyze("int i = new A();", NOT_ASSIGNABLE);
 
 // TODO(karlklose): constructors are not yet implemented.
 //  compiler.parseScript(
@@ -673,7 +677,7 @@
 //
 //  analyze("Foo x = new Foo(0);");
 //  analyze("Foo x = new Foo();", MessageKind.MISSING_ARGUMENT);
-//  analyze("Foo x = new Foo('');", MessageKind.NOT_ASSIGNABLE);
+//  analyze("Foo x = new Foo('');", NOT_ASSIGNABLE);
 //  analyze("Foo x = new Foo(0, null);", MessageKind.ADDITIONAL_ARGUMENT);
 //
 //  analyze("Foo x = new Foo.foo();");
@@ -681,7 +685,7 @@
 //
 //  analyze("Foo x = new Foo.bar();");
 //  analyze("Foo x = new Foo.bar(0);");
-//  analyze("Foo x = new Foo.bar('');", MessageKind.NOT_ASSIGNABLE);
+//  analyze("Foo x = new Foo.bar('');", NOT_ASSIGNABLE);
 //  analyze("Foo x = new Foo.bar(0, null);",
 //          MessageKind.ADDITIONAL_ARGUMENT);
 //
@@ -691,17 +695,17 @@
 testConditionalExpression() {
   analyze("int i = true ? 2 : 1;");
   analyze("int i = true ? 'hest' : 1;");
-  analyze("int i = true ? 'hest' : 'fisk';", MessageKind.NOT_ASSIGNABLE);
+  analyze("int i = true ? 'hest' : 'fisk';", NOT_ASSIGNABLE);
   analyze("String s = true ? 'hest' : 'fisk';");
 
   analyze("true ? 1 : 2;");
   analyze("null ? 1 : 2;");
-  analyze("0 ? 1 : 2;", MessageKind.NOT_ASSIGNABLE);
-  analyze("'' ? 1 : 2;", MessageKind.NOT_ASSIGNABLE);
+  analyze("0 ? 1 : 2;", NOT_ASSIGNABLE);
+  analyze("'' ? 1 : 2;", NOT_ASSIGNABLE);
   analyze("{ int i; true ? i = 2.7 : 2; }",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
   analyze("{ int i; true ? 2 : i = 2.7; }",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
   analyze("{ int i; i = true ? 2.7 : 2; }");
 }
 
@@ -709,13 +713,13 @@
   analyze("if (true) {}");
   analyze("if (null) {}");
   analyze("if (0) {}",
-  MessageKind.NOT_ASSIGNABLE);
+  NOT_ASSIGNABLE);
   analyze("if ('') {}",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
   analyze("{ int i = 27; if (true) { i = 2.7; } else {} }",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
   analyze("{ int i = 27; if (true) {} else { i = 2.7; } }",
-          MessageKind.NOT_ASSIGNABLE);
+          NOT_ASSIGNABLE);
 }
 
 testThis() {
@@ -727,7 +731,7 @@
   ClassElement foo = library.find(const SourceString("Foo"));
   foo.ensureResolved(compiler);
   Element method = foo.lookupLocalMember(const SourceString('method'));
-  analyzeIn(method, "{ int i = this; }", MessageKind.NOT_ASSIGNABLE);
+  analyzeIn(method, "{ int i = this; }", NOT_ASSIGNABLE);
   analyzeIn(method, "{ Object o = this; }");
   analyzeIn(method, "{ Foo f = this; }");
 }
@@ -748,7 +752,7 @@
   ClassElement B = library.find(const SourceString("B"));
   B.ensureResolved(compiler);
   Element method = B.lookupLocalMember(const SourceString('method'));
-  analyzeIn(method, "{ int i = super.field; }", MessageKind.NOT_ASSIGNABLE);
+  analyzeIn(method, "{ int i = super.field; }", NOT_ASSIGNABLE);
   analyzeIn(method, "{ Object o = super.field; }");
   analyzeIn(method, "{ String s = super.field; }");
 }
@@ -885,53 +889,53 @@
   //      on e2'.
 
   // `0` is not assignable to operator + on `a`.
-  check('c = a + 0;', MessageKind.NOT_ASSIGNABLE);
+  check('c = a + 0;', NOT_ASSIGNABLE);
   // `a + b` is not assignable to `z`.
-  check('z = a + b;', MessageKind.NOT_ASSIGNABLE);
+  check('z = a + b;', NOT_ASSIGNABLE);
 
   // `-a` is not assignable to `z`.
-  check('z = -a;', MessageKind.NOT_ASSIGNABLE);
+  check('z = -a;', NOT_ASSIGNABLE);
 
   // `0` is not assignable to operator [] on `a`.
-  check('c = a[0];', MessageKind.NOT_ASSIGNABLE);
+  check('c = a[0];', NOT_ASSIGNABLE);
   // `a[b]` is not assignable to `z`.
-  check('z = a[b];', MessageKind.NOT_ASSIGNABLE);
+  check('z = a[b];', NOT_ASSIGNABLE);
 
   // `0` is not assignable to operator [] on `a`.
   // Warning suppressed for `0` is not assignable to operator []= on `a`.
-  check('a[0] *= c;', MessageKind.NOT_ASSIGNABLE);
+  check('a[0] *= c;', NOT_ASSIGNABLE);
   // `z` is not assignable to operator * on `a[0]`.
-  check('a[b] *= z;', MessageKind.NOT_ASSIGNABLE);
+  check('a[b] *= z;', NOT_ASSIGNABLE);
 
-  check('b = a++;', MessageKind.NOT_ASSIGNABLE);
-  check('b = ++a;', MessageKind.NOT_ASSIGNABLE);
-  check('b = a--;', MessageKind.NOT_ASSIGNABLE);
-  check('b = --a;', MessageKind.NOT_ASSIGNABLE);
+  check('b = a++;', NOT_ASSIGNABLE);
+  check('b = ++a;', NOT_ASSIGNABLE);
+  check('b = a--;', NOT_ASSIGNABLE);
+  check('b = --a;', NOT_ASSIGNABLE);
 
-  check('c = a[b]++;', MessageKind.NOT_ASSIGNABLE);
-  check('c = ++a[b];', MessageKind.NOT_ASSIGNABLE);
-  check('c = a[b]--;', MessageKind.NOT_ASSIGNABLE);
-  check('c = --a[b];', MessageKind.NOT_ASSIGNABLE);
+  check('c = a[b]++;', NOT_ASSIGNABLE);
+  check('c = ++a[b];', NOT_ASSIGNABLE);
+  check('c = a[b]--;', NOT_ASSIGNABLE);
+  check('c = --a[b];', NOT_ASSIGNABLE);
 
   check('z = a == b;');
   check('z = a != b;');
 
   for (String o in ['&&', '||']) {
     check('z = z $o z;');
-    check('z = a $o z;', MessageKind.NOT_ASSIGNABLE);
-    check('z = z $o b;', MessageKind.NOT_ASSIGNABLE);
+    check('z = a $o z;', NOT_ASSIGNABLE);
+    check('z = z $o b;', NOT_ASSIGNABLE);
     check('z = a $o b;',
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
     check('a = a $o b;',
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE,
-         MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE,
+         NOT_ASSIGNABLE]);
   }
 
   check('z = !z;');
-  check('z = !a;', MessageKind.NOT_ASSIGNABLE);
-  check('a = !z;', MessageKind.NOT_ASSIGNABLE);
+  check('z = !a;', NOT_ASSIGNABLE);
+  check('a = !z;', NOT_ASSIGNABLE);
   check('a = !a;',
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
 
   // Tests against MismatchA.
@@ -945,34 +949,34 @@
   // Tests against int operator +(MismatchA other) => 0;
 
   // `a + b` is not assignable to `c`.
-  check('c = a + b;', MessageKind.NOT_ASSIGNABLE);
+  check('c = a + b;', NOT_ASSIGNABLE);
   // `a + b` is not assignable to `a`.
-  check('a += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a += b;', NOT_ASSIGNABLE);
   // `a[0] + b` is not assignable to `a[0]`.
-  check('a[0] += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a[0] += b;', NOT_ASSIGNABLE);
 
   // 1 is not applicable to operator +.
-  check('b = a++;', MessageKind.NOT_ASSIGNABLE);
+  check('b = a++;', NOT_ASSIGNABLE);
   // 1 is not applicable to operator +.
   // `++a` of type int is not assignable to `b`.
   check('b = ++a;',
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   // 1 is not applicable to operator +.
-  check('b = a[0]++;', MessageKind.NOT_ASSIGNABLE);
+  check('b = a[0]++;', NOT_ASSIGNABLE);
   // 1 is not applicable to operator +.
   // `++a[0]` of type int is not assignable to `b`.
   check('b = ++a[0];',
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   // Tests against: MismatchA operator -(int other) => this;
 
   // `a - b` is not assignable to `c`.
-  check('c = a + b;', MessageKind.NOT_ASSIGNABLE);
+  check('c = a + b;', NOT_ASSIGNABLE);
   // `a - b` is not assignable to `a`.
-  check('a += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a += b;', NOT_ASSIGNABLE);
   // `a[0] - b` is not assignable to `a[0]`.
-  check('a[0] += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a[0] += b;', NOT_ASSIGNABLE);
 
   check('b = a--;');
   check('b = --a;');
@@ -993,16 +997,16 @@
   // void operator []=(String key, MismatchB value) {}
 
   // `0` is not applicable to operator []= on `a`.
-  check('a[0] = b;', MessageKind.NOT_ASSIGNABLE);
+  check('a[0] = b;', NOT_ASSIGNABLE);
 
   // `0` is not applicable to operator []= on `a`.
-  check('a[0] += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a[0] += b;', NOT_ASSIGNABLE);
   // `""` is not applicable to operator [] on `a`.
-  check('a[""] += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a[""] += b;', NOT_ASSIGNABLE);
   // `c` is not applicable to operator [] on `a`.
   // `c` is not applicable to operator []= on `a`.
   check('a[c] += b;',
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
 
   // Tests against MismatchB.
@@ -1018,26 +1022,26 @@
   // void operator[]=(int key, String value) {}
 
   // `b` is not assignable to `a[0]`.
-  check('a[0] += b;', MessageKind.NOT_ASSIGNABLE);
+  check('a[0] += b;', NOT_ASSIGNABLE);
   // `0` is not applicable to operator + on `a[0]`.
   check('a[0] += "";',
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
   // `true` is not applicable to operator + on `a[0]`.
   // `true` is not assignable to `a[0]`.
   check('a[0] += true;',
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 }
 
 void testFieldInitializers() {
   analyzeTopLevel("""int i = 0;""");
-  analyzeTopLevel("""int i = '';""", MessageKind.NOT_ASSIGNABLE);
+  analyzeTopLevel("""int i = '';""", NOT_ASSIGNABLE);
 
   analyzeTopLevel("""class Class {
                        int i = 0;
                      }""");
   analyzeTopLevel("""class Class {
                        int i = '';
-                     }""", MessageKind.NOT_ASSIGNABLE);
+                     }""", NOT_ASSIGNABLE);
 }
 
 void testTypeVariableExpressions() {
@@ -1051,11 +1055,11 @@
   Element method = foo.lookupLocalMember(const SourceString('method'));
 
   analyzeIn(method, "{ Type type = T; }");
-  analyzeIn(method, "{ T type = T; }", MessageKind.NOT_ASSIGNABLE);
-  analyzeIn(method, "{ int type = T; }", MessageKind.NOT_ASSIGNABLE);
+  analyzeIn(method, "{ T type = T; }", NOT_ASSIGNABLE);
+  analyzeIn(method, "{ int type = T; }", NOT_ASSIGNABLE);
 
   analyzeIn(method, "{ String typeName = T.toString(); }");
-  analyzeIn(method, "{ T.foo; }", MessageKind.MEMBER_NOT_FOUND);
+  analyzeIn(method, "{ T.foo; }", MEMBER_NOT_FOUND);
   analyzeIn(method, "{ T.foo = 0; }", MessageKind.PROPERTY_NOT_FOUND);
   analyzeIn(method, "{ T.foo(); }", MessageKind.METHOD_NOT_FOUND);
   analyzeIn(method, "{ T + 1; }", MessageKind.OPERATOR_NOT_FOUND);
@@ -1070,23 +1074,23 @@
 
   // Check direct access.
   analyze('Type m() => int;');
-  analyze('int m() => int;', MessageKind.NOT_ASSIGNABLE);
+  analyze('int m() => int;', NOT_ASSIGNABLE);
 
   // Check access in assignment.
   analyze('m(Type val) => val = Class;');
-  analyze('m(int val) => val = Class;', MessageKind.NOT_ASSIGNABLE);
+  analyze('m(int val) => val = Class;', NOT_ASSIGNABLE);
 
   // Check access as argument.
   analyze('m(Type val) => m(int);');
-  analyze('m(int val) => m(int);', MessageKind.NOT_ASSIGNABLE);
+  analyze('m(int val) => m(int);', NOT_ASSIGNABLE);
 
   // Check access as argument in member access.
   analyze('m(Type val) => m(int).foo;');
-  analyze('m(int val) => m(int).foo;', MessageKind.NOT_ASSIGNABLE);
+  analyze('m(int val) => m(int).foo;', NOT_ASSIGNABLE);
 
   // Check static property access.
   analyze('m() => Class.field;');
-  analyze('m() => (Class).field;', MessageKind.MEMBER_NOT_FOUND);
+  analyze('m() => (Class).field;', MEMBER_NOT_FOUND);
 
   // Check static method access.
   analyze('m() => Class.method();');
@@ -1118,7 +1122,7 @@
               String a;
               Class(int this.a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
   check(r'''class Class {
               var a;
               Class(int a) : this.a = a;
@@ -1128,7 +1132,7 @@
               String a;
               Class(int a) : this.a = a;
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
 
   // Check this-calls.
   check(r'''class Class {
@@ -1142,7 +1146,7 @@
               Class(this.a);
               Class.named(int a) : this(a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
   check(r'''class Class {
               String a;
               Class(var a) : this.a = a;
@@ -1154,7 +1158,7 @@
               Class(String a) : this.a = a;
               Class.named(int a) : this(a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
 
   // Check super-calls.
   check(r'''class Super {
@@ -1172,7 +1176,7 @@
             class Class extends Super {
               Class.named(int a) : super(a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
   check(r'''class Super {
               String a;
               Super(var a) : this.a = a;
@@ -1188,7 +1192,7 @@
             class Class extends Super {
               Class.named(int a) : super(a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
 
   // Check super-calls involving generics.
   check(r'''class Super<T> {
@@ -1206,7 +1210,7 @@
             class Class extends Super<String> {
               Class.named(int a) : super(a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
   check(r'''class Super<T> {
               T a;
               Super(var a) : this.a = a;
@@ -1222,7 +1226,7 @@
             class Class extends Super<String> {
               Class.named(int a) : super(a);
             }
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
 
   // Check instance creations.
   check(r'''class Class {
@@ -1236,7 +1240,7 @@
               Class(this.a);
             }
             method(int a) => new Class(a);
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
   check(r'''class Class {
               String a;
               Class(var a) : this.a = a;
@@ -1248,7 +1252,7 @@
               Class(String a) : this.a = a;
             }
             method(int a) => new Class(a);
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
 
   // Check instance creations involving generics.
   check(r'''class Class<T> {
@@ -1262,7 +1266,7 @@
               Class(this.a);
             }
             method(int a) => new Class<String>(a);
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
   check(r'''class Class<T> {
               T a;
               Class(var a) : this.a = a;
@@ -1274,7 +1278,7 @@
               Class(String a) : this.a = a;
             }
             method(int a) => new Class<String>(a);
-            ''', MessageKind.NOT_ASSIGNABLE);
+            ''', NOT_ASSIGNABLE);
 }
 
 void testGetterSetterInvocation() {
@@ -1314,41 +1318,41 @@
 
   check("variable = '';");
   check("int v = variable;");
-  check("variable = 0;", MessageKind.NOT_ASSIGNABLE);
-  check("String v = variable;", MessageKind.NOT_ASSIGNABLE);
+  check("variable = 0;", NOT_ASSIGNABLE);
+  check("String v = variable;", NOT_ASSIGNABLE);
   // num is not assignable to String (the type of the setter).
-  check("variable += 0;", MessageKind.NOT_ASSIGNABLE);
+  check("variable += 0;", NOT_ASSIGNABLE);
   // String is not assignable to int (the argument type of the operator + on the
   // getter) and num (the result type of the operation) is not assignable to
   // String (the type of the setter).
   check("variable += '';",
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   check("c.instanceField = '';");
   check("int v = c.instanceField;");
-  check("c.instanceField = 0;", MessageKind.NOT_ASSIGNABLE);
-  check("String v = c.instanceField;", MessageKind.NOT_ASSIGNABLE);
+  check("c.instanceField = 0;", NOT_ASSIGNABLE);
+  check("String v = c.instanceField;", NOT_ASSIGNABLE);
 
   // num is not assignable to String (the type of the setter).
-  check("c.instanceField += 0;", MessageKind.NOT_ASSIGNABLE);
+  check("c.instanceField += 0;", NOT_ASSIGNABLE);
   // String is not assignable to int (the argument type of the operator + on the
   // getter) and num (the result type of the operation) is not assignable to
   // String (the type of the setter).
   check("c.instanceField += '';",
-      [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+      [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   check("Class.staticField = '';");
   check("int v = Class.staticField;");
-  check("Class.staticField = 0;", MessageKind.NOT_ASSIGNABLE);
-  check("String v = Class.staticField;", MessageKind.NOT_ASSIGNABLE);
+  check("Class.staticField = 0;", NOT_ASSIGNABLE);
+  check("String v = Class.staticField;", NOT_ASSIGNABLE);
 
   // num is not assignable to String (the type of the setter).
-  check("Class.staticField += 0;", MessageKind.NOT_ASSIGNABLE);
+  check("Class.staticField += 0;", NOT_ASSIGNABLE);
   // String is not assignable to int (the argument type of the operator + on the
   // getter) and num (the result type of the operation) is not assignable to
   // String (the type of the setter).
   check("Class.staticField += '';",
-        [MessageKind.NOT_ASSIGNABLE, MessageKind.NOT_ASSIGNABLE]);
+        [NOT_ASSIGNABLE, NOT_ASSIGNABLE]);
 
   check("int v = c.overriddenField;");
   check("c.overriddenField = 0;");
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index d71a582..5b87bf8 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -117,8 +117,6 @@
 int_parse_radix_test: Skip # Timeout
 
 [ $arch == simmips && $checked ]
-hash_map2_test: Pass, Crash # Too far PC relative branch (?)
-list_test: Pass, Crash # Invalid relative branch offset. Issue 11851.
 collection_length_test: Pass, Timeout
 
 [ $arch == simmips && $mode == debug ]
diff --git a/tests/corelib/hash_map2_test.dart b/tests/corelib/hash_map2_test.dart
index cc4ed3e..a43afd2 100644
--- a/tests/corelib/hash_map2_test.dart
+++ b/tests/corelib/hash_map2_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+// VMOptions=--use-far-branches
 
 // Tests of hash map behavior, with focus in iteration and concurrent
 // modification errors.
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index 8883e49..97552a6 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+// VMOptions=--use-far-branches
 
 import "dart:collection";
 import "dart:typed_data";
diff --git a/tests/html/element_offset_test.dart b/tests/html/element_offset_test.dart
new file mode 100644
index 0000000..f402642
--- /dev/null
+++ b/tests/html/element_offset_test.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_offset_test;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'dart:async';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+  void initPage() {
+    var level1 = new UListElement()
+      ..classes.add('level-1')
+      ..children.add(new LIElement()..innerHtml = 'I');
+    var itemii = new LIElement()
+      ..classes.add('item-ii')
+      ..style.position = 'relative'
+      ..style.top = '4px'
+      ..innerHtml = 'II';
+    level1.children.add(itemii);
+    var level2 = new UListElement();
+    itemii.children.add(level2);
+    var itema = new LIElement()
+      ..classes.add('item-a')
+      ..innerHtml = 'A';
+    var item1 = new LIElement()
+      ..classes.add('item-1')
+      ..innerHtml = '1';
+    var item2 = new LIElement()
+      ..classes.add('item-2')
+      ..innerHtml = '2';
+    var level3 = new UListElement()
+      ..children.addAll([item1, item2]);
+    var itemb = new LIElement()
+      ..classes.add('item-b')
+      ..style.position = 'relative'
+      ..style.top = '20px'
+      ..style.left = '150px'
+      ..innerHtml = 'B'
+      ..children.add(level3);
+    level2.children.addAll([itema, itemb, new LIElement()..innerHtml = 'C']);
+    document.body.append(level1);
+    document.body.style.whiteSpace = 'nowrap';
+
+    var bar = new DivElement()..classes.add('bar');
+    var style = bar.style;
+    style..position = 'absolute'
+         ..top = '8px'
+         ..left = '90px';
+    var baz = new DivElement()..classes.add('baz');
+    style = baz.style;
+    style..position = 'absolute'
+         ..top = '600px'
+         ..left = '7000px';
+    bar.children.add(baz);
+
+    var quux = new DivElement()..classes.add('quux');
+    var qux = new DivElement()
+      ..classes.add('qux')
+      ..children.add(quux);
+
+    document.body.append(bar);
+    document.body.append(qux);
+  }
+
+  group('offset', () {
+    setUp(initPage);
+
+    test('offsetTo', () {
+      var itema = query('.item-a');
+      var itemb = query('.item-b');
+      var item1 = query('.item-1');
+      var itemii = query('.item-ii');
+      var level1 = query('.level-1');
+      var baz = query('.baz');
+      var bar = query('.bar');
+      var qux = query('.qux');
+      var quux = query('.quux');
+
+      var point = itema.offsetTo(itemii);
+      expect(point.x, 40);
+      expect(point.y, inInclusiveRange(17, 20));
+
+      expect(baz.offsetTo(bar).x, 7000);
+      expect(baz.offsetTo(bar).y, inInclusiveRange(599, 604));
+
+      qux.style.position = 'fixed';
+      expect(quux.offsetTo(qux).x, 0);
+      expect(quux.offsetTo(qux).y, 0);
+
+      point = item1.offsetTo(itemb);
+      expect(point.x, 40);
+      expect(point.y, inInclusiveRange(17, 20));
+      point = itemb.offsetTo(itemii);
+      expect(point.x, 190);
+      expect(point.y, inInclusiveRange(54, 60));
+      point = item1.offsetTo(itemii);
+      expect(point.x, 230);
+      expect(point.y, inInclusiveRange(74, 80));
+    });
+
+    test('documentOffset', () {
+      var bar = query('.bar');
+      var baz = query('.baz');
+      var qux = query('.qux');
+      var quux = query('.quux');
+      var itema = query('.item-a');
+      var itemb = query('.item-b');
+      var item1 = query('.item-1');
+      var itemii = query('.item-ii');
+
+      expect(itema.documentOffset.x, 88);
+      expect(itema.documentOffset.y, inInclusiveRange(119, 160));
+
+      expect(itemii.documentOffset.x, 48);
+      expect(itemii.documentOffset.y, inInclusiveRange(101, 145));
+
+      expect(itemb.documentOffset.x, 238);
+      expect(itemb.documentOffset.y, inInclusiveRange(157, 205));
+
+      expect(item1.documentOffset.x, 278);
+      expect(item1.documentOffset.y, inInclusiveRange(175, 222));
+
+      expect(bar.documentOffset.x, 90);
+      expect(bar.documentOffset.y, 8);
+
+      expect(baz.documentOffset.x, 7090);
+      expect(baz.documentOffset.y, 608);
+
+      expect(qux.documentOffset.x, 8);
+      expect(qux.documentOffset.y, inInclusiveRange(221, 240));
+
+      expect(quux.documentOffset.x, 8);
+      expect(quux.documentOffset.y, inInclusiveRange(221, 240));
+    });
+  });
+}
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index c360c8f..7e13741 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -728,132 +728,4 @@
       expect(range[1], isInputElement);
     });
   });
-  void initPage() {
-    var level1 = new UListElement()
-      ..classes.add('level-1')
-      ..children.add(new LIElement()..innerHtml = 'I');
-    var itemii = new LIElement()
-      ..classes.add('item-ii')
-      ..style.position = 'relative'
-      ..style.top = '4px'
-      ..innerHtml = 'II';
-    level1.children.add(itemii);
-    var level2 = new UListElement();
-    itemii.children.add(level2);
-    var itema = new LIElement()
-      ..classes.add('item-a')
-      ..innerHtml = 'A';
-    var item1 = new LIElement()
-      ..classes.add('item-1')
-      ..innerHtml = '1';
-    var item2 = new LIElement()
-      ..classes.add('item-2')
-      ..innerHtml = '2';
-    var level3 = new UListElement()
-      ..children.addAll([item1, item2]);
-    var itemb = new LIElement()
-      ..classes.add('item-b')
-      ..style.position = 'relative'
-      ..style.top = '20px'
-      ..style.left = '150px'
-      ..innerHtml = 'B'
-      ..children.add(level3);
-    level2.children.addAll([itema, itemb, new LIElement()..innerHtml = 'C']);
-    document.body.append(level1);
-
-    var bar = new DivElement()..classes.add('bar');
-    var style = bar.style;
-    style..position = 'absolute'
-         ..top = '8px'
-         ..left = '90px';
-    var baz = new DivElement()..classes.add('baz');
-    style = baz.style;
-    style..position = 'absolute'
-         ..top = '600px'
-         ..left = '7000px';
-    bar.children.add(baz);
-
-    var quux = new DivElement()..classes.add('quux');
-    var qux = new DivElement()
-      ..classes.add('qux')
-      ..children.add(quux);
-
-    document.body.append(bar);
-    document.body.append(qux);
-  }
-
-  group('offset', () {
-    setUp(initPage);
-
-    test('offsetTo', () {
-      var itema = query('.item-a');
-      var itemb = query('.item-b');
-      var item1 = query('.item-1');
-      var itemii = query('.item-ii');
-      var level1 = query('.level-1');
-      var baz = query('.baz');
-      var bar = query('.bar');
-      var qux = query('.qux');
-      var quux = query('.quux');
-
-      var point = itema.offsetTo(itemii);
-      // TODO(efortuna): Make cross-machine reproducible.
-      /*expect(point.x, 40);
-      expect(point.y, inInclusiveRange(17, 20));
-
-      expect(baz.offsetTo(bar).x, 7000);
-      expect(baz.offsetTo(bar).y, inInclusiveRange(599, 604));
-
-      qux.style.position = 'fixed';
-      expect(quux.offsetTo(qux).x, 0);
-      expect(quux.offsetTo(qux).y, 0);
-
-      point = item1.offsetTo(itemb);
-      expect(point.x, 40);
-      expect(point.y, inInclusiveRange(17, 20));
-      point = itemb.offsetTo(itemii);
-      expect(point.x, 190);
-      expect(point.y, inInclusiveRange(54, 60));
-      point = item1.offsetTo(itemii);
-      expect(point.x, 230);
-      expect(point.y, inInclusiveRange(74, 80));*/
-    });
-
-    test('documentOffset', () {
-      var bar = query('.bar');
-      var baz = query('.baz');
-      var qux = query('.qux');
-      var quux = query('.quux');
-      var itema = query('.item-a');
-      var itemb = query('.item-b');
-      var item1 = query('.item-1');
-      var itemii = query('.item-ii');
-
-      // TODO(efortuna): Make cross-machine reproducible.
-      /*expect(itema.documentOffset.x, 88);
-      expect(itema.documentOffset.y, inInclusiveRange(119, 160));
-
-      expect(itemii.documentOffset.x, 48);
-      expect(itemii.documentOffset.y, inInclusiveRange(101, 145));
-
-      expect(itemb.documentOffset.x, 238);
-      expect(itemb.documentOffset.y, inInclusiveRange(157, 205));
-
-      expect(item1.documentOffset.x, 278);
-      expect(item1.documentOffset.y, inInclusiveRange(175, 222));
-
-      expect(bar.documentOffset.x, 90);
-      expect(bar.documentOffset.y, 8);
-
-      expect(baz.documentOffset.x, 7090);
-      expect(baz.documentOffset.y, 608);
-
-      expect(qux.documentOffset.x, 8);
-      expect(qux.documentOffset.y, inInclusiveRange(221, 232));
-
-      expect(quux.documentOffset.x, 8);
-      expect(quux.documentOffset.y, inInclusiveRange(221, 232));*/
-    });
-  });
-
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index 67c7754..e03aa5c 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -332,7 +332,6 @@
 element_types_test/supported_keygen: Fail
 element_types_test/supported_object: Fail
 element_types_test/supported_shadow: Fail
-element_types_test/supported_template: Fail
 element_types_test/supported_track: Fail
 fileapi_test/supported: Fail
 indexeddb_1_test/supportsDatabaseNames: Fail
@@ -346,13 +345,19 @@
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
 notifications_test/supported: Fail
-rtc_test/supported: Fail # Release build does not enable by default.
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
 touchevent_test/supported: Fail
 websql_test/supported: Fail
 xhr_test/supported_HttpRequestProgressEvent: Fail
 
+[ $runtime == ff && $system == windows ]
+rtc_test/supported: Fail # Release build does not enable by default.
+element_types_test/supported_template: Fail
+
+[ $runtime == ff && $system == linux ]
+rtc_test/functionality: Fail # Issue: 12109.
+
 [ $runtime == ie9 && ($system == linux || $system == macos) ]
 *: Skip
 
diff --git a/tests/html/window_test.dart b/tests/html/window_test.dart
new file mode 100644
index 0000000..a663d1b
--- /dev/null
+++ b/tests/html/window_test.dart
@@ -0,0 +1,13 @@
+library WindowTest;
+import '../../pkg/unittest/lib/unittest.dart';
+import '../../pkg/unittest/lib/html_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlConfiguration();
+
+  test('scrollXY', () {
+    expect(window.scrollX, 0);
+    expect(window.scrollY, 0);
+  });
+}
diff --git a/tests/language/arithmetic_test.dart b/tests/language/arithmetic_test.dart
index effcee9..00f6eb1 100644
--- a/tests/language/arithmetic_test.dart
+++ b/tests/language/arithmetic_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program to test arithmetic operations.
-// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --use-far-branches
 
 library arithmetic_test;
 import "package:expect/expect.dart";
diff --git a/tests/language/function_malformed_result_type_test.dart b/tests/language/function_malformed_result_type_test.dart
index d010be7..2895975 100644
--- a/tests/language/function_malformed_result_type_test.dart
+++ b/tests/language/function_malformed_result_type_test.dart
@@ -1,22 +1,13 @@
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+
 // Dart test for a function with a malformed result type.
 
 import "package:expect/expect.dart";
 
 class C<T, U> {}
 
-isCheckedMode() {
-  try {
-    var i = 1;
-    String s = i;
-    return false;
-  } catch (e) {
-    return true;
-  }
-}
-
 main() {
   {
     C<int> f() => null;
@@ -37,7 +28,8 @@
     } on TypeError catch (error) {
       got_type_error = true;
     }
-    // Type error expected in checked mode only.
-    Expect.isTrue(got_type_error == isCheckedMode());
+    // Type error not expected in production nor checked mode since C<int>
+    // is handled like C<dynamic,dynamic>.
+    Expect.isFalse(got_type_error);
   }
 }
diff --git a/tests/language/is_not_class2_negative_test.dart b/tests/language/is_not_class2_test.dart
similarity index 76%
rename from tests/language/is_not_class2_negative_test.dart
rename to tests/language/is_not_class2_test.dart
index 3883910..710c72d 100644
--- a/tests/language/is_not_class2_negative_test.dart
+++ b/tests/language/is_not_class2_test.dart
@@ -1,7 +1,10 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// Dart test program for catch that we expect a class after an 'is'.
+
+// Dart test program for catch that we expect a class after an 'is'. This is
+// not a negative test since 'aa' is a malformed type and therefore should be
+// treated as dynamic.
 
 class A {
   const A();
@@ -12,7 +15,7 @@
     var a = new A();
     var aa = new A();
 
-    if (a is aa) {
+    if (a is aa) { // static warning
       return 0;
     }
     return 0;
diff --git a/tests/language/language.status b/tests/language/language.status
index 585874d..67e3e67 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -80,6 +80,40 @@
 const_constructor_mixin2_test/01: Fail # Issue 11917
 const_constructor_mixin3_test/01: Fail # Issue 11917
 
+is_not_class2_test: Fail # Issue 9055
+list_literal_syntax_test/01: Fail # Issue 9055
+list_literal_syntax_test/02: Fail # Issue 9055
+list_literal_syntax_test/03: Fail # Issue 9055
+malformed_inheritance_test/02: Fail # Issue 9055
+malformed_inheritance_test/04: Fail # Issue 9055
+malformed_inheritance_test/06: Fail # Issue 9055
+malformed_test/none: Fail # Issue 9055
+prefix9_test: Fail # Issue 9055
+try_catch_on_syntax_test/07: Fail # Issue 9055
+try_catch_syntax_test/08: Fail # Issue 9055
+type_variable_bounds_test/08: Fail # Issue 9055
+wrong_number_type_arguments_test/01: Fail # Issue 9055
+
+[ $compiler == none && $checked ]
+function_malformed_result_type_test: Fail # Issue 9055
+new_expression_type_args_test/02: Fail # Issue 9055
+prefix16_test: Fail # Issue 9055
+type_parameter_test/01: Fail # Issue 9055
+type_parameter_test/02: Fail # Issue 9055
+type_parameter_test/03: Fail # Issue 9055
+type_parameter_test/04: Fail # Issue 9055
+type_parameter_test/05: Fail # Issue 9055
+type_parameter_test/06: Fail # Issue 9055
+type_variable_bounds_test/07: Fail # Issue 9055
+type_variable_scope2_test: Fail # Issue 9055
+type_variable_scope_test/00: Fail # Issue 9055
+type_variable_scope_test/01: Fail # Issue 9055
+type_variable_scope_test/02: Fail # Issue 9055
+type_variable_scope_test/03: Fail # Issue 9055
+type_variable_scope_test/04: Fail # Issue 9055
+type_variable_scope_test/05: Fail # Issue 9055
+wrong_number_type_arguments_test/02: Fail # Issue 9055
+
 [ $compiler == none && $unchecked ]
 
 # Only checked mode reports an error on type assignment
@@ -98,8 +132,6 @@
 compile_time_constant_checked3_test/05: Fail, OK
 compile_time_constant_checked3_test/06: Fail, OK
 
-type_parameter_test/05: Fail, OK # No way of specifying a compile-time type error in checked mode only.
-
 
 [ $compiler == none && $runtime == drt ]
 type_variable_field_initializer_closure_test: Fail # issue 8847
@@ -199,7 +231,6 @@
 final_syntax_test/03: Fail # http://dartbug.com/5519
 final_syntax_test/04: Fail # http://dartbug.com/5519
 getter_no_setter_test/01: Fail # http://dartbug.com/5519
-isnot_malformed_type_test/01: Fail # http://dartbug.com/5519
 named_parameters_aggregated_test/01: Fail # http://dartbug.com/5519
 named_parameters_aggregated_test/03: Fail # http://dartbug.com/5519
 not_enough_positional_arguments_test/01: Fail # http://dartbug.com/5519
@@ -248,7 +279,6 @@
 function_type_alias5_test/01: Fail
 function_type_alias5_test/02: Fail
 function_type_alias7_test/00: Fail
-instanceof3_test: Fail
 parameter_initializer6_negative_test: Fail # Issue 3502
 syntax_test/47: Fail
 # DartVM problem.
@@ -265,7 +295,6 @@
 
 named_parameters_aggregated_test/05: Fail # Compile-time error reported instead of static type warning.
 
-type_variable_bounds_test/07: Fail # Wrongly reports compile-time error.
 new_expression_type_args_test/00: Fail # Wrongly reports compile-time error.
 new_expression_type_args_test/01: Fail # Wrongly reports compile-time error.
 
@@ -308,6 +337,18 @@
 
 bound_closure_equality_test: Fail # Issue 10849
 
+is_not_class2_test: Fail # Issue 9055
+list_literal_syntax_test/01: Fail # Issue 9055
+list_literal_syntax_test/02: Fail # Issue 9055
+list_literal_syntax_test/03: Fail # Issue 9055
+malformed_inheritance_test/02: Fail # Issue 9055
+malformed_inheritance_test/04: Fail # Issue 9055
+malformed_inheritance_test/06: Fail # Issue 9055
+malformed_test/none: Fail # Issue 9055
+try_catch_on_syntax_test/07: Fail # Issue 9055
+try_catch_syntax_test/08: Fail # Issue 9055
+
+
 [ $compiler == dart2dart && $minified ]
 super_getter_setter_test: Fail # Issue 11065.
 
@@ -328,6 +369,4 @@
 *: Skip
 
 [ $arch == simmips ]
-arithmetic_test: Crash  # Too far relative branch.
-large_implicit_getter_test: Crash  # Too far relative branch.
 try_catch4_test: Fail
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index f689f2e..82e8b5f 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -121,6 +121,10 @@
 
 function_type_alias6_test/00: fail # Issue 11987
 function_type_alias9_test/00: crash # Issue 11987
+list_literal_syntax_test/01: fail # Issue 12103
+list_literal_syntax_test/02: fail # Issue 12103
+list_literal_syntax_test/03: fail # Issue 12103
+malformed_test/none: fail
 named_parameters_aggregated_test/03: fail
 no_such_method_negative_test: fail
 non_const_super_negative_test: fail
@@ -185,8 +189,6 @@
 
 # test issue 10890; on-catch UnknownType is a static warning, not error
 try_catch_on_syntax_test/01: fail
-try_catch_on_syntax_test/07: fail
-try_catch_syntax_test/08: fail
 
 # test issue 10899; it is static warning, not error, to call methods of class literal
 class_literal_test/02: fail
@@ -245,11 +247,6 @@
 method_override5_test: fail # issue 11497
 method_override6_test: fail # issue 11497
 
-# testing framework problem: we do report warning, framework does not understand it
-# may be https://codereview.chromium.org/18174010/ will fix this
-type_variable_bounds_test/08: fail
-wrong_number_type_arguments_test/01: fail
-
 # test issue 11575, classes with abstrac members are not marked as abstract
 abstract_factory_constructor_test/none: fail
 abstract_syntax_test/none: fail
@@ -293,10 +290,4 @@
 getters_setters2_test/03: fail
 type_variable_bounds3_test/00: fail
 type_variable_bounds2_test/05: fail
-type_variable_scope_test/00: fail
-type_variable_scope_test/01: fail
-type_variable_scope_test/02: fail
-type_variable_scope_test/03: fail
-type_variable_scope_test/04: fail
-type_variable_scope_test/05: fail
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 99249b5..fa07442 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -40,9 +40,6 @@
 *vm_test: Skip
 *vm_negative_test: Skip
 
-[ ($compiler == dart2js || $compiler == dart2dart) && $unchecked ]
-type_parameter_test/05: Fail, OK # No way of specifying a compile-time type error in checked mode only.
-
 [ $compiler == dart2js && $checked ]
 checked_setter2_test: Fail # dartbug.com/11273
 default_factory2_test/01: Fail
@@ -65,9 +62,7 @@
 factory_redirection_test/14: Fail # redirecting to redirecting factory
 type_checks_in_factory_method_test: Fail # Expect.equals(expected: <true>, actual: <false>) fails. -- checked mode test.
 
-prefix16_test: Fail # dartbug.com/9056
 assertion_test: Fail
-type_variable_bounds_test/07: Fail # Wrongly reports compile-time error.
 
 double_to_string_as_exponential2_test: Fail # toStringAsExponential doesn't check if argument is an integer.
 double_to_string_as_fixed2_test: Fail # toStringAsFixed doesn't check if argument is an integer.
@@ -117,7 +112,6 @@
 getter_no_setter_test/01: Fail # http://dartbug.com/5519
 isnot_malformed_type_test/01: Fail # http://dartbug.com/5519
 not_enough_positional_arguments_test/01: Fail # http://dartbug.com/5519
-no_such_method_dispatcher_test: Fail # http://dartbug.com/11937
 error_stacktrace_test: Fail # (Issue 11681).
 
 constructor_negative_test: Pass # Wrong reason: the expression 'C()' is valid with class literals.
@@ -163,7 +157,6 @@
 named_parameters_aggregated_test/05: Fail # Absence of positional parameters before named parameters does not trigger static type warning.
 pseudo_kw_test: Fail # Unexpected token '('
 super_implicit_closure_test: Fail # internal error: super property read not implemented
-on_catch_malformed_type_test: Fail # Malformed types cause compile-time errors.
 
 # Missing compilation error for wrong number of type arguments.
 mixin_type_parameters_errors_test/01: Fail
diff --git a/tests/language/large_implicit_getter_test.dart b/tests/language/large_implicit_getter_test.dart
index 8dac849..b7293b2 100644
--- a/tests/language/large_implicit_getter_test.dart
+++ b/tests/language/large_implicit_getter_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program for testing compilation of large implicit getters.
-// VMOptions=--optimization-counter-threshold=10
+// VMOptions=--optimization-counter-threshold=10 --use-far-branches
 
 List<List> panels = [
 [6853.940039224797,6050.837897021371]
diff --git a/tests/language/list_literal_syntax_test.dart b/tests/language/list_literal_syntax_test.dart
index 83f23a9..c9c3320 100644
--- a/tests/language/list_literal_syntax_test.dart
+++ b/tests/language/list_literal_syntax_test.dart
@@ -10,18 +10,18 @@
   var list;
   list = <int
     I /// 00: compile-time error
-    , int /// 01: compile-time error
+    , int /// 01: static type warning
     >[0];
   Expect.equals(1, list.length);
 
   list = <int
-    , int /// 02: compile-time error
+    , int /// 02: static type warning
     , int /// 02: continued
     >[0];
   Expect.equals(1, list.length);
 
   list = <int
-    , int /// 03: compile-time error
+    , int /// 03: static type warning
     , int /// 03: continued
     , int /// 03: continued
     >[0];
diff --git a/tests/language/malformed_inheritance_test.dart b/tests/language/malformed_inheritance_test.dart
new file mode 100644
index 0000000..5473e3b
--- /dev/null
+++ b/tests/language/malformed_inheritance_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Tests that malformed types used in extends, implements, and with clauses
+// cause compile-time errors.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class C
+  extends Unresolved /// 01: compile-time error
+  extends A<Unresolved> /// 02: static type warning
+  extends Object with Unresolved /// 03: compile-time error
+  extends Object with A<Unresolved> /// 04: static type warning
+  implements Unresolved /// 05: compile-time error
+  implements A<Unresolved> /// 06: static type warning
+{
+
+}
+
+void main() {
+  new C();
+  Expect.isTrue(new C() is A<String> && new C() is A<int>); /// 02: continued
+  Expect.isTrue(new C() is A<String> && new C() is A<int>); /// 04: continued
+  Expect.isTrue(new C() is A<String> && new C() is A<int>); /// 06: continued
+}
\ No newline at end of file
diff --git a/tests/language/malformed_test.dart b/tests/language/malformed_test.dart
new file mode 100644
index 0000000..eb2834a
--- /dev/null
+++ b/tests/language/malformed_test.dart
@@ -0,0 +1,145 @@
+// 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.
+
+// Tests that malformed types are handled as dynamic, and that types with the
+// wrong number of type arguments are handled as raw types.
+
+import 'package:expect/expect.dart';
+
+checkIsUnresolved(var v) {
+  Expect.isTrue(v is Unresolved);
+  Expect.isTrue(v is Unresolved<int>);
+  Expect.isTrue(v is prefix.Unresolved);
+  Expect.isTrue(v is prefix.Unresolved<int>);
+}
+
+checkIsListUnresolved(bool expect, var v) {
+  Expect.equals(expect, v is List<Unresolved>);
+  Expect.equals(expect, v is List<Unresolved<int>>);
+  Expect.equals(expect, v is List<prefix.Unresolved>);
+  Expect.equals(expect, v is List<prefix.Unresolved<int>>);
+  Expect.equals(expect, v is List<int, String>);
+}
+
+checkIsListDynamic(bool expect, var v) {
+  checkIsListUnresolved(true, v);
+  Expect.equals(expect, v is List<int> && v is List<String>);
+}
+
+checkAsUnresolved(var v) {
+  Expect.equals(v, v as Unresolved);
+  Expect.equals(v, v as Unresolved<int>);
+  Expect.equals(v, v as prefix.Unresolved);
+  Expect.equals(v, v as prefix.Unresolved<int>);
+}
+
+checkAsListUnresolved(bool expect, var v) {
+  if (expect) {
+    Expect.equals(v, v as List<Unresolved>);
+    Expect.equals(v, v as List<Unresolved<int>>);
+    Expect.equals(v, v as List<prefix.Unresolved>);
+    Expect.equals(v, v as List<prefix.Unresolved<int>>);
+    Expect.equals(v, v as List<int, String>);
+  } else {
+    Expect.throws(() => v as List<Unresolved>, (e) => e is CastError);
+    Expect.throws(() => v as List<Unresolved<int>>, (e) => e is CastError);
+    Expect.throws(() => v as List<prefix.Unresolved>, (e) => e is CastError);
+    Expect.throws(() => v as List<prefix.Unresolved<int>>,
+                  (e) => e is CastError);
+    Expect.throws(() => v as List<int, String>, (e) => e is CastError);
+  }
+}
+
+checkIsMapDynamic(bool first, bool second, var v) {
+  Expect.equals(first, v is Map<String, Object> && v is Map<int, Object>);
+  Expect.equals(second, v is Map<Object, int> && v is Map<Object, String>);
+}
+
+
+void main() {
+  checkIsUnresolved('');
+  checkIsUnresolved(0);
+  checkIsListUnresolved(false, '');
+  checkIsListUnresolved(true, new List());
+  checkIsListUnresolved(true, new List<int>());
+  checkIsListUnresolved(true, new List<String>());
+  checkIsListUnresolved(true, new List<int, String>());
+
+  checkAsUnresolved('');
+  checkAsUnresolved(0);
+  checkAsListUnresolved(false, '');
+  checkAsListUnresolved(true, new List());
+  checkAsListUnresolved(true, new List<int>());
+  checkAsListUnresolved(true, new List<String>());
+  checkAsListUnresolved(true, new List<int, String>());
+
+  checkIsListDynamic(true, []);
+  checkIsListDynamic(true, <>[]); /// 01: compile-time error
+// TODO(johnniwinther): Create runtime type information on literal lists.
+//  checkIsListDynamic(false, <int>[]);
+  checkIsListDynamic(true, <Unresolved>[]);
+  checkIsListDynamic(true, <Unresolved<int>>[]);
+  checkIsListDynamic(true, <prefix.Unresolved>[]);
+  checkIsListDynamic(true, <prefix.Unresolved<int>>[]);
+  checkIsListDynamic(true, <int, String>[]);
+
+  checkIsListDynamic(true, new List());
+  checkIsListDynamic(true, new List<>()); /// 02: compile-time error
+  checkIsListDynamic(true, new List<Unresolved>());
+  checkIsListDynamic(true, new List<Unresolved<int>>());
+  checkIsListDynamic(true, new List<prefix.Unresolved>());
+  checkIsListDynamic(true, new List<prefix.Unresolved<int>>());
+  checkIsListDynamic(true, new List<int, String>());
+
+  checkIsMapDynamic(true, true, {});
+  checkIsMapDynamic(true, true, <>{}); /// 03: compile-time error
+  checkIsMapDynamic(true, true, <int>{});
+// TODO(johnniwinther): Create runtime type information on literal maps.
+//  checkIsMapDynamic(false, false, <String, int>{});
+  checkIsMapDynamic(true, true, <String, int, String>{});
+//  checkIsMapDynamic(true, false, <Unresolved, int>{});
+//  checkIsMapDynamic(false, true, <String, Unresolved<int>>{});
+//  checkIsMapDynamic(true, false,  <prefix.Unresolved, int>{});
+//  checkIsMapDynamic(false, true, <String, prefix.Unresolved<int>>{});
+
+  checkIsMapDynamic(true, true, new Map());
+  checkIsMapDynamic(true, true, new Map<>); /// 04: compile-time error
+  checkIsMapDynamic(true, true, new Map<int>());
+  checkIsMapDynamic(false, false, new Map<String, int>());
+  checkIsMapDynamic(true, true, new Map<String, int, String>());
+  checkIsMapDynamic(true, false, new Map<Unresolved, int>());
+  checkIsMapDynamic(false, true, new Map<String, Unresolved<int>>());
+  checkIsMapDynamic(true, false,  new Map<prefix.Unresolved, int>());
+  checkIsMapDynamic(false, true, new Map<String, prefix.Unresolved<int>>());
+
+  Expect.throws(() => new Unresolved(), (e) => true);
+  Expect.throws(() => new Unresolved<int>(), (e) => true);
+  Expect.throws(() => new prefix.Unresolved(), (e) => true);
+  Expect.throws(() => new prefix.Unresolved<int>(), (e) => true);
+
+  try {
+    throw 'foo';
+  } on Unresolved catch (e) {
+  } catch (e) {
+    Expect.fail();
+  }
+  try {
+    throw 'foo';
+  } on Unresolved<int> catch (e) {
+  } catch (e) {
+    Expect.fail();
+  }
+  try {
+    throw 'foo';
+  } on prefix.Unresolved catch (e) {
+  } catch (e) {
+    Expect.fail();
+  }
+  try {
+    throw 'foo';
+  } on prefix.Unresolved<int> catch (e) {
+  } catch (e) {
+    Expect.fail();
+  }
+}
\ No newline at end of file
diff --git a/tests/language/new_expression_type_args_test.dart b/tests/language/new_expression_type_args_test.dart
index c454c17..3f298f4 100644
--- a/tests/language/new_expression_type_args_test.dart
+++ b/tests/language/new_expression_type_args_test.dart
@@ -10,7 +10,7 @@
 
   // OK when used within instance method, but not in static method.
   m3() => new A<T>();
-  static m4() => new A<T>(); /// 02: static type warning, dynamic type error
+  static m4() => new A<T>(); /// 02: static type warning
 }
 
 main() {
diff --git a/tests/language/no_such_method_dispatcher_test.dart b/tests/language/no_such_method_dispatcher_test.dart
index fa4e10d..ca115913 100644
--- a/tests/language/no_such_method_dispatcher_test.dart
+++ b/tests/language/no_such_method_dispatcher_test.dart
@@ -16,17 +16,6 @@
 
 class B extends A { }
 
-
-call_bar(x) => x.bar();
-
-testMessage() {
-  try {
-    call_bar(5);
-  } catch (e) {
-    Expect.isTrue(e.toString().indexOf("method not found") != -1);
-  }
-}
-
 class C {
   C(this.pos, this.named, this.posArgs, this.namedArgs);
   var pos, named;
@@ -69,9 +58,5 @@
     Expect.equals(123, c.bar(100, n1:101, n2:102));
     Expect.equals(123, c.bar(100, n2:102, n1:101));
   }
-
-  // Test NoSuchMethodError message.
-  for (var i = 0; i < 20; i++) testMessage();
-
 }
 
diff --git a/tests/language/no_such_method_error_message_vm_test.dart b/tests/language/no_such_method_error_message_vm_test.dart
new file mode 100644
index 0000000..481e3fe0
--- /dev/null
+++ b/tests/language/no_such_method_error_message_vm_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.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+// Test error message with noSuchMethodError: non-existent names
+// should result in a "method not found" message.
+
+call_bar(x) => x.bar();
+
+testMessage() {
+  try {
+    call_bar(5);
+  } catch (e) {
+    Expect.isTrue(e.toString().indexOf("method not found") != -1);
+  }
+}
+
+
+main() {
+  for (var i = 0; i < 20; i++) testMessage();
+}
+
diff --git a/tests/language/on_catch_malformed_type_test.dart b/tests/language/on_catch_malformed_type_test.dart
index ae5e043..a7e18ef 100644
--- a/tests/language/on_catch_malformed_type_test.dart
+++ b/tests/language/on_catch_malformed_type_test.dart
@@ -2,29 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Check that malformed types in on-catch are handled correctly, that is
-// catches all in production mode and throws a type error in checked mode.
-
-isCheckedMode() {
-  try {
-    String s = 1;
-    return false;
-  } on TypeError catch(e) {
-    return true;
-  }
-}
-
-checkTypeError(f()) {
-  if(isCheckedMode()) {
-    try {
-      f();
-      Expect.fail("Type error expected in checking mode");
-    } on TypeError catch(ok) {
-    }
-  } else {
-    f();
-  }
-}
+// Check that malformed types in on-catch are handled correctly, that is,
+// are treated as dynamic and thus catches all in bith production and checked
+// mode.
 
 catchUnresolvedBefore() {
   try {
@@ -43,8 +23,7 @@
     Expect.fail("This code shouldn't be executed");
   } on Unavailable catch(ex) {
     // This is tested before the catch block below.
-    // In production mode the test is always true, in checked mode
-    // it throws a type error.
+    // In both production and checked mode the test is always true.
   } on String catch(oks) {
     Expect.fail("This code shouldn't be executed");
   }
@@ -52,5 +31,5 @@
 
 main() {
   catchUnresolvedBefore();
-  checkTypeError(catchUnresolvedAfter);
+  catchUnresolvedAfter();
 }
diff --git a/tests/language/prefix16_test.dart b/tests/language/prefix16_test.dart
index 4fca6b0..98e4f0d 100644
--- a/tests/language/prefix16_test.dart
+++ b/tests/language/prefix16_test.dart
@@ -2,17 +2,16 @@
 // 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.
 //
-// Unresolved imported symbols are handled differently in production mode and
-// check modes. In this test, the function myFunc is malformed, because
+// Unresolved imported symbols are treated as dynamic
+// In this test, the function myFunc contains malformed types because
 // lib12.Library13 is not resolved.
-// In checked mode, the assignment type check throws a run time type error.
-// In production, no assignment type checks are performed.
 
 library Prefix16NegativeTest.dart;
 import "package:expect/expect.dart";
 import "library12.dart" as lib12;
 
 typedef lib12.Library13 myFunc(lib12.Library13 param);
+typedef lib12.Library13 myFunc2(lib12.Library13 param, int i);
 
 isCheckedMode() {
   try {
@@ -28,6 +27,7 @@
   {
     bool got_type_error = false;
     try {
+      // Malformed myFunc treated as (dynamic) => dynamic.
       myFunc i = 0;
     } on TypeError catch (error) {
       got_type_error = true;
@@ -36,14 +36,27 @@
     Expect.isTrue(got_type_error == isCheckedMode());
   }
   {
-    bool got_type_error = false;
     try {
-      // In production mode, malformed myFunc is mapped to (dynamic) => dynamic.
+      // Malformed myFunc treated as (dynamic) => dynamic.
       Expect.isTrue(((int x) => x) is myFunc);
     } on TypeError catch (error) {
-      got_type_error = true;
+      Expect.fail();
     }
-    // Type error in checked mode only.
-    Expect.isTrue(got_type_error == isCheckedMode());
+  }
+  {
+    try {
+      // Malformed myFunc2 treated as (dynamic,int) => dynamic.
+      Expect.isTrue(((int x, int y) => x) is myFunc2);
+    } on TypeError catch (error) {
+      Expect.fail();
+    }
+  }
+  {
+    try {
+      // Malformed myFunc2 treated as (dynamic,int) => dynamic.
+      Expect.isFalse(((int x, String y) => x) is myFunc2);
+    } on TypeError catch (error) {
+      Expect.fail();
+    }
   }
 }
diff --git a/tests/language/prefix9_negative_test.dart b/tests/language/prefix9_test.dart
similarity index 84%
rename from tests/language/prefix9_negative_test.dart
rename to tests/language/prefix9_test.dart
index 51df506..6b6bc39 100644
--- a/tests/language/prefix9_negative_test.dart
+++ b/tests/language/prefix9_test.dart
@@ -6,7 +6,7 @@
 import "package:expect/expect.dart";
 
 // Local variables can shadow type parameters and hence should result in an
-// error.
+// static warning.
 
 class Test<T> {
   Test.named(T this.fld);
@@ -21,6 +21,6 @@
 main() {
   Param test = new Param.named(10);
   var Param;
-  var i = new Test<Param>.named(test);  // This should be an error.
+  var i = new Test<Param>.named(test);  // This should be a static warning.
   Expect.equals(10, i.fld.fld);
 }
diff --git a/tests/language/try_catch_on_syntax_test.dart b/tests/language/try_catch_on_syntax_test.dart
index cf79fdd7..1b5e4a5 100644
--- a/tests/language/try_catch_on_syntax_test.dart
+++ b/tests/language/try_catch_on_syntax_test.dart
@@ -16,7 +16,6 @@
     try {
       throw new MyException1();
     }
-    on MyException3 catch (e) { } /// 01: compile-time error
     on on MyException2 catch (e) { } /// 02: compile-time error
     catch MyException2 catch (e) { } /// 03: compile-time error
     catch catch catch (e) { } /// 04: compile-time error
@@ -29,7 +28,7 @@
     } on MyException catch (e) {
       foo = 3;
     }
-    on UndefinedClass /// 07: compile-time error
+    on UndefinedClass /// 07: static type warning
     catch(e) { foo = 4; }
     Expect.equals(2, foo);
   }
diff --git a/tests/language/try_catch_syntax_test.dart b/tests/language/try_catch_syntax_test.dart
index 1e712c2..68b8aec 100644
--- a/tests/language/try_catch_syntax_test.dart
+++ b/tests/language/try_catch_syntax_test.dart
@@ -31,7 +31,7 @@
 
 testIllegalCatch() {
   try { } catch () { }              /// 07: compile-time error
-  try { } on MammaMia catch (e) { } /// 08: compile-time error
+  try { } on MammaMia catch (e) { } /// 08: static type warning
   try { } catch (var e) { }         /// 09: compile-time error
   try { } catch (final e) { }       /// 10: compile-time error
   try { } catch (int e) { }         /// 11: compile-time error
diff --git a/tests/language/type_parameter_test.dart b/tests/language/type_parameter_test.dart
index 7b0a996..7a39eeb 100644
--- a/tests/language/type_parameter_test.dart
+++ b/tests/language/type_parameter_test.dart
@@ -17,32 +17,30 @@
   }
 
   static
-  T /// 01: static type warning, dynamic type error
+  T /// 01: static type warning
   staticMethod(
-  T /// 02: static type warning, dynamic type error
+  T /// 02: static type warning
   a) {
     final
-    T /// 03: static type warning, dynamic type error
+    T /// 03: static type warning
     a = "not_null";
     print(a);
     return a;
   }
 
   static final
-  T /// 04: static type warning, dynamic type error
+  T /// 04: static type warning
   staticFinalField = "not_null";
 
   static const
-  // TODO(regis): Support 'compile-time type error' in test.dart and use below.
-  T /// 05: static type warning, compile-time error
+  T /// 05: static type warning
   staticConstField = "not_null";
 
   static not_null() => "not_null";
   static final
-  T /// 06: static type warning, dynamic type error
+  T /// 06: static type warning
   staticFinalField2 = not_null();
 
-
   // Assigning null to a malformed type is not a dynamic error.
   static
   T staticMethod2(T a) {
diff --git a/tests/language/type_variable_bounds_test.dart b/tests/language/type_variable_bounds_test.dart
index 30bf61c..612edb2 100644
--- a/tests/language/type_variable_bounds_test.dart
+++ b/tests/language/type_variable_bounds_test.dart
@@ -61,10 +61,10 @@
   new Box<String>().makeFoo();
 
   // Fisk does not exist.
-  new Box<Fisk>(); /// 07: static type warning, dynamic type error
+  new Box<Fisk>(); /// 07: static type warning
 
   // Too many type arguments.
-  new Box<Object, Object>(); /// 08: compile-time error
+  new Box<Object, Object>(); /// 08: static type warning
 
   // Fisk does not exist.
   Box<Fisk> box = null; /// 09: static type warning
diff --git a/tests/language/type_variable_scope2_test.dart b/tests/language/type_variable_scope2_test.dart
index 569daee..2a008f9 100644
--- a/tests/language/type_variable_scope2_test.dart
+++ b/tests/language/type_variable_scope2_test.dart
@@ -4,17 +4,8 @@
 
 import "package:expect/expect.dart";
 
-// Test that malformed type arguments are reported in checked mode.
-
-isCheckedMode() {
-  try {
-    var i = 1;
-    String s = i;
-    return false;
-  } catch (e) {
-    return true;
-  }
-}
+// Test that malformed type arguments treated as dynamic in both production and
+// checked mode.
 
 class Foo<T> {
   // T is not in scope for a static method.
@@ -24,13 +15,11 @@
 }
 
 main() {
-  bool got_type_error = false;
   try {
     Expect.isTrue(Foo.m() is Foo);
   } on TypeError catch (error) {
     print(error);
-    got_type_error = true;
+    // No type error in production nor checked mode.
+    Expect.fail();
   }
-  // Type error in checked mode only.
-  Expect.isTrue(got_type_error == isCheckedMode());
 }
diff --git a/tests/language/type_variable_scope_test.dart b/tests/language/type_variable_scope_test.dart
index 2cee662..cfc770d 100644
--- a/tests/language/type_variable_scope_test.dart
+++ b/tests/language/type_variable_scope_test.dart
@@ -8,11 +8,11 @@
   Foo() { }
 
   static
-  Foo<T> /// 00: dynamic type error
+  Foo<T> /// 00: static type warning
   m(
-    Foo<T> /// 01: dynamic type error
+    Foo<T> /// 01: static type warning
     f) {
-    Foo<T> x = new Foo<String>(); /// 02: dynamic type error
+    Foo<T> x = new Foo<String>(); /// 02: static type warning
     return new Foo<String>();
   }
 
@@ -22,14 +22,14 @@
   }
 
   // T is not in scope for a static field.
-  static Foo<T> f1; /// 03: dynamic type error
+  static Foo<T> f1; /// 03: static type warning
 
   static
-  Foo<T> /// 04: dynamic type error
+  Foo<T> /// 04: static type warning
   get f { return new Foo<String>(); }
 
   static void set f(
-                    Foo<T> /// 05: dynamic type error
+                    Foo<T> /// 05: static type warning
                     value) {}
 }
 
diff --git a/tests/language/wrong_number_type_arguments_test.dart b/tests/language/wrong_number_type_arguments_test.dart
index 8d84160..4cfa40b 100644
--- a/tests/language/wrong_number_type_arguments_test.dart
+++ b/tests/language/wrong_number_type_arguments_test.dart
@@ -15,29 +15,7 @@
 main() {
   foo = null;
   var bar = new Map
-  <String> /// 01: compile-time error
+  <String> /// 01: static type warning
   ();
-  testNonNullAssignment(); /// 02: continued
-}
-
-isCheckedMode() {
-  try {
-    var i = 1;
-    String s = i;
-    return false;
-  } catch (e) {
-    return true;
-  }
-}
-
-void testNonNullAssignment() {
-  bool got_type_error = false;
-  try {
-    baz = new Map();
-  } on TypeError catch (error) {
-    print(error);
-    got_type_error = true;
-  }
-  // Type error in checked mode only.
-  Expect.isTrue(got_type_error == isCheckedMode());
+  baz = new Map(); /// 02: continued
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 1dac7ed..faa078e 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -106,5 +106,4 @@
 *: Skip
 
 [ $arch == simmips ]
-typed_data/float32x4_shuffle_test: Skip # Issue 11851.
 convert/chunked_conversion_utf88_test: Pass, Slow # Issue 12025.
diff --git a/tests/lib/typed_data/float32x4_shuffle_test.dart b/tests/lib/typed_data/float32x4_shuffle_test.dart
index 5492259..21044bf 100644
--- a/tests/lib/typed_data/float32x4_shuffle_test.dart
+++ b/tests/lib/typed_data/float32x4_shuffle_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --use-far-branches
 
 // Library tag to be able to run in html test framework.
 library float32x4_shuffle_test;
@@ -1310,7 +1311,7 @@
 
 
 main() {
-  for (int i = 0; i < 4000; i++) {
+  for (int i = 0; i < 20; i++) {
     testShuffle0();
     testShuffle1();
     testShuffle2();
diff --git a/tests/standalone/double_smi_comparison_test.dart b/tests/standalone/double_smi_comparison_test.dart
new file mode 100644
index 0000000..1e18c46
--- /dev/null
+++ b/tests/standalone/double_smi_comparison_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Test correct comparison (equality and relational) when mixing double and
+// Smi arguments. We convert Smi to doubles and to the operation. This is
+// not correct in 64-bit mode where not every Smi can be converted to a
+// double without loss of precision.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+equalityFunc(a, b) => a == b;
+
+lessThanFunc(a, b) => a < b;
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    Expect.isFalse(equalityFunc(1.0, 4));
+    Expect.isTrue(lessThanFunc(1.0, 4));
+  }
+  Expect.isFalse(equalityFunc(3459045988797251776, 3459045988797251777));
+  Expect.isTrue(lessThanFunc(3459045988797251776, 3459045988797251777));
+}
diff --git a/tests/standalone/io/stdin_sync_test.dart b/tests/standalone/io/stdin_sync_test.dart
index a2ad75da18..f687837 100644
--- a/tests/standalone/io/stdin_sync_test.dart
+++ b/tests/standalone/io/stdin_sync_test.dart
@@ -10,7 +10,7 @@
   void test(String line, List<String> expected) {
     var script = join(dirname(Platform.script), "stdin_sync_script.dart");
     Process.start(Platform.executable,
-                  [script]..addAll(
+                  ["--checked", script]..addAll(
                       expected.map(stringify))).then((process) {
       process.stdin.write(line);
       process.stdin.close();
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 784c209..6622e10 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -113,6 +113,7 @@
 debugger/*: Skip # Do not run standalone vm debugger tests with dart2js.
 left_shift_bit_and_op_test: Skip # Integers exceed dart2js precision.
 pow_test: Skip # Precision > 53 bits.
+double_smi_comparison_test: Skip # Precision > 53 bits.
 http_launch_test: Skip
 53bit_overflow_test: Skip
 53bit_overflow_literal_test: Skip
diff --git a/tools/VERSION b/tools/VERSION
index 9288722..0e05268 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 6
-BUILD 12
-PATCH 1
+BUILD 13
+PATCH 0
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 47666a2..fbb0ee9 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -85,6 +85,8 @@
     'Window.location',
     'Window.open',
     'Window.requestAnimationFrame',
+    'Window.scrollX',
+    'Window.scrollY'
     # 'WorkerContext.indexedDB', # Workers
     ], dart2jsOnly=True)
 
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index cf2dd3a..4c78373 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -281,6 +281,13 @@
   void moveTo(Point p) {
     $dom_moveTo(p.x, p.y);
   }
+
+$if DART2JS
+  int get scrollX => JS('bool', '("scrollX" in #)', this) ? JS('int', 
+      '#.scrollX', this) : document.documentElement.scrollLeft;
+  int get scrollY => JS('bool', '("scrollY" in #)', this) ? JS('int', 
+      '#.scrollY', this) : document.documentElement.scrollTop;
+$endif
 }
 
 /**
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index c1e696c..cde8b9d 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -424,12 +424,15 @@
       'user_pref("dom.disable_open_during_load", false);';
   static const String disableDefaultCheck =
       'user_pref("browser.shell.checkDefaultBrowser", false);';
+  static const String disableScriptTimeLimit =
+      'user_pref("dom.max_script_run_time", 0);';
 
   Future _createPreferenceFile(var path) {
     var file = new File("${path.toString()}/user.js");
     var randomFile = file.openSync(mode: FileMode.WRITE);
     randomFile.writeStringSync(enablePopUp);
     randomFile.writeStringSync(disableDefaultCheck);
+    randomFile.writeStringSync(disableScriptTimeLimit);
     randomFile.close();
   }
 
diff --git a/tools/testing/perf_testing/run_perf_tests.py b/tools/testing/perf_testing/run_perf_tests.py
index 5ce3f85..67f724a 100755
--- a/tools/testing/perf_testing/run_perf_tests.py
+++ b/tools/testing/perf_testing/run_perf_tests.py
@@ -427,6 +427,8 @@
     """Check whether data should be captured for this platform/variant
     combination.
     """
+    if variant == 'dart_html' and platform != 'dartium':
+      return False
     if platform == 'dartium' and (variant == 'js' or variant == 'dart2js_html'):
       # Testing JavaScript performance on Dartium is a waste of time. Should be
       # same as Chrome.