Version 0.5.1.0 .

svn merge -r 21754:22069  https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@22072 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/.gitignore b/.gitignore
index 4da6b24..d82160d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
 /*.sln
 /*.suo
 /*.target.mk
+*.host.mk
 /*.vcproj
 /*.vcxproj
 /*.vcxproj.filters
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
index 03e009d..0f60a71 100644
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ b/compiler/java/com/google/dart/compiler/parser/DartParser.java
@@ -5628,7 +5628,7 @@
         && !Elements.isLibrarySource(source, "/crypto/crypto.dart")
         && !Elements.isLibrarySource(source, "/uri/uri.dart")
         && !Elements.isLibrarySource(source, "/utf/utf.dart")
-        && !Elements.isLibrarySource(source, "/typeddata/typeddata.dart")
+        && !Elements.isLibrarySource(source, "/typed_data/typed_data.dart")
         ) {
       super.reportError(position, errorCode);
     }
diff --git a/dart.gyp b/dart.gyp
index 6eea60b..1abc0ef 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -50,6 +50,7 @@
       'dependencies': [
         'runtime/dart-runtime.gyp:dart',
         'utils/compiler/compiler.gyp:dart2js',
+        'utils/pub/pub.gyp:pub',
         'analyzer',
         'compiler',
       ],
@@ -62,6 +63,7 @@
             'tools/create_sdk.py',
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot',
+            '<(SHARED_INTERMEDIATE_DIR)/pub.dart.snapshot',
             '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer',
             '<(PRODUCT_DIR)/dartanalyzer/dartanalyzer.jar',
           ],
@@ -72,8 +74,7 @@
             'python',
             'tools/create_sdk.py',
             '--sdk_output_dir', '<(PRODUCT_DIR)/dart-sdk',
-            '--utils_snapshot_location',
-             '<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot'
+            '--snapshot_location', '<(SHARED_INTERMEDIATE_DIR)/'
           ],
           'message': 'Creating SDK.',
         },
diff --git a/pkg/analyzer_experimental/pubspec.yaml b/pkg/analyzer_experimental/pubspec.yaml
index 5cd79cb..616b361 100644
--- a/pkg/analyzer_experimental/pubspec.yaml
+++ b/pkg/analyzer_experimental/pubspec.yaml
@@ -1,5 +1,4 @@
 name: analyzer_experimental
-version: 0.1.5
 author: Dart Team <misc@dartlang.org>
 description: Experimental static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/args/lib/args.dart b/pkg/args/lib/args.dart
index 1337b46..be1a6ef 100644
--- a/pkg/args/lib/args.dart
+++ b/pkg/args/lib/args.dart
@@ -6,6 +6,19 @@
  * This library lets you define parsers for parsing raw command-line arguments
  * into a set of options and values using [GNU][] and [POSIX][] style options.
  *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       args: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [args package on pub.dartlang.org](http://pub.dartlang.org/packages/args).
+ *
  * ## Defining options ##
  *
  * To use this library, you create an [ArgParser] object which will contain
@@ -209,6 +222,7 @@
  *
  * [posix]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
  * [gnu]: http://www.gnu.org/prep/standards/standards.html#Command_002dLine-Interfaces
+ * [pub]: http://pub.dartlang.org
  */
 library args;
 
diff --git a/pkg/http/lib/http.dart b/pkg/http/lib/http.dart
index 07457cd..dda24f24 100644
--- a/pkg/http/lib/http.dart
+++ b/pkg/http/lib/http.dart
@@ -4,6 +4,19 @@
 
 /// A composable, [Future]-based library for making HTTP requests.
 ///
+/// ## Installing ##
+///
+/// Use [pub][] to install this package. Add the following to your
+/// `pubspec.yaml` file.
+///
+///     dependencies:
+///       http: any
+///
+/// Then run `pub install`.
+///
+/// For more information, see the
+/// [http package on pub.dartlang.org](http://pub.dartlang.org/packages/http).
+///
 /// The easiest way to use this library is via the top-level functions. They
 /// allow you to make individual HTTP requests with minimal hassle:
 ///
@@ -50,10 +63,12 @@
 ///         return _inner.send(request);
 ///       }
 ///     }
+///
+/// [pub]: http://pub.dartlang.org
 library http;
 
 import 'dart:async';
-import 'dart:typeddata';
+import 'dart:typed_data';
 import 'dart:uri';
 
 import 'src/client.dart';
diff --git a/pkg/http/lib/src/base_client.dart b/pkg/http/lib/src/base_client.dart
index eb9fca7..df6e730 100644
--- a/pkg/http/lib/src/base_client.dart
+++ b/pkg/http/lib/src/base_client.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:typeddata';
+import 'dart:typed_data';
 import 'dart:uri';
 
 import 'base_request.dart';
diff --git a/pkg/http/lib/src/byte_stream.dart b/pkg/http/lib/src/byte_stream.dart
index f2c6a0b..eba08d4 100644
--- a/pkg/http/lib/src/byte_stream.dart
+++ b/pkg/http/lib/src/byte_stream.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:typeddata';
+import 'dart:typed_data';
 
 import 'utils.dart';
 
diff --git a/pkg/http/lib/src/client.dart b/pkg/http/lib/src/client.dart
index 302b8c7..bf214c4 100644
--- a/pkg/http/lib/src/client.dart
+++ b/pkg/http/lib/src/client.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:typeddata';
+import 'dart:typed_data';
 
 import 'base_client.dart';
 import 'base_request.dart';
diff --git a/pkg/http/lib/src/request.dart b/pkg/http/lib/src/request.dart
index 9d68508..20da3c1 100644
--- a/pkg/http/lib/src/request.dart
+++ b/pkg/http/lib/src/request.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:typeddata';
+import 'dart:typed_data';
 import 'dart:uri';
 
 import 'base_request.dart';
diff --git a/pkg/http/lib/src/response.dart b/pkg/http/lib/src/response.dart
index 2376f72..c036fe9 100644
--- a/pkg/http/lib/src/response.dart
+++ b/pkg/http/lib/src/response.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async';
 import 'dart:io';
-import 'dart:typeddata';
+import 'dart:typed_data';
 
 import 'base_request.dart';
 import 'base_response.dart';
diff --git a/pkg/http/lib/src/utils.dart b/pkg/http/lib/src/utils.dart
index 26b8d0f..d99b9be 100644
--- a/pkg/http/lib/src/utils.dart
+++ b/pkg/http/lib/src/utils.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 import 'dart:crypto';
 import 'dart:io';
-import 'dart:typeddata';
+import 'dart:typed_data';
 import 'dart:uri';
 import 'dart:utf';
 
diff --git a/pkg/http/test/utils.dart b/pkg/http/test/utils.dart
index ab3f5f6..25bb92e 100644
--- a/pkg/http/test/utils.dart
+++ b/pkg/http/test/utils.dart
@@ -27,7 +27,7 @@
 
 /// Starts a new HTTP server.
 Future startServer() {
-  return SafeHttpServer.bind("127.0.0.1", 0).then((s) {
+  return SafeHttpServer.bind("localhost", 0).then((s) {
     _server = s;
     s.listen((request) {
       var path = request.uri.path;
@@ -108,8 +108,10 @@
 
 /// Stops the current HTTP server.
 void stopServer() {
-  _server.close();
-  _server = null;
+  if (_server != null) {
+    _server.close();
+    _server = null;
+  }
 }
 
 /// Removes eight spaces of leading indentation from a multiline string.
diff --git a/pkg/intl/lib/date_format.dart b/pkg/intl/lib/date_format.dart
index 88b54d66..bfc9244 100644
--- a/pkg/intl/lib/date_format.dart
+++ b/pkg/intl/lib/date_format.dart
@@ -16,11 +16,14 @@
  * date-time strings under certain locales. Date elements that vary across
  * locales include month name, weekname, field, order, etc.
  *
- * The actual date for the locales must be obtained. This can currently be done
- * in one of three ways, determined by which library you import. If you only
- * want to use en_US formatting you can use it directly, as a copy of that
- * locale is hard-coded into the formatter. In all other cases,
- * the [initializeDateFormatting] method must be called and will return a future
+ * Formatting dates in the default "en_US" format does not require any
+ * initialization. e.g.
+ *       print(new DateFormat.yMMMd().format(new Date.now()));
+ *
+ * But for other locales, the formatting data for the locale must be
+ * obtained. This can currently be done
+ * in one of three ways, determined by which library you import. In all cases,
+ * the "initializeDateFormatting" method must be called and will return a future
  * that is complete once the locale data is available. The result of the future
  * isn't important, but the data for that locale is available to the date
  * formatting and parsing once it completes.
@@ -28,7 +31,7 @@
  * The easiest option is that the data may be available locally, imported in a
  * library that contains data for all the locales.
  *       import 'package:intl/date_symbol_data_local.dart';
- *       initializeDateFormatting("en_US", null).then((_) => runMyCode());
+ *       initializeDateFormatting("fr_FR", null).then((_) => runMyCode());
  *
  * If we are running outside of a browser, we may want to read the data
  * from files in the file system.
@@ -473,7 +476,7 @@
    * A series of regular expressions used to parse a format string into its
    * component fields.
    */
-  static List<Pattern> _matchers = [
+  static List<RegExp> _matchers = [
       // Quoted String - anything between single quotes, with escaping
       //   of single quotes by doubling them.
       // e.g. in the pattern "hh 'o''clock'" will match 'o''clock'
diff --git a/pkg/intl/lib/extract_messages.dart b/pkg/intl/lib/extract_messages.dart
index fb57341..47bcbbbeb 100755
--- a/pkg/intl/lib/extract_messages.dart
+++ b/pkg/intl/lib/extract_messages.dart
@@ -32,6 +32,12 @@
 import 'package:intl/src/intl_message.dart';
 
 /**
+ * If this is true, print warnings for skipped messages. Otherwise, warnings
+ * are suppressed.
+ */
+bool suppressWarnings = false;
+
+/**
  * Parse the dart program represented in [sourceCode] and return a Map from
  * message names to [IntlMessage] instances. The [origin] is a string
  * describing where the source came from, and is used in error messages.
@@ -195,9 +201,9 @@
   void addIntlMessage(MethodInvocation node) {
     if (!looksLikeIntlMessage(node)) return;
     var reason = checkValidity(node);
-    if (!(reason == null)) {
+    if (reason != null && !suppressWarnings) {
       print("Skipping invalid Intl.message invocation\n    <$node>");
-      print("  reason: $reason");
+      print("    reason: $reason");
       reportErrorLocation(node);
       return;
     }
@@ -227,11 +233,11 @@
   }
 
   void reportErrorLocation(ASTNode node) {
-    if (origin != null) print("from $origin");
+    if (origin != null) print("    from $origin");
     LineInfo info = root.lineInfo;
     if (info != null) {
       LineInfo_Location line = info.getLocation(node.offset);
-      print("line: ${line.lineNumber}, column: ${line.columnNumber}");
+      print("    line: ${line.lineNumber}, column: ${line.columnNumber}");
     }
   }
 }
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index 26fb304..c40d1f6 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -47,6 +47,12 @@
 List<String> allLocales = [];
 
 /**
+ * If we have more than one set of messages to generate in a particular
+ * directory we may want to prefix some to distinguish them.
+ */
+String generatedFilePrefix = '';
+
+/**
  * This represents a message and its translation. We assume that the translation
  * has some identifier that allows us to figure out the original message it
  * corresponds to, and that it may want to transform the translated text in
@@ -101,13 +107,15 @@
   result.write(entries.join(",\n"));
   result.write("\n  };\n}");
 
-  var output = new File(path.join(targetDir, "messages_$locale.dart"));
+  var output = new File(path.join(targetDir,
+      "${generatedFilePrefix}messages_$locale.dart"));
   output.writeAsStringSync(result.toString());
 }
 
 /**
- * This returns the mostly constant string used in [generated] for the
- * beginning of the file, parameterized by [locale].
+ * This returns the mostly constant string used in
+ * [generateIndividualMessageFile] for the beginning of the file,
+ * parameterized by [locale].
  */
 String prologue(String locale) => """
 /**
@@ -136,7 +144,7 @@
   var output = new StringBuffer();
   output.write(mainPrologue);
   for (var each in allLocales) {
-    var baseFile = 'messages_$each.dart';
+    var baseFile = '${generatedFilePrefix}messages_$each.dart';
     var file = importForGeneratedFile(baseFile);
     output.write("import '$file' as ${asLibraryName(each)};\n");
   }
@@ -172,7 +180,7 @@
 """;
 
 /**
- * Constant string used in [generateMainImportfile] as the end of the file.
+ * Constant string used in [generateMainImportFile] as the end of the file.
  */
 const closing = """
     default: return null;
diff --git a/pkg/intl/lib/intl.dart b/pkg/intl/lib/intl.dart
index 9a9c529..e0e32ee 100644
--- a/pkg/intl/lib/intl.dart
+++ b/pkg/intl/lib/intl.dart
@@ -7,12 +7,27 @@
  * message formatting and replacement, date and number formatting and parsing,
  * and utilities for working with Bidirectional text.
  *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       intl: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [intl package on pub.dartlang.org](http://pub.dartlang.org/packages/intl).
+ *
  * For things that require locale or other data, there are multiple different
  * ways of making that data available, which may require importing different
  * libraries. See the class comments for more details.
  *
  * There is also a simple example application that can be found in the
  * `example/basic` directory.
+ *
+ * [pub]: http://pub.dartlang.org
  */
 library intl;
 
@@ -241,7 +256,7 @@
    *
    * In either case, the purpose of this is to delay calling [message_function]
    * until the proper locale has been set. This returns the result of calling
-   * [msg_function], which could be of an arbitrary type.
+   * [message_function], which could be of an arbitrary type.
    */
   static withLocale(String locale, Function message_function) {
     // We have to do this silliness because Locale is not known at compile time,
diff --git a/pkg/intl/lib/message_lookup_by_library.dart b/pkg/intl/lib/message_lookup_by_library.dart
index e3d1fb7..fde0551 100644
--- a/pkg/intl/lib/message_lookup_by_library.dart
+++ b/pkg/intl/lib/message_lookup_by_library.dart
@@ -6,7 +6,7 @@
  * Message/plural format library with locale support. This can have different
  * implementations based on the mechanism for finding the localized versions
  * of messages. This version expects them to be in a library named e.g.
- * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which
+ * 'messages_en_US'. The prefix is set in the "initializeMessages" call, which
  * must be made for a locale before any lookups can be done.
  *
  * See Intl class comment or `tests/message_format_test.dart` for more examples.
diff --git a/pkg/intl/lib/number_format.dart b/pkg/intl/lib/number_format.dart
index 1745178..3f642ca 100644
--- a/pkg/intl/lib/number_format.dart
+++ b/pkg/intl/lib/number_format.dart
@@ -562,7 +562,7 @@
     return true;
   }
 
-  /** Variables used in [parseTrunk] and [parseTrunkCharacter]. */
+  /** Variables used in [_parseTrunk] and [parseTrunkCharacter]. */
   var decimalPos;
   var digitLeftCount;
   var zeroDigitCount;
diff --git a/pkg/intl/test/data_directory.dart b/pkg/intl/test/data_directory.dart
index de16e00..4a003bf 100644
--- a/pkg/intl/test/data_directory.dart
+++ b/pkg/intl/test/data_directory.dart
@@ -27,7 +27,7 @@
   /**
    * A helper function that returns false (indicating we should stop iterating)
    * if the argument to the previous call was 'intl' and also sets
-   * the outer scope [foundIntl].
+   * the outer scope [foundIntlDir].
    */
   bool checkForIntlDir(String each) {
     if (foundIntlDir) return false;
diff --git a/pkg/intl/test/date_time_format_test_core.dart b/pkg/intl/test/date_time_format_test_core.dart
index a4fb30d..7e007e4 100644
--- a/pkg/intl/test/date_time_format_test_core.dart
+++ b/pkg/intl/test/date_time_format_test_core.dart
@@ -124,7 +124,7 @@
  * Exercise all of the formats we have explicitly defined on a particular
  * locale. [expectedResults] is a map from ICU format names to the
  * expected result of formatting [date] according to that format in
- * [locale].
+ * [localeName].
  */
 testLocale(String localeName, Map expectedResults, DateTime date) {
   var intl = new Intl(localeName);
diff --git a/pkg/intl/test/message_extraction/extract_to_json.dart b/pkg/intl/test/message_extraction/extract_to_json.dart
index 7d719ee..5b6f316 100644
--- a/pkg/intl/test/message_extraction/extract_to_json.dart
+++ b/pkg/intl/test/message_extraction/extract_to_json.dart
@@ -25,10 +25,19 @@
 import 'dart:json' as json;
 import 'package:pathos/path.dart' as path;
 import 'package:intl/src/intl_message.dart';
-import 'find_output_directory.dart';
+import 'package:args/args.dart';
 
 main() {
   var args = new Options().arguments;
+  var targetDir;
+  var parser = new ArgParser();
+  parser.addFlag("suppress-warnings", defaultsTo: false,
+      callback: (x) => suppressWarnings = x);
+
+  void setTargetDir(value) => targetDir = value;
+
+  parser.addOption("output-dir", defaultsTo: '.', callback: setTargetDir);
+  parser.parse(args);
   if (args.length == 0) {
     print('Usage: extract_to_json [--output-dir=<dir>] [files.dart]');
     print('Accepts Dart files and produces intl_messages.json');
@@ -39,7 +48,6 @@
     var messages = parseFile(new File(arg));
     messages.forEach((k, v) => allMessages.add(toJson(v)));
   }
-  var targetDir = findOutputDirectory(args);
   var file = new File(path.join(targetDir, 'intl_messages.json'));
   file.writeAsStringSync(json.stringify(allMessages));
 }
diff --git a/pkg/intl/test/message_extraction/find_output_directory.dart b/pkg/intl/test/message_extraction/find_output_directory.dart
deleted file mode 100644
index bb62389..0000000
--- a/pkg/intl/test/message_extraction/find_output_directory.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * A shared library for finding the valu eof the --output-dir parameter
- * which all of these programs use.
- */
-library find_output_directory;
-
-const directiveName = '--output-dir=';
-
-_asString(list) => new String.fromCharCodes(list);
-
-findOutputDirectory(List<String> args) {
-  var directive = args.firstWhere(
-      (x) => x.contains(directiveName),
-      orElse: () => null);
-  if (directive == null) return '.';
-  var file = directive.codeUnits.skip(directiveName.length);
-  return _asString(file);
-}
-
diff --git a/pkg/intl/test/message_extraction/generate_from_json.dart b/pkg/intl/test/message_extraction/generate_from_json.dart
index 7bbb878..0759507 100644
--- a/pkg/intl/test/message_extraction/generate_from_json.dart
+++ b/pkg/intl/test/message_extraction/generate_from_json.dart
@@ -22,7 +22,7 @@
 import 'package:intl/generate_localized.dart';
 import 'dart:json' as json;
 import 'package:pathos/path.dart' as path;
-import 'find_output_directory.dart';
+import 'package:args/args.dart';
 
 /**
  * Keeps track of all the messages we have processed so far, keyed by message
@@ -31,19 +31,29 @@
 Map<String, IntlMessage> messages;
 
 main() {
+  var targetDir;
   var args = new Options().arguments;
+  var parser = new ArgParser();
+  parser.addFlag("suppress-warnings", defaultsTo: false,
+      callback: (x) => suppressWarnings = x);
+  parser.addOption("output-dir", defaultsTo: '.',
+      callback: (x) => targetDir = x);
+  parser.addOption("generated-file-prefix", defaultsTo: '',
+      callback: (x) => generatedFilePrefix = x);
+  parser.parse(args);
   if (args.length == 0) {
-    print('Usage: generate_from_json [--output-dir=<dir>] [originalFiles.dart]'
-        ' [translationFiles.json]');
+    print('Usage: generate_from_json [--output-dir=<dir>]'
+        ' [generated-file-prefix=<prefix>] file1.dart file2.dart ...'
+        ' outputFile.json');
     exit(0);
   }
 
-  var targetDir = findOutputDirectory(args);
-  var isDart = new RegExp(r'\.dart');
-  var isJson = new RegExp(r'\.json');
-  var dartFiles = args.where(isDart.hasMatch).toList();
-  var jsonFiles = args.where(isJson.hasMatch).toList();
+  var dartFiles = args.where((x) => x.endsWith("dart")).toList();
+  var jsonFiles = args.where((x) => x.endsWith(".json")).toList();
 
+  // We're re-parsing the original files to find the corresponding messages,
+  // so if there are warnings extracting the messages, suppress them.
+  suppressWarnings = true;
   var allMessages = dartFiles.map((each) => parseFile(new File(each)));
 
   messages = new Map();
@@ -51,11 +61,12 @@
     eachMap.forEach((key, value) => messages[key] = value);
   }
   for (var arg in jsonFiles) {
-    var file = new File(path.join(targetDir, arg));
-    var translations = generateLocaleFile(file, targetDir);
+    var file = new File(arg);
+    generateLocaleFile(file, targetDir);
   }
 
-  var mainImportFile = new File(path.join(targetDir, 'messages_all.dart'));
+  var mainImportFile = new File(path.join(targetDir,
+      '${generatedFilePrefix}messages_all.dart'));
   mainImportFile.writeAsStringSync(generateMainImportFile());
 }
 
diff --git a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
index 3f7977c..f936f11 100644
--- a/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
+++ b/pkg/intl/test/message_extraction/make_hardcoded_translation.dart
@@ -13,7 +13,7 @@
 import 'dart:io';
 import 'dart:json' as json;
 import 'package:pathos/path.dart' as path;
-import 'find_output_directory.dart';
+import 'package:args/args.dart';
 
 /** A list of the French translations that we will produce. */
 var french = {
@@ -95,8 +95,11 @@
         '[originalFile.dart]');
     exit(0);
   }
+  var parser = new ArgParser();
+  parser.addOption("output-dir", defaultsTo: '.',
+      callback: (value) => targetDir = value);
+  parser.parse(args);
 
-  targetDir = findOutputDirectory(args);
   var fileArgs = args.where((x) => x.contains('.json'));
 
   var messages = json.parse(new File(fileArgs.first).readAsStringSync());
diff --git a/pkg/intl/test/message_extraction/message_extraction_test.dart b/pkg/intl/test/message_extraction/message_extraction_test.dart
index 92aa3e6..24f8fc5 100644
--- a/pkg/intl/test/message_extraction/message_extraction_test.dart
+++ b/pkg/intl/test/message_extraction/message_extraction_test.dart
@@ -48,8 +48,13 @@
  * Translate a file path into this test directory, regardless of the
  * working directory.
  */
-String dir([String s]) =>
-    path.join(intlDirectory, 'test', 'message_extraction', s);
+String dir([String s]) {
+  if (s != null && s.startsWith("--")) { // Don't touch command-line options.
+    return s;
+  } else {
+   return path.join(intlDirectory, 'test', 'message_extraction', s);
+  }
+}
 
 main() {
   test("Test round trip message extraction, translation, code generation, "
@@ -68,8 +73,8 @@
 
 void deleteGeneratedFiles() {
   var files = [dir('intl_messages.json'), dir('translation_fr.json'),
-      dir('messages_fr.dart'), dir('messages_de_DE.dart'),
-      dir('translation_de_DE.json'), dir('messages_all.dart')];
+      dir('foo_messages_fr.dart'), dir('foo_messages_de_DE.dart'),
+      dir('translation_de_DE.json'), dir('foo_messages_all.dart')];
   files.map((name) => new File(name)).forEach((x) {
     if (x.existsSync()) x.deleteSync();});
 }
@@ -107,7 +112,7 @@
 
 Future<ProcessResult> extractMessages(ProcessResult previousResult) => run(
     previousResult,
-    ['extract_to_json.dart', 'sample_with_messages.dart',
+    ['extract_to_json.dart', '--suppress-warnings', 'sample_with_messages.dart',
         'part_of_sample_with_messages.dart']);
 
 Future<ProcessResult> generateTranslationFiles(ProcessResult previousResult) =>
@@ -118,7 +123,8 @@
 Future<ProcessResult> generateCodeFromTranslation(ProcessResult previousResult)
     => run(
         previousResult,
-        ['generate_from_json.dart', 'sample_with_messages.dart',
+        ['generate_from_json.dart', '--generated-file-prefix=foo_',
+         'sample_with_messages.dart',
              'part_of_sample_with_messages.dart', 'translation_fr.json',
              'translation_de_DE.json' ]);
 
@@ -135,9 +141,8 @@
 
   var output = results.stdout;
   var lines = output.split("\n");
-  // If it looks like these are CRLF delimited, then use that. Wish strings
-  // just implemented last.
-  if (lines.first.codeUnits.last == "\r".codeUnits.first) {
+  // If it looks like these are CRLF delimited, then use that.
+  if (lines.first.endsWith("\r")) {
     lines = output.split("\r\n");
   }
   lineIterator = lines.iterator..moveNext();
diff --git a/pkg/intl/test/message_extraction/sample_with_messages.dart b/pkg/intl/test/message_extraction/sample_with_messages.dart
index ada1d79..a0e334c 100644
--- a/pkg/intl/test/message_extraction/sample_with_messages.dart
+++ b/pkg/intl/test/message_extraction/sample_with_messages.dart
@@ -13,7 +13,7 @@
 import "package:intl/message_lookup_by_library.dart";
 import "dart:async";
 import "package:intl/src/intl_helpers.dart";
-import "messages_all.dart";
+import "foo_messages_all.dart";
 
 part 'part_of_sample_with_messages.dart';
 
diff --git a/pkg/logging/lib/logging.dart b/pkg/logging/lib/logging.dart
index 222ff1e..94bf5f3 100644
--- a/pkg/logging/lib/logging.dart
+++ b/pkg/logging/lib/logging.dart
@@ -6,6 +6,22 @@
  * Provides APIs for debugging and error logging. This library introduces
  * abstractions similar to those used in other languages, such as the Closure JS
  * Logger and java.util.logging.Logger.
+ *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       logging: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [logging package on pub.dartlang.org][pkg].
+ *
+ * [pub]: http://pub.dartlang.org
+ * [pkg]: http://pub.dartlang.org/packages/logging
  */
 library logging;
 
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index ba49c2b..c86e377 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -6,6 +6,21 @@
  * This library contains the definitions of annotations that provide additional
  * semantic information about the program being annotated. These annotations are
  * intended to be used by tools to provide a better user experience.
+ *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       meta: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [meta package on pub.dartlang.org](http://pub.dartlang.org/packages/meta).
+ *
+ * [pub]: http://pub.dartlang.org
  */
 library meta;
 
diff --git a/pkg/oauth2/lib/oauth2.dart b/pkg/oauth2/lib/oauth2.dart
index 7fdb205..592589d 100644
--- a/pkg/oauth2/lib/oauth2.dart
+++ b/pkg/oauth2/lib/oauth2.dart
@@ -6,6 +6,19 @@
 /// behalf of a user, and making authorized HTTP requests with the user's OAuth2
 /// credentials.
 ///
+/// ## Installing ##
+///
+/// Use [pub][] to install this package. Add the following to your
+/// `pubspec.yaml` file.
+///
+///     dependencies:
+///       oauth2: any
+///
+/// Then run `pub install`.
+///
+/// For more information, see the
+/// [oauth2 package on pub.dartlang.org][pkg].
+///
 /// OAuth2 allows a client (the program using this library) to access and
 /// manipulate a resource that's owned by a resource owner (the end user) and
 /// lives on a remote server. The client directs the resource owner to an
@@ -100,6 +113,9 @@
 ///         }).then((file) => file.close()).then((_) => result);
 ///       });
 ///     }).then(print);
+///
+/// [pub]: http://pub.dartlang.org
+/// [pkg]: http://pub.dartlang.org/packages/oauth2
 library oauth2;
 
 export 'src/authorization_code_grant.dart';
diff --git a/pkg/pathos/lib/path.dart b/pkg/pathos/lib/path.dart
index 5136871..8d83077 100644
--- a/pkg/pathos/lib/path.dart
+++ b/pkg/pathos/lib/path.dart
@@ -3,6 +3,22 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// A comprehensive, cross-platform path manipulation library.
+///
+/// ## Installing ##
+///
+/// Use [pub][] to install this package. Add the following to your
+/// `pubspec.yaml` file.
+///
+///     dependencies:
+///       pathos: any
+///
+/// Then run `pub install`.
+///
+/// For more information, see the
+/// [pathos package on pub.dartlang.org][pkg].
+///
+/// [pub]: http://pub.dartlang.org
+/// [pkg]: http://pub.dartlang.org/packages/pathos
 library path;
 
 import 'dart:io' as io;
diff --git a/pkg/pkg.status b/pkg/pkg.status
index d638e12..af3a270 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -2,9 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-serialization/test/*: Skip # http://dartbug.com/9894
-
-
 # Run this test manually to verify that the fixnum library produces
 # the same results as native ints on a set of directed and random inputs.
 # Skip it when running automated tests because it times out.  This
@@ -31,9 +28,8 @@
 webdriver/test/webdriver_test: Skip
 
 
-[ $compiler == dart2js && $runtime == drt ]
-unittest/test/unittest_test: Pass, Fail, Crash # Bug in v8, http://dartbug.com/9407
-
+[ $runtime == d8 || $runtime == jsshell ]
+unittest/test/unittest_test: Pass, Fail # http://dartbug.com/10109
 
 [$compiler == dart2dart]
 *: Skip
@@ -129,9 +125,6 @@
 unittest/test/mock_test: Fail
 unittest/test/mock_regexp_negative_test: Fail
 
-[ $compiler == dart2js && $csp && $runtime == drt ]
-unittest/test/unittest_test: Pass, Fail, Crash # Bug in v8, http://dartbug.com/9407
-
 [ $compiler == none && $runtime == drt ]
 dartdoc/test/dartdoc_test: Skip # See dartbug.com/4541.
 
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index 6e7b754..05beb14 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -7,6 +7,19 @@
 // TODO(nweiz): Port the non-Pub-specific scheduled test libraries from Pub.
 /// A package for writing readable tests of asynchronous behavior.
 ///
+/// ## Installing ##
+///
+/// Use [pub][] to install this package. Add the following to your
+/// `pubspec.yaml` file.
+///
+///     dependencies:
+///       scheduled_test: any
+///
+/// Then run `pub install`.
+///
+/// For more information, see the
+/// [scheduled_test package on pub.dartlang.org][pkg].
+///
 /// This package works by building up a queue of asynchronous tasks called a
 /// "schedule", then executing those tasks in order. This allows the tests to
 /// read like synchronous, linear code, despite executing asynchronously.
@@ -171,6 +184,9 @@
 /// If a single task might take a long time, you can also manually tell the
 /// [Schedule] that it's making progress by calling [Schedule.heartbeat], which
 /// will reset the timeout whenever it's called.
+///
+/// [pub]: http://pub.dartlang.org
+/// [pkg]: http://pub.dartlang.org/packages/scheduled_test
 library scheduled_test;
 
 import 'dart:async';
@@ -242,10 +258,11 @@
 /// Creates a new named group of tests. This has the same semantics as
 /// [unittest.group].
 void group(String description, void body()) {
+  _ensureInitialized();
+  _ensureSetUpForTopLevel();
   unittest.group(description, () {
     var wasInGroup = _inGroup;
     _inGroup = true;
-    _setUpScheduledTest();
     body();
     _inGroup = wasInGroup;
   });
@@ -295,20 +312,38 @@
 /// Registers callbacks for [unittest.setUp] and [unittest.tearDown] that set up
 /// and tear down the scheduled test infrastructure.
 void _setUpScheduledTest([void setUpFn()]) {
-  if (!_inGroup) _setUpForTopLevel = true;
-
-  unittest.setUp(() {
-    if (currentSchedule != null) {
-      throw new StateError('There seems to be another scheduled test '
-          'still running.');
-    }
-    _currentSchedule = new Schedule();
-    _setUpFn = setUpFn;
-  });
-
-  unittest.tearDown(() {
-    _currentSchedule = null;
-  });
+  if (!_inGroup) {
+    _setUpForTopLevel = true;
+    unittest.setUp(() {
+      if (currentSchedule != null) {
+        throw new StateError('There seems to be another scheduled test '
+            'still running.');
+      }
+      _currentSchedule = new Schedule();
+      if (_setUpFn != null) {
+        var parentFn = _setUpFn;
+        _setUpFn = () { parentFn(); setUpFn(); };
+      } else {
+        _setUpFn = setUpFn;
+      }
+    });
+ 
+    unittest.tearDown(() {
+      _currentSchedule = null;
+      _setUpFn = null;
+    });
+  } else {
+    unittest.setUp(() {
+      if (currentSchedule == null) {
+        throw new StateError('No schedule allocated.');
+      } else if (_setUpFn != null) {
+        var parentFn = _setUpFn;
+        _setUpFn = () { parentFn(); setUpFn(); };
+      } else {
+        _setUpFn = setUpFn;
+      }
+    });
+  }
 }
 
 /// Ensures that the global configuration for `scheduled_test` has been
diff --git a/pkg/scheduled_test/lib/src/schedule.dart b/pkg/scheduled_test/lib/src/schedule.dart
index ecdf4dd..d5eb9af 100644
--- a/pkg/scheduled_test/lib/src/schedule.dart
+++ b/pkg/scheduled_test/lib/src/schedule.dart
@@ -62,7 +62,6 @@
   ScheduleState get state => _state;
   ScheduleState _state = ScheduleState.SET_UP;
 
-  // TODO(nweiz): make this a read-only view once issue 8321 is fixed.
   /// Errors thrown by the task queues.
   ///
   /// When running tasks in [tasks], this will always be empty. If an error
@@ -74,11 +73,13 @@
   ///
   /// Any out-of-band callbacks that throw errors will also have those errors
   /// added to this list.
-  final errors = <ScheduleError>[];
+  List<ScheduleError> get errors =>
+      new UnmodifiableListView<ScheduleError>(_errors);
+  final _errors = <ScheduleError>[];
 
-  // TODO(nweiz): make this a read-only view once issue 8321 is fixed.
   /// Additional debugging info registered via [addDebugInfo].
-  final debugInfo = <String>[];
+  List<String> get debugInfo => new UnmodifiableListView<String>(_debugInfo);
+  final _debugInfo = <String>[];
 
   /// The task queue that's currently being run. One of [tasks], [onException],
   /// or [onComplete]. This starts as [tasks], and can only be `null` after the
@@ -212,7 +213,7 @@
   /// fails. Unlike [signalError], this won't cause the test to fail, nor will
   /// it short-circuit the current [TaskQueue]; it's just useful for providing
   /// additional information that may not fit cleanly into an existing error.
-  void addDebugInfo(String info) => debugInfo.add(info);
+  void addDebugInfo(String info) => _debugInfo.add(info);
 
   /// Notifies the schedule of an error that occurred in a task or out-of-band
   /// callback after the appropriate queue has timed out. If this schedule is
@@ -318,7 +319,7 @@
   /// [ScheduleError].
   void _addError(error) {
     if (error is ScheduleError && errors.contains(error)) return;
-    errors.add(new ScheduleError.from(this, error));
+    _errors.add(new ScheduleError.from(this, error));
   }
 }
 
@@ -346,9 +347,8 @@
 
 /// A queue of asynchronous tasks to execute in order.
 class TaskQueue {
-  // TODO(nweiz): make this a read-only view when issue 8321 is fixed.
   /// The tasks in the queue.
-  Iterable<Task> get contents => _contents;
+  List<Task> get contents => new UnmodifiableListView<Task>(_contents);
   final _contents = new Queue<Task>();
 
   /// The name of the queue, for debugging purposes.
@@ -377,10 +377,10 @@
   /// Whether to stop running after the current task.
   bool _aborted = false;
 
-  // TODO(nweiz): make this a read-only view when issue 8321 is fixed.
   /// The descriptions of all callbacks that are blocking the completion of
   /// [this].
-  Iterable<String> get pendingCallbacks => _pendingCallbacks;
+  List<String> get pendingCallbacks =>
+      new UnmodifiableListView<String>(_pendingCallbacks);
   final _pendingCallbacks = new Queue<String>();
 
   /// A completer that will be completed once [_pendingCallbacks] becomes empty
diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
index e77f531..2dfc127 100644
--- a/pkg/scheduled_test/lib/src/task.dart
+++ b/pkg/scheduled_test/lib/src/task.dart
@@ -27,10 +27,10 @@
   /// The queue to which this [Task] belongs.
   final TaskQueue queue;
 
-  // TODO(nweiz): make this a read-only view when issue 8321 is fixed.
   /// Child tasks that have been spawned while running this task. This will be
   /// empty if this task is a nested task.
-  final children = new Queue<Task>();
+  List<Task> get children => new UnmodifiableListView(_children);
+  final _children = new Queue<Task>();
 
   /// A [FutureGroup] that will complete once all current child tasks are
   /// finished running. This will be null if no child tasks are currently
@@ -110,7 +110,7 @@
   /// finished.
   Future runChild(fn(), String description) {
     var task = new Task._child(fn, description, this);
-    children.add(task);
+    _children.add(task);
     if (_childGroup == null || _childGroup.completed) {
       _childGroup = new FutureGroup();
     }
diff --git a/pkg/scheduled_test/test/scheduled_test/set_up_test.dart b/pkg/scheduled_test/test/scheduled_test/set_up_test.dart
index 0d83d20..5462f51 100644
--- a/pkg/scheduled_test/test/scheduled_test/set_up_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/set_up_test.dart
@@ -79,7 +79,7 @@
     test('test 2', () => expect(onExceptionRun, isTrue));
   }, passing: ['test 2']);
 
-  expectTestsPass("setUp doesn't apply to child groups", () {
+  expectTestsPass("setUp applies to child groups", () {
     var setUpRun = false;
     setUp(() {
       setUpRun = true;
@@ -94,7 +94,7 @@
 
     group('group', () {
       test('inner', () {
-        expect(setUpRun, isFalse);
+        expect(setUpRun, isTrue);
       });
     });
   });
@@ -140,4 +140,41 @@
       });
     });
   });
-}
\ No newline at end of file
+
+  expectTestsPass("setUp calls are chained", () {
+    var setUpOuterRun = false;
+    var setUpInnerRun = false;
+    group('outer group', () {
+      setUp(() {
+        setUpOuterRun = true;
+        currentSchedule.onComplete.schedule(() {
+          setUpOuterRun = false;
+        });
+      });
+      group('intermediate group with no setUp', () {
+        group('inner group', () {
+          setUp(() {
+            setUpInnerRun = true;
+            currentSchedule.onComplete.schedule(() {
+              setUpInnerRun = false;
+            });
+          });
+          test('inner', () {
+            expect(setUpOuterRun, isTrue);
+            expect(setUpInnerRun, isTrue);
+          });
+        });
+      });
+      test('outer', () {
+        expect(setUpOuterRun, isTrue);
+        expect(setUpInnerRun, isFalse);
+      });
+    });
+
+    test('top', () {
+      expect(setUpOuterRun, isFalse);
+      expect(setUpInnerRun, isFalse);
+    });
+  });
+
+}
diff --git a/pkg/serialization/lib/serialization.dart b/pkg/serialization/lib/serialization.dart
index 130be27..88c30e8 100644
--- a/pkg/serialization/lib/serialization.dart
+++ b/pkg/serialization/lib/serialization.dart
@@ -7,6 +7,19 @@
  * [Serialization] is defined in terms of [SerializationRule]s and supports
  * reading and writing to different formats.
  *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       serialization: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [serialization package on pub.dartlang.org][pkg].
+ *
  * Setup
  * =====
  * A simple example of usage is
@@ -64,23 +77,25 @@
  *        }
  *      }
  *
- * The class needs four different methods. The [appliesTo] method tells us if
+ * The class needs four different methods. The [CustomRule.appliesTo]
+ * method tells us if
  * the rule should be used to write an object. In this example we use a test
  * based on runtimeType. We could also use an "is Address" test, but if Address
  * has subclasses that would find those as well, and we want a separate rule
- * for each. The [getState] method should
+ * for each. The [CustomRule.getState] method should
  * return all the state of the object that we want to recreate,
  * and should be either a Map or a List. If you want to write to human-readable
  * formats where it's useful to be able to look at the data as a map from
  * field names to values, then it's better to return it as a map. Otherwise it's
  * more efficient to return it as a list. You just need to be sure that the
- * [create] and [setState] methods interpret the same way as [getState] does.
+ * [CustomRule.create] and [CustomRule.setState] methods interpret the data the
+ * same way as [CustomRule.getState] does.
  *
- * The [create] method will create the new object and return it. While it's
+ * The [CustomRule.create] method will create the new object and return it. While it's
  * possible to create the object and set all its state in this one method, that
  * increases the likelihood of problems with cycles. So it's better to use the
- * minimum necessary information in [create] and do more of the work in
- * [setState].
+ * minimum necessary information in [CustomRule.create] and do more of the work
+ * in [CustomRule.setState].
  *
  * The other way to do this is not creating a subclass, but by using a
  * [ClosureRule] and giving it functions for how to create
@@ -133,7 +148,8 @@
  * isolate.
  *
  * We can write objects in different formats by passing a [Format] object to
- * the [write] method or by getting a [Writer] object. The available formats
+ * the [Serialization.write] method or by getting a [Writer] object.
+ * The available formats
  * include the default, a simple "flat" format that doesn't include field names,
  * and a simple JSON format that produces output more suitable for talking to
  * services that expect JSON in a predefined format. Examples of these are
@@ -149,7 +165,7 @@
  *
  * Reading
  * =======
- * To read objects, the corresponding [read] method can be used.
+ * To read objects, the corresponding [Serialization.read] method can be used.
  *
  *       Address input = serialization.read(input);
  *
@@ -158,13 +174,15 @@
  * rules to be different, but they need to be able to read the same
  * representation. For most practical purposes right now they should be the
  * same. The simplest way to achieve this is by having the serialization
- * variable [selfDescribing] be true. In that case the rules themselves are also
+ * variable [Serialization.selfDescribing] be true. In that case the rules
+ * themselves are also
  * stored along with the serialized data, and can be read back on the receiving
  * end. Note that this may not work for all rules or all formats. The
- * [selfDescribing] variable is true by default, but the [SimpleJsonFormat] does
- * not support it, since the point is to provide a representation in a form
+ * [Serialization.selfDescribing] variable is true by default, but the
+ * [SimpleJsonFormat] does not support it, since the point is to provide a
+ * representation in a form
  * other services might expect. Using CustomRule or ClosureRule also does not
- * yet work with the [selfDescribing] variable.
+ * yet work with the [Serialization.selfDescribing] variable.
  *
  * Named Objects
  * =============
@@ -174,13 +192,16 @@
  * take a [ClassMirror] in their constructor, and we cannot serialize those. So
  * when we read the rules, we must provide a Map<String, Object> which maps from
  * the simple name of classes we are interested in to a [ClassMirror]. This can
- * be provided either in the [namedObjects] variable of the Serialization,
+ * be provided either in the [Serialization.namedObjects],
  * or as an additional parameter to the reading and writing methods on the
  * [Reader] or [Writer] respectively.
  *
  *     new Serialization()
  *       ..addRuleFor(new Person(), constructorFields: ["name"])
  *       ..namedObjects['Person'] = reflect(new Person()).type;
+ *
+ * [pub]: http://pub.dartlang.org
+ * [pkg]: http://pub.dartlang.org/packages/serialization
  */
 library serialization;
 
@@ -319,6 +340,7 @@
     // it will always find the first one.
     addRule(new ListRuleEssential());
     addRule(new MapRule());
+    addRule(new SymbolRule());
   }
 
   /**
@@ -445,7 +467,8 @@
             'constructorFields', 'regularFields', []],
           fields: [])
       ..addRule(new NamedObjectRule())
-      ..addRule(new MirrorRule());
+      ..addRule(new MirrorRule())
+      ..addRule(new SymbolRule());
     meta.namedObjects = namedObjects;
     return meta;
   }
diff --git a/pkg/serialization/lib/src/basic_rule.dart b/pkg/serialization/lib/src/basic_rule.dart
index b3e3a95..dbf54ed 100644
--- a/pkg/serialization/lib/src/basic_rule.dart
+++ b/pkg/serialization/lib/src/basic_rule.dart
@@ -94,7 +94,7 @@
    */
   setFieldWith(String fieldName, SetWithFunction setWith) {
     fields.addAllByName([fieldName]);
-    _NamedField field = fields.named(fieldName);
+    _NamedField field = fields.named(_asSymbol(fieldName));
     Function setter = (setWith == null) ? field.defaultSetter : setWith;
     field.customSetter = setter;
   }
@@ -224,8 +224,8 @@
     return mirror.reflectee;
   }
 
-  /** For all [state] not required in the constructor, set it in the [object],
-   * resolving references in the context of [reader].
+  /** For all [rawState] not required in the constructor, set it in the
+   * [object], resolving references in the context of [reader].
    */
   inflateNonEssential(rawState, object, Reader reader) {
     InstanceMirror mirror = reflect(object);
@@ -284,7 +284,7 @@
   final _FieldList fieldList;
 
   /**
-   * Our position in the [contents] collection of [fieldList]. This is used
+   * Our position in the [fieldList._contents] collection. This is used
    * to index into the state, so it's extremely important.
    */
   int index;
@@ -310,9 +310,9 @@
    * [fieldList] models.
    */
   static bool _isReallyAField(value, _FieldList fieldList) {
-    if (!(value is String)) return false;
-    return hasField(value, fieldList.mirror) ||
-        hasGetter(value, fieldList.mirror);
+    var symbol = _asSymbol(value);
+    return hasField(symbol, fieldList.mirror) ||
+        hasGetter(symbol, fieldList.mirror);
   }
 
   /** Private constructor. */
@@ -332,7 +332,7 @@
   /**
    * Return true if this field is treated as essential state, either because
    * it is used in the constructor, or because it's been designated
-   * using [setFieldWith].
+   * using [BasicRule.setFieldWith].
    */
   bool get isEssential => usedInConstructor;
 
@@ -352,20 +352,32 @@
  */
 class _NamedField extends _Field {
   /** The name of the field (or getter) */
-  final name;
+  String _name;
+  Symbol nameSymbol;
 
-  /** The special way to set this value registered, if this has a value. */
+  /**
+   * If this is set, then it is used as a way to set the value rather than
+   * using the default mechanism.
+   */
   Function customSetter;
 
-  _NamedField._internal(this.name, fieldList) : super._internal(fieldList);
+  _NamedField._internal(fieldName, fieldList) : super._internal(fieldList) {
+    nameSymbol = _asSymbol(fieldName);
+    if (nameSymbol == null) {
+      throw new SerializationException("Invalid field name $fieldName");
+    }
+  }
 
-  operator ==(x) => x is _NamedField && (name == x.name);
+  String get name =>
+      _name == null ? _name = MirrorSystem.getName(nameSymbol) : _name;
+
+  operator ==(x) => x is _NamedField && (nameSymbol == x.nameSymbol);
   int get hashCode => name.hashCode;
 
   /**
    * Return true if this field is treated as essential state, either because
    * it is used in the constructor, or because it's been designated
-   * using [setFieldWith].
+   * using [BasicRule.setFieldWith].
    */
   bool get isEssential => super.isEssential || customSetter != null;
 
@@ -374,16 +386,15 @@
     setter(object, value);
   }
 
-  valueIn(InstanceMirror mirror) =>
-      deprecatedFutureValue(mirror.getFieldAsync(name)).reflectee;
+  valueIn(InstanceMirror mirror) => mirror.getField(nameSymbol).reflectee;
 
   /** Return the function to use to set our value. */
   Function get setter =>
       (customSetter != null) ? customSetter : defaultSetter;
 
-  /** Return a default setter function. */
+  /** The default setter function. */
   void defaultSetter(InstanceMirror object, value) {
-    object.setFieldAsync(name, reflect(value));
+    object.setField(nameSymbol, value);
   }
 
   String toString() => 'Field($name)';
@@ -421,8 +432,8 @@
  */
 class _FieldList extends IterableBase {
   /**
-   * All of our fields, indexed by name. Note that the names are not
-   * necessarily strings.
+   * All of our fields, indexed by name. Note that the names are
+   * typically Symbols, but can also be arbitrary constants.
    */
   Map<dynamic, _Field> allFields = new Map<dynamic, _Field>();
 
@@ -434,7 +445,7 @@
   List _constructorFields = const [];
 
   /** The list of fields to exclude if we are computing the list ourselves. */
-  List<String> _excludeFields = const [];
+  List<Symbol> _excludedFieldNames = const [];
 
   /** The mirror we will use to compute the fields. */
   final ClassMirror mirror;
@@ -448,15 +459,17 @@
   _FieldList(this.mirror);
 
   /** Look up a field by [name]. */
-  _Field named(String name) => allFields[name];
+  _Field named(name) => allFields[name];
 
   /** Set the fields to be used in the constructor. */
   set constructorFields(List fieldNames) {
     if (fieldNames == null || fieldNames.isEmpty) return;
     _constructorFields = [];
     for (var each in fieldNames) {
-      var field = new _Field(each, this)..usedInConstructor = true;
-      allFields[each] = field;
+      var symbol = _asSymbol(each);
+      var name = _Field._isReallyAField(symbol, this) ? symbol : each;
+      var field = new _Field(name, this)..usedInConstructor = true;
+      allFields[name] = field;
       _constructorFields.add(field);
     }
     invalidate();
@@ -478,7 +491,7 @@
     if (allFields.length > _constructorFields.length) {
       throw "You can't specify both excludeFields and regular fields";
     }
-    _excludeFields = fields;
+    _excludedFieldNames = fields.map((x) => new Symbol(x)).toList();
   }
 
   int get length => allFields.length;
@@ -487,14 +500,16 @@
   void addAllNotExplicitlyExcluded(Iterable<String> aCollection) {
     if (aCollection == null) return;
     var names = aCollection;
-    names = names.where((x) => !_excludeFields.contains(x));
+    names = names.where((x) => !_excludedFieldNames.contains(x));
     addAllByName(names);
   }
 
   /** Add all the fields with the given names without any special properties. */
   void addAllByName(Iterable<String> names) {
     for (var each in names) {
-      allFields.putIfAbsent(each, () => new _Field(each, this));
+      var symbol = _asSymbol(each);
+      var field = new _Field(symbol, this);
+      allFields.putIfAbsent(symbol, () => new _Field(symbol, this));
     }
     invalidate();
   }
@@ -562,7 +577,8 @@
     var fields = publicFields(mirror);
     var getters = publicGetters(mirror);
     var gettersWithSetters = getters.where( (each)
-        => mirror.setters["${each.simpleName}="] != null);
+        => mirror.setters[
+            new Symbol("${MirrorSystem.getName(each.simpleName)}=")] != null);
     var gettersThatMatchConstructor = getters.where((each)
         => (named(each.simpleName) != null) &&
             (named(each.simpleName).usedInConstructor)).toList();
@@ -590,11 +606,12 @@
 
   /** The name of the constructor to use, if not the default constructor.*/
   String name;
+  Symbol nameSymbol;
 
   /**
    * The indices of the fields used as constructor arguments. We will look
-   * these up in the state by number. These correspond to the index in the
-   * [contents] of the FieldList, which will be alphabetically sorted.
+   * these up in the state by number. The index is according to a list of the
+   * fields in alphabetical order by name.
    */
   List<int> fieldNumbers;
 
@@ -604,6 +621,7 @@
    */
   Constructor(this.type, this.name, this.fieldNumbers) {
     if (name == null) name = '';
+    nameSymbol = new Symbol(name);
     if (fieldNumbers == null) fieldNumbers = const [];
   }
 
@@ -614,9 +632,16 @@
   constructFrom(state, Reader r) {
     // TODO(alanknight): Handle named parameters
     Iterable inflated = fieldNumbers.map(
-        (x) => (x is int) ? reflect(r.inflateReference(state[x])) : reflect(x));
-    var result = type.newInstanceAsync(name, inflated.toList());
-    return deprecatedFutureValue(result);
+        (x) => (x is int) ? r.inflateReference(state[x]) : x);
+    var result;
+    try {
+      result = type.newInstance(nameSymbol, inflated.toList());
+    } on MirroredError catch (e) {
+      // Mirrored "compile-time" errors do not get treated as exceptions
+      // in the debugger, so explicitly re-throw. Issue dartbug.com/10054.
+      throw e;
+    }
+    return result;
   }
 }
 
@@ -637,3 +662,21 @@
 
   asMap() => _map;
 }
+
+/**
+ * Return a symbol corresponding to [value], which may be a String or a
+ * Symbol. If it is any other type, or if the string is an
+ * invalid symbol, return null;
+ */
+_asSymbol(value) {
+  if (value is Symbol) return value;
+  if (value is String) {
+    try {
+      return new Symbol(value);
+    } on ArgumentError {
+      return null;
+    };
+  } else {
+    return null;
+  }
+}
\ No newline at end of file
diff --git a/pkg/serialization/lib/src/format.dart b/pkg/serialization/lib/src/format.dart
index 4e57384..d42707d 100644
--- a/pkg/serialization/lib/src/format.dart
+++ b/pkg/serialization/lib/src/format.dart
@@ -82,7 +82,7 @@
  * with nesting of those.
  * Note that since the classes of objects aren't normally stored, this isn't
  * enough information to read back the objects. However, if the
- * If the [storeRoundTripData] field of the format is set to true, then this
+ * If the [storeRoundTripInfo] field of the format is set to true, then this
  * will store the rule number along with the data, allowing reconstruction.
  */
 class SimpleJsonFormat extends Format {
@@ -195,7 +195,7 @@
   }
 
   /**
-   * Convert nested references in [data] into [Reference] objects.
+   * Convert nested references in [input] into [Reference] objects.
    */
   recursivelyFixUp(input, Reader r, List result) {
     var data = input;
diff --git a/pkg/serialization/lib/src/mirrors_helpers.dart b/pkg/serialization/lib/src/mirrors_helpers.dart
index aeeb509..4058514 100644
--- a/pkg/serialization/lib/src/mirrors_helpers.dart
+++ b/pkg/serialization/lib/src/mirrors_helpers.dart
@@ -30,7 +30,8 @@
 
 /** Return true if the class has a field named [name]. Note that this
  * includes private fields, but excludes statics. */
-bool hasField(String name, ClassMirror mirror) {
+bool hasField(Symbol name, ClassMirror mirror) {
+  if (name == null) return false;
   var field = mirror.variables[name];
   if (field != null && !field.isStatic) return true;
   var superclass = mirror.superclass;
@@ -53,7 +54,8 @@
 }
 
 /** Return true if the class has a getter named [name] */
-bool hasGetter(String name, ClassMirror mirror) {
+bool hasGetter(Symbol name, ClassMirror mirror) {
+  if (name == null) return false;
   var getter = mirror.getters[name];
   if (getter != null && !getter.isStatic) return true;
   var superclass = mirror.superclass;
diff --git a/pkg/serialization/lib/src/reader_writer.dart b/pkg/serialization/lib/src/reader_writer.dart
index 2209f78..e25a3ec 100644
--- a/pkg/serialization/lib/src/reader_writer.dart
+++ b/pkg/serialization/lib/src/reader_writer.dart
@@ -211,7 +211,8 @@
   }
 
   /**
-   * Return true if the [namedObjects] collection has a reference to [object].
+   * Return true if the [Serialization.namedObjects] collection has a
+   * reference to [object].
    */
   // TODO(alanknight): Should the writer also have its own namedObjects
   // collection specific to the particular write, or is that just adding
@@ -219,7 +220,8 @@
   hasNameFor(object) => serialization._hasNameFor(object);
 
   /**
-   * Return the name we have for this object in the [namedObjects] collection.
+   * Return the name we have for this object in the [Serialization.namedObjects]
+   * collection.
    */
   nameFor(object) => serialization._nameFor(object);
 
@@ -278,7 +280,7 @@
 
   /**
    * The resulting objects, indexed according to the same scheme as
-   * [data], where each rule has a number, and rules keep track of the objects
+   * _data, where each rule has a number, and rules keep track of the objects
    * that they serialize, in order.
    */
   List<List> objects;
@@ -579,7 +581,7 @@
   /**
    * Convert the reference to a map in JSON format. This is specific to the
    * custom JSON format we define, and must be consistent with the
-   * [asReference] method.
+   * [Reader.asReference] method.
    */
   // TODO(alanknight): This is a hack both in defining a toJson specific to a
   // particular representation, and the use of a bogus sentinel "__Ref"
diff --git a/pkg/serialization/lib/src/serialization_rule.dart b/pkg/serialization/lib/src/serialization_rule.dart
index d63f07a..0fc6f3e 100644
--- a/pkg/serialization/lib/src/serialization_rule.dart
+++ b/pkg/serialization/lib/src/serialization_rule.dart
@@ -387,24 +387,25 @@
  * qualifiedName and attempts to look it up in both the namedObjects
  * collection, or if it's not found there, by looking it up in the mirror
  * system. When reading, the user is responsible for supplying the appropriate
- * values in [namedObjects] or in the [externals] paramter to
+ * values in [Serialization.namedObjects] or in the [externals] paramter to
  * [Serialization.read].
  */
 class MirrorRule extends NamedObjectRule {
   bool appliesTo(object, Writer writer) => object is DeclarationMirror;
-  nameFor(DeclarationMirror object, Writer writer) => object.qualifiedName;
+  nameFor(DeclarationMirror object, Writer writer) =>
+      MirrorSystem.getName(object.qualifiedName);
 
   inflateEssential(state, Reader r) {
     var qualifiedName = r.resolveReference(state.first);
     var lookupFull = r.objectNamed(qualifiedName, (x) => null);
     if (lookupFull != null) return lookupFull;
     var separatorIndex = qualifiedName.lastIndexOf(".");
-    var lib = qualifiedName.substring(0, separatorIndex);
+    var lib = new Symbol(qualifiedName.substring(0, separatorIndex));
     var type = qualifiedName.substring(separatorIndex + 1);
     var lookup = r.objectNamed(type, (x) => null);
     if (lookup != null) return lookup;
-    var libMirror = currentMirrorSystem().libraries[lib];
-    return libMirror.classes[type];
+    var libMirror = currentMirrorSystem().findLibrary(lib).first;
+    return libMirror.classes[new Symbol(type)];
   }
 }
 
@@ -469,6 +470,16 @@
   get hasVariableLengthEntries => true;
 }
 
+/** A hard-coded rule for serializing Symbols. */
+class SymbolRule extends CustomRule {
+  bool appliesTo(instance, _) => instance is Symbol;
+  getState(instance) => [MirrorSystem.getName(instance)];
+  create(state) => new Symbol(state[0]);
+  setState(symbol, state) {}
+  int get dataLength => 1;
+  bool get hasVariableLengthEntries => false;
+}
+
 /** Create a lazy list/map that will inflate its items on demand in [r]. */
 _lazy(l, Reader r) {
   if (l is List) return new _LazyList(l, r);
diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
index 2987fe0..47c8a6ae 100644
--- a/pkg/serialization/test/serialization_test.dart
+++ b/pkg/serialization/test/serialization_test.dart
@@ -123,9 +123,16 @@
     var stream = new Stream([3,4,5]);
     expect((stream..next()).next(), 4);
     expect(stream.position, 2);
+    // The Symbol class does not allow us to create symbols for private
+    // variables. However, the mirror system uses them. So we get the symbol
+    // we want from the mirror.
+    // TODO(alanknight): Either delete this test and decide we shouldn't
+    // attempt to access private variables or fix this properly.
+    var _collectionSym = reflect(stream).type.variables.keys.firstWhere(
+        (x) => MirrorSystem.getName(x) == "_collection");
     var s = new Serialization()
       ..addRuleFor(stream,
-          constructorFields: ['_collection']);
+          constructorFields: [_collectionSym]);
     var state = states(stream, s).first;
     // Define names for the variable offsets to make this more readable.
     var _collection = 0, position = 1;
@@ -211,7 +218,7 @@
     var w = new Writer(s);
     w.trace = new Trace(w);
     w.write(n1);
-    expect(w.states.length, 5); // prims, lists, essential lists, basic
+    expect(w.states.length, 6); // prims, lists, essential lists, basic, symbol
     var children = 0, name = 1, parent = 2;
     var nodeRule = s.rules.firstWhere((x) => x is BasicRule);
     List rootNode = w.states[nodeRule.number].where(
@@ -510,6 +517,15 @@
     expect(new Reader(s).asReference(map["person"]) is Reference, isTrue);
   });
 
+  test("MirrorRule with lookup by qualified name rather than named object", () {
+    var s = new Serialization()..addRule(new MirrorRule());
+    var m = reflectClass(Address);
+    var output = s.write(m);
+    var input = s.read(output);
+    expect(input is ClassMirror, isTrue);
+    expect(MirrorSystem.getName(input.simpleName), "Address");
+  });
+
 }
 
 /******************************************************************************
@@ -651,7 +667,7 @@
 
 /**
  * Run a round-trip test on a simple tree of nodes, using a serialization
- * that's returned by the [serializerSetup] function.
+ * that's returned by the [serializerSetUp] function.
  */
 runRoundTripTest(Function serializerSetUp) {
   Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
diff --git a/pkg/source_maps/lib/source_maps.dart b/pkg/source_maps/lib/source_maps.dart
index 4e24dea..1594827 100644
--- a/pkg/source_maps/lib/source_maps.dart
+++ b/pkg/source_maps/lib/source_maps.dart
@@ -4,6 +4,21 @@
 
 /// Source maps library.
 ///
+/// ## Installing ##
+///
+/// Use [pub][] to install this package. Add the following to your
+/// `pubspec.yaml` file.
+///
+///     dependencies:
+///       source_maps: any
+///
+/// Then run `pub install`.
+///
+/// For more information, see the
+/// [source_maps package on pub.dartlang.org][pkg].
+///
+/// ## Using ##
+///
 /// Create a source map using [SourceMapBuilder]. For example:
 ///     var json = (new SourceMapBuilder()
 ///         ..add(inputSpan1, outputSpan1)
@@ -17,6 +32,9 @@
 /// object. For example:
 ///     var mapping = parse(json);
 ///     mapping.spanFor(outputSpan1.line, outputSpan1.column)
+///
+/// [pub]: http://pub.dartlang.org
+/// [pkg]: http://pub.dartlang.org/packages/source_maps
 library source_maps;
 
 export "builder.dart";
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
index fa0c313..54f99db 100644
--- a/pkg/stack_trace/lib/src/trace.dart
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -4,6 +4,7 @@
 
 library trace;
 
+import 'dart:collection';
 import 'dart:uri';
 import 'dart:math' as math;
 
@@ -13,7 +14,6 @@
 
 /// A stack trace, comprised of a list of stack frames.
 class Trace implements StackTrace {
-  // TODO(nweiz): make this read-only once issue 8321 is fixed.
   /// The stack frames that comprise this stack trace.
   final List<Frame> frames;
 
@@ -63,7 +63,7 @@
 
   /// Returns a new [Trace] comprised of [frames].
   Trace(Iterable<Frame> frames)
-      : frames = frames.toList();
+      : frames = new UnmodifiableListView<Frame>(frames.toList());
 
   // TODO(nweiz): Keep track of which [Frame]s are part of the partial stack
   // trace and only print them.
diff --git a/pkg/stack_trace/lib/src/utils.dart b/pkg/stack_trace/lib/src/utils.dart
index 790dec8..50ccab3 100644
--- a/pkg/stack_trace/lib/src/utils.dart
+++ b/pkg/stack_trace/lib/src/utils.dart
@@ -15,7 +15,14 @@
     throw new ArgumentError("Uri $uri must have scheme 'file:'.");
   }
   if (Platform.operatingSystem != 'windows') return uri.path;
-  return uri.path.replaceFirst("/", "").replaceAll("/", "\\");
+  if (uri.path.startsWith("/")) {
+    // Drive-letter paths look like "file:///C:/path/to/file". The replaceFirst
+    // removes the extra initial slash.
+    return uri.path.replaceFirst("/", "").replaceAll("/", "\\");
+  } else {
+    // Network paths look like "file://hostname/path/to/file".
+    return "\\\\${uri.path.replaceAll("/", "\\")}";
+  }
 }
 
 /// Converts a local path string to a `file:` [Uri].
@@ -23,7 +30,11 @@
   pathString = path.absolute(pathString);
   if (Platform.operatingSystem != 'windows') {
     return Uri.parse('file://$pathString');
+  } else if (path.rootPrefix(pathString).startsWith('\\\\')) {
+    // Network paths become "file://hostname/path/to/file".
+    return Uri.parse('file:${pathString.replaceAll("\\", "/")}');
   } else {
+    // Drive-letter paths become "file:///C:/path/to/file".
     return Uri.parse('file:///${pathString.replaceAll("\\", "/")}');
   }
 }
diff --git a/pkg/stack_trace/lib/stack_trace.dart b/pkg/stack_trace/lib/stack_trace.dart
index 5747b85..f031f95 100644
--- a/pkg/stack_trace/lib/stack_trace.dart
+++ b/pkg/stack_trace/lib/stack_trace.dart
@@ -2,6 +2,23 @@
 // 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.
 
+/**
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       stack_trace: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [stack_trace package on pub.dartlang.org][pkg].
+ *
+ * [pub]: http://pub.dartlang.org
+ * [pkg]: http://pub.dartlang.org/packages/stack_trace
+ */
 library stack_trace;
 
 export 'src/trace.dart';
diff --git a/pkg/unittest/lib/matcher.dart b/pkg/unittest/lib/matcher.dart
index 6584198..8110432 100644
--- a/pkg/unittest/lib/matcher.dart
+++ b/pkg/unittest/lib/matcher.dart
@@ -4,6 +4,22 @@
 /**
  * The matcher library provides a 3rd generation assertion mechanism, drawing
  * inspiration from [Hamcrest](http://code.google.com/p/hamcrest/).
+ *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       matcher: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [matcher package on pub.dartlang.org][pkg].
+ *
+ * [pub]: http://pub.dartlang.org
+ * [pkg]: http://pub.dartlang.org/packages/matcher
  */
 library matcher;
 
diff --git a/pkg/unittest/lib/mock.dart b/pkg/unittest/lib/mock.dart
index 9ee6d8a..cacaec7 100644
--- a/pkg/unittest/lib/mock.dart
+++ b/pkg/unittest/lib/mock.dart
@@ -5,6 +5,21 @@
 /**
  * A simple mocking/spy library.
  *
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       mock: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [mock package on pub.dartlang.org](http://pub.dartlang.org/packages/mock).
+ *
+ * ## Using ##
+ *
  * To create a mock objects for some class T, create a new class using:
  *
  *     class MockT extends Mock implements T {};
@@ -87,6 +102,7 @@
  *       }
  *     }
  *
+ * [pub]: http://pub.dartlang.org
  */
 
 library mock;
diff --git a/pkg/unittest/lib/src/core_matchers.dart b/pkg/unittest/lib/src/core_matchers.dart
index e8606aa..980e7a0 100644
--- a/pkg/unittest/lib/src/core_matchers.dart
+++ b/pkg/unittest/lib/src/core_matchers.dart
@@ -177,9 +177,8 @@
         var aType = typeName(actual);
         var includeTypes = eType != aType;
         // If we have recursed, show the expected value too; if not,
-        // expect() will show it for us. As expect will not show type
-        // mismatches at the top level we handle those here too.
-        if (includeTypes || depth > 1) {
+        // expect() will show it for us.
+        if (depth > 0) {
           reason.add('expected ');
           if (includeTypes) {
             reason.add(eType).add(':');
@@ -191,6 +190,9 @@
           reason.add(aType).add(':');
         }
         reason.addDescriptionOf(actual);
+        if (includeTypes && depth == 0) {
+          reason.add(' (not type ').add(eType).add(')');
+        }
       }
     }
     if (reason != null && location.length > 0) {
@@ -706,8 +708,8 @@
   final String _featureName;
   final Matcher _matcher;
 
-  const CustomMatcher(this._featureDescription, this._featureName,
-      this._matcher);
+  CustomMatcher(this._featureDescription, this._featureName, matcher)
+      : this._matcher = wrapMatcher(matcher);
 
   /** Override this to extract the interesting feature.*/
   featureValueOf(actual) => actual;
diff --git a/pkg/unittest/lib/src/test_case.dart b/pkg/unittest/lib/src/test_case.dart
index 13d59f5..8e761f6 100644
--- a/pkg/unittest/lib/src/test_case.dart
+++ b/pkg/unittest/lib/src/test_case.dart
@@ -61,9 +61,9 @@
   Completer _testComplete;
 
   TestCase._internal(this.id, this.description, this.testFunction)
-  : currentGroup = _currentGroup,
-    setUp = _testSetup,
-    tearDown = _testTeardown;
+  : currentGroup = _currentContext.fullName,
+    setUp = _currentContext.testSetup,
+    tearDown = _currentContext.testTeardown;
 
   bool get isComplete => !enabled || result != null;
 
@@ -83,7 +83,10 @@
     --_callbackFunctionsOutstanding;
     if (f is Future) {
       return f.then((_) => _finishTest())
-       .catchError((error) => fail("${error}"));
+        .catchError((error) {
+          var stack = getAttachedStackTrace(error);
+          _registerException(this, error, stack);
+        });
     } else {
       _finishTest();
       return null;
@@ -118,7 +121,8 @@
           // a failed setUp. There is no right answer, but doing it
           // seems to be the more conservative approach, because
           // unittest will not stop at a test failure.
-          error("$description: Test setup failed: $e");
+          var stack = getAttachedStackTrace(e);
+          error("$description: Test setup failed: $e", "$stack");
         });
     } else {
       var f = _runTest();
diff --git a/pkg/unittest/lib/unittest.dart b/pkg/unittest/lib/unittest.dart
index 50d308b..b2abf069 100644
--- a/pkg/unittest/lib/unittest.dart
+++ b/pkg/unittest/lib/unittest.dart
@@ -5,9 +5,20 @@
 /**
  * A library for writing dart unit tests.
  *
- * To import this library, install the
- * [unittest package](http://pub.dartlang.org/packages/unittest) via the pub
- * package manager. See the [Getting Started](http://pub.dartlang.org/doc)
+ * ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       unittest: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [unittest package on pub.dartlang.org][pkg].
+ *
+ * See the [Getting Started](http://pub.dartlang.org/doc)
  * guide for more details.
  *
  * ##Concepts##
@@ -150,6 +161,8 @@
  *       });
  *     }
  *
+ * [pub]: http://pub.dartlang.org
+ * [pkg]: http://pub.dartlang.org/packages/unittest
  */
 library unittest;
 
@@ -192,24 +205,85 @@
 void logMessage(String message) =>
     _config.onLogMessage(currentTestCase, message);
 
-/**
- * Description text of the current test group. If multiple groups are nested,
- * this will contain all of their text concatenated.
- */
-String _currentGroup = '';
-
 /** Separator used between group names and test names. */
 String groupSep = ' ';
 
-// TODO(nweiz): present an unmodifiable view of this once issue 8321 is fixed.
+final List<TestCase> _testCases = new List<TestCase>();
+
 /** Tests executed in this suite. */
-final List<TestCase> testCases = new List<TestCase>();
+final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases);
 
-/** Setup function called before each test in a group */
-Function _testSetup;
+/**
+ * Setup and teardown functions for a group and its parents, the latter
+ * for chaining.
+ */
+class GroupContext {
+  final GroupContext parent;
 
-/** Teardown function called after each test in a group */
-Function _testTeardown;
+  /** Description text of the current test group. */
+  final String _name;
+
+  /** Setup function called before each test in a group. */
+  Function _testSetup;
+
+  get testSetup => _testSetup;
+
+  get parentSetup => (parent == null) ? null : parent.testSetup;
+
+  set testSetup(Function setup) {
+    var preSetup = parentSetup;
+    if (preSetup == null) {
+      _testSetup = setup;
+    } else {
+      _testSetup = () {
+        var f = preSetup();
+        if (f is Future) {
+          return f.then((_) => setup());
+        } else {
+          return setup();
+        }
+      };
+    }
+  }
+
+  /** Teardown function called after each test in a group. */
+  Function _testTeardown;
+
+  get testTeardown => _testTeardown;
+
+  get parentTeardown => (parent == null) ? null : parent.testTeardown;
+
+  set testTeardown(Function teardown) {
+    var postTeardown = parentTeardown;
+    if (postTeardown == null) {
+      _testTeardown = teardown;
+    } else {
+      _testTeardown = () {
+        var f = teardown();
+        if (f is Future) {
+          return f.then((_) => postTeardown());
+        } else {
+          return postTeardown();
+        }
+      };
+    }
+  }
+
+  String get fullName => (parent == null || parent == _rootContext)
+      ? _name
+      : "${parent.fullName}$groupSep$_name";
+
+  GroupContext([this.parent, this._name = '']) {
+    _testSetup = parentSetup;
+    _testTeardown = parentTeardown;
+  }
+}
+
+// We use a 'dummy' context for the top level to eliminate null
+// checks when querying the context. This allows us to easily
+//  support top-level setUp/tearDown functions as well.
+GroupContext _rootContext = new GroupContext();
+GroupContext _currentContext = _rootContext;
 
 int _currentTestCaseIndex = 0;
 
@@ -252,8 +326,8 @@
  */
 void test(String spec, TestFunction body) {
   ensureInitialized();
-  testCases.add(new TestCase._internal(testCases.length + 1, _fullSpec(spec),
-                                       body));
+  _testCases.add(new TestCase._internal(testCases.length + 1, _fullSpec(spec),
+                                        body));
 }
 
 /**
@@ -275,8 +349,9 @@
 
   ensureInitialized();
 
-  _soloTest = new TestCase._internal(testCases.length + 1, _fullSpec(spec), body);
-  testCases.add(_soloTest);
+  _soloTest = new TestCase._internal(testCases.length + 1, _fullSpec(spec),
+                                     body);
+  _testCases.add(_soloTest);
 }
 
 /** Sentinel value for [_SpreadArgsHelper]. */
@@ -292,10 +367,9 @@
   final int minExpectedCalls;
   final int maxExpectedCalls;
   final Function isDone;
-  final int testNum;
   final String id;
   int actualCalls = 0;
-  TestCase testCase;
+  final TestCase testCase;
   bool complete;
   static const sentinel = const _Sentinel();
 
@@ -307,19 +381,14 @@
             ? minExpected
             : maxExpected,
         this.isDone = isDone,
-        testNum = _currentTestCaseIndex,
+        this.testCase = currentTestCase,
         this.id = _makeCallbackId(id, callback) {
     ensureInitialized();
-    if (!(_currentTestCaseIndex >= 0 &&
-           _currentTestCaseIndex < testCases.length &&
-           testCases[_currentTestCaseIndex] != null)) {
-      print("No valid test, did you forget to run your test inside a call "
-          "to test()?");
+    if (testCase == null) {
+      throw new StateError("No valid test. Did you forget to run your test "
+          "inside a call to test()?");
     }
-    assert(_currentTestCaseIndex >= 0 &&
-           _currentTestCaseIndex < testCases.length &&
-           testCases[_currentTestCaseIndex] != null);
-    testCase = testCases[_currentTestCaseIndex];
+
     if (isDone != null || minExpected > 0) {
       testCase._callbackFunctionsOutstanding++;
       complete = false;
@@ -328,7 +397,7 @@
     }
   }
 
-  static _makeCallbackId(String id, Function callback) {
+  static String _makeCallbackId(String id, Function callback) {
     // Try to create a reasonable id.
     if (id != null) {
       return "$id ";
@@ -349,7 +418,7 @@
     return '';
   }
 
-  shouldCallBack() {
+  bool shouldCallBack() {
     ++actualCalls;
     if (testCase.isComplete) {
       // Don't run if the test is done. We don't throw here as this is not
@@ -369,7 +438,7 @@
     return true;
   }
 
-  after() {
+  void after() {
     if (!complete) {
       if (minExpectedCalls > 0 && actualCalls < minExpectedCalls) return;
       if (isDone != null && !isDone()) return;
@@ -381,31 +450,6 @@
     }
   }
 
-  invoke([arg0 = sentinel, arg1 = sentinel, arg2 = sentinel,
-          arg3 = sentinel, arg4 = sentinel]) {
-    return _guardAsync(() {
-      if (!shouldCallBack()) {
-        return;
-      } else if (arg0 == sentinel) {
-        return callback();
-      } else if (arg1 == sentinel) {
-        return callback(arg0);
-      } else if (arg2 == sentinel) {
-        return callback(arg0, arg1);
-      } else if (arg3 == sentinel) {
-        return callback(arg0, arg1, arg2);
-      } else if (arg4 == sentinel) {
-        return callback(arg0, arg1, arg2, arg3);
-      } else {
-        testCase.error(
-           'unittest lib does not support callbacks with more than'
-              ' 4 arguments.',
-           '');
-      }
-    },
-    after, testNum);
-  }
-
   invoke0() {
     return _guardAsync(
         () {
@@ -413,7 +457,7 @@
             return callback();
           }
         },
-        after, testNum);
+        after, testCase);
   }
 
   invoke1(arg1) {
@@ -423,7 +467,7 @@
             return callback(arg1);
           }
         },
-        after, testNum);
+        after, testCase);
   }
 
   invoke2(arg1, arg2) {
@@ -433,7 +477,7 @@
             return callback(arg1, arg2);
           }
         },
-        after, testNum);
+        after, testCase);
   }
 }
 
@@ -441,21 +485,6 @@
  * Indicate that [callback] is expected to be called a [count] number of times
  * (by default 1). The unittest framework will wait for the callback to run the
  * specified [count] times before it continues with the following test.  Using
- * [_expectAsync] will also ensure that errors that occur within [callback] are
- * tracked and reported. [callback] should take between 0 and 4 positional
- * arguments (named arguments are not supported here). [id] can be used
- * to provide more descriptive error messages if the callback is called more
- * often than expected.
- */
-Function _expectAsync(Function callback,
-                     {int count: 1, int max: 0, String id}) {
-  return new _SpreadArgsHelper(callback, count, max, null, id).invoke;
-}
-
-/**
- * Indicate that [callback] is expected to be called a [count] number of times
- * (by default 1). The unittest framework will wait for the callback to run the
- * specified [count] times before it continues with the following test.  Using
  * [expectAsync0] will also ensure that errors that occur within [callback] are
  * tracked and reported. [callback] should take 0 positional arguments (named
  * arguments are not supported). [id] can be used to provide more
@@ -489,20 +518,6 @@
 
 /**
  * Indicate that [callback] is expected to be called until [isDone] returns
- * true. The unittest framework checks [isDone] after each callback and only
- * when it returns true will it continue with the following test. Using
- * [expectAsyncUntil] will also ensure that errors that occur within
- * [callback] are tracked and reported. [callback] should take between 0 and
- * 4 positional arguments (named arguments are not supported). [id] can be
- * used to identify the callback in error messages (for example if it is called
- * after the test case is complete).
- */
-Function _expectAsyncUntil(Function callback, Function isDone, {String id}) {
-  return new _SpreadArgsHelper(callback, 0, -1, isDone, id).invoke;
-}
-
-/**
- * Indicate that [callback] is expected to be called until [isDone] returns
  * true. The unittest framework check [isDone] after each callback and only
  * when it returns true will it continue with the following test. Using
  * [expectAsyncUntil0] will also ensure that errors that occur within
@@ -537,19 +552,6 @@
  * function will be able to handle exceptions by directing them to the correct
  * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that
  * might optionally be called but may never be called during the test.
- * [callback] should take between 0 and 4 positional arguments (named arguments
- * are not supported). [id] can be used to identify the callback in error
- * messages (for example if it is called after the test case is complete).
- */
-Function _protectAsync(Function callback, {String id}) {
-  return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke;
-}
-
-/**
- * Wraps the [callback] in a new function and returns that function. The new
- * function will be able to handle exceptions by directing them to the correct
- * test. This is thus similar to expectAsync0. Use it to wrap any callbacks that
- * might optionally be called but may never be called during the test.
  * [callback] should take 0 positional arguments (named arguments are not
  * supported). [id] can be used to identify the callback in error
  * messages (for example if it is called after the test case is complete).
@@ -581,46 +583,27 @@
  */
 void group(String description, void body()) {
   ensureInitialized();
-  // Concatenate the new group.
-  final parentGroup = _currentGroup;
-  if (_currentGroup != '') {
-    // Add a space.
-    _currentGroup = '$_currentGroup$groupSep$description';
-  } else {
-    // The first group.
-    _currentGroup = description;
-  }
-
-  // Groups can be nested, so we need to preserve the current
-  // settings for test setup/teardown.
-  Function parentSetup = _testSetup;
-  Function parentTeardown = _testTeardown;
-
+  _currentContext = new GroupContext(_currentContext, description);
   try {
-    _testSetup = null;
-    _testTeardown = null;
     body();
   } catch (e, trace) {
     var stack = (trace == null) ? '' : ': ${trace.toString()}';
     _uncaughtErrorMessage = "${e.toString()}$stack";
   } finally {
     // Now that the group is over, restore the previous one.
-    _currentGroup = parentGroup;
-    _testSetup = parentSetup;
-    _testTeardown = parentTeardown;
+    _currentContext = _currentContext.parent;
   }
 }
 
 /**
  * Register a [setUp] function for a test [group]. This function will
- * be called before each test in the group is run. Note that if groups
- * are nested only the most locally scoped [setUpTest] function will be run.
+ * be called before each test in the group is run.
  * [setUp] and [tearDown] should be called within the [group] before any
  * calls to [test]. The [setupTest] function can be asynchronous; in this
  * case it must return a [Future].
  */
 void setUp(Function setupTest) {
-  _testSetup = setupTest;
+  _currentContext.testSetup = setupTest;
 }
 
 /**
@@ -632,12 +615,12 @@
  * case it must return a [Future].
  */
 void tearDown(Function teardownTest) {
-  _testTeardown = teardownTest;
+  _currentContext.testTeardown = teardownTest;
 }
 
 /** Advance to the next test case. */
 void _nextTestCase() {
-  _defer(() {
+  runAsync(() {
     _currentTestCaseIndex++;
     _nextBatch();
   });
@@ -656,19 +639,6 @@
   }
 }
 
-/**
- * Runs [callback] at the end of the event loop. Note that we don't wrap
- * the callback in guardAsync; this is for test framework functions which
- * should not be throwing unexpected exceptions that end up failing test
- * cases! Furthermore, we need the final exception to be thrown but not
- * caught by the test framework if any test cases failed. However, tests
- * that make use of a similar defer function *should* wrap the callback
- * (as we do in unitttest_test.dart).
- */
-_defer(void callback()) {
-  (new Future.value()).then((_) => callback());
-}
-
 void rerunTests() {
   _uncaughtErrorMessage = null;
   _initialized = true; // We don't want to reset the test array.
@@ -690,14 +660,13 @@
   } else if (testFilter is Function) {
     filterFunction = testFilter;
   }
-  testCases.retainWhere(filterFunction);
+  _testCases.retainWhere(filterFunction);
 }
 
 /** Runs all queued tests, one at a time. */
 void runTests() {
   _ensureInitialized(false);
   _currentTestCaseIndex = 0;
-  _currentGroup = '';
 
   // If we are soloing a test, remove all the others.
   if (_soloTest != null) {
@@ -706,7 +675,7 @@
 
   _config.onStart();
 
-  _defer(() {
+  runAsync(() {
     _nextBatch();
   });
 }
@@ -718,15 +687,15 @@
  * The value returned by [tryBody] (if any) is returned by [guardAsync].
  */
 guardAsync(Function tryBody) {
-  return _guardAsync(tryBody, null, _currentTestCaseIndex);
+  return _guardAsync(tryBody, null, currentTestCase);
 }
 
-_guardAsync(Function tryBody, Function finallyBody, int testNum) {
-  assert(testNum >= 0);
+_guardAsync(Function tryBody, Function finallyBody, TestCase testCase) {
+  assert(testCase != null);
   try {
     return tryBody();
   } catch (e, trace) {
-    _registerException(testNum, e, trace);
+    _registerException(testCase, e, trace);
   } finally {
     if (finallyBody != null) finallyBody();
   }
@@ -736,19 +705,19 @@
  * Registers that an exception was caught for the current test.
  */
 void registerException(e, [trace]) {
-  _registerException(_currentTestCaseIndex, e, trace);
+  _registerException(currentTestCase, e, trace);
 }
 
 /**
  * Registers that an exception was caught for the current test.
  */
-void _registerException(testNum, e, [trace]) {
+void _registerException(TestCase testCase, e, [trace]) {
   trace = trace == null ? '' : trace.toString();
   String message = (e is TestFailure) ? e.message : 'Caught $e';
-  if (testCases[testNum].result == null) {
-    testCases[testNum].fail(message, trace);
+  if (testCase.result == null) {
+    testCase.fail(message, trace);
   } else {
-    testCases[testNum].error(message, trace);
+    testCase.error(message, trace);
   }
 }
 
@@ -764,7 +733,7 @@
       break;
     }
     final testCase = testCases[_currentTestCaseIndex];
-    var f = _guardAsync(testCase._run, null, _currentTestCaseIndex);
+    var f = _guardAsync(testCase._run, null, testCase);
     if (f != null) {
       f.whenComplete(() {
         _nextTestCase(); // Schedule the next test.
@@ -796,8 +765,9 @@
 }
 
 String _fullSpec(String spec) {
-  if (spec == null) return '$_currentGroup';
-  return _currentGroup != '' ? '$_currentGroup$groupSep$spec' : spec;
+  var group = '${_currentContext.fullName}';
+  if (spec == null) return group;
+  return group != '' ? '$group$groupSep$spec' : spec;
 }
 
 /**
@@ -825,7 +795,7 @@
   if (configAutoStart && _config.autoStart) {
     // Immediately queue the suite up. It will run after a timeout (i.e. after
     // main() has returned).
-    _defer(runTests);
+    runAsync(runTests);
   }
 }
 
diff --git a/pkg/unittest/test/matchers_test.dart b/pkg/unittest/test/matchers_test.dart
index be286ea..4f1ae6e 100644
--- a/pkg/unittest/test/matchers_test.dart
+++ b/pkg/unittest/test/matchers_test.dart
@@ -30,7 +30,7 @@
 }
 
 class HasPrice extends CustomMatcher {
-  const HasPrice(matcher) :
+  HasPrice(matcher) :
     super("Widget with a price that is", "price", matcher);
   featureValueOf(actual) => actual.price;
 }
@@ -237,20 +237,25 @@
       shouldPass(b, hasLength(2));
     });
 
-    test('type mismatch', () {
-      var a = new DateTime.utc(2000);
-      var b = a.toString();
-      // We should get something like:
-      //    Expected: '2000-01-01 00:00:00.000Z'
-      //    but: expected String:'2000-01-01 00:00:00.000Z'
-      //    but was DateTime:<2000-01-01 00:00:00.000Z>.
-      // However, if minification is applied, then the type names
-      // will be shortened to two letters. The key thing is that
-      // there will be a "but: expected" part in the middle;
-      // this only happens with type mismatches or mismatches
-      // inside container types.
-      shouldFail(a, equals(b),
-          matches(new RegExp("^Expected.*but: expected .*but was.*\$")));
+    test('scalar type mismatch', () {
+      shouldFail('error', equals(5.1),
+          matches("^Expected: <5\.1>"
+                  "     but: was .*:'error' \\(not type .*\\)\.\$"));
+    });
+
+    test('nested type mismatch', () {
+      shouldFail(['error'], equals([5.1]),
+          matches(r"^Expected: <\[5\.1\]>"
+                  "     but: expected double:<5\.1> "
+                  "but was .*:'error' mismatch at position 0\.\$"));
+    });
+
+    test('doubly-nested type mismatch', () {
+      shouldFail([['error']], equals([[5.1]]),
+          matches(r"^Expected: <\[\[5\.1\]\]>"
+                  "     but: expected double:<5\.1> "
+                  "but was .*:'error' mismatch at position 0 "
+                  "mismatch at position 0\.\$"));
     });
   });
 
@@ -502,7 +507,7 @@
       shouldPass(d, orderedEquals([1, 2]));
       shouldFail(d, orderedEquals([2, 1]),
           "Expected: equals <[2, 1]> ordered "
-          "but: was <1> mismatch at position 0.");
+          "but: expected <2> but was <1> mismatch at position 0.");
     });
 
     test('unorderedEquals', () {
@@ -702,6 +707,7 @@
     test("Feature Matcher", () {
       var w = new Widget();
       w.price = 10;
+      shouldPass(w, new HasPrice(10));
       shouldPass(w, new HasPrice(greaterThan(0)));
       shouldFail(w, new HasPrice(greaterThan(10)),
           'Expected: Widget with a price that is a value greater than <10> '
diff --git a/pkg/unittest/test/unittest_test.dart b/pkg/unittest/test/unittest_test.dart
index 24ff29d..aa1bd97 100644
--- a/pkg/unittest/test/unittest_test.dart
+++ b/pkg/unittest/test/unittest_test.dart
@@ -68,6 +68,26 @@
   }
 }
 
+makeDelayedSetup(index, s) => () {
+  return new Future.delayed(new Duration(milliseconds:1), () {
+    s.write('l$index U ');
+  });
+};
+
+makeDelayedTeardown(index, s) => () {
+  return new Future.delayed(new Duration(milliseconds:1), () {
+    s.write('l$index D ');
+  });
+};
+
+makeImmediateSetup(index, s) => () {
+  s.write('l$index U ');
+};
+
+makeImmediateTeardown(index, s) => () {
+  s.write('l$index D ');
+};
+
 runTest() {
   port.receive((String testName, sendport) {
     var testConfig = new TestConfiguration(sendport);
@@ -292,8 +312,38 @@
       });
       test('foo6', () {
       });
+    } else if (testName == 'testCases immutable') {
+      test(testName, () {
+        expect(() => testCases.clear(), throwsUnsupportedError);
+        expect(() => testCases.removeLast(), throwsUnsupportedError);
+      });
     } else if (testName == 'runTests without tests') {
       runTests();
+    } else if (testName == 'nested groups setup/teardown') {
+      StringBuffer s = new StringBuffer();
+      group('level 1', () {
+        setUp(makeDelayedSetup(1, s));
+        group('level 2', () {
+          setUp(makeImmediateSetup(2, s));
+          tearDown(makeDelayedTeardown(2, s));
+          group('level 3', () {
+            group('level 4', () {
+              setUp(makeDelayedSetup(4, s));
+              tearDown(makeImmediateTeardown(4, s));
+              group('level 5', () {
+                setUp(makeImmediateSetup(5, s));
+                group('level 6', () {
+                  tearDown(makeDelayedTeardown(6, s));
+                  test('inner', () {});
+                });
+              });
+            });
+          });
+        });
+      });
+      test('after nest', () {
+        expect(s.toString(), "l1 U l2 U l4 U l5 U l6 D l4 D l2 D ");
+      });
     }
   });
 }
@@ -348,7 +398,12 @@
         'fail2:failure:'
         'error2:Callback called more times than expected (1).:'
         'foo6'),
-    'runTests without tests': buildStatusString(0, 0, 0, null)
+    'testCases immutable':
+        buildStatusString(1, 0, 0, 'testCases immutable'),
+    'runTests without tests': buildStatusString(0, 0, 0, null),
+    'nested groups setup/teardown':
+        buildStatusString(2, 0, 0,
+            'level 1 level 2 level 3 level 4 level 5 level 6 inner::after nest')
   };
 
   tests.forEach((String name, String expected) {
diff --git a/pkg/webdriver/lib/webdriver.dart b/pkg/webdriver/lib/webdriver.dart
index fbae2d3..724332d9 100644
--- a/pkg/webdriver/lib/webdriver.dart
+++ b/pkg/webdriver/lib/webdriver.dart
@@ -14,6 +14,21 @@
 /**
  * WebDriver bindings for Dart.
  *
+* ## Installing ##
+ *
+ * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
+ * file.
+ *
+ *     dependencies:
+ *       webdriver: any
+ *
+ * Then run `pub install`.
+ *
+ * For more information, see the
+ * [webdriver package on pub.dartlang.org][pkg].
+ *
+ * ## Using ##
+ *
  * These bindings are based on the WebDriver JSON wire protocol spec
  * (http://code.google.com/p/selenium/wiki/JsonWireProtocol). Not
  * all of these commands are implemented yet by WebDriver itself.
@@ -50,6 +65,9 @@
  *    }).then((_) {
  *      session = null;
  *    });
+ *
+ * [pub]: http://pub.dartlang.org
+ * [pkg]: http://pub.dartlang.org/packages/webdriver
  */
 
 void writeStringToFile(String fileName, String contents) {
diff --git a/pkg/yaml/lib/yaml.dart b/pkg/yaml/lib/yaml.dart
index 94e3d42..85861d5 100644
--- a/pkg/yaml/lib/yaml.dart
+++ b/pkg/yaml/lib/yaml.dart
@@ -4,6 +4,21 @@
 
 /// A parser for [YAML](http://www.yaml.org/).
 ///
+/// ## Installing ##
+///
+/// Use [pub][] to install this package. Add the following to your
+/// `pubspec.yaml` file.
+///
+///     dependencies:
+///       yaml: any
+///
+/// Then run `pub install`.
+///
+/// For more information, see the
+/// [yaml package on pub.dartlang.org][pkg].
+///
+/// ## Using ##
+///
 /// Use [loadYaml] to load a single document, or [loadYamlStream] to load a
 /// stream of documents. For example:
 ///
@@ -22,6 +37,9 @@
 ///       var doc = loadYaml("YAML: YAML Ain't Markup Language");
 ///       print(json.stringify(doc));
 ///     }
+///
+/// [pub]: http://pub.dartlang.org
+/// [pkg]: http://pub.dartlang.org/packages/yaml
 library yaml;
 
 import 'src/composer.dart';
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index b910a10..ffc22e2 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -4,19 +4,32 @@
 
 {
   'variables': {
-    'io_cc_file': '<(SHARED_INTERMEDIATE_DIR)/io_gen.cc',
-    'io_patch_cc_file': '<(SHARED_INTERMEDIATE_DIR)/io_patch_gen.cc',
+    # We place most generated source files in LIB_DIR (rather than, say
+    # SHARED_INTERMEDIATE_DIR) because it is toolset specific. This avoids
+    # two problems. First, if a generated source file has architecture specific
+    # code, we'll get two different files in two different directories. Second,
+    # if a generated source file is needed to build a target with multiple
+    # toolsets, we avoid having duplicate Makefile targets.
+    'gen_source_dir': '<(LIB_DIR)',
+
+    'io_cc_file': '<(gen_source_dir)/io_gen.cc',
+    'io_patch_cc_file': '<(gen_source_dir)/io_patch_gen.cc',
     'builtin_in_cc_file': 'builtin_in.cc',
-    'builtin_cc_file': '<(SHARED_INTERMEDIATE_DIR)/builtin_gen.cc',
+    'builtin_cc_file': '<(gen_source_dir)/builtin_gen.cc',
     'snapshot_in_cc_file': 'snapshot_in.cc',
-    'snapshot_bin_file': '<(SHARED_INTERMEDIATE_DIR)/snapshot_gen.bin',
+    'snapshot_bin_file': '<(gen_source_dir)/snapshot_gen.bin',
+    'resources_cc_file': '<(gen_source_dir)/resources_gen.cc',
+
+    # The program that creates snapshot_gen.cc is only built and run on the
+    # host, but it must be available when dart is built for the target. Thus,
+    # we keep it in a shared location.
     'snapshot_cc_file': '<(SHARED_INTERMEDIATE_DIR)/snapshot_gen.cc',
-    'resources_cc_file': '<(SHARED_INTERMEDIATE_DIR)/resources_gen.cc',
   },
   'targets': [
     {
       'target_name': 'generate_builtin_cc_file',
       'type': 'none',
+      'toolsets':['target','host'],
       'includes': [
         'builtin_sources.gypi',
       ],
@@ -37,7 +50,7 @@
             '--output', '<(builtin_cc_file)',
             '--input_cc', '<(builtin_in_cc_file)',
             '--include', 'bin/builtin.h',
-            '--var_name', 'Builtin::builtin_source_',
+            '--var_name', 'dart::bin::Builtin::builtin_source_',
             '<@(_sources)',
           ],
           'message': 'Generating ''<(builtin_cc_file)'' file.'
@@ -47,8 +60,9 @@
     {
       'target_name': 'generate_io_cc_file',
       'type': 'none',
+      'toolsets':['target','host'],
       'variables': {
-        'io_dart': '<(SHARED_INTERMEDIATE_DIR)/io_gen.dart',
+        'io_dart': '<(gen_source_dir)/io_gen.dart',
       },
       'sources': [
         'io.dart',
@@ -89,7 +103,7 @@
             '--output', '<(io_cc_file)',
             '--input_cc', '<(builtin_in_cc_file)',
             '--include', 'bin/builtin.h',
-            '--var_name', 'Builtin::io_source_',
+            '--var_name', 'dart::bin::Builtin::io_source_',
             '<(io_dart)',
           ],
           'message': 'Generating ''<(io_cc_file)'' file.'
@@ -99,6 +113,7 @@
     {
       'target_name': 'generate_io_patch_cc_file',
       'type': 'none',
+      'toolsets':['target','host'],
       'includes': [
         'io_sources.gypi',
       ],
@@ -119,7 +134,7 @@
             '--output', '<(io_patch_cc_file)',
             '--input_cc', '<(builtin_in_cc_file)',
             '--include', 'bin/builtin.h',
-            '--var_name', 'Builtin::io_patch_',
+            '--var_name', 'dart::bin::Builtin::io_patch_',
             '<@(_sources)',
           ],
           'message': 'Generating ''<(io_patch_cc_file)'' file.'
@@ -129,6 +144,7 @@
     {
       'target_name': 'libdart_builtin',
       'type': 'static_library',
+      'toolsets':['target','host'],
       'dependencies': [
         'generate_builtin_cc_file',
         'generate_io_cc_file',
@@ -218,6 +234,7 @@
     {
       'target_name': 'libdart_withcore',
       'type': 'static_library',
+      'toolsets':['target','host'],
       'dependencies': [
         'libdart_lib_withcore',
         'libdart_vm',
@@ -243,6 +260,7 @@
       # Completely statically linked binary for generating snapshots.
       'target_name': 'gen_snapshot',
       'type': 'executable',
+      'toolsets':['host'],
       'dependencies': [
         'libdart_withcore',
         'libdart_builtin',
@@ -276,8 +294,9 @@
       # Generate snapshot bin file.
       'target_name': 'generate_snapshot_bin',
       'type': 'none',
+      'toolsets':['host'],
       'dependencies': [
-        'gen_snapshot',
+        'gen_snapshot#host',
       ],
       'actions': [
         {
@@ -305,8 +324,9 @@
       # Generate snapshot file.
       'target_name': 'generate_snapshot_file',
       'type': 'none',
+      'toolsets':['host'],
       'dependencies': [
-        'generate_snapshot_bin',
+        'generate_snapshot_bin#host',
       ],
       'actions': [
         {
@@ -365,7 +385,7 @@
         'libdart',
         'libdart_builtin',
         'libdart_io',
-        'generate_snapshot_file',
+        'generate_snapshot_file#host',
         'generate_resources_cc_file',
       ],
       'include_dirs': [
@@ -478,7 +498,7 @@
       ],
       'include_dirs': [
         '..',
-        '<(SHARED_INTERMEDIATE_DIR)',
+        '<(gen_source_dir)',
       ],
       'sources': [
         'run_vm_tests.cc',
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 2af1339..a2d646c 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -10,6 +10,9 @@
 #include "bin/dartutils.h"
 #include "bin/io_natives.h"
 
+namespace dart {
+namespace bin {
+
 Builtin::builtin_lib_props Builtin::builtin_libraries_[] = {
   /* { url_, source_, patch_url_, patch_source_, has_natives_ } */
   { DartUtils::kBuiltinLibURL, builtin_source_, NULL, NULL, true },
@@ -64,3 +67,6 @@
   DART_CHECK_VALID(library);
   return library;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index 4a33b6c..67fc9fb 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -12,6 +12,9 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 
+namespace dart {
+namespace bin {
+
 #define FUNCTION_NAME(name) Builtin_##name
 #define REGISTER_FUNCTION(name, count)                                         \
   { ""#name, FUNCTION_NAME(name), count },
@@ -59,5 +62,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Builtin);
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_BUILTIN_H_
diff --git a/runtime/bin/builtin_gen_snapshot.cc b/runtime/bin/builtin_gen_snapshot.cc
index af68759..c76cd55 100644
--- a/runtime/bin/builtin_gen_snapshot.cc
+++ b/runtime/bin/builtin_gen_snapshot.cc
@@ -10,6 +10,9 @@
 #include "bin/dartutils.h"
 
 
+namespace dart {
+namespace bin {
+
 Builtin::builtin_lib_props Builtin::builtin_libraries_[] = {
   /* { url_, source_, patch_url_, patch_source_, has_natives_ } */
   { DartUtils::kBuiltinLibURL, builtin_source_, NULL, NULL, true },
@@ -65,3 +68,6 @@
   DART_CHECK_VALID(library);
   return library;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 555dfe5..86f9aee 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -12,6 +12,9 @@
 #include "platform/assert.h"
 
 
+namespace dart {
+namespace bin {
+
 // Lists the native functions implementing basic functionality in
 // standalone dart, such as printing, file I/O, and platform information.
 // Advanced I/O classes like sockets and process management are implemented
@@ -109,3 +112,6 @@
   Builtin::PrintString(stdout, Dart_GetNativeArgument(args, 0));
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/builtin_nolib.cc b/runtime/bin/builtin_nolib.cc
index 048aa86..6ca4a20 100644
--- a/runtime/bin/builtin_nolib.cc
+++ b/runtime/bin/builtin_nolib.cc
@@ -10,6 +10,10 @@
 #include "bin/dartutils.h"
 #include "bin/io_natives.h"
 
+
+namespace dart {
+namespace bin {
+
 Builtin::builtin_lib_props Builtin::builtin_libraries_[] = {
   /* { url_, source_, patch_url_, patch_source_, has_natives_ } */
   { DartUtils::kBuiltinLibURL, NULL, NULL, NULL, true },
@@ -64,3 +68,6 @@
   DART_CHECK_VALID(library);
   return library;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/common.cc b/runtime/bin/common.cc
index 261557d..030fcfa 100644
--- a/runtime/bin/common.cc
+++ b/runtime/bin/common.cc
@@ -6,6 +6,9 @@
 #include "bin/isolate_data.h"
 #include "include/dart_api.h"
 
+namespace dart {
+namespace bin {
+
 void FUNCTION_NAME(Common_IsBuiltinList)(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle list = Dart_GetNativeArgument(args, 0);
@@ -54,3 +57,6 @@
   Dart_SetReturnValue(args, Dart_NewBoolean(builtin_array));
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/crypto.cc b/runtime/bin/crypto.cc
index af5886d..cd707dd 100644
--- a/runtime/bin/crypto.cc
+++ b/runtime/bin/crypto.cc
@@ -8,6 +8,9 @@
 #include "include/dart_api.h"
 
 
+namespace dart {
+namespace bin {
+
 void FUNCTION_NAME(Crypto_GetRandomBytes)(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle count_obj = Dart_GetNativeArgument(args, 0);
@@ -34,3 +37,6 @@
   delete[] buffer;
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/crypto.h b/runtime/bin/crypto.h
index b155972..1feaf9c 100644
--- a/runtime/bin/crypto.h
+++ b/runtime/bin/crypto.h
@@ -9,6 +9,9 @@
 #include "bin/utils.h"
 
 
+namespace dart {
+namespace bin {
+
 class Crypto {
  public:
   static bool GetRandomBytes(intptr_t count, uint8_t* buffer);
@@ -18,5 +21,8 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Crypto);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_CRYPTO_H_
 
diff --git a/runtime/bin/crypto_android.cc b/runtime/bin/crypto_android.cc
index 701a208..61b87a1 100644
--- a/runtime/bin/crypto_android.cc
+++ b/runtime/bin/crypto_android.cc
@@ -12,6 +12,9 @@
 #include "bin/crypto.h"
 
 
+namespace dart {
+namespace bin {
+
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   intptr_t fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY));
   if (fd < 0) return false;
@@ -20,4 +23,7 @@
   return bytes_read == count;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/crypto_linux.cc b/runtime/bin/crypto_linux.cc
index 7ff6b6e..849fe71 100644
--- a/runtime/bin/crypto_linux.cc
+++ b/runtime/bin/crypto_linux.cc
@@ -12,6 +12,9 @@
 #include "bin/crypto.h"
 
 
+namespace dart {
+namespace bin {
+
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   intptr_t fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY));
   if (fd < 0) return false;
@@ -20,4 +23,7 @@
   return bytes_read == count;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/crypto_macos.cc b/runtime/bin/crypto_macos.cc
index 0a44ff8..19745fc 100644
--- a/runtime/bin/crypto_macos.cc
+++ b/runtime/bin/crypto_macos.cc
@@ -12,6 +12,9 @@
 #include "bin/crypto.h"
 
 
+namespace dart {
+namespace bin {
+
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   intptr_t fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY));
   if (fd < 0) return false;
@@ -20,4 +23,7 @@
   return bytes_read == count;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/crypto_win.cc b/runtime/bin/crypto_win.cc
index 8f4952f..01b82a9 100644
--- a/runtime/bin/crypto_win.cc
+++ b/runtime/bin/crypto_win.cc
@@ -10,6 +10,9 @@
 #include "bin/crypto.h"
 
 
+namespace dart {
+namespace bin {
+
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
   uint32_t num;
   intptr_t read = 0;
@@ -25,4 +28,7 @@
   return true;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 37cf816..3379b16 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -12,6 +12,9 @@
 #include "platform/assert.h"
 #include "platform/globals.h"
 
+namespace dart {
+namespace bin {
+
 const char* DartUtils::original_working_directory = NULL;
 const char* DartUtils::kDartScheme = "dart:";
 const char* DartUtils::kDartExtensionScheme = "dart-ext:";
@@ -391,6 +394,9 @@
     return Dart_LoadScriptFromSnapshot(text_buffer, len);
   } else {
     Dart_Handle source = Dart_NewStringFromUTF8(text_buffer, len);
+    if (Dart_IsError(source)) {
+      return source;
+    }
     return Dart_LoadScript(resolved_script_uri, source, 0, 0);
   }
 }
@@ -746,3 +752,6 @@
   result->SetAt(2, error_message);
   return result;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 83457dc..074cc12 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -10,6 +10,9 @@
 #include "include/dart_api.h"
 #include "platform/globals.h"
 
+namespace dart {
+namespace bin {
+
 // Forward declarations.
 class File;
 
@@ -494,4 +497,7 @@
   DISALLOW_COPY_AND_ASSIGN(CObjectExternalUint8Array);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_DARTUTILS_H_
diff --git a/runtime/bin/dbg_connection.cc b/runtime/bin/dbg_connection.cc
index 583d737..dc6dc84 100644
--- a/runtime/bin/dbg_connection.cc
+++ b/runtime/bin/dbg_connection.cc
@@ -18,6 +18,9 @@
 #include "include/dart_api.h"
 
 
+namespace dart {
+namespace bin {
+
 int DebuggerConnectionHandler::listener_fd_ = -1;
 dart::Monitor DebuggerConnectionHandler::handler_lock_;
 
@@ -180,7 +183,7 @@
 void DebuggerConnectionHandler::HandleMessages() {
   static JSONDebuggerCommand generic_debugger_commands[] = {
     { "interrupt", HandleInterruptCmd },
-    { "isolates", HandleIsolatesListCmd },
+    { "getIsolateIds", HandleIsolatesListCmd },
     { NULL, NULL }
   };
 
@@ -294,7 +297,11 @@
   // listen, accept connections from debuggers, read and handle/dispatch
   // debugger commands received on these connections.
   ASSERT(listener_fd_ == -1);
-  listener_fd_ = ServerSocket::CreateBindListen(address, port_number, 1);
+
+  OSError *os_error;
+  SocketAddresses* addresses = Socket::LookupAddress(address, -1, &os_error);
+  listener_fd_ = ServerSocket::CreateBindListen(
+      addresses->GetAt(0)->addr(), port_number, 1);
   DebuggerConnectionImpl::StartHandler(port_number);
 }
 
@@ -404,7 +411,11 @@
   MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len());
   int msg_id = msg_parser.MessageId();
   ASSERT(msg_id >= 0);
-  in_msg->SendErrorReply(msg_id, "isolate list command unimplemented");
+  dart::TextBuffer msg(64);
+  msg.Printf("{ \"id\": %d, \"result\": { \"isolateIds\": [", msg_id);
+  DbgMsgQueueList::ListIsolateIds(&msg);
+  msg.Printf("]}}");
+  in_msg->SendReply(&msg);
 }
 
 
@@ -438,3 +449,6 @@
   // Return true if a connection has been established.
   return singleton_handler != NULL;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/dbg_connection.h b/runtime/bin/dbg_connection.h
index 791ab13..37080fb 100644
--- a/runtime/bin/dbg_connection.h
+++ b/runtime/bin/dbg_connection.h
@@ -27,6 +27,9 @@
 #endif
 
 
+namespace dart {
+namespace bin {
+
 // Forward declarations.
 class DbgMessage;
 class MessageBuffer;
@@ -105,4 +108,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(DebuggerConnectionHandler);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_DBG_CONNECTION_H_
diff --git a/runtime/bin/dbg_connection_android.cc b/runtime/bin/dbg_connection_android.cc
index 0fc57ac..92fb7ca5 100644
--- a/runtime/bin/dbg_connection_android.cc
+++ b/runtime/bin/dbg_connection_android.cc
@@ -15,6 +15,10 @@
 #include "bin/log.h"
 #include "bin/socket.h"
 
+
+namespace dart {
+namespace bin {
+
 int DebuggerConnectionImpl::epoll_fd_ = -1;
 int DebuggerConnectionImpl::wakeup_fds_[2] = {-1, -1};
 
@@ -119,4 +123,7 @@
   return TEMP_FAILURE_RETRY(read(socket, buf, len));
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/dbg_connection_android.h b/runtime/bin/dbg_connection_android.h
index f762c73..c1c16c5 100644
--- a/runtime/bin/dbg_connection_android.h
+++ b/runtime/bin/dbg_connection_android.h
@@ -10,6 +10,9 @@
 #include <sys/socket.h>
 
 
+namespace dart {
+namespace bin {
+
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
@@ -28,4 +31,7 @@
   static int epoll_fd_;
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_DBG_CONNECTION_ANDROID_H_
diff --git a/runtime/bin/dbg_connection_linux.cc b/runtime/bin/dbg_connection_linux.cc
index c278987..020b8cb 100644
--- a/runtime/bin/dbg_connection_linux.cc
+++ b/runtime/bin/dbg_connection_linux.cc
@@ -15,6 +15,10 @@
 #include "bin/log.h"
 #include "bin/socket.h"
 
+
+namespace dart {
+namespace bin {
+
 int DebuggerConnectionImpl::epoll_fd_ = -1;
 int DebuggerConnectionImpl::wakeup_fds_[2] = {-1, -1};
 
@@ -119,4 +123,7 @@
   return TEMP_FAILURE_RETRY(read(socket, buf, len));
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/dbg_connection_linux.h b/runtime/bin/dbg_connection_linux.h
index 12b0395..94a9664 100644
--- a/runtime/bin/dbg_connection_linux.h
+++ b/runtime/bin/dbg_connection_linux.h
@@ -10,6 +10,9 @@
 #include <sys/socket.h>
 
 
+namespace dart {
+namespace bin {
+
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
@@ -28,4 +31,7 @@
   static int epoll_fd_;
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_DBG_CONNECTION_LINUX_H_
diff --git a/runtime/bin/dbg_connection_macos.cc b/runtime/bin/dbg_connection_macos.cc
index a3e17fd..4fd2d1d 100644
--- a/runtime/bin/dbg_connection_macos.cc
+++ b/runtime/bin/dbg_connection_macos.cc
@@ -21,6 +21,9 @@
 #include "platform/utils.h"
 
 
+namespace dart {
+namespace bin {
+
 #define INVALID_FD -1
 
 int DebuggerConnectionImpl::kqueue_fd_ = INVALID_FD;
@@ -173,4 +176,7 @@
   return TEMP_FAILURE_RETRY(read(socket, buf, len));
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/dbg_connection_macos.h b/runtime/bin/dbg_connection_macos.h
index f6962ff..9665700 100644
--- a/runtime/bin/dbg_connection_macos.h
+++ b/runtime/bin/dbg_connection_macos.h
@@ -10,6 +10,9 @@
 #include <sys/socket.h>
 
 
+namespace dart {
+namespace bin {
+
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
@@ -42,5 +45,7 @@
   static int kqueue_fd_;
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_DBG_CONNECTION_MACOS_H_
diff --git a/runtime/bin/dbg_connection_win.cc b/runtime/bin/dbg_connection_win.cc
index a241c85..bd650a4 100644
--- a/runtime/bin/dbg_connection_win.cc
+++ b/runtime/bin/dbg_connection_win.cc
@@ -9,6 +9,10 @@
 
 #include "bin/eventhandler.h"
 
+
+namespace dart {
+namespace bin {
+
 void DebuggerConnectionImpl::ThreadEntry(uword args) {
   ListenSocket* listen_socket =
       reinterpret_cast<ListenSocket*>(DebuggerConnectionHandler::listener_fd_);
@@ -43,4 +47,7 @@
   return recv(client_socket->socket(), buf, len, 0);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/dbg_connection_win.h b/runtime/bin/dbg_connection_win.h
index 24ac711..2a9feb2 100644
--- a/runtime/bin/dbg_connection_win.h
+++ b/runtime/bin/dbg_connection_win.h
@@ -5,6 +5,9 @@
 #ifndef BIN_DBG_CONNECTION_WIN_H_
 #define BIN_DBG_CONNECTION_WIN_H_
 
+namespace dart {
+namespace bin {
+
 class DebuggerConnectionImpl {
  public:
   static void StartHandler(int port_number);
@@ -15,4 +18,7 @@
   static void ThreadEntry(uword args);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_DBG_CONNECTION_WIN_H_
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 4d9422d..5713657 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -15,6 +15,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 bool MessageParser::IsValidMessage() const {
   if (buf_length_ == 0) {
     return false;
@@ -805,7 +809,7 @@
   msg.Printf("{ \"id\": %d, ", msg_id);
   msg.Printf("\"result\": { \"lines\": [");
   Dart_Handle elem;
-  bool num_elems = 0;
+  intptr_t num_elems = 0;
   for (intptr_t i = 0; i < info_len; i++) {
     elem = Dart_ListGetAt(info, i);
     if (Dart_IsNull(elem)) {
@@ -1160,6 +1164,21 @@
 }
 
 
+void DbgMsgQueueList::ListIsolateIds(dart::TextBuffer* msg) {
+  MutexLocker ml(&msg_queue_list_lock_);
+  if (list_ == NULL) {
+    return;  // No items in the list.
+  }
+  DbgMsgQueue* queue = list_;
+  msg->Printf("%"Pd64"", queue->isolate_id());
+  queue = queue->next();
+  while (queue != NULL) {
+    msg->Printf(",%"Pd64"", queue->isolate_id());
+    queue = queue->next();
+  }
+}
+
+
 void DbgMsgQueueList::BptResolvedHandler(Dart_IsolateId isolate_id,
                                          intptr_t bp_id,
                                          const Dart_CodeLocation& location) {
@@ -1231,3 +1250,6 @@
   }
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/dbg_message.h b/runtime/bin/dbg_message.h
index e30a421..85be1a5 100644
--- a/runtime/bin/dbg_message.h
+++ b/runtime/bin/dbg_message.h
@@ -15,6 +15,9 @@
 #include "platform/thread.h"
 
 
+namespace dart {
+namespace bin {
+
 // TODO(hausner): Need better error handling.
 #define ASSERT_NOT_ERROR(handle)          \
   ASSERT(!Dart_IsError(handle))
@@ -245,6 +248,9 @@
   static void IsolateEventHandler(Dart_IsolateId isolate_id,
                                   Dart_IsolateEvent kind);
 
+  // Print list of isolate ids of all message queues into text buffer.
+  static void ListIsolateIds(dart::TextBuffer* msg);
+
  private:
   static DbgMsgQueue* GetIsolateMsgQueueLocked(Dart_IsolateId isolate_id);
 
@@ -255,4 +261,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(DbgMsgQueueList);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_DBG_MESSAGE_H_
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index c218595..758df5a 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -10,6 +10,9 @@
 #include "platform/assert.h"
 
 
+namespace dart {
+namespace bin {
+
 // Forward declaration.
 static void DirectoryService(Dart_Port, Dart_Port, Dart_CObject*);
 
@@ -375,3 +378,6 @@
       args));
   return true;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 331b4c4..a8dde3d 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -11,6 +11,10 @@
 #include "platform/globals.h"
 #include "platform/thread.h"
 
+
+namespace dart {
+namespace bin {
+
 class DirectoryListing {
  public:
   virtual ~DirectoryListing() {}
@@ -114,5 +118,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Directory);
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_DIRECTORY_H_
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index 58060d8..7c30274 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -17,6 +17,10 @@
 #include "bin/file.h"
 #include "bin/platform.h"
 
+
+namespace dart {
+namespace bin {
+
 class PathBuffer {
  public:
   PathBuffer() : length(0) {
@@ -515,4 +519,7 @@
   return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index 2f86f5b..67ac947 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -17,6 +17,10 @@
 #include "bin/file.h"
 #include "bin/platform.h"
 
+
+namespace dart {
+namespace bin {
+
 class PathBuffer {
  public:
   PathBuffer() : length(0) {
@@ -482,4 +486,7 @@
   return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index ece3685..5c7b115 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -17,6 +17,10 @@
 #include "bin/file.h"
 #include "bin/platform.h"
 
+
+namespace dart {
+namespace bin {
+
 class PathBuffer {
  public:
   PathBuffer() : length(0) {
@@ -482,4 +486,7 @@
   return (TEMP_FAILURE_RETRY(rename(path, new_path)) == 0);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index 79c7b08..dc6cd69 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -13,6 +13,11 @@
 
 #include "bin/log.h"
 
+#undef DeleteFile
+
+namespace dart {
+namespace bin {
+
 class PathBuffer {
  public:
   PathBuffer() : length(0) {
@@ -524,4 +529,7 @@
   return (move_status != 0);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/eventhandler.cc b/runtime/bin/eventhandler.cc
index c1e88e7..94f0778 100644
--- a/runtime/bin/eventhandler.cc
+++ b/runtime/bin/eventhandler.cc
@@ -9,6 +9,9 @@
 #include "include/dart_api.h"
 
 
+namespace dart {
+namespace bin {
+
 static const int kNativeEventHandlerFieldIndex = 0;
 static const intptr_t kTimerId = -1;
 static const intptr_t kInvalidId = -2;
@@ -76,3 +79,6 @@
   event_handler->SendData(id, dart_port, data);
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index c487c52..5d7832e 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -8,6 +8,9 @@
 #include "bin/builtin.h"
 #include "bin/isolate_data.h"
 
+namespace dart {
+namespace bin {
+
 // Flags used to provide information and actions to the eventhandler
 // when sending a message about a file descriptor. These flags should
 // be kept in sync with the constants in socket_impl.dart. For more
@@ -24,6 +27,8 @@
   kPipe = 17,
 };
 
+}  // namespace bin
+}  // namespace dart
 
 // The event handler delegation class is OS specific.
 #if defined(TARGET_OS_ANDROID)
@@ -38,6 +43,9 @@
 #error Unknown target os.
 #endif
 
+namespace dart {
+namespace bin {
+
 class EventHandler {
  public:
   void SendData(intptr_t id, Dart_Port dart_port, int64_t data) {
@@ -62,5 +70,7 @@
   EventHandlerImplementation delegate_;
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_EVENTHANDLER_H_
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index 2a708fd..9f7a8ee 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -24,6 +24,9 @@
 #include "platform/utils.h"
 
 
+namespace dart {
+namespace bin {
+
 static const int kInterruptMessageSize = sizeof(InterruptMessage);
 static const int kInfinityTimeout = -1;
 static const int kTimerId = -1;
@@ -425,4 +428,7 @@
   return dart::Utils::WordHash(fd + 1);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/eventhandler_android.h b/runtime/bin/eventhandler_android.h
index dfe2ff2..5196023 100644
--- a/runtime/bin/eventhandler_android.h
+++ b/runtime/bin/eventhandler_android.h
@@ -15,6 +15,10 @@
 
 #include "platform/hashmap.h"
 
+
+namespace dart {
+namespace bin {
+
 class InterruptMessage {
  public:
   intptr_t id;
@@ -118,5 +122,7 @@
   int epoll_fd_;
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_EVENTHANDLER_ANDROID_H_
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index 8cda792..e2e2746 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -24,6 +24,9 @@
 #include "platform/utils.h"
 
 
+namespace dart {
+namespace bin {
+
 static const int kInterruptMessageSize = sizeof(InterruptMessage);
 static const int kInfinityTimeout = -1;
 static const int kTimerId = -1;
@@ -431,4 +434,7 @@
   return dart::Utils::WordHash(fd + 1);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/eventhandler_linux.h b/runtime/bin/eventhandler_linux.h
index e44e283..4c423f2 100644
--- a/runtime/bin/eventhandler_linux.h
+++ b/runtime/bin/eventhandler_linux.h
@@ -10,10 +10,15 @@
 #endif
 
 #include <unistd.h>
+#include <sys/epoll.h>
 #include <sys/socket.h>
 
 #include "platform/hashmap.h"
 
+
+namespace dart {
+namespace bin {
+
 class InterruptMessage {
  public:
   intptr_t id;
@@ -117,5 +122,7 @@
   int epoll_fd_;
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_EVENTHANDLER_LINUX_H_
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index 5972cfb..6823ef8 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -23,6 +23,9 @@
 #include "platform/utils.h"
 
 
+namespace dart {
+namespace bin {
+
 static const int kInterruptMessageSize = sizeof(InterruptMessage);
 static const int kInfinityTimeout = -1;
 static const int kTimerId = -1;
@@ -435,4 +438,7 @@
   return dart::Utils::WordHash(fd + 1);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/eventhandler_macos.h b/runtime/bin/eventhandler_macos.h
index cbc6040..4303586 100644
--- a/runtime/bin/eventhandler_macos.h
+++ b/runtime/bin/eventhandler_macos.h
@@ -10,10 +10,15 @@
 #endif
 
 #include <unistd.h>
+#include <sys/event.h>  // NOLINT
 #include <sys/socket.h>
 
 #include "platform/hashmap.h"
 
+
+namespace dart {
+namespace bin {
+
 class InterruptMessage {
  public:
   intptr_t id;
@@ -130,5 +135,7 @@
   int kqueue_fd_;
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_EVENTHANDLER_MACOS_H_
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 3ed6e3f..6a43dd5 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -20,6 +20,9 @@
 #include "platform/thread.h"
 
 
+namespace dart {
+namespace bin {
+
 static const int kBufferSize = 32 * 1024;
 
 static const int kInfinityTimeout = -1;
@@ -991,4 +994,7 @@
   SendData(kShutdownId, 0, 0);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 09044e0..30d229b 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -15,6 +15,9 @@
 #include "bin/builtin.h"
 
 
+namespace dart {
+namespace bin {
+
 // Forward declarations.
 class EventHandlerImplementation;
 class Handle;
@@ -392,5 +395,7 @@
   HANDLE completion_port_;
 };
 
+}  // namespace bin
+}  // namespace dart
 
 #endif  // BIN_EVENTHANDLER_WIN_H_
diff --git a/runtime/bin/extensions.cc b/runtime/bin/extensions.cc
index d8b13f9..71eaeac 100644
--- a/runtime/bin/extensions.cc
+++ b/runtime/bin/extensions.cc
@@ -12,6 +12,10 @@
 #include "bin/dartutils.h"
 #include "bin/file.h"
 
+
+namespace dart {
+namespace bin {
+
 Dart_Handle Extensions::LoadExtension(const char* extension_url,
                                       Dart_Handle parent_library) {
   char* library_path = strdup(extension_url);
@@ -62,3 +66,6 @@
   ASSERT(result[size - 1] == '\0');
   return result;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/extensions.h b/runtime/bin/extensions.h
index a233a25..6f3853c 100644
--- a/runtime/bin/extensions.h
+++ b/runtime/bin/extensions.h
@@ -8,6 +8,10 @@
 #include "include/dart_api.h"
 #include "platform/globals.h"
 
+
+namespace dart {
+namespace bin {
+
 class Extensions {
  public:
   // TODO(whesse): Make extension load from a relative path relative to
@@ -28,4 +32,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Extensions);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_EXTENSIONS_H_
diff --git a/runtime/bin/extensions_android.cc b/runtime/bin/extensions_android.cc
index b136736..72c757f 100644
--- a/runtime/bin/extensions_android.cc
+++ b/runtime/bin/extensions_android.cc
@@ -8,6 +8,10 @@
 #include "bin/extensions.h"
 #include <dlfcn.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 void* Extensions::LoadExtensionLibrary(const char* library_path,
                                        const char* extension_name) {
   const char* strings[] = { library_path, "/lib",
@@ -25,4 +29,7 @@
   return result;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/extensions_linux.cc b/runtime/bin/extensions_linux.cc
index 8321efe..3920ade 100644
--- a/runtime/bin/extensions_linux.cc
+++ b/runtime/bin/extensions_linux.cc
@@ -8,6 +8,10 @@
 #include "bin/extensions.h"
 #include <dlfcn.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 void* Extensions::LoadExtensionLibrary(const char* library_path,
                                        const char* extension_name) {
   const char* strings[] = { library_path, "/lib",
@@ -25,4 +29,7 @@
   return result;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/extensions_macos.cc b/runtime/bin/extensions_macos.cc
index 6d7842a..bfda5e7 100644
--- a/runtime/bin/extensions_macos.cc
+++ b/runtime/bin/extensions_macos.cc
@@ -8,6 +8,10 @@
 #include "bin/extensions.h"
 #include <dlfcn.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 void* Extensions::LoadExtensionLibrary(const char* library_path,
                                        const char* extension_name) {
   const char* strings[] = { library_path, "/lib",
@@ -25,4 +29,7 @@
   return result;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc
index 9e8a653..0f764d3 100644
--- a/runtime/bin/extensions_win.cc
+++ b/runtime/bin/extensions_win.cc
@@ -8,6 +8,10 @@
 #include "bin/extensions.h"
 #include "bin/utils.h"
 
+
+namespace dart {
+namespace bin {
+
 void* Extensions::LoadExtensionLibrary(const char* library_path,
                                        const char* extension_name) {
   const char* strings[] = { library_path, "/", extension_name, ".dll", NULL };
@@ -23,4 +27,7 @@
   return GetProcAddress(reinterpret_cast<HMODULE>(lib_handle), symbol);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/fdutils.h b/runtime/bin/fdutils.h
index 6771f21..da4fcf5 100644
--- a/runtime/bin/fdutils.h
+++ b/runtime/bin/fdutils.h
@@ -8,6 +8,10 @@
 #include "bin/builtin.h"
 #include "platform/globals.h"
 
+
+namespace dart {
+namespace bin {
+
 class FDUtils {
  public:
   static bool SetCloseOnExec(intptr_t fd);
@@ -41,4 +45,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(FDUtils);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_FDUTILS_H_
diff --git a/runtime/bin/fdutils_android.cc b/runtime/bin/fdutils_android.cc
index 18b4ec3..7a60387 100644
--- a/runtime/bin/fdutils_android.cc
+++ b/runtime/bin/fdutils_android.cc
@@ -13,6 +13,9 @@
 #include "bin/fdutils.h"
 
 
+namespace dart {
+namespace bin {
+
 bool FDUtils::SetCloseOnExec(intptr_t fd) {
   intptr_t status;
   status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD));
@@ -136,4 +139,7 @@
   return count;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/fdutils_linux.cc b/runtime/bin/fdutils_linux.cc
index 84c2194..a763c9b 100644
--- a/runtime/bin/fdutils_linux.cc
+++ b/runtime/bin/fdutils_linux.cc
@@ -13,6 +13,9 @@
 #include "bin/fdutils.h"
 
 
+namespace dart {
+namespace bin {
+
 bool FDUtils::SetCloseOnExec(intptr_t fd) {
   intptr_t status;
   status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD));
@@ -136,4 +139,7 @@
   return count;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/fdutils_macos.cc b/runtime/bin/fdutils_macos.cc
index 7087add..65f2832 100644
--- a/runtime/bin/fdutils_macos.cc
+++ b/runtime/bin/fdutils_macos.cc
@@ -13,6 +13,9 @@
 #include "bin/fdutils.h"
 
 
+namespace dart {
+namespace bin {
+
 bool FDUtils::SetCloseOnExec(intptr_t fd) {
   intptr_t status;
   status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD));
@@ -137,4 +140,7 @@
   return count;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index c9fc1b2..de9d1e9 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -12,8 +12,10 @@
 
 #include "include/dart_api.h"
 
-static const int kMSPerSecond = 1000;
+namespace dart {
+namespace bin {
 
+static const int kMSPerSecond = 1000;
 
 // Forward declaration.
 static void FileService(Dart_Port, Dart_Port, Dart_CObject*);
@@ -1169,3 +1171,6 @@
   }
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 944fd6a..9e12463 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -16,6 +16,10 @@
 #include "platform/globals.h"
 #include "platform/thread.h"
 
+
+namespace dart {
+namespace bin {
+
 // Forward declaration.
 class FileHandle;
 
@@ -164,4 +168,7 @@
   DISALLOW_COPY_AND_ASSIGN(File);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_FILE_H_
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 2d7c99d..9bb5e1a 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -16,6 +16,10 @@
 #include "bin/builtin.h"
 #include "bin/log.h"
 
+
+namespace dart {
+namespace bin {
+
 class FileHandle {
  public:
   explicit FileHandle(int fd) : fd_(fd) { }
@@ -315,4 +319,7 @@
       File::kDifferent;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index 8126ff9..26c047d 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -16,6 +16,10 @@
 #include "bin/builtin.h"
 #include "bin/log.h"
 
+
+namespace dart {
+namespace bin {
+
 class FileHandle {
  public:
   explicit FileHandle(int fd) : fd_(fd) { }
@@ -316,4 +320,7 @@
       File::kDifferent;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index a5af904..0b99153 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -18,6 +18,10 @@
 #include "bin/fdutils.h"
 #include "bin/log.h"
 
+
+namespace dart {
+namespace bin {
+
 class FileHandle {
  public:
   explicit FileHandle(int fd) : fd_(fd) { }
@@ -324,4 +328,7 @@
       File::kDifferent;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/file_test.cc b/runtime/bin/file_test.cc
index 5765cf2..20c6bf7 100644
--- a/runtime/bin/file_test.cc
+++ b/runtime/bin/file_test.cc
@@ -8,6 +8,9 @@
 #include "vm/unit_test.h"
 
 
+namespace dart {
+namespace bin {
+
 // Helper method to be able to run the test from the runtime
 // directory, or the top directory.
 static const char* GetFileName(const char* name) {
@@ -56,3 +59,6 @@
   EXPECT_EQ(18, file->Position());
   delete file;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 78074cc..6877fb3 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -17,6 +17,10 @@
 #include "bin/builtin.h"
 #include "bin/log.h"
 
+
+namespace dart {
+namespace bin {
+
 class FileHandle {
  public:
   explicit FileHandle(int fd) : fd_(fd) { }
@@ -551,4 +555,7 @@
   }
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
index 1a609c5..a423651 100644
--- a/runtime/bin/filter.cc
+++ b/runtime/bin/filter.cc
@@ -8,6 +8,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 const int kZlibFlagMemUsage = 8;
 const int kZLibFlagWindowBits = 15;
 const int kZLibFlagUseGZipHeader = 16;
@@ -304,3 +308,5 @@
   }
 }
 
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/filter.h b/runtime/bin/filter.h
index cc3a0a9..fcfaa0e 100644
--- a/runtime/bin/filter.h
+++ b/runtime/bin/filter.h
@@ -10,6 +10,10 @@
 
 #include "../third_party/zlib/zlib.h"
 
+
+namespace dart {
+namespace bin {
+
 class Filter {
  public:
   virtual ~Filter() {}
@@ -80,5 +84,7 @@
   DISALLOW_COPY_AND_ASSIGN(ZLibInflateFilter);
 };
 
-#endif  // BIN_FILTER_H_
+}  // namespace bin
+}  // namespace dart
 
+#endif  // BIN_FILTER_H_
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index ea69119..d5e0a5e 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -18,6 +18,10 @@
 
 #include "platform/globals.h"
 
+
+namespace dart {
+namespace bin {
+
 #define CHECK_RESULT(result)                                                   \
   if (Dart_IsError(result)) {                                                  \
     free(snapshot_buffer);                                                     \
@@ -296,6 +300,11 @@
     return ResolveUri(library_url_string, url_string);
   }
 
+  if (DartUtils::IsDartIOLibURL(url_string) && mapped_url_string == NULL) {
+    // No url mapping for dart:io. Load original version.
+    return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
+  }
+
   Dart_Handle resolved_url = url;
   if (mapped_url_string != NULL) {
     // Mapped urls are relative to working directory.
@@ -428,13 +437,8 @@
 static void SetupForGenericSnapshotCreation() {
   SetupForUriResolution();
 
-  // TODO(regis): Reenable this code for mips when possible.
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
   Dart_Handle library = LoadGenericSnapshotCreationScript(Builtin::kIOLibrary);
   VerifyLoaded(library);
-#endif
 }
 
 
@@ -528,3 +532,10 @@
   }
   return 0;
 }
+
+}  // namespace bin
+}  // namespace dart
+
+int main(int argc, char** argv) {
+  return dart::bin::main(argc, argv);
+}
diff --git a/runtime/bin/io.dart b/runtime/bin/io.dart
index 4b2e666..2bec045 100644
--- a/runtime/bin/io.dart
+++ b/runtime/bin/io.dart
@@ -14,6 +14,6 @@
 import 'dart:json' as JSON;
 import "dart:math";
 import "dart:nativewrappers";
-import "dart:typeddata";
+import "dart:typed_data";
 import "dart:uri";
 import "dart:utf";
diff --git a/runtime/bin/io_buffer.cc b/runtime/bin/io_buffer.cc
index b1bc958..65fe234 100644
--- a/runtime/bin/io_buffer.cc
+++ b/runtime/bin/io_buffer.cc
@@ -4,6 +4,10 @@
 
 #include "bin/io_buffer.h"
 
+
+namespace dart {
+namespace bin {
+
 Dart_Handle IOBuffer::Allocate(intptr_t size, uint8_t **buffer) {
   uint8_t* data = Allocate(size);
   Dart_Handle result = Dart_NewExternalTypedData(kUint8,
@@ -22,3 +26,6 @@
 uint8_t* IOBuffer::Allocate(intptr_t size) {
   return new uint8_t[size];
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/io_buffer.h b/runtime/bin/io_buffer.h
index 0c73164..06ce0a6 100644
--- a/runtime/bin/io_buffer.h
+++ b/runtime/bin/io_buffer.h
@@ -9,6 +9,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 class IOBuffer {
  public:
   // Allocate an IO buffer dart object (of type Uint8List) backed by
@@ -37,4 +41,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(IOBuffer);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_IO_BUFFER_H_
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index a5c6a9f..0b4cedd 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -13,6 +13,9 @@
 #include "platform/assert.h"
 
 
+namespace dart {
+namespace bin {
+
 // Lists the native functions implementing advanced dart:io classes.
 // Some classes, like File and Directory, list their implementations in
 // builtin_natives.cc instead.
@@ -91,3 +94,6 @@
   }
   return NULL;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/io_natives.h b/runtime/bin/io_natives.h
index 1745555..dac7fce 100644
--- a/runtime/bin/io_natives.h
+++ b/runtime/bin/io_natives.h
@@ -7,7 +7,14 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 Dart_NativeFunction IONativeLookup(Dart_Handle name,
                                    int argument_count);
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_IO_NATIVES_H_
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index 7824285..9b0806e 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -8,6 +8,10 @@
 #include "include/dart_api.h"
 #include "platform/globals.h"
 
+
+namespace dart {
+namespace bin {
+
 // Forward declaration.
 class EventHandler;
 
@@ -30,4 +34,7 @@
   DISALLOW_COPY_AND_ASSIGN(IsolateData);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_ISOLATE_DATA_H_
diff --git a/runtime/bin/log.h b/runtime/bin/log.h
index c495840..10629d5 100644
--- a/runtime/bin/log.h
+++ b/runtime/bin/log.h
@@ -9,6 +9,10 @@
 
 #include "platform/globals.h"
 
+
+namespace dart {
+namespace bin {
+
 class Log {
  public:
   // Print formatted output for debugging.
@@ -34,4 +38,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Log);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_LOG_H_
diff --git a/runtime/bin/log_android.cc b/runtime/bin/log_android.cc
index 5f878f2..e8d8e68 100644
--- a/runtime/bin/log_android.cc
+++ b/runtime/bin/log_android.cc
@@ -10,6 +10,10 @@
 #include <stdio.h>  // NOLINT
 #include <android/log.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 // TODO(gram): We should be buffering the data and only outputting
 // it when we see a '\n'.
 
@@ -21,4 +25,7 @@
   __android_log_vprint(ANDROID_LOG_ERROR, "Dart", format, args);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/log_linux.cc b/runtime/bin/log_linux.cc
index 0b825af..f398c9e 100644
--- a/runtime/bin/log_linux.cc
+++ b/runtime/bin/log_linux.cc
@@ -9,6 +9,10 @@
 
 #include <stdio.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 void Log::VPrint(const char* format, va_list args) {
   vfprintf(stdout, format, args);
   fflush(stdout);
@@ -19,4 +23,7 @@
   fflush(stdout);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/log_macos.cc b/runtime/bin/log_macos.cc
index 87c9075..3711245 100644
--- a/runtime/bin/log_macos.cc
+++ b/runtime/bin/log_macos.cc
@@ -9,6 +9,10 @@
 
 #include <stdio.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 void Log::VPrint(const char* format, va_list args) {
   vfprintf(stdout, format, args);
   fflush(stdout);
@@ -19,4 +23,7 @@
   fflush(stderr);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/log_win.cc b/runtime/bin/log_win.cc
index 30c265d..9fb69cf 100644
--- a/runtime/bin/log_win.cc
+++ b/runtime/bin/log_win.cc
@@ -9,6 +9,10 @@
 
 #include <stdio.h>  // NOLINT
 
+
+namespace dart {
+namespace bin {
+
 void Log::VPrint(const char* format, va_list args) {
   vfprintf(stdout, format, args);
   fflush(stdout);
@@ -19,4 +23,7 @@
   fflush(stderr);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 41f2ba9..96ec295 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -23,11 +23,13 @@
 #include "bin/vmstats_impl.h"
 #include "platform/globals.h"
 
+namespace dart {
+namespace bin {
+
 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise
 // it is initialized to NULL.
 extern const uint8_t* snapshot_buffer;
 
-
 // Global state that stores a pointer to the application script snapshot.
 static bool generate_script_snapshot = false;
 static File* snapshot_file = NULL;
@@ -862,3 +864,10 @@
 
   return Process::GlobalExitCode();
 }
+
+}  // namespace bin
+}  // namespace dart
+
+int main(int argc, char** argv) {
+  return dart::bin::main(argc, argv);
+}
diff --git a/runtime/bin/native_service.cc b/runtime/bin/native_service.cc
index 9d4c3e8..37506aa 100644
--- a/runtime/bin/native_service.cc
+++ b/runtime/bin/native_service.cc
@@ -8,6 +8,9 @@
 #include "bin/thread.h"
 
 
+namespace dart {
+namespace bin {
+
 NativeService::NativeService(const char* name,
                              Dart_NativeMessageHandler handler,
                              int number_of_ports)
@@ -38,3 +41,6 @@
   service_ports_index_ = (service_ports_index_ + 1) % service_ports_size_;
   return result;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/native_service.h b/runtime/bin/native_service.h
index 8bb4330..ff1b0bf 100644
--- a/runtime/bin/native_service.h
+++ b/runtime/bin/native_service.h
@@ -9,6 +9,10 @@
 #include "platform/globals.h"
 #include "platform/thread.h"
 
+
+namespace dart {
+namespace bin {
+
 // Utility class to set up a native service and allocate Dart native
 // ports to interact with it from Dart code. The number of native ports
 // allocated for each service is limited.
@@ -42,4 +46,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(NativeService);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_NATIVE_SERVICE_H_
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 7e76c09..c47194e 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -6,6 +6,8 @@
 #include "bin/platform.h"
 #include "include/dart_api.h"
 
+namespace dart {
+namespace bin {
 
 void FUNCTION_NAME(Platform_NumberOfProcessors)(Dart_NativeArguments args) {
   Dart_EnterScope();
@@ -73,3 +75,6 @@
   }
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 9ee2172..54412ba 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -7,6 +7,10 @@
 
 #include "bin/builtin.h"
 
+
+namespace dart {
+namespace bin {
+
 class Platform {
  public:
   // Perform platform specific initialization.
@@ -35,4 +39,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Platform);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_PLATFORM_H_
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index 435f16b..e069d5a 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -12,6 +12,9 @@
 #include <unistd.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 bool Platform::Initialize() {
   // Turn off the signal handler for SIGPIPE as it causes the process
   // to terminate on writing to a closed pipe. Without the signal
@@ -69,4 +72,7 @@
   delete[] env;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 48f6154..4a70ee5 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -12,6 +12,9 @@
 #include <unistd.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 bool Platform::Initialize() {
   // Turn off the signal handler for SIGPIPE as it causes the process
   // to terminate on writing to a closed pipe. Without the signal
@@ -69,4 +72,7 @@
   delete[] env;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index d538eb7..e1b914b 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -13,6 +13,9 @@
 #include <unistd.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 bool Platform::Initialize() {
   // Turn off the signal handler for SIGPIPE as it causes the process
   // to terminate on writing to a closed pipe. Without the signal
@@ -74,4 +77,7 @@
   delete[] env;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index a71a455..3ba9303 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -9,6 +9,10 @@
 #include "bin/log.h"
 #include "bin/socket.h"
 
+
+namespace dart {
+namespace bin {
+
 bool Platform::Initialize() {
   // Nothing to do on Windows.
   return true;
@@ -59,4 +63,7 @@
   delete[] env;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index c112e85..df53cd5 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -9,6 +9,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 static const int kProcessIdNativeField = 0;
 
 int Process::global_exit_code_ = 0;
@@ -260,3 +264,6 @@
   Dart_SetReturnValue(args, external_array);
   Dart_ExitScope();
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/process.h b/runtime/bin/process.h
index d0ac1bc..c0d8b8b 100644
--- a/runtime/bin/process.h
+++ b/runtime/bin/process.h
@@ -10,6 +10,9 @@
 #include "platform/globals.h"
 
 
+namespace dart {
+namespace bin {
+
 class Process {
  public:
   // Start a new process providing access to stdin, stdout, stderr and
@@ -59,4 +62,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Process);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_PROCESS_H_
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index f0bbb83..677097b 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -22,6 +22,9 @@
 #include "bin/thread.h"
 
 
+namespace dart {
+namespace bin {
+
 // ProcessInfo is used to map a process id to the file descriptor for
 // the pipe used to communicate the exit code of the process to Dart.
 // ProcessInfo objects are kept in the static singly-linked
@@ -570,4 +573,7 @@
   return static_cast<intptr_t>(getpid());
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 9ff0ce7..838dc27 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -23,6 +23,10 @@
 
 extern char **environ;
 
+
+namespace dart {
+namespace bin {
+
 // ProcessInfo is used to map a process id to the file descriptor for
 // the pipe used to communicate the exit code of the process to Dart.
 // ProcessInfo objects are kept in the static singly-linked
@@ -566,4 +570,7 @@
   return static_cast<intptr_t>(getpid());
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index fb60ecd..0022a8b 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -22,6 +22,10 @@
 
 extern char **environ;
 
+
+namespace dart {
+namespace bin {
+
 // ProcessInfo is used to map a process id to the file descriptor for
 // the pipe used to communicate the exit code of the process to Dart.
 // ProcessInfo objects are kept in the static singly-linked
@@ -564,4 +568,7 @@
   return static_cast<intptr_t>(getpid());
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index 407dd37..1237f13 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -14,6 +14,10 @@
 #include "bin/thread.h"
 #include "bin/utils.h"
 
+
+namespace dart {
+namespace bin {
+
 static const int kReadHandle = 0;
 static const int kWriteHandle = 1;
 
@@ -663,4 +667,7 @@
   return static_cast<intptr_t>(GetCurrentProcessId());
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/resources.h b/runtime/bin/resources.h
index 6279bba..0f3f7c3 100644
--- a/runtime/bin/resources.h
+++ b/runtime/bin/resources.h
@@ -11,6 +11,9 @@
 #include "platform/assert.h"
 
 
+namespace dart {
+namespace bin {
+
 class Resources {
  public:
   static const int kNoSuchInstance = -1;
@@ -50,4 +53,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_RESOURCES_H_
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index e66ff35..4f7bd6b 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -30,6 +30,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 bool SSLFilter::library_initialized_ = false;
 dart::Mutex SSLFilter::mutex_;  // To protect library initialization.
 // The password is needed when creating secure server sockets.  It can
@@ -560,19 +564,17 @@
 
   // SetPeerAddress
   PRNetAddr host_address;
-  char host_entry_buffer[PR_NETDB_BUF_SIZE];
-  PRHostEnt host_entry;
-  PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer,
-                                 PR_NETDB_BUF_SIZE, &host_entry);
-  if (rv != PR_SUCCESS) {
-    ThrowPRException("Failed PR_GetHostByName call");
+  PRAddrInfo* info = PR_GetAddrInfoByName(host_name,
+                                          PR_AF_UNSPEC,
+                                          PR_AI_ADDRCONFIG);
+  if (info == NULL) {
+    ThrowPRException("Failed PR_GetAddrInfoByName call");
   }
 
-  int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address);
-  if (index == -1 || index == 0) {
-    ThrowPRException("Failed PR_EnumerateHostEnt call");
-  }
+  PR_EnumerateAddrInfo(0, info, port, &host_address);
+
   memio_SetPeerName(filter_, &host_address);
+  PR_FreeAddrInfo(info);
 }
 
 
@@ -716,3 +718,6 @@
   }
   return bytes_processed;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/secure_socket.h b/runtime/bin/secure_socket.h
index 551fde0..536a77a 100644
--- a/runtime/bin/secure_socket.h
+++ b/runtime/bin/secure_socket.h
@@ -20,6 +20,10 @@
 #include "platform/globals.h"
 #include "platform/thread.h"
 
+
+namespace dart {
+namespace bin {
+
 static void ThrowException(const char* message) {
   Dart_Handle socket_io_exception =
       DartUtils::NewDartSocketIOException(message, Dart_Null());
@@ -120,4 +124,7 @@
   DISALLOW_COPY_AND_ASSIGN(SSLFilter);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_SECURE_SOCKET_H_
diff --git a/runtime/bin/snapshot_empty.cc b/runtime/bin/snapshot_empty.cc
index abc5522..f8c3f95 100644
--- a/runtime/bin/snapshot_empty.cc
+++ b/runtime/bin/snapshot_empty.cc
@@ -13,4 +13,11 @@
 #endif
 #include <stddef.h>
 
+
+namespace dart {
+namespace bin {
+
 const uint8_t* snapshot_buffer = NULL;
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/snapshot_in.cc b/runtime/bin/snapshot_in.cc
index b281cd5..2e2a497 100644
--- a/runtime/bin/snapshot_in.cc
+++ b/runtime/bin/snapshot_in.cc
@@ -13,6 +13,10 @@
 #endif
 #include <stddef.h>
 
+
+namespace dart {
+namespace bin {
+
 // The string on the next line will be filled in with the contents of the
 // generated snapshot binary file.
 // This string forms the content of a snapshot which is loaded in by dart.
@@ -20,3 +24,6 @@
   %s
 };
 const uint8_t* snapshot_buffer = snapshot_buffer_;
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 3a35ea2..2593238 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -14,6 +14,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 static const int kSocketIdNativeField = 0;
 
 dart::Mutex Socket::mutex_;
@@ -21,19 +25,37 @@
 Dart_Port* Socket::service_ports_ = NULL;
 int Socket::service_ports_index_ = 0;
 
+
+static Dart_Handle GetSockAddr(Dart_Handle obj, RawAddr* addr) {
+  Dart_TypedData_Type data_type;
+  uint8_t* data = NULL;
+  intptr_t len;
+  Dart_Handle result = Dart_TypedDataAcquireData(
+      obj, &data_type, reinterpret_cast<void**>(&data), &len);
+  if (Dart_IsError(result)) return result;
+  memmove(reinterpret_cast<void *>(addr), data, len);
+  return Dart_Null();
+}
+
+
 void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
-  const char* host = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+  Dart_Handle host_obj = Dart_GetNativeArgument(args, 1);
+  RawAddr addr;
+  Dart_Handle result = GetSockAddr(host_obj, &addr);
   int64_t port = 0;
-  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &port)) {
-    intptr_t socket = Socket::CreateConnect(host, port);
+  if (!Dart_IsError(result) &&
+      DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &port)) {
+    intptr_t socket = Socket::CreateConnect(addr, port);
+    OSError error;
+    Dart_TypedDataReleaseData(host_obj);
     if (socket >= 0) {
       Dart_Handle err = Socket::SetSocketIdNativeField(socket_obj, socket);
       if (Dart_IsError(err)) Dart_PropagateError(err);
       Dart_SetReturnValue(args, Dart_True());
     } else {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+      Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
     }
   } else {
     OSError os_error(-1, "Invalid argument", OSError::kUnknown);
@@ -251,7 +273,8 @@
   if (Dart_IsError(err)) Dart_PropagateError(err);
   OSError os_error;
   intptr_t port = 0;
-  char host[INET_ADDRSTRLEN];
+  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+  char host[INET6_ADDRSTRLEN];
   if (Socket::GetRemotePeer(socket, host, &port)) {
     Dart_Handle list = Dart_NewList(2);
     Dart_ListSetAt(list, 0, Dart_NewStringFromCString(host));
@@ -310,17 +333,19 @@
 void FUNCTION_NAME(ServerSocket_CreateBindListen)(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle socket_obj = Dart_GetNativeArgument(args, 0);
-  Dart_Handle bind_address_obj = Dart_GetNativeArgument(args, 1);
+  Dart_Handle host_obj = Dart_GetNativeArgument(args, 1);
+  RawAddr addr;
+  Dart_Handle result = GetSockAddr(host_obj, &addr);
   Dart_Handle port_obj = Dart_GetNativeArgument(args, 2);
   Dart_Handle backlog_obj = Dart_GetNativeArgument(args, 3);
   int64_t port = 0;
   int64_t backlog = 0;
-  if (Dart_IsString(bind_address_obj) &&
+  if (!Dart_IsError(result) &&
       DartUtils::GetInt64Value(port_obj, &port) &&
       DartUtils::GetInt64Value(backlog_obj, &backlog)) {
-    const char* bind_address = DartUtils::GetStringValue(bind_address_obj);
-    intptr_t socket =
-        ServerSocket::CreateBindListen(bind_address, port, backlog);
+    intptr_t socket = ServerSocket::CreateBindListen(addr, port, backlog);
+    OSError error;
+    Dart_TypedDataReleaseData(host_obj);
     if (socket >= 0) {
       Dart_Handle err = Socket::SetSocketIdNativeField(socket_obj, socket);
       if (Dart_IsError(err)) Dart_PropagateError(err);
@@ -330,7 +355,7 @@
         OSError os_error(-1, "Invalid host", OSError::kUnknown);
         Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
       } else {
-        Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+        Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
       }
     }
   } else {
@@ -366,15 +391,43 @@
 
 
 static CObject* LookupRequest(const CObjectArray& request) {
-  if (request.Length() == 2 && request[1]->IsString()) {
+  if (request.Length() == 3 &&
+      request[1]->IsString() &&
+      request[2]->IsInt32()) {
     CObjectString host(request[1]);
+    CObjectInt32 type(request[2]);
     CObject* result = NULL;
     OSError* os_error = NULL;
-    const char* ip_address =
-        Socket::LookupIPv4Address(host.CString(), &os_error);
-    if (ip_address != NULL) {
-      result = new CObjectString(CObject::NewString(ip_address));
-      free(const_cast<char*>(ip_address));
+    SocketAddresses* addresses =
+        Socket::LookupAddress(host.CString(), type.Value(), &os_error);
+    if (addresses != NULL) {
+      CObjectArray* array = new CObjectArray(
+          CObject::NewArray(addresses->count() + 1));
+      array->SetAt(0, new CObjectInt32(CObject::NewInt32(0)));
+      for (intptr_t i = 0; i < addresses->count(); i++) {
+        SocketAddress* addr = addresses->GetAt(i);
+        CObjectArray* entry = new CObjectArray(CObject::NewArray(3));
+
+        CObjectInt32* type = new CObjectInt32(
+            CObject::NewInt32(addr->GetType()));
+        entry->SetAt(0, type);
+
+        CObjectString* as_string = new CObjectString(CObject::NewString(
+            addr->as_string()));
+        entry->SetAt(1, as_string);
+
+        RawAddr raw = addr->addr();
+        CObjectUint8Array* data = new CObjectUint8Array(CObject::NewUint8Array(
+            SocketAddress::GetAddrLength(raw)));
+        memmove(data->Buffer(),
+                reinterpret_cast<void *>(&raw),
+                SocketAddress::GetAddrLength(raw));
+
+        entry->SetAt(2, data);
+        array->SetAt(i + 1, entry);
+      }
+      result = array;
+      delete addresses;
     } else {
       result = CObject::NewOSError(os_error);
       delete os_error;
@@ -480,3 +533,6 @@
 Dart_Handle Socket::GetSocketIdNativeField(Dart_Handle socket, intptr_t* id) {
   return Dart_GetNativeInstanceField(socket, kSocketIdNativeField, id);
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index b68b782..aa8d198 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -24,6 +24,93 @@
 #endif
 
 
+namespace dart {
+namespace bin {
+
+union RawAddr {
+  struct sockaddr_in in;
+  struct sockaddr_in6 in6;
+  struct sockaddr_storage ss;
+  struct sockaddr addr;
+};
+
+class SocketAddress {
+ public:
+  enum {
+    TYPE_ANY = -1,
+    TYPE_IPV4,
+    TYPE_IPV6,
+  };
+
+  explicit SocketAddress(struct addrinfo* addrinfo);
+
+  int GetType() {
+    if (addr_.ss.ss_family == AF_INET6) return TYPE_IPV6;
+    return TYPE_IPV4;
+  }
+
+  const char* as_string() const { return as_string_; }
+  const RawAddr& addr() const { return addr_; }
+
+  static intptr_t GetAddrLength(const RawAddr& addr) {
+    return addr.ss.ss_family == AF_INET6 ?
+        sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+  }
+
+  static int16_t FromType(int type) {
+    if (type == TYPE_ANY) return AF_UNSPEC;
+    if (type == TYPE_IPV4) return AF_INET;
+    ASSERT(type == TYPE_IPV6 && "Invalid type");
+    return AF_INET6;
+  }
+
+  static void SetAddrPort(RawAddr* addr, intptr_t port) {
+    if (addr->ss.ss_family == AF_INET) {
+      addr->in.sin_port = htons(port);
+    } else {
+      addr->in6.sin6_port = htons(port);
+    }
+  }
+
+  static intptr_t GetAddrPort(RawAddr* addr) {
+    if (addr->ss.ss_family == AF_INET) {
+      return ntohs(addr->in.sin_port);
+    } else {
+      return ntohs(addr->in6.sin6_port);
+    }
+  }
+
+ private:
+  char as_string_[INET6_ADDRSTRLEN];
+  RawAddr addr_;
+
+  DISALLOW_COPY_AND_ASSIGN(SocketAddress);
+};
+
+class SocketAddresses {
+ public:
+  explicit SocketAddresses(intptr_t count)
+      : count_(count),
+        addresses_(new SocketAddress*[count_]) {}
+
+  ~SocketAddresses() {
+    for (intptr_t i = 0; i < count_; i++) {
+      delete addresses_[i];
+    }
+    delete[] addresses_;
+  }
+
+  intptr_t count() const { return count_; }
+  SocketAddress* GetAt(intptr_t i) const { return addresses_[i]; }
+  void SetAt(intptr_t i, SocketAddress* addr) { addresses_[i] = addr; }
+
+ private:
+  const intptr_t count_;
+  SocketAddress** addresses_;
+
+  DISALLOW_COPY_AND_ASSIGN(SocketAddresses);
+};
+
 class Socket {
  public:
   enum SocketRequest {
@@ -34,7 +121,8 @@
   static intptr_t Available(intptr_t fd);
   static int Read(intptr_t fd, void* buffer, intptr_t num_bytes);
   static int Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
-  static intptr_t CreateConnect(const char* host, const intptr_t port);
+  static intptr_t CreateConnect(RawAddr addr,
+                                const intptr_t port);
   static intptr_t GetPort(intptr_t fd);
   static bool GetRemotePeer(intptr_t fd, char* host, intptr_t* port);
   static void GetError(intptr_t fd, OSError* os_error);
@@ -45,9 +133,10 @@
   static bool SetBlocking(intptr_t fd);
   static bool SetNoDelay(intptr_t fd, bool enabled);
 
-  // Perform a IPv4 hostname lookup. Returns the hostname string in
-  // IPv4 dotted-decimal format.
-  static const char* LookupIPv4Address(char* host, OSError** os_error);
+  // Perform a hostname lookup. Returns the SocketAddresses.
+  static SocketAddresses* LookupAddress(const char* host,
+                                        int type,
+                                        OSError** os_error);
 
   static Dart_Port GetServicePort();
 
@@ -76,7 +165,7 @@
   //
   //   -1: system error (errno set)
   //   -5: invalid bindAddress
-  static intptr_t CreateBindListen(const char* bindAddress,
+  static intptr_t CreateBindListen(RawAddr addr,
                                    intptr_t port,
                                    intptr_t backlog);
 
@@ -84,4 +173,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(ServerSocket);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_SOCKET_H_
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 7e3871d..e4b99bd 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -17,18 +17,33 @@
 #include "bin/log.h"
 
 
+namespace dart {
+namespace bin {
+
+SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
+  const char* result = inet_ntop(addrinfo->ai_family,
+                                 &raw->in.sin_addr,
+                                 as_string_,
+                                 INET6_ADDRSTRLEN);
+  if (result == NULL) as_string_[0] = 0;
+  memmove(reinterpret_cast<void *>(&addr_),
+          addrinfo->ai_addr,
+          addrinfo->ai_addrlen);
+}
+
+
 bool Socket::Initialize() {
   // Nothing to do on Android.
   return true;
 }
 
 
-intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
+intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
   intptr_t fd;
-  struct hostent* server;
-  struct sockaddr_in server_address;
 
-  fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
+  fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
   if (fd < 0) {
     Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
     return -1;
@@ -37,24 +52,15 @@
   FDUtils::SetCloseOnExec(fd);
   Socket::SetNonBlocking(fd);
 
-  server = gethostbyname(host);
-  if (server == NULL) {
-    TEMP_FAILURE_RETRY(close(fd));
-    Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
-    return -1;
-  }
-
-  server_address.sin_family = AF_INET;
-  server_address.sin_port = htons(port);
-  bcopy(server->h_addr, &server_address.sin_addr.s_addr, server->h_length);
-  memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
+  SocketAddress::SetAddrPort(&addr, port);
   intptr_t result = TEMP_FAILURE_RETRY(
       connect(fd,
-              reinterpret_cast<struct sockaddr *>(&server_address),
-              sizeof(server_address)));
+              &addr.addr,
+              SocketAddress::GetAddrLength(addr)));
   if (result == 0 || errno == EINPROGRESS) {
     return fd;
   }
+  TEMP_FAILURE_RETRY(close(fd));
   return -1;
 }
 
@@ -92,38 +98,44 @@
 
 intptr_t Socket::GetPort(intptr_t fd) {
   ASSERT(fd >= 0);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (TEMP_FAILURE_RETRY(
           getsockname(fd,
-                      reinterpret_cast<struct sockaddr *>(&socket_address),
+                      &raw.addr,
                       &size))) {
     Log::PrintErr("Error getsockname: %s\n", strerror(errno));
     return 0;
   }
-  return ntohs(socket_address.sin_port);
+  return SocketAddress::GetAddrPort(&raw);
 }
 
 
 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
   ASSERT(fd >= 0);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (TEMP_FAILURE_RETRY(
           getpeername(fd,
-                      reinterpret_cast<struct sockaddr *>(&socket_address),
+                      &raw.addr,
                       &size))) {
     Log::PrintErr("Error getpeername: %s\n", strerror(errno));
     return false;
   }
-  if (inet_ntop(socket_address.sin_family,
-                reinterpret_cast<const void *>(&socket_address.sin_addr),
+  const void* src;
+  if (raw.ss.ss_family == AF_INET6) {
+    src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
+  } else {
+    src = reinterpret_cast<const void*>(&raw.in.sin_addr);
+  }
+  if (inet_ntop(raw.ss.ss_family,
+                src,
                 host,
                 INET_ADDRSTRLEN) == NULL) {
     Log::PrintErr("Error inet_ntop: %s\n", strerror(errno));
     return false;
   }
-  *port = ntohs(socket_address.sin_port);
+  *port = SocketAddress::GetAddrPort(&raw);
   return true;
 }
 
@@ -145,12 +157,15 @@
 }
 
 
-const char* Socket::LookupIPv4Address(char* host, OSError** os_error) {
-  // Perform a name lookup for an IPv4 address.
+SocketAddresses* Socket::LookupAddress(const char* host,
+                                       int type,
+                                       OSError** os_error) {
+  // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
-  hints.ai_family = AF_INET;
+  hints.ai_family = SocketAddress::FromType(type);
   hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = 0;
   hints.ai_protocol = IPPROTO_TCP;
   struct addrinfo* info = NULL;
   int status = getaddrinfo(host, 0, &hints, &info);
@@ -161,38 +176,30 @@
                             OSError::kGetAddressInfo);
     return NULL;
   }
-  // Convert the address into IPv4 dotted decimal notation.
-  char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN));
-  sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr);
-  const char* result = inet_ntop(AF_INET,
-                                 reinterpret_cast<void *>(&sockaddr->sin_addr),
-                                 buffer,
-                                 INET_ADDRSTRLEN);
-  if (result == NULL) {
-    free(buffer);
-    return NULL;
+  intptr_t count = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  ASSERT(result == buffer);
-  return buffer;
+  SocketAddresses* addresses = new SocketAddresses(count);
+  intptr_t i = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
+      addresses->SetAt(i, new SocketAddress(c));
+      i++;
+    }
+  }
+  freeaddrinfo(info);
+  return addresses;
 }
 
 
-intptr_t ServerSocket::CreateBindListen(const char* host,
+intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog) {
   intptr_t fd;
-  struct sockaddr_in server_address;
 
-  in_addr_t s_addr = inet_addr(host);
-  if (s_addr == INADDR_NONE) {
-    return -5;
-  }
-
-  fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
-  if (fd < 0) {
-    Log::PrintErr("Error CreateBind: %s\n", strerror(errno));
-    return -1;
-  }
+  fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
+  if (fd < 0) return -1;
 
   FDUtils::SetCloseOnExec(fd);
 
@@ -200,22 +207,23 @@
   TEMP_FAILURE_RETRY(
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
-  server_address.sin_family = AF_INET;
-  server_address.sin_port = htons(port);
-  server_address.sin_addr.s_addr = s_addr;
-  memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
+  if (addr.ss.ss_family == AF_INET6) {
+    optval = 0;
+    TEMP_FAILURE_RETRY(
+        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
+  }
 
+  SocketAddress::SetAddrPort(&addr, port);
   if (TEMP_FAILURE_RETRY(
           bind(fd,
-               reinterpret_cast<struct sockaddr *>(&server_address),
-               sizeof(server_address))) < 0) {
+               &addr.addr,
+               SocketAddress::GetAddrLength(addr))) < 0) {
     TEMP_FAILURE_RETRY(close(fd));
-    Log::PrintErr("Error Bind: %s\n", strerror(errno));
     return -1;
   }
 
-  if (TEMP_FAILURE_RETRY(listen(fd, backlog)) != 0) {
-    Log::PrintErr("Error Listen: %s\n", strerror(errno));
+  if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
+    TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
 
@@ -285,4 +293,7 @@
                                        sizeof(on))) == 0;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 23e492c..e881f5d 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -19,18 +19,33 @@
 #include "bin/socket.h"
 
 
+namespace dart {
+namespace bin {
+
+SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
+  const char* result = inet_ntop(addrinfo->ai_family,
+                                 &raw->in.sin_addr,
+                                 as_string_,
+                                 INET6_ADDRSTRLEN);
+  if (result == NULL) as_string_[0] = 0;
+  memmove(reinterpret_cast<void *>(&addr_),
+          addrinfo->ai_addr,
+          addrinfo->ai_addrlen);
+}
+
+
 bool Socket::Initialize() {
   // Nothing to do on Linux.
   return true;
 }
 
 
-intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
+intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
   intptr_t fd;
-  struct hostent server;
-  struct sockaddr_in server_address;
 
-  fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
+  fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
   if (fd < 0) {
     Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
     return -1;
@@ -39,28 +54,15 @@
   FDUtils::SetCloseOnExec(fd);
   Socket::SetNonBlocking(fd);
 
-  static const size_t kTempBufSize = 1024;
-  char temp_buf[kTempBufSize];
-  struct hostent *unused;
-  int err;
-  if (gethostbyname_r(
-          host, &server, temp_buf, kTempBufSize, &unused, &err) != 0) {
-    TEMP_FAILURE_RETRY(close(fd));
-    Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
-    return -1;
-  }
-
-  server_address.sin_family = AF_INET;
-  server_address.sin_port = htons(port);
-  bcopy(server.h_addr, &server_address.sin_addr.s_addr, server.h_length);
-  memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
+  SocketAddress::SetAddrPort(&addr, port);
   intptr_t result = TEMP_FAILURE_RETRY(
       connect(fd,
-              reinterpret_cast<struct sockaddr *>(&server_address),
-              sizeof(server_address)));
+              &addr.addr,
+              SocketAddress::GetAddrLength(addr)));
   if (result == 0 || errno == EINPROGRESS) {
     return fd;
   }
+  TEMP_FAILURE_RETRY(close(fd));
   return -1;
 }
 
@@ -98,38 +100,44 @@
 
 intptr_t Socket::GetPort(intptr_t fd) {
   ASSERT(fd >= 0);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (TEMP_FAILURE_RETRY(
           getsockname(fd,
-                      reinterpret_cast<struct sockaddr *>(&socket_address),
+                      &raw.addr,
                       &size))) {
     Log::PrintErr("Error getsockname: %s\n", strerror(errno));
     return 0;
   }
-  return ntohs(socket_address.sin_port);
+  return SocketAddress::GetAddrPort(&raw);
 }
 
 
 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
   ASSERT(fd >= 0);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (TEMP_FAILURE_RETRY(
           getpeername(fd,
-                      reinterpret_cast<struct sockaddr *>(&socket_address),
+                      &raw.addr,
                       &size))) {
     Log::PrintErr("Error getpeername: %s\n", strerror(errno));
     return false;
   }
-  if (inet_ntop(socket_address.sin_family,
-                reinterpret_cast<const void *>(&socket_address.sin_addr),
+  const void* src;
+  if (raw.ss.ss_family == AF_INET6) {
+    src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
+  } else {
+    src = reinterpret_cast<const void*>(&raw.in.sin_addr);
+  }
+  if (inet_ntop(raw.ss.ss_family,
+                src,
                 host,
                 INET_ADDRSTRLEN) == NULL) {
     Log::PrintErr("Error inet_ntop: %s\n", strerror(errno));
     return false;
   }
-  *port = ntohs(socket_address.sin_port);
+  *port = SocketAddress::GetAddrPort(&raw);
   return true;
 }
 
@@ -161,12 +169,15 @@
 }
 
 
-const char* Socket::LookupIPv4Address(char* host, OSError** os_error) {
-  // Perform a name lookup for an IPv4 address.
+SocketAddresses* Socket::LookupAddress(const char* host,
+                                       int type,
+                                       OSError** os_error) {
+  // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
-  hints.ai_family = AF_INET;
+  hints.ai_family = SocketAddress::FromType(type);
   hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = 0;
   hints.ai_protocol = IPPROTO_TCP;
   struct addrinfo* info = NULL;
   int status = getaddrinfo(host, 0, &hints, &info);
@@ -177,34 +188,29 @@
                             OSError::kGetAddressInfo);
     return NULL;
   }
-  // Convert the address into IPv4 dotted decimal notation.
-  char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN));
-  sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr);
-  const char* result = inet_ntop(AF_INET,
-                                 reinterpret_cast<void *>(&sockaddr->sin_addr),
-                                 buffer,
-                                 INET_ADDRSTRLEN);
-  if (result == NULL) {
-    free(buffer);
-    return NULL;
+  intptr_t count = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  ASSERT(result == buffer);
-  return buffer;
+  SocketAddresses* addresses = new SocketAddresses(count);
+  intptr_t i = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
+      addresses->SetAt(i, new SocketAddress(c));
+      i++;
+    }
+  }
+  freeaddrinfo(info);
+  return addresses;
 }
 
 
-intptr_t ServerSocket::CreateBindListen(const char* host,
+intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog) {
   intptr_t fd;
-  struct sockaddr_in server_address;
 
-  in_addr_t s_addr = inet_addr(host);
-  if (s_addr == INADDR_NONE) {
-    return -5;
-  }
-
-  fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
+  fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
   if (fd < 0) return -1;
 
   FDUtils::SetCloseOnExec(fd);
@@ -213,15 +219,17 @@
   TEMP_FAILURE_RETRY(
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
-  server_address.sin_family = AF_INET;
-  server_address.sin_port = htons(port);
-  server_address.sin_addr.s_addr = s_addr;
-  memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
+  if (addr.ss.ss_family == AF_INET6) {
+    optval = 0;
+    TEMP_FAILURE_RETRY(
+        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
+  }
 
+  SocketAddress::SetAddrPort(&addr, port);
   if (TEMP_FAILURE_RETRY(
           bind(fd,
-               reinterpret_cast<struct sockaddr *>(&server_address),
-               sizeof(server_address))) < 0) {
+               &addr.addr,
+               SocketAddress::GetAddrLength(addr))) < 0) {
     TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
@@ -297,4 +305,7 @@
                                        sizeof(on))) == 0;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index ff1e28e..bf17056 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -19,18 +19,33 @@
 #include "bin/socket.h"
 
 
+namespace dart {
+namespace bin {
+
+SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
+  const char* result = inet_ntop(addrinfo->ai_family,
+                                 &raw->in.sin_addr,
+                                 as_string_,
+                                 INET6_ADDRSTRLEN);
+  if (result == NULL) as_string_[0] = 0;
+  memmove(reinterpret_cast<void *>(&addr_),
+          addrinfo->ai_addr,
+          addrinfo->ai_addrlen);
+}
+
+
 bool Socket::Initialize() {
   // Nothing to do on Mac OS.
   return true;
 }
 
 
-intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
+intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
   intptr_t fd;
-  struct hostent* server;
-  struct sockaddr_in server_address;
 
-  fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
+  fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
   if (fd < 0) {
     Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
     return -1;
@@ -39,24 +54,15 @@
   FDUtils::SetCloseOnExec(fd);
   Socket::SetNonBlocking(fd);
 
-  server = gethostbyname(host);
-  if (server == NULL) {
-    VOID_TEMP_FAILURE_RETRY(close(fd));
-    Log::PrintErr("Error CreateConnect: %s\n", strerror(errno));
-    return -1;
-  }
-
-  server_address.sin_family = AF_INET;
-  server_address.sin_port = htons(port);
-  bcopy(server->h_addr, &server_address.sin_addr.s_addr, server->h_length);
-  memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
+  SocketAddress::SetAddrPort(&addr, port);
   intptr_t result = TEMP_FAILURE_RETRY(
       connect(fd,
-              reinterpret_cast<struct sockaddr *>(&server_address),
-              sizeof(server_address)));
+              &addr.addr,
+              SocketAddress::GetAddrLength(addr)));
   if (result == 0 || errno == EINPROGRESS) {
     return fd;
   }
+  VOID_TEMP_FAILURE_RETRY(close(fd));
   return -1;
 }
 
@@ -94,38 +100,44 @@
 
 intptr_t Socket::GetPort(intptr_t fd) {
   ASSERT(fd >= 0);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (TEMP_FAILURE_RETRY(
           getsockname(fd,
-                      reinterpret_cast<struct sockaddr *>(&socket_address),
+                      &raw.addr,
                       &size))) {
     Log::PrintErr("Error getsockname: %s\n", strerror(errno));
     return 0;
   }
-  return ntohs(socket_address.sin_port);
+  return SocketAddress::GetAddrPort(&raw);
 }
 
 
 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
   ASSERT(fd >= 0);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (TEMP_FAILURE_RETRY(
           getpeername(fd,
-                      reinterpret_cast<struct sockaddr *>(&socket_address),
+                      &raw.addr,
                       &size))) {
     Log::PrintErr("Error getpeername: %s\n", strerror(errno));
     return false;
   }
-  if (inet_ntop(socket_address.sin_family,
-                reinterpret_cast<const void *>(&socket_address.sin_addr),
+  const void* src;
+  if (raw.ss.ss_family == AF_INET6) {
+    src = reinterpret_cast<const void*>(&raw.in6.sin6_addr);
+  } else {
+    src = reinterpret_cast<const void*>(&raw.in.sin_addr);
+  }
+  if (inet_ntop(raw.ss.ss_family,
+                src,
                 host,
                 INET_ADDRSTRLEN) == NULL) {
     Log::PrintErr("Error inet_ntop: %s\n", strerror(errno));
     return false;
   }
-  *port = ntohs(socket_address.sin_port);
+  *port = SocketAddress::GetAddrPort(&raw);
   return true;
 }
 
@@ -157,12 +169,15 @@
 }
 
 
-const char* Socket::LookupIPv4Address(char* host, OSError** os_error) {
-  // Perform a name lookup for an IPv4 address.
+SocketAddresses* Socket::LookupAddress(const char* host,
+                                       int type,
+                                       OSError** os_error) {
+  // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
-  hints.ai_family = AF_INET;
+  hints.ai_family = SocketAddress::FromType(type);
   hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = 0;
   hints.ai_protocol = IPPROTO_TCP;
   struct addrinfo* info = NULL;
   int status = getaddrinfo(host, 0, &hints, &info);
@@ -173,34 +188,29 @@
                             OSError::kGetAddressInfo);
     return NULL;
   }
-  // Convert the address into IPv4 dotted decimal notation.
-  char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN));
-  sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr);
-  const char* result = inet_ntop(AF_INET,
-                                 reinterpret_cast<void *>(&sockaddr->sin_addr),
-                                 buffer,
-                                 INET_ADDRSTRLEN);
-  if (result == NULL) {
-    free(buffer);
-    return NULL;
+  intptr_t count = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  ASSERT(result == buffer);
-  return buffer;
+  SocketAddresses* addresses = new SocketAddresses(count);
+  intptr_t i = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
+      addresses->SetAt(i, new SocketAddress(c));
+      i++;
+    }
+  }
+  freeaddrinfo(info);
+  return addresses;
 }
 
 
-intptr_t ServerSocket::CreateBindListen(const char* host,
+intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog) {
   intptr_t fd;
-  struct sockaddr_in server_address;
 
-  in_addr_t s_addr = inet_addr(host);
-  if (s_addr == INADDR_NONE) {
-    return -5;
-  }
-
-  fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
+  fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
   if (fd < 0) return -1;
 
   FDUtils::SetCloseOnExec(fd);
@@ -209,21 +219,23 @@
   VOID_TEMP_FAILURE_RETRY(
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
-  server_address.sin_family = AF_INET;
-  server_address.sin_port = htons(port);
-  server_address.sin_addr.s_addr = s_addr;
-  memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
+  if (addr.ss.ss_family == AF_INET6) {
+    optval = 0;
+    VOID_TEMP_FAILURE_RETRY(
+        setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
+  }
 
+  SocketAddress::SetAddrPort(&addr, port);
   if (TEMP_FAILURE_RETRY(
           bind(fd,
-               reinterpret_cast<struct sockaddr *>(&server_address),
-               sizeof(server_address))) < 0) {
+               &addr.addr,
+               SocketAddress::GetAddrLength(addr))) < 0) {
     VOID_TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
 
   if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
-    TEMP_FAILURE_RETRY(close(fd));
+    VOID_TEMP_FAILURE_RETRY(close(fd));
     return -1;
   }
 
@@ -283,4 +295,7 @@
                                        sizeof(on))) == 0;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 67fbadf..daa59c6 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 patch class RawServerSocket  {
-  /* patch */ static Future<RawServerSocket> bind([String address = "127.0.0.1",
+  /* patch */ static Future<RawServerSocket> bind([address = "127.0.0.1",
                                                    int port = 0,
                                                    int backlog = 0]) {
     return _RawServerSocket.bind(address, port, backlog);
@@ -12,12 +12,36 @@
 
 
 patch class RawSocket {
-  /* patch */ static Future<RawSocket> connect(String host, int port) {
+  /* patch */ static Future<RawSocket> connect(host, int port) {
     return _RawSocket.connect(host, port);
   }
 }
 
 
+patch class InternetAddress {
+  /* patch */ static Future<List<InternetAddress>> lookup(
+      String host, {InternetAddressType type: InternetAddressType.IPv4}) {
+    return _NativeSocket.lookup(host, type: type);
+  }
+}
+
+class _InternetAddress implements InternetAddress {
+  final InternetAddressType type;
+  final String address;
+  final String host;
+  final Uint8List _sockaddr_storage;
+
+  _InternetAddress(InternetAddressType this.type,
+                   String this.address,
+                   String this.host,
+                   List<int> this._sockaddr_storage);
+
+  String toString() {
+    return "InternetAddress('$address', ${type.name})";
+  }
+}
+
+
 // The _NativeSocket class encapsulates an OS socket.
 class _NativeSocket extends NativeFieldWrapperClass1 {
   // Bit flags used when communicating between the eventhandler and
@@ -74,57 +98,95 @@
   // Holds the port of the socket, null if not known.
   int localPort;
 
-  // Holds the host or address used to connect or bind the socket.
-  String localHost;
+  // Holds the address used to connect or bind the socket.
+  InternetAddress address;
 
   // Native port for socket services.
   static SendPort socketService;
 
-  static Future<_NativeSocket> connect(String host, int port) {
-    var completer = new Completer();
+  static Future<List<InternetAddress>> lookup(
+      String host, {InternetAddressType type: InternetAddressType.IPv4}) {
     ensureSocketService();
-    socketService.call([HOST_NAME_LOOKUP, host]).then((response) {
-      if (isErrorResponse(response)) {
-        completer.completeError(
-            createError(response, "Failed host name lookup"));
-      } else {
-        var socket = new _NativeSocket.normal();
-        socket.localHost = host;
-        var result = socket.nativeCreateConnect(response, port);
-        if (result is OSError) {
-          completer.completeError(createError(result, "Connection failed"));
-        } else {
-          // Setup handlers for receiving the first write event which
-          // indicate that the socket is fully connected.
-          socket.setHandlers(
-              write: () {
-                socket.setListening(read: false, write: false);
-                completer.complete(socket);
-              },
-              error: (e) {
-                socket.close();
-                completer.completeError(createError(e, "Connection failed"));
-              }
-          );
-          socket.setListening(read: false, write: true);
-        }
-      }
-    });
-    return completer.future;
+    return socketService.call([HOST_NAME_LOOKUP, host, type._value])
+        .then((response) {
+          if (isErrorResponse(response)) {
+            throw createError(response, "Failed host name lookup");
+          } else {
+            return response.skip(1).map((result) {
+              var type = new InternetAddressType._from(result[0]);
+              return new _InternetAddress(type, result[1], host, result[2]);
+            }).toList();
+          }
+        });
   }
 
-  static Future<_NativeSocket> bind(String address,
+  static Future<_NativeSocket> connect(host, int port) {
+    return new Future.value(host)
+        .then((host) {
+          if (host is _InternetAddress) return host;
+          return lookup(host)
+              .then((list) {
+                if (list.length == 0) {
+                  throw createError(response, "Failed host name lookup");
+                }
+                return list[0];
+              });
+        })
+        .then((address) {
+          ensureSocketService();
+          var socket = new _NativeSocket.normal();
+          socket.address = address;
+          var result = socket.nativeCreateConnect(
+              address._sockaddr_storage, port);
+          if (result is OSError) {
+            throw createError(result, "Connection failed");
+          } else {
+            var completer = new Completer();
+            // Setup handlers for receiving the first write event which
+            // indicate that the socket is fully connected.
+            socket.setHandlers(
+                write: () {
+                  socket.setListening(read: false, write: false);
+                  completer.complete(socket);
+                },
+                error: (e) {
+                  socket.close();
+                  completer.completeError(createError(e, "Connection failed"));
+                }
+            );
+            socket.setListening(read: false, write: true);
+            return completer.future;
+          }
+        });
+  }
+
+  static Future<_NativeSocket> bind(host,
                                     int port,
                                     int backlog) {
-    var socket = new _NativeSocket.listen();
-    socket.localHost = address;
-    var result = socket.nativeCreateBindListen(address, port, backlog);
-    if (result is OSError) {
-      return new Future.error(
-          new SocketIOException("Failed to create server socket", result));
-    }
-    if (port != 0) socket.localPort = port;
-    return new Future.value(socket);
+    return new Future.value(host)
+        .then((host) {
+          if (host is _InternetAddress) return host;
+          return lookup(host)
+              .then((list) {
+                if (list.length == 0) {
+                  throw createError(response, "Failed host name lookup");
+                }
+                return list[0];
+              });
+        })
+        .then((address) {
+          var socket = new _NativeSocket.listen();
+          socket.address = address;
+          var result = socket.nativeCreateBindListen(address._sockaddr_storage,
+                                                     port,
+                                                     backlog);
+          if (result is OSError) {
+            throw new SocketIOException(
+                "Failed to create server socket", result);
+          }
+          if (port != 0) socket.localPort = port;
+          return socket;
+        });
   }
 
   _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET {
@@ -194,6 +256,8 @@
   _NativeSocket accept() {
     var socket = new _NativeSocket.normal();
     if (nativeAccept(socket) != true) return null;
+    socket.localPort = localPort;
+    socket.address = address;
     return socket;
   }
 
@@ -206,8 +270,6 @@
     return nativeGetRemotePeer()[1];
   }
 
-  String get host => localHost;
-
   String get remoteHost {
     return nativeGetRemotePeer()[0];
   }
@@ -409,8 +471,9 @@
   nativeRead(int len) native "Socket_Read";
   nativeWrite(List<int> buffer, int offset, int bytes)
       native "Socket_WriteList";
-  nativeCreateConnect(String host, int port) native "Socket_CreateConnect";
-  nativeCreateBindListen(String address, int port, int backlog)
+  nativeCreateConnect(List<int> addr,
+                      int port) native "Socket_CreateConnect";
+  nativeCreateBindListen(List<int> addr, int port, int backlog)
       native "ServerSocket_CreateBindListen";
   nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
   int nativeGetPort() native "Socket_GetPort";
@@ -427,7 +490,7 @@
   final _NativeSocket _socket;
   StreamController<RawSocket> _controller;
 
-  static Future<_RawServerSocket> bind(String address,
+  static Future<_RawServerSocket> bind(address,
                                        int port,
                                        int backlog) {
     if (port < 0 || port > 0xFFFF)
@@ -503,7 +566,7 @@
   bool _readEventsEnabled = true;
   bool _writeEventsEnabled = true;
 
-  static Future<RawSocket> connect(String host, int port) {
+  static Future<RawSocket> connect(host, int port) {
     return _NativeSocket.connect(host, port)
         .then((socket) => new _RawSocket(socket));
   }
@@ -571,7 +634,7 @@
 
   int get remotePort => _socket.remotePort;
 
-  String get host => _socket.host;
+  InternetAddress get address => _socket.address;
 
   String get remoteHost => _socket.remoteHost;
 
@@ -621,7 +684,7 @@
 
 
 patch class ServerSocket {
-  /* patch */ static Future<ServerSocket> bind([String address = "127.0.0.1",
+  /* patch */ static Future<ServerSocket> bind([address = "127.0.0.1",
                                                 int port = 0,
                                                 int backlog = 0]) {
     return _ServerSocket.bind(address, port, backlog);
@@ -632,7 +695,7 @@
                     implements ServerSocket {
   final _socket;
 
-  static Future<_ServerSocket> bind(String address,
+  static Future<_ServerSocket> bind(address,
                                     int port,
                                     int backlog) {
     return _RawServerSocket.bind(address, port, backlog)
@@ -659,7 +722,7 @@
 
 
 patch class Socket {
-  /* patch */ static Future<Socket> connect(String host, int port) {
+  /* patch */ static Future<Socket> connect(host, int port) {
     return RawSocket.connect(host, port).then(
         (socket) => new _Socket(socket));
   }
@@ -771,6 +834,7 @@
   _SocketStreamConsumer _consumer;
   IOSink _sink;
   var _subscription;
+  var _detachReady;
 
   _Socket(RawSocket this._raw) {
     _controller = new StreamController<List<int>>(
@@ -851,6 +915,17 @@
   String get remoteHost => _raw.remoteHost;
   int get remotePort => _raw.remotePort;
 
+  Future _detachRaw() {
+    _detachReady = new Completer();
+    _sink.close();
+    return _detachReady.future.then((_) {
+      assert(_consumer.buffer == null);
+      var raw = _raw;
+      _raw = null;
+      return [raw, _subscription];
+    });
+  }
+
   // Ensure a subscription on the raw socket. Both the stream and the
   // consumer needs a subscription as they share the error and done
   // events from the raw socket.
@@ -938,9 +1013,13 @@
   }
 
   void _consumerDone() {
-    if (_raw != null) {
-      _raw.shutdown(SocketDirection.SEND);
-      _disableWriteEvent();
+    if (_detachReady != null) {
+      _detachReady.complete(null);
+    } else {
+      if (_raw != null) {
+        _raw.shutdown(SocketDirection.SEND);
+        _disableWriteEvent();
+      }
     }
   }
 }
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 54f6639..12b76d8 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -11,6 +11,31 @@
 #include "bin/log.h"
 #include "bin/socket.h"
 
+
+namespace dart {
+namespace bin {
+
+SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
+  ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
+  RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
+
+  // Clear the port before calling WSAAddressToString as WSAAddressToString
+  // includes the port in the formatted string.
+  DWORD len = INET6_ADDRSTRLEN;
+  int err = WSAAddressToStringA(&raw->addr,
+                                sizeof(RawAddr),
+                                NULL,
+                                as_string_,
+                                &len);
+
+  if (err != 0) {
+    as_string_[0] = 0;
+  }
+  memmove(reinterpret_cast<void *>(&addr_),
+          addrinfo->ai_addr,
+          addrinfo->ai_addrlen);
+}
+
 bool Socket::Initialize() {
   static bool socket_initialized = false;
   if (socket_initialized) return true;
@@ -47,36 +72,36 @@
 intptr_t Socket::GetPort(intptr_t fd) {
   ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
   SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (getsockname(socket_handle->socket(),
-                  reinterpret_cast<struct sockaddr *>(&socket_address),
-                  &size)) {
-    Log::PrintErr("Error getsockname: %s\n", strerror(errno));
+                  &raw.addr,
+                  &size) == SOCKET_ERROR) {
+    Log::PrintErr("Error getsockname: %d\n", WSAGetLastError());
     return 0;
   }
-  return ntohs(socket_address.sin_port);
+  return SocketAddress::GetAddrPort(&raw);
 }
 
 
 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) {
   ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
   SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
-  struct sockaddr_in socket_address;
-  socklen_t size = sizeof(socket_address);
+  RawAddr raw;
+  socklen_t size = sizeof(raw);
   if (getpeername(socket_handle->socket(),
-                  reinterpret_cast<struct sockaddr *>(&socket_address),
+                  &raw.addr,
                   &size)) {
-    Log::PrintErr("Error getpeername: %s\n", strerror(errno));
+    Log::PrintErr("Error getpeername: %d\n", WSAGetLastError());
     return false;
   }
-  *port = ntohs(socket_address.sin_port);
+  *port = SocketAddress::GetAddrPort(&raw);
   // Clear the port before calling WSAAddressToString as WSAAddressToString
   // includes the port in the formatted string.
-  socket_address.sin_port = 0;
-  DWORD len = INET_ADDRSTRLEN;
-  int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(&socket_address),
-                                sizeof(socket_address),
+  SocketAddress::SetAddrPort(&raw, 0);
+  DWORD len = INET6_ADDRSTRLEN;
+  int err = WSAAddressToStringA(&raw.addr,
+                                sizeof(raw),
                                 NULL,
                                 host,
                                 &len);
@@ -87,8 +112,8 @@
   return true;
 }
 
-intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
-  SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
+intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) {
+  SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0);
   if (s == INVALID_SOCKET) {
     return -1;
   }
@@ -105,29 +130,11 @@
     FATAL("Failed setting SO_LINGER on socket");
   }
 
-  // Perform a name lookup for an IPv4 address.
-  struct addrinfo hints;
-  memset(&hints, 0, sizeof(hints));
-  hints.ai_family = AF_INET;
-  hints.ai_socktype = SOCK_STREAM;
-  hints.ai_protocol = IPPROTO_TCP;
-  struct addrinfo* result = NULL;
-  status = getaddrinfo(host, 0, &hints, &result);
-  if (status != NO_ERROR) {
-    return -1;
-  }
-
-  // Copy IPv4 address and set the port.
-  struct sockaddr_in server_address;
-  memcpy(&server_address,
-         reinterpret_cast<sockaddr_in *>(result->ai_addr),
-         sizeof(server_address));
-  server_address.sin_port = htons(port);
-  freeaddrinfo(result);  // Free data allocated by getaddrinfo.
+  SocketAddress::SetAddrPort(&addr, port);
   status = connect(
       s,
-      reinterpret_cast<struct sockaddr*>(&server_address),
-      sizeof(server_address));
+      &addr.addr,
+      SocketAddress::GetAddrLength(addr));
   if (status == SOCKET_ERROR) {
     DWORD rc = WSAGetLastError();
     closesocket(s);
@@ -192,13 +199,17 @@
 }
 
 
-const char* Socket::LookupIPv4Address(char* host, OSError** os_error) {
-  // Perform a name lookup for an IPv4 address.
+SocketAddresses* Socket::LookupAddress(const char* host,
+                                       int type,
+                                       OSError** os_error) {
   Initialize();
+
+  // Perform a name lookup for a host name.
   struct addrinfo hints;
   memset(&hints, 0, sizeof(hints));
-  hints.ai_family = AF_INET;
+  hints.ai_family = SocketAddress::FromType(type);
   hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = 0;
   hints.ai_protocol = IPPROTO_TCP;
   struct addrinfo* info = NULL;
   int status = getaddrinfo(host, 0, &hints, &info);
@@ -209,35 +220,27 @@
     *os_error = new OSError();
     return NULL;
   }
-  // Convert the address into IPv4 dotted decimal notation.
-  char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN));
-  sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr);
-
-  // Clear the port before calling WSAAddressToString as WSAAddressToString
-  // includes the port in the formatted string.
-  DWORD len = INET_ADDRSTRLEN;
-  int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(sockaddr),
-                                sizeof(sockaddr_in),
-                                NULL,
-                                buffer,
-                                &len);
-  if (err != 0) {
-    free(buffer);
-    return NULL;
+  intptr_t count = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
   }
-  return buffer;
+  SocketAddresses* addresses = new SocketAddresses(count);
+  intptr_t i = 0;
+  for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
+    if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
+      addresses->SetAt(i, new SocketAddress(c));
+      i++;
+    }
+  }
+  freeaddrinfo(info);
+  return addresses;
 }
 
 
-intptr_t ServerSocket::CreateBindListen(const char* host,
+intptr_t ServerSocket::CreateBindListen(RawAddr addr,
                                         intptr_t port,
                                         intptr_t backlog) {
-  unsigned long socket_addr = inet_addr(host);  // NOLINT
-  if (socket_addr == INADDR_NONE) {
-    return -5;
-  }
-
-  SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, IPPROTO_TCP);
   if (s == INVALID_SOCKET) {
     return -1;
   }
@@ -255,14 +258,19 @@
     return -1;
   }
 
-  sockaddr_in addr;
-  memset(&addr, 0, sizeof(addr));
-  addr.sin_family = AF_INET;
-  addr.sin_addr.s_addr = socket_addr;
-  addr.sin_port = htons(port);
+  if (addr.ss.ss_family == AF_INET6) {
+    optval = false;
+    setsockopt(s,
+               IPPROTO_IPV6,
+               IPV6_V6ONLY,
+               reinterpret_cast<const char*>(&optval),
+               sizeof(optval));
+  }
+
+  SocketAddress::SetAddrPort(&addr, port);
   status = bind(s,
-                reinterpret_cast<struct sockaddr *>(&addr),
-                sizeof(addr));
+                &addr.addr,
+                SocketAddress::GetAddrLength(addr));
   if (status == SOCKET_ERROR) {
     DWORD rc = WSAGetLastError();
     closesocket(s);
@@ -321,4 +329,7 @@
                     sizeof(on)) == 0;
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/test_extension.cc b/runtime/bin/test_extension.cc
index c1da730..327f015 100644
--- a/runtime/bin/test_extension.cc
+++ b/runtime/bin/test_extension.cc
@@ -5,6 +5,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 Dart_NativeFunction ResolveName(Dart_Handle name, int argc);
 
 DART_EXPORT Dart_Handle test_extension_Init(Dart_Handle parent_library) {
@@ -50,3 +54,6 @@
   }
   return NULL;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/thread.h b/runtime/bin/thread.h
index a3c5a92..23091f0 100644
--- a/runtime/bin/thread.h
+++ b/runtime/bin/thread.h
@@ -8,6 +8,10 @@
 #include "platform/assert.h"
 #include "platform/thread.h"
 
+
+namespace dart {
+namespace bin {
+
 class MutexLocker  {
  public:
   explicit MutexLocker(dart::Mutex* mutex) : mutex_(mutex) {
@@ -55,4 +59,7 @@
   DISALLOW_COPY_AND_ASSIGN(MonitorLocker);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_THREAD_H_
diff --git a/runtime/bin/utils.h b/runtime/bin/utils.h
index c0aab6b..60beef1 100644
--- a/runtime/bin/utils.h
+++ b/runtime/bin/utils.h
@@ -11,6 +11,10 @@
 #include "include/dart_api.h"
 #include "platform/globals.h"
 
+
+namespace dart {
+namespace bin {
+
 class OSError {
  public:
   enum SubSystem {
@@ -85,4 +89,7 @@
   static void Sleep(int64_t millis);
 };
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_UTILS_H_
diff --git a/runtime/bin/utils_android.cc b/runtime/bin/utils_android.cc
index 180dc39..25022b5 100644
--- a/runtime/bin/utils_android.cc
+++ b/runtime/bin/utils_android.cc
@@ -12,6 +12,10 @@
 #include "bin/utils.h"
 #include "platform/assert.h"
 
+
+namespace dart {
+namespace bin {
+
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
   set_sub_system(kSystem);
   set_code(errno);
@@ -91,4 +95,7 @@
   usleep(millis * 1000);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/bin/utils_linux.cc b/runtime/bin/utils_linux.cc
index 3defd39..e8230c8 100644
--- a/runtime/bin/utils_linux.cc
+++ b/runtime/bin/utils_linux.cc
@@ -12,6 +12,10 @@
 #include "bin/utils.h"
 #include "platform/assert.h"
 
+
+namespace dart {
+namespace bin {
+
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
   set_sub_system(kSystem);
   set_code(errno);
@@ -91,4 +95,7 @@
   usleep(millis * 1000);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/utils_macos.cc b/runtime/bin/utils_macos.cc
index f717edd..69c738e 100644
--- a/runtime/bin/utils_macos.cc
+++ b/runtime/bin/utils_macos.cc
@@ -12,6 +12,10 @@
 #include "bin/utils.h"
 #include "platform/assert.h"
 
+
+namespace dart {
+namespace bin {
+
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
   set_sub_system(kSystem);
   set_code(errno);
@@ -91,4 +95,7 @@
   usleep(millis * 1000);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index 6c25d5b..b926dd7 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -11,6 +11,10 @@
 #include "bin/utils.h"
 #include "bin/log.h"
 
+
+namespace dart {
+namespace bin {
+
 static void FormatMessageIntoBuffer(DWORD code,
                                     wchar_t* buffer,
                                     int buffer_length) {
@@ -145,4 +149,7 @@
   ::Sleep(millis);
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/bin/vmstats.h b/runtime/bin/vmstats.h
index 14716e8..6143b95 100644
--- a/runtime/bin/vmstats.h
+++ b/runtime/bin/vmstats.h
@@ -7,6 +7,10 @@
 
 #include "include/dart_api.h"
 
+
+namespace dart {
+namespace bin {
+
 /**
  * A VM status callback. Status plug-ins implement and register this
  * function using Dart_RegisterStatusPlugin. When Dart_GetVMStatus is
@@ -34,4 +38,7 @@
  */
 DART_EXPORT int Dart_RegisterVmStatusPlugin(Dart_VmStatusCallback callback);
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_VMSTATS_H_
diff --git a/runtime/bin/vmstats_impl.cc b/runtime/bin/vmstats_impl.cc
index d2e0af6..b73fe64 100644
--- a/runtime/bin/vmstats_impl.cc
+++ b/runtime/bin/vmstats_impl.cc
@@ -14,6 +14,10 @@
 #include "include/dart_debugger_api.h"
 #include "platform/json.h"
 
+
+namespace dart {
+namespace bin {
+
 #define BUFSIZE 8192
 #define RETRY_PAUSE 100  // milliseconds
 
@@ -55,15 +59,15 @@
   // TODO(tball): allow host to be specified.
   char* host = const_cast<char*>(DEFAULT_HOST);
   OSError* os_error;
-  const char* host_ip = Socket::LookupIPv4Address(host, &os_error);
-  if (host_ip == NULL) {
+  SocketAddresses* addresses = Socket::LookupAddress(host, -1, &os_error);
+  if (addresses == NULL) {
     Log::PrintErr("Failed IP lookup of VmStats host %s: %s\n",
                   host, os_error->message());
     return;
   }
-
   const intptr_t BACKLOG = 128;  // Default value from HttpServer.dart
-  int64_t address = ServerSocket::CreateBindListen(host_ip, port, BACKLOG);
+  int64_t address = ServerSocket::CreateBindListen(
+      addresses->GetAt(0)->addr(), port, BACKLOG);
   if (address < 0) {
     Log::PrintErr("Failed binding VmStats socket: %s:%d\n", host, port);
     return;
@@ -472,3 +476,6 @@
   }
   return NULL;
 }
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/vmstats_impl.h b/runtime/bin/vmstats_impl.h
index a348a7a..ed92e87 100644
--- a/runtime/bin/vmstats_impl.h
+++ b/runtime/bin/vmstats_impl.h
@@ -12,6 +12,10 @@
 #include "bin/isolate_data.h"
 #include "platform/thread.h"
 
+
+namespace dart {
+namespace bin {
+
 // VmStats is a HTTP singleton service that reports status information
 // of the running VM.
 
@@ -105,4 +109,8 @@
   DISALLOW_COPY_AND_ASSIGN(VmStatusService);
 };
 
+
+}  // namespace bin
+}  // namespace dart
+
 #endif  // BIN_VMSTATS_IMPL_H_
diff --git a/runtime/bin/vmstats_impl_android.cc b/runtime/bin/vmstats_impl_android.cc
index e460e70..5baa0d4 100644
--- a/runtime/bin/vmstats_impl_android.cc
+++ b/runtime/bin/vmstats_impl_android.cc
@@ -10,6 +10,9 @@
 #include <signal.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 static void sig_handler(int sig, siginfo_t* siginfo, void*) {
   if (sig == SIGQUIT) {
     VmStats::DumpStack();
@@ -29,5 +32,8 @@
   }
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_ANDROID)
 
diff --git a/runtime/bin/vmstats_impl_linux.cc b/runtime/bin/vmstats_impl_linux.cc
index ae2277a..93efbf2 100644
--- a/runtime/bin/vmstats_impl_linux.cc
+++ b/runtime/bin/vmstats_impl_linux.cc
@@ -10,6 +10,9 @@
 #include <signal.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 static void sig_handler(int sig, siginfo_t* siginfo, void*) {
   if (sig == SIGQUIT) {
     VmStats::DumpStack();
@@ -29,5 +32,7 @@
   }
 }
 
-#endif  // defined(TARGET_OS_LINUX)
+}  // namespace bin
+}  // namespace dart
 
+#endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/bin/vmstats_impl_macos.cc b/runtime/bin/vmstats_impl_macos.cc
index 29686a1..23cf179 100644
--- a/runtime/bin/vmstats_impl_macos.cc
+++ b/runtime/bin/vmstats_impl_macos.cc
@@ -10,6 +10,9 @@
 #include <signal.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 static void sig_handler(int sig, siginfo_t* siginfo, void*) {
   if (sig == SIGQUIT) {
     VmStats::DumpStack();
@@ -29,5 +32,7 @@
   }
 }
 
-#endif  // defined(TARGET_OS_MACOS)
+}  // namespace bin
+}  // namespace dart
 
+#endif  // defined(TARGET_OS_MACOS)
diff --git a/runtime/bin/vmstats_impl_win.cc b/runtime/bin/vmstats_impl_win.cc
index 7ff384c..3157801 100644
--- a/runtime/bin/vmstats_impl_win.cc
+++ b/runtime/bin/vmstats_impl_win.cc
@@ -10,6 +10,9 @@
 #include <signal.h>  // NOLINT
 
 
+namespace dart {
+namespace bin {
+
 static void sig_handler(int sig) {
   if (sig == SIGBREAK) {
     VmStats::DumpStack();
@@ -23,4 +26,7 @@
   }
 }
 
+}  // namespace bin
+}  // namespace dart
+
 #endif  // defined(TARGET_OS_WINDOWS)
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index db2f10f..7519576 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -11,8 +11,9 @@
     'third_party/jscre/jscre.gypi',
   ],
   'variables': {
+    'gen_source_dir': '<(LIB_DIR)',
     'version_in_cc_file': 'vm/version_in.cc',
-    'version_cc_file': '<(SHARED_INTERMEDIATE_DIR)/version.cc',
+    'version_cc_file': '<(gen_source_dir)/version.cc',
 
     # Disable the OpenGLUI embedder by default on desktop OSes.  Note,
     # to build this on the desktop, you need GLUT installed.
@@ -61,6 +62,7 @@
     {
       'target_name': 'generate_version_cc_file',
       'type': 'none',
+      'toolsets':['target','host'],
       'dependencies': [
         'libdart_dependency_helper',
       ],
@@ -94,8 +96,9 @@
     {
       'target_name': 'libdart_dependency_helper',
       'type': 'executable',
+      'toolsets':['target','host'],
       # The dependencies here are the union of the dependencies of libdart and
-      # libdart_withcore. 
+      # libdart_withcore.
       'dependencies': [
         'libdart_lib_withcore',
         'libdart_lib',
diff --git a/runtime/embedders/openglui/common/extension.cc b/runtime/embedders/openglui/common/extension.cc
index eb32a3d..3e1885e 100644
--- a/runtime/embedders/openglui/common/extension.cc
+++ b/runtime/embedders/openglui/common/extension.cc
@@ -875,9 +875,10 @@
 
       if (values != NULL) {
         Dart_CObject result;
-        result.type = Dart_CObject::kUint8Array;
-        result.value.as_byte_array.values = values;
-        result.value.as_byte_array.length = length;
+        result.type = Dart_CObject::kTypedData;
+        result.value.as_typed_data.type = Dart_CObject::kUint8Array;
+        result.value.as_typed_data.values = values;
+        result.value.as_typed_data.length = length;
         Dart_PostCObject(reply_port_id, &result);
         free(values);
         // It is OK that result is destroyed when function exits.
diff --git a/runtime/embedders/openglui/common/vm_glue.cc b/runtime/embedders/openglui/common/vm_glue.cc
index 77564e54..4836c8a 100644
--- a/runtime/embedders/openglui/common/vm_glue.cc
+++ b/runtime/embedders/openglui/common/vm_glue.cc
@@ -89,7 +89,7 @@
 }
 
 // Returns true on success, false on failure.
-bool VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
+Dart_Isolate VMGlue::CreateIsolateAndSetupHelper(const char* script_uri,
                                          const char* main,
                                          void* data,
                                          char** error) {
@@ -98,7 +98,7 @@
       Dart_CreateIsolate(script_uri, main, NULL, data, error);
   if (isolate == NULL) {
     LOGE("Couldn't create isolate: %s", *error);
-    return false;
+    return NULL;
   }
 
   LOGI("Entering scope");
@@ -110,10 +110,10 @@
   CHECK_RESULT(result);
 
   Dart_ExitScope();
-  return true;
+  return isolate;
 }
 
-bool VMGlue::CreateIsolateAndSetup(const char* script_uri,
+Dart_Isolate VMGlue::CreateIsolateAndSetup(const char* script_uri,
   const char* main,
   void* data, char** error) {
   return CreateIsolateAndSetupHelper(script_uri,
diff --git a/runtime/embedders/openglui/common/vm_glue.h b/runtime/embedders/openglui/common/vm_glue.h
index f340b56..8f84377 100644
--- a/runtime/embedders/openglui/common/vm_glue.h
+++ b/runtime/embedders/openglui/common/vm_glue.h
@@ -50,11 +50,11 @@
 
   static Dart_Handle CheckError(Dart_Handle);
 
-  static bool CreateIsolateAndSetupHelper(const char* script_uri,
+  static Dart_Isolate CreateIsolateAndSetupHelper(const char* script_uri,
                                           const char* main,
                                           void* data,
                                           char** error);
-  static bool CreateIsolateAndSetup(const char* script_uri,
+  static Dart_Isolate CreateIsolateAndSetup(const char* script_uri,
                                     const char* main,
                                     void* data, char** error);
   static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
diff --git a/runtime/embedders/openglui/openglui_embedder.gypi b/runtime/embedders/openglui/openglui_embedder.gypi
index dc66642..c3671ee 100644
--- a/runtime/embedders/openglui/openglui_embedder.gypi
+++ b/runtime/embedders/openglui/openglui_embedder.gypi
@@ -176,7 +176,7 @@
         'targets': [
           {
             'target_name': 'emulator_embedder',
-            'type': 'shared_library',
+            'type': 'static_library',
             'dependencies': [
               'skia-desktop',
               'libdart_lib_withcore',
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 5da6c6a..fcb839d 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -943,8 +943,8 @@
  *
  * The string encoding in the 'value.as_string' is UTF-8.
  *
- * All the different types from dart:typeddata are exposed as type
- * kTypedData. The specific type from dart:typeddata is in the type
+ * All the different types from dart:typed_data are exposed as type
+ * kTypedData. The specific type from dart:typed_data is in the type
  * field of the as_typed_data structure. The length in the
  * as_typed_data structure is always in bytes.
  */
diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart
index 1ebc5b7..bb68f0b 100644
--- a/runtime/lib/array.dart
+++ b/runtime/lib/array.dart
@@ -43,7 +43,7 @@
         "Cannot remove element of a non-extendable array");
   }
 
-  void remove(Object element) {
+  bool remove(Object element) {
     throw new UnsupportedError(
         "Cannot remove element of a non-extendable array");
   }
@@ -67,7 +67,7 @@
     if (start < 0 || start > this.length) {
       throw new RangeError.range(start, 0, this.length);
     }
-    if (end < 0 || end > this.length) {
+    if (end < start || end > this.length) {
       throw new RangeError.range(end, start, this.length);
     }
     int length = end - start;
@@ -310,7 +310,7 @@
         "Cannot modify an immutable array");
   }
 
-  void remove(Object element) {
+  bool remove(Object element) {
     throw new UnsupportedError(
         "Cannot modify an immutable array");
   }
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 0a27429..3f7f5d2 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -3,6 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:math";
-import "dart:typeddata";
+import "dart:typed_data";
 
 import "dart:_collection-dev" as _symbol_dev;
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 37ab065..7d763e3 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -125,10 +125,14 @@
     }
     var args_mismatch = _existingArgumentNames != null;
     StringBuffer msg_buf = new StringBuffer(_developerMessage(args_mismatch));
+    String receiver_str = Error.safeToString(_receiver);
+    if ("Type: class '::'" == receiver_str) {
+      receiver_str = "top-level";
+    }
     if (!args_mismatch) {
       msg_buf.write(
           "NoSuchMethodError : method not found: '$_memberName'\n"
-          "Receiver: ${Error.safeToString(_receiver)}\n"
+          "Receiver: $receiver_str\n"
           "Arguments: [$actual_buf]");
     } else {
       String actualParameters = actual_buf.toString();
@@ -143,7 +147,7 @@
       msg_buf.write(
           "NoSuchMethodError: incorrect number of arguments passed to "
           "method named '$_memberName'\n"
-          "Receiver: ${Error.safeToString(_receiver)}\n"
+          "Receiver: $receiver_str\n"
           "Tried calling: $_memberName($actualParameters)\n"
           "Found: $_memberName($formalParameters)");
     }
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 1ebe8c2..f65380b 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -43,13 +43,14 @@
     return result;
   }
 
-  void remove(Object element) {
+  bool remove(Object element) {
     for (int i = 0; i < this.length; i++) {
       if (this[i] == element) {
         removeAt(i);
-        return;
+        return true;
       }
     }
+    return false;
   }
 
   void insertAll(int index, Iterable<T> iterable) {
@@ -237,10 +238,10 @@
   }
 
   void forEach(f(T element)) {
-    // TODO(srdjan): Use IterableMixinWorkaround.forEach(this, f);
-    // Accessing the list directly improves DeltaBlue performance by 25%.
+    int initialLength = length;
     for (int i = 0; i < length; i++) {
       f(this[i]);
+      if (length != initialLength) throw new ConcurrentModificationError(this);
     }
   }
 
diff --git a/runtime/lib/integers.cc b/runtime/lib/integers.cc
index f6133dd..d368415 100644
--- a/runtime/lib/integers.cc
+++ b/runtime/lib/integers.cc
@@ -189,15 +189,11 @@
     if (len > 0) {
       const char* cstr = value.ToCString();
       ASSERT(cstr != NULL);
-      // Dart differences from strtol:
-      // a) '+5' is not a valid integer (leading plus).
-      if (cstr[0] != '+') {
-        char* p_end = NULL;
-        const int64_t int_value = strtol(cstr, &p_end, 10);
-        if (p_end == (cstr + len)) {
-          if ((Smi::kMinValue <= int_value) && (int_value <= Smi::kMaxValue)) {
-            return Smi::New(int_value);
-          }
+      char* p_end = NULL;
+      const int64_t int_value = strtoll(cstr, &p_end, 10);
+      if (p_end == (cstr + len)) {
+        if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) {
+          return Integer::New(int_value);
         }
       }
     }
diff --git a/runtime/lib/integers_patch.dart b/runtime/lib/integers_patch.dart
index de4abdb..05d47cf 100644
--- a/runtime/lib/integers_patch.dart
+++ b/runtime/lib/integers_patch.dart
@@ -6,7 +6,63 @@
 // VM implementation of int.
 
 patch class int {
-  static int _parse(String str) native "Integer_parse";
+
+  static bool _isWhitespace(int codePoint) {
+    return
+      (codePoint == 32) || // Space.
+      ((9 <= codePoint) && (codePoint <= 13)); // CR, LF, TAB, etc.
+  }
+
+  static int _tryParseSmi(String str) {
+    if (str.isEmpty) return null;
+    var ix = 0;
+    var endIx = str.length - 1;
+    // Find first and last non-whitespace.
+    while (ix <= endIx) {
+      if (!_isWhitespace(str.codeUnitAt(ix))) break;
+      ix++;
+    }
+    if (endIx < ix) {
+      return null;  // Empty.
+    }
+    while (endIx > ix) {
+      if (!_isWhitespace(str.codeUnitAt(endIx))) break;
+      endIx--;
+    }
+
+    var isNegative = false;
+    var c = str.codeUnitAt(ix);
+    // Check for leading '+' or '-'.
+    if ((c == 0x2b) || (c == 0x2d)) {
+      ix++;
+      isNegative = (c == 0x2d);
+      if (ix > endIx) {
+        return null;  // Empty.
+      }
+    }
+    if ((endIx - ix) >= 9) {
+      return null;  // May not fit into a Smi.
+    }
+    var result = 0;
+    for (int i = ix; i <= endIx; i++) {
+      var c = str.codeUnitAt(i) - 0x30;
+      if ((c > 9) || (c < 0)) {
+        return null;
+      }
+      result = result * 10 + c;
+    }
+    return isNegative ? -result : result;
+  }
+
+  static int _parse(String str) {
+    int res = _tryParseSmi(str);
+    if (res == null) {
+      res = _native_parse(str);
+    }
+    return res;
+  }
+
+  static int _native_parse(String str) native "Integer_parse";
 
   static int _throwFormatException(String source) {
     throw new FormatException(source);
diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
index d17d82e..5682bec 100644
--- a/runtime/lib/math_patch.dart
+++ b/runtime/lib/math_patch.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.
 
-import "dart:typeddata";
+import "dart:typed_data";
 
 // A VM patch of the dart:math library.
 patch num pow(num x, num exponent) {
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 31c1f4e..62c22e0 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -4,7 +4,6 @@
 
 #include "include/dart_api.h"
 #include "include/dart_debugger_api.h"
-#include "platform/json.h"
 #include "vm/dart_api_impl.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/dart_entry.h"
@@ -272,7 +271,7 @@
   if (Dart_IsLibrary(target)) {
     Dart_Handle cls_name = NewString("_LazyLibraryMirror");
     Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
-    Dart_Handle args[] = { Dart_LibraryName(target) };
+    Dart_Handle args[] = { Dart_LibraryUrl(target) };
     return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
   }
 
@@ -296,13 +295,13 @@
       Dart_Handle cls_name = NewString("_LazyTypeMirror");
       Dart_Handle cls = Dart_GetClass(MirrorLib(), cls_name);
       Dart_Handle lib = Dart_ClassGetLibrary(target);
-      Dart_Handle lib_name;
+      Dart_Handle lib_url;
       if (Dart_IsNull(lib)) {
-        lib_name = Dart_Null();
+        lib_url = Dart_Null();
       } else {
-        lib_name = Dart_LibraryName(lib);
+        lib_url = Dart_LibraryUrl(lib);
       }
-      Dart_Handle args[] = { lib_name, Dart_ClassName(target) };
+      Dart_Handle args[] = { lib_url, Dart_ClassName(target) };
       return Dart_New(cls, Dart_Null(), ARRAY_SIZE(args), args);
     }
   }
@@ -871,13 +870,11 @@
     if (Dart_IsError(lib)) {
       return lib;
     }
-    Dart_Handle lib_key = Dart_LibraryName(lib);
     Dart_Handle lib_mirror = CreateLibraryMirror(lib);
     if (Dart_IsError(lib_mirror)) {
       return lib_mirror;
     }
-    // TODO(turnidge): Check for duplicate library names.
-    result = MapAdd(map, lib_key, lib_mirror);
+    result = MapAdd(map, lib_url, lib_mirror);
   }
   return map;
 }
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 4546ab0..614e5589 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -62,14 +62,21 @@
   return buf.toString();
 }
 
-class _LocalMirrorSystemImpl implements MirrorSystem {
-  // TODO(ahe): [libraries] should be Map<Uri, LibraryMirror>.
+Map<Uri, LibraryMirror> _createLibrariesMap(Map<String, LibraryMirror> map) {
+    var result = new Map<Uri, LibraryMirror>();
+    map.forEach((String url, LibraryMirror mirror) {
+      result[Uri.parse(url)] = mirror;
+    });
+    return result;
+}
+
+class _LocalMirrorSystemImpl extends MirrorSystem {
   // Change parameter back to "this.libraries" when native code is changed.
   _LocalMirrorSystemImpl(Map<String, LibraryMirror> libraries, this.isolate)
-      : _functionTypes = new Map<String, FunctionTypeMirror>(),
-        this.libraries = _convertStringToSymbolMap(libraries);
+      : this.libraries = _createLibrariesMap(libraries),
+        _functionTypes = new Map<String, FunctionTypeMirror>();
 
-  final Map<Symbol, LibraryMirror> libraries;
+  final Map<Uri, LibraryMirror> libraries;
   final IsolateMirror isolate;
 
   TypeMirror _dynamicType = null;
@@ -401,12 +408,11 @@
 }
 
 class _LazyTypeMirror {
-  _LazyTypeMirror(String libraryName, String typeName)
-      : this.libraryName = _s(libraryName),
-        this.typeName = _s(typeName);
+  _LazyTypeMirror(String this.libraryUrl, String typeName)
+      : this.typeName = _s(typeName);
 
   TypeMirror resolve(MirrorSystem mirrors) {
-    if (libraryName == null) {
+    if (libraryUrl == null) {
       if (typeName == const Symbol('dynamic')) {
         return mirrors.dynamicType;
       } else if (typeName == const Symbol('void')) {
@@ -416,7 +422,7 @@
             "Mirror for type '$typeName' is not implemented");
       }
     }
-    var resolved = mirrors.libraries[libraryName].members[typeName];
+    var resolved = mirrors.libraries[Uri.parse(libraryUrl)].members[typeName];
     if (resolved == null) {
       throw new UnimplementedError(
           "Mirror for type '$typeName' is not implemented");
@@ -424,7 +430,7 @@
     return resolved;
   }
 
-  final Symbol libraryName;
+  final String libraryUrl;
   final Symbol typeName;
 }
 
@@ -758,24 +764,24 @@
 
 
 class _LazyLibraryMirror {
-  _LazyLibraryMirror(String libraryName)
-      : this.libraryName = _s(libraryName);
+  _LazyLibraryMirror(String this.libraryUrl);
 
   LibraryMirror resolve(MirrorSystem mirrors) {
-    return mirrors.libraries[libraryName];
+    return mirrors.libraries[Uri.parse(libraryUrl)];
   }
 
-  final Symbol libraryName;
+  final String libraryUrl;
 }
 
 class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl
     implements LibraryMirror {
   _LocalLibraryMirrorImpl(ref,
                           String simpleName,
-                          this.url,
+                          String url,
                           Map<String, Mirror> members)
       : this.simpleName = _s(simpleName),
         this.members = _convertStringToSymbolMap(members),
+        this.uri = Uri.parse(url),
         super(ref);
 
   final Symbol simpleName;
@@ -797,7 +803,7 @@
         'LibraryMirror.location is not implemented');
   }
 
-  final String url;
+  final Uri uri;
   final Map<Symbol, Mirror> members;
 
   Map<Symbol, ClassMirror> _classes = null;
diff --git a/runtime/lib/simd128.cc b/runtime/lib/simd128.cc
index 25e8db7..81894fe 100644
--- a/runtime/lib/simd128.cc
+++ b/runtime/lib/simd128.cc
@@ -26,6 +26,15 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Float32x4_splat, 2) {
+  ASSERT(AbstractTypeArguments::CheckedHandle(
+      arguments->NativeArgAt(0)).IsNull());
+  GET_NON_NULL_NATIVE_ARGUMENT(Double, v, arguments->NativeArgAt(1));
+  float _v = v.value();
+  return Float32x4::New(_v, _v, _v, _v);
+}
+
+
 DEFINE_NATIVE_ENTRY(Float32x4_zero, 1) {
   ASSERT(AbstractTypeArguments::CheckedHandle(
       arguments->NativeArgAt(0)).IsNull());
diff --git a/runtime/lib/typeddata.cc b/runtime/lib/typed_data.cc
similarity index 92%
rename from runtime/lib/typeddata.cc
rename to runtime/lib/typed_data.cc
index 29e7af3..4a47d71 100644
--- a/runtime/lib/typeddata.cc
+++ b/runtime/lib/typed_data.cc
@@ -78,25 +78,32 @@
   return Integer::null();
 }
 
-
-#define COPY_DATA(type, dst, src)                                              \
-  const type& dst_array = type::Cast(dst);                                     \
-  const type& src_array = type::Cast(src);                                     \
-  intptr_t element_size_in_bytes = dst_array.ElementSizeInBytes();             \
-  intptr_t length_in_bytes = length.Value() * element_size_in_bytes;           \
-  intptr_t src_offset_in_bytes = src_start.Value() * element_size_in_bytes;    \
-  intptr_t dst_offset_in_bytes = dst_start.Value() * element_size_in_bytes;    \
-  SetRangeCheck(src_offset_in_bytes,                                           \
-                length_in_bytes,                                               \
-                src_array.LengthInBytes(),                                     \
-                element_size_in_bytes);                                        \
-  SetRangeCheck(dst_offset_in_bytes,                                           \
-                length_in_bytes,                                               \
-                dst_array.LengthInBytes(),                                     \
-                element_size_in_bytes);                                        \
-  type::Copy(dst_array, dst_offset_in_bytes,                                   \
-             src_array, src_offset_in_bytes,                                   \
-             length_in_bytes);
+template <typename DstType, typename SrcType>
+static RawBool* CopyData(const Instance& dst, const Instance& src,
+                         const Smi& dst_start, const Smi& src_start,
+                         const Smi& length) {
+  const DstType& dst_array = DstType::Cast(dst);
+  const SrcType& src_array = SrcType::Cast(src);
+  intptr_t element_size_in_bytes = dst_array.ElementSizeInBytes();
+  intptr_t dst_offset_in_bytes = dst_start.Value() * element_size_in_bytes;
+  intptr_t src_offset_in_bytes = src_start.Value() * element_size_in_bytes;
+  intptr_t length_in_bytes = length.Value() * element_size_in_bytes;
+  if (dst_array.ElementType() != src_array.ElementType()) {
+    return Bool::False().raw();
+  }
+  SetRangeCheck(src_offset_in_bytes,
+                length_in_bytes,
+                src_array.LengthInBytes(),
+                element_size_in_bytes);
+  SetRangeCheck(dst_offset_in_bytes,
+                length_in_bytes,
+                dst_array.LengthInBytes(),
+                element_size_in_bytes);
+  TypedData::Copy<DstType, SrcType>(dst_array, dst_offset_in_bytes,
+                                    src_array, src_offset_in_bytes,
+                                    length_in_bytes);
+  return Bool::True().raw();
+}
 
 DEFINE_NATIVE_ENTRY(TypedData_setRange, 5) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, dst, arguments->NativeArgAt(0));
@@ -112,17 +119,22 @@
     args.SetAt(0, error);
     Exceptions::ThrowByType(Exceptions::kArgument, args);
   }
-  if ((dst.IsTypedData() || dst.IsExternalTypedData()) &&
-      (dst.clazz() == src.clazz())) {
-    if (dst.IsTypedData()) {
-      ASSERT(src.IsTypedData());
-      COPY_DATA(TypedData, dst, src);
-    } else {
-      ASSERT(src.IsExternalTypedData());
-      ASSERT(dst.IsExternalTypedData());
-      COPY_DATA(ExternalTypedData, dst, src);
+  if (dst.IsTypedData()) {
+    if (src.IsTypedData()) {
+      return CopyData<TypedData, TypedData>(
+          dst, src, dst_start, src_start, length);
+    } else if (src.IsExternalTypedData()) {
+      return CopyData<TypedData, ExternalTypedData>(
+          dst, src, dst_start, src_start, length);
     }
-    return Bool::True().raw();
+  } else if (dst.IsExternalTypedData()) {
+    if (src.IsTypedData()) {
+      return CopyData<ExternalTypedData, TypedData>(
+          dst, src, dst_start, src_start, length);
+    } else if (src.IsExternalTypedData()) {
+      return CopyData<ExternalTypedData, ExternalTypedData>(
+          dst, src, dst_start, src_start, length);
+    }
   }
   return Bool::False().raw();
 }
diff --git a/runtime/lib/typeddata.dart b/runtime/lib/typed_data.dart
similarity index 95%
rename from runtime/lib/typeddata.dart
rename to runtime/lib/typed_data.dart
index ddf79f4..9fb8f15 100644
--- a/runtime/lib/typeddata.dart
+++ b/runtime/lib/typed_data.dart
@@ -240,6 +240,9 @@
   /* patch */ factory Float32x4(double x, double y, double z, double w) {
     return new _Float32x4(x, y, z, w);
   }
+  /* patch */ factory Float32x4.splat(double v) {
+    return new _Float32x4.splat(v);
+  }
   /* patch */ factory Float32x4.zero() {
     return new _Float32x4.zero();
   }
@@ -373,6 +376,16 @@
         "Cannot add to a non-extendable array");
   }
 
+  void insert(int index, value) {
+    throw new UnsupportedError(
+        "Cannot insert into a non-extendable array");
+  }
+
+  void insertAll(int index, Iterable values) {
+    throw new UnsupportedError(
+        "Cannot insert into a non-extendable array");
+  }
+
   void sort([int compare(var a, var b)]) {
     return IterableMixinWorkaround.sortList(this, compare);
   }
@@ -395,7 +408,12 @@
         "Cannot remove from a non-extendable array");
   }
 
-  void remove(Object element) {
+  bool remove(Object element) {
+    throw new UnsupportedError(
+        "Cannot remove from a non-extendable array");
+  }
+
+  bool removeAt(int index) {
     throw new UnsupportedError(
         "Cannot remove from a non-extendable array");
   }
@@ -446,8 +464,8 @@
         "Cannot remove from a non-extendable array");
   }
 
-  List toList() {
-    return new List.from(this);
+  List toList({bool growable: true}) {
+    return new List.from(this, growable: growable);
   }
 
   Set toSet() {
@@ -2015,6 +2033,7 @@
 class _Float32x4 implements Float32x4 {
   factory _Float32x4(double x, double y, double z, double w)
       native "Float32x4_fromDoubles";
+  factory _Float32x4.splat(double v) native "Float32x4_splat";
   factory _Float32x4.zero() native "Float32x4_zero";
   Float32x4 operator +(Float32x4 other) {
     return _add(other);
@@ -2191,7 +2210,7 @@
 
 class _TypedListView extends _TypedListBase implements TypedData {
   _TypedListView(ByteBuffer _buffer, int _offset, int _length)
-    : _typeddata = _buffer,  // This assignment is type safe.
+    : _typedData = _buffer,  // This assignment is type safe.
       offsetInBytes = _offset,
       length = _length {
   }
@@ -2204,10 +2223,10 @@
   }
 
   ByteBuffer get buffer {
-    return _typeddata.buffer;
+    return _typedData.buffer;
   }
 
-  final TypedData _typeddata;
+  final TypedData _typedData;
   final int offsetInBytes;
   final int length;
 }
@@ -2232,7 +2251,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getInt8(offsetInBytes +
+    return _typedData._getInt8(offsetInBytes +
                                (index * Int8List.BYTES_PER_ELEMENT));
   }
 
@@ -2240,7 +2259,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setInt8(offsetInBytes + (index * Int8List.BYTES_PER_ELEMENT),
+    _typedData._setInt8(offsetInBytes + (index * Int8List.BYTES_PER_ELEMENT),
                         _toInt8(value));
   }
 
@@ -2283,7 +2302,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getUint8(offsetInBytes +
+    return _typedData._getUint8(offsetInBytes +
                                 (index * Uint8List.BYTES_PER_ELEMENT));
   }
 
@@ -2291,7 +2310,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT),
+    _typedData._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT),
                          _toUint8(value));
   }
 
@@ -2335,7 +2354,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getUint8(offsetInBytes +
+    return _typedData._getUint8(offsetInBytes +
                                 (index * Uint8List.BYTES_PER_ELEMENT));
   }
 
@@ -2343,7 +2362,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT),
+    _typedData._setUint8(offsetInBytes + (index * Uint8List.BYTES_PER_ELEMENT),
                          _toClampedUint8(value));
   }
 
@@ -2386,7 +2405,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getInt16(offsetInBytes +
+    return _typedData._getInt16(offsetInBytes +
                                 (index * Int16List.BYTES_PER_ELEMENT));
   }
 
@@ -2394,7 +2413,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setInt16(offsetInBytes + (index * Int16List.BYTES_PER_ELEMENT),
+    _typedData._setInt16(offsetInBytes + (index * Int16List.BYTES_PER_ELEMENT),
                          _toInt16(value));
   }
 
@@ -2437,7 +2456,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getUint16(offsetInBytes +
+    return _typedData._getUint16(offsetInBytes +
                                  (index * Uint16List.BYTES_PER_ELEMENT));
   }
 
@@ -2445,7 +2464,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setUint16(offsetInBytes + (index * Uint16List.BYTES_PER_ELEMENT),
+    _typedData._setUint16(offsetInBytes + (index * Uint16List.BYTES_PER_ELEMENT),
                           _toUint16(value));
   }
 
@@ -2488,7 +2507,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getInt32(offsetInBytes +
+    return _typedData._getInt32(offsetInBytes +
                                 (index * Int32List.BYTES_PER_ELEMENT));
   }
 
@@ -2496,7 +2515,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setInt32(offsetInBytes + (index * Int32List.BYTES_PER_ELEMENT),
+    _typedData._setInt32(offsetInBytes + (index * Int32List.BYTES_PER_ELEMENT),
                          _toInt32(value));
   }
 
@@ -2539,7 +2558,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getUint32(offsetInBytes +
+    return _typedData._getUint32(offsetInBytes +
                                  (index * Uint32List.BYTES_PER_ELEMENT));
   }
 
@@ -2547,7 +2566,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setUint32(offsetInBytes + (index * Uint32List.BYTES_PER_ELEMENT),
+    _typedData._setUint32(offsetInBytes + (index * Uint32List.BYTES_PER_ELEMENT),
                           _toUint32(value));
   }
 
@@ -2590,7 +2609,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getInt64(offsetInBytes +
+    return _typedData._getInt64(offsetInBytes +
                                 (index * Int64List.BYTES_PER_ELEMENT));
   }
 
@@ -2598,7 +2617,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setInt64(offsetInBytes + (index * Int64List.BYTES_PER_ELEMENT),
+    _typedData._setInt64(offsetInBytes + (index * Int64List.BYTES_PER_ELEMENT),
                          _toInt64(value));
   }
 
@@ -2641,7 +2660,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getUint64(offsetInBytes +
+    return _typedData._getUint64(offsetInBytes +
                                  (index * Uint64List.BYTES_PER_ELEMENT));
   }
 
@@ -2649,7 +2668,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setUint64(offsetInBytes + (index * Uint64List.BYTES_PER_ELEMENT),
+    _typedData._setUint64(offsetInBytes + (index * Uint64List.BYTES_PER_ELEMENT),
                           _toUint64(value));
   }
 
@@ -2692,7 +2711,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getFloat32(offsetInBytes +
+    return _typedData._getFloat32(offsetInBytes +
                                   (index * Float32List.BYTES_PER_ELEMENT));
   }
 
@@ -2700,7 +2719,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setFloat32(offsetInBytes +
+    _typedData._setFloat32(offsetInBytes +
                            (index * Float32List.BYTES_PER_ELEMENT), value);
   }
 
@@ -2743,7 +2762,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getFloat64(offsetInBytes +
+    return _typedData._getFloat64(offsetInBytes +
                                   (index * Float64List.BYTES_PER_ELEMENT));
   }
 
@@ -2751,7 +2770,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setFloat64(offsetInBytes +
+    _typedData._setFloat64(offsetInBytes +
                           (index * Float64List.BYTES_PER_ELEMENT), value);
   }
 
@@ -2794,7 +2813,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    return _typeddata._getFloat32x4(offsetInBytes +
+    return _typedData._getFloat32x4(offsetInBytes +
                                   (index * Float32x4List.BYTES_PER_ELEMENT));
   }
 
@@ -2802,7 +2821,7 @@
     if (index < 0 || index >= length) {
       _throwRangeError(index, length);
     }
-    _typeddata._setFloat32x4(offsetInBytes +
+    _typedData._setFloat32x4(offsetInBytes +
                              (index * Float32x4List.BYTES_PER_ELEMENT), value);
   }
 
@@ -2828,7 +2847,7 @@
 
 class _ByteDataView implements ByteData {
   _ByteDataView(ByteBuffer _buffer, int _offsetInBytes, int _lengthInBytes)
-    : _typeddata = _buffer,  // _buffer is guaranteed to be a TypedData here.
+    : _typedData = _buffer,  // _buffer is guaranteed to be a TypedData here.
       _offset = _offsetInBytes,
       length = _lengthInBytes {
     _rangeCheck(_buffer.lengthInBytes, _offset, length);
@@ -2838,7 +2857,7 @@
   // Method(s) implementing TypedData interface.
 
   ByteBuffer get buffer {
-    return _typeddata.buffer;
+    return _typedData.buffer;
   }
 
   int get lengthInBytes {
@@ -2855,33 +2874,33 @@
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    return _typeddata._getInt8(_offset + byteOffset);
+    return _typedData._getInt8(_offset + byteOffset);
   }
   void setInt8(int byteOffset, int value) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    _typeddata._setInt8(_offset + byteOffset, _toInt8(value));
+    _typedData._setInt8(_offset + byteOffset, _toInt8(value));
   }
 
   int getUint8(int byteOffset) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    return _typeddata._getUint8(_offset + byteOffset);
+    return _typedData._getUint8(_offset + byteOffset);
   }
   void setUint8(int byteOffset, int value) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    _typeddata._setUint8(_offset + byteOffset, _toUint8(value));
+    _typedData._setUint8(_offset + byteOffset, _toUint8(value));
   }
 
   int getInt16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getInt16(_offset + byteOffset);
+    var result = _typedData._getInt16(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -2897,14 +2916,14 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianInt16(set_value, endian._littleEndian);
     }
-    _typeddata._setInt16(_offset + byteOffset, set_value);
+    _typedData._setInt16(_offset + byteOffset, set_value);
   }
 
   int getUint16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getUint16(_offset + byteOffset);
+    var result = _typedData._getUint16(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -2920,14 +2939,14 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianUint16(set_value, endian._littleEndian);
     }
-    _typeddata._setUint16(_offset + byteOffset, set_value);
+    _typedData._setUint16(_offset + byteOffset, set_value);
   }
 
   int getInt32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getInt32(_offset + byteOffset);
+    var result = _typedData._getInt32(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -2943,14 +2962,14 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianInt32(set_value, endian._littleEndian);
     }
-    _typeddata._setInt32(_offset + byteOffset, set_value);
+    _typedData._setInt32(_offset + byteOffset, set_value);
   }
 
   int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getUint32(_offset + byteOffset);
+    var result = _typedData._getUint32(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -2966,14 +2985,14 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianUint32(set_value, endian._littleEndian);
     }
-    _typeddata._setUint32(_offset + byteOffset, set_value);
+    _typedData._setUint32(_offset + byteOffset, set_value);
   }
 
   int getInt64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getInt64(_offset + byteOffset);
+    var result = _typedData._getInt64(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -2989,14 +3008,14 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianInt64(set_value, endian._littleEndian);
     }
-    _typeddata._setInt64(_offset + byteOffset, set_value);
+    _typedData._setInt64(_offset + byteOffset, set_value);
   }
 
   int getUint64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getUint64(_offset + byteOffset);
+    var result = _typedData._getUint64(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -3012,7 +3031,7 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianUint64(set_value, endian._littleEndian);
     }
-    _typeddata._setUint64(_offset + byteOffset, set_value);
+    _typedData._setUint64(_offset + byteOffset, set_value);
   }
 
   double getFloat32(int byteOffset,
@@ -3020,7 +3039,7 @@
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getFloat32(_offset + byteOffset);
+    var result = _typedData._getFloat32(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -3036,7 +3055,7 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianFloat32(set_value, endian._littleEndian);
     }
-    _typeddata._setFloat32(_offset + byteOffset, set_value);
+    _typedData._setFloat32(_offset + byteOffset, set_value);
   }
 
   double getFloat64(int byteOffset,
@@ -3044,7 +3063,7 @@
     if (byteOffset < 0 || byteOffset >= length) {
       _throwRangeError(byteOffset, length);
     }
-    var result = _typeddata._getFloat64(_offset + byteOffset);
+    var result = _typedData._getFloat64(_offset + byteOffset);
     if (identical(endian, Endianness.HOST_ENDIAN)) {
       return result;
     }
@@ -3060,7 +3079,7 @@
     if (!identical(endian, Endianness.HOST_ENDIAN)) {
       set_value = _toEndianFloat64(set_value, endian._littleEndian);
     }
-    _typeddata._setFloat64(_offset + byteOffset, set_value);
+    _typedData._setFloat64(_offset + byteOffset, set_value);
   }
 
   Float32x4 getFloat32x4(int byteOffset,
@@ -3069,7 +3088,7 @@
       _throwRangeError(byteOffset, length);
     }
     // TODO(johnmccutchan) : Need to resolve this for endianity.
-    return _typeddata._getFloat32x4(_offset + byteOffset);
+    return _typedData._getFloat32x4(_offset + byteOffset);
   }
   void setFloat32x4(int byteOffset,
                     Float32x4 value,
@@ -3078,7 +3097,7 @@
       _throwRangeError(byteOffset, length);
     }
     // TODO(johnmccutchan) : Need to resolve this for endianity.
-    _typeddata._setFloat32x4(_offset + byteOffset, value);
+    _typedData._setFloat32x4(_offset + byteOffset, value);
 
   }
 
@@ -3103,7 +3122,7 @@
       native "ByteData_ToEndianFloat64";
 
 
-  final TypedData _typeddata;
+  final TypedData _typedData;
   final int _offset;
   final int length;
 }
diff --git a/runtime/lib/typeddata_sources.gypi b/runtime/lib/typed_data_sources.gypi
similarity index 74%
rename from runtime/lib/typeddata_sources.gypi
rename to runtime/lib/typed_data_sources.gypi
index fc5ba11..28d6a53 100644
--- a/runtime/lib/typeddata_sources.gypi
+++ b/runtime/lib/typed_data_sources.gypi
@@ -2,12 +2,12 @@
 # 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.
 
-# Sources visible via dart:typeddata library.
+# Sources visible via dart:typed_data library.
 
 {
   'sources': [
-    'typeddata.cc',
-    'typeddata.dart',
+    'typed_data.cc',
+    'typed_data.dart',
     'simd128.cc',
   ],
 }
diff --git a/runtime/platform/c99_support_win.h b/runtime/platform/c99_support_win.h
index 2859f0c..71ec127 100644
--- a/runtime/platform/c99_support_win.h
+++ b/runtime/platform/c99_support_win.h
@@ -65,4 +65,10 @@
   }
 }
 
+// Windows does not have strtoll defined.
+#if defined(_MSC_VER)
+#define strtoll _strtoi64
+#endif
+
+
 #endif  // PLATFORM_C99_SUPPORT_WIN_H_
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 2d566bb..f99e065 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -123,13 +123,34 @@
 #elif defined(_M_IX86) || defined(__i386__)
 #define HOST_ARCH_IA32 1
 #define ARCH_IS_32_BIT 1
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
+#define kFpuRegisterSize 8
+typedef double fpu_register_t;
+#else
 #define kFpuRegisterSize 16
 typedef simd128_value_t fpu_register_t;
+#endif
 #elif defined(__ARMEL__)
 #define HOST_ARCH_ARM 1
 #define ARCH_IS_32_BIT 1
 #define kFpuRegisterSize 8
 typedef double fpu_register_t;
+typedef struct {
+  union {
+    uint32_t u;
+    float    f;
+  } data_[4];
+} simd_value_t;
+#define simd_value_safe_load(addr)                                             \
+  (*reinterpret_cast<simd_value_t *>(addr))
+#define simd_value_safe_store(addr, value)                                     \
+  do {                                                                         \
+    reinterpret_cast<simd_value_t *>(addr)->data_[0] = value.data_[0];         \
+    reinterpret_cast<simd_value_t *>(addr)->data_[1] = value.data_[1];         \
+    reinterpret_cast<simd_value_t *>(addr)->data_[2] = value.data_[2];         \
+    reinterpret_cast<simd_value_t *>(addr)->data_[3] = value.data_[3];         \
+  } while (0)
+
 #elif defined(__MIPSEL__)
 #define HOST_ARCH_MIPS 1
 #define ARCH_IS_32_BIT 1
diff --git a/runtime/tests/vm/dart/byte_array_optimized_test.dart b/runtime/tests/vm/dart/byte_array_optimized_test.dart
index 80bba34..fafef82 100644
--- a/runtime/tests/vm/dart/byte_array_optimized_test.dart
+++ b/runtime/tests/vm/dart/byte_array_optimized_test.dart
@@ -6,7 +6,7 @@
 library byte_array_test;
 
 import "package:expect/expect.dart";
-import 'dart:typeddata';
+import 'dart:typed_data';
 
 // This test exercises optimized [] and []= operators
 // on byte array views.
diff --git a/runtime/tests/vm/dart/byte_array_test.dart b/runtime/tests/vm/dart/byte_array_test.dart
index f57f551..0f3fe96 100644
--- a/runtime/tests/vm/dart/byte_array_test.dart
+++ b/runtime/tests/vm/dart/byte_array_test.dart
@@ -6,7 +6,7 @@
 library byte_array_test;
 
 import "package:expect/expect.dart";
-import 'dart:typeddata';
+import 'dart:typed_data';
 
 class ByteArrayTest {
   static testInt8ListImpl(Int8List array) {
diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
index 772ce66..e7927c2 100644
--- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart
+++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart
@@ -13,6 +13,7 @@
 import 'dart:async';
 import 'dart:isolate';
 import 'dart:mirrors';
+import 'dart:uri';
 
 ReceivePort exit_port;
 Set expectedTests;
@@ -115,7 +116,7 @@
                 lib_mirror.qualifiedName);
   Expect.equals(null, lib_mirror.owner);
   Expect.isFalse(lib_mirror.isPrivate);
-  Expect.isTrue(lib_mirror.url.contains('isolate_mirror_local_test.dart'));
+  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());
@@ -300,10 +301,10 @@
 
 void testLibrariesMap(Map libraries) {
   // Just look for a couple of well-known libs.
-  LibraryMirror core_lib = libraries[const Symbol('dart.core')];
+  LibraryMirror core_lib = libraries[Uri.parse('dart:core')];
   Expect.isTrue(core_lib is LibraryMirror);
 
-  LibraryMirror mirror_lib = libraries[const Symbol('dart.mirrors')];
+  LibraryMirror mirror_lib = libraries[Uri.parse('dart:mirrors')];
   Expect.isTrue(mirror_lib is LibraryMirror);
 
   // Lookup an interface from a library and make sure it is sane.
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 40077cf..6e71bf0 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -72,6 +72,7 @@
 # Tests missing code generation support.
 cc/CorelibCompileAll: Skip
 cc/Dart2JSCompileAll: Skip
+cc/Debug_InterruptIsolate: Skip
 # Tests needing Dart execution.
 dart/*: Skip
 
diff --git a/runtime/third_party/double-conversion/src/double-conversion.gypi b/runtime/third_party/double-conversion/src/double-conversion.gypi
index 8466d5d..aa474b8 100644
--- a/runtime/third_party/double-conversion/src/double-conversion.gypi
+++ b/runtime/third_party/double-conversion/src/double-conversion.gypi
@@ -5,6 +5,7 @@
     {
       'target_name': 'libdouble_conversion',
       'type': 'static_library',
+      'toolsets':['target','host'],
       'dependencies': [
       ],
       'include_dirs': [
diff --git a/runtime/third_party/jscre/jscre.gypi b/runtime/third_party/jscre/jscre.gypi
index 46ecb7e..acb6d8c 100644
--- a/runtime/third_party/jscre/jscre.gypi
+++ b/runtime/third_party/jscre/jscre.gypi
@@ -5,6 +5,7 @@
     {
       'target_name': 'libjscre',
       'type': 'static_library',
+      'toolsets':['target','host'],
       'dependencies': [
       ],
       'include_dirs': [
diff --git a/runtime/tools/create_resources.py b/runtime/tools/create_resources.py
index f657ea1..d2c0cea 100644
--- a/runtime/tools/create_resources.py
+++ b/runtime/tools/create_resources.py
@@ -62,7 +62,10 @@
 
 ''' % date.today().year
   cc_text += '#include "bin/resources.h"\n\n'
+  cc_text += 'namespace dart {\n'
+  cc_text += 'namespace bin {\n'
   cc_text += makeResources(root_dir, input_files)
+  cc_text += '}  // namespace bin\n} // namespace dart\n'
   open(output_file, 'w').write(cc_text)
   return True
 
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index f003889..49d0db2 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -40,19 +40,7 @@
 #if defined(USING_SIMULATOR)
   integer_division_supported_ = true;
 #else
-  Assembler assembler;
-  __ mrc(R0, 15, 0, 0, 2, 0);
-  __ Lsr(R0, R0, 24);
-  __ and_(R0, R0, ShifterOperand(0xf));
-  __ Ret();
-
-  const Code& code =
-      Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler));
-  Instructions& instructions = Instructions::Handle(code.instructions());
-  typedef int32_t (*DetectCPUFeatures)();
-  int32_t features =
-      reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())();
-  integer_division_supported_ = features != 0;
+  integer_division_supported_ = false;
 #endif  // defined(USING_SIMULATOR)
 #if defined(DEBUG)
   initialized_ = true;
@@ -477,6 +465,13 @@
 }
 
 
+void Assembler::smull(Register rd_lo, Register rd_hi,
+                      Register rn, Register rm, Condition cond) {
+  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
+  EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm);
+}
+
+
 void Assembler::umull(Register rd_lo, Register rd_hi,
                       Register rn, Register rm, Condition cond) {
   // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
@@ -1236,27 +1231,29 @@
 
 
 // Uses a code sequence that can easily be decoded.
-void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) {
+void Assembler::LoadWordFromPoolOffset(Register rd,
+                                       int32_t offset,
+                                       Condition cond) {
   ASSERT(rd != PP);
   int32_t offset_mask = 0;
   if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) {
-    ldr(rd, Address(PP, offset));
+    ldr(rd, Address(PP, offset), cond);
   } else {
     int32_t offset_hi = offset & ~offset_mask;  // signed
     uint32_t offset_lo = offset & offset_mask;  // unsigned
     // Inline a simplified version of AddImmediate(rd, PP, offset_hi).
     ShifterOperand shifter_op;
     if (ShifterOperand::CanHold(offset_hi, &shifter_op)) {
-      add(rd, PP, shifter_op);
+      add(rd, PP, shifter_op, cond);
     } else {
       movw(rd, Utils::Low16Bits(offset_hi));
       const uint16_t value_high = Utils::High16Bits(offset_hi);
       if (value_high != 0) {
-        movt(rd, value_high);
+        movt(rd, value_high, cond);
       }
-      add(rd, PP, ShifterOperand(LR));
+      add(rd, PP, ShifterOperand(LR), cond);
     }
-    ldr(rd, Address(rd, offset_lo));
+    ldr(rd, Address(rd, offset_lo), cond);
   }
 }
 
@@ -1269,24 +1266,24 @@
 }
 
 
-void Assembler::LoadObject(Register rd, const Object& object) {
+void Assembler::LoadObject(Register rd, const Object& object, Condition cond) {
   // Smis and VM heap objects are never relocated; do not use object pool.
   if (object.IsSmi()) {
-    LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()));
+    LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond);
   } else if (object.InVMHeap()) {
     // Make sure that class CallPattern is able to decode this load immediate.
     const int32_t object_raw = reinterpret_cast<int32_t>(object.raw());
-    movw(rd, Utils::Low16Bits(object_raw));
+    movw(rd, Utils::Low16Bits(object_raw), cond);
     const uint16_t value_high = Utils::High16Bits(object_raw);
     if (value_high != 0) {
-      movt(rd, value_high);
+      movt(rd, value_high, cond);
     }
   } else {
     // Make sure that class CallPattern is able to decode this load from the
     // object pool.
     const int32_t offset =
         Array::data_offset() + 4*AddObject(object) - kHeapObjectTag;
-    LoadWordFromPoolOffset(rd, offset);
+    LoadWordFromPoolOffset(rd, offset, cond);
   }
 }
 
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 7875246..7039d8b 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -393,6 +393,8 @@
            Condition cond = AL);
   void mls(Register rd, Register rn, Register rm, Register ra,
            Condition cond = AL);
+  void smull(Register rd_lo, Register rd_hi, Register rn, Register rm,
+             Condition cond = AL);
   void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
              Condition cond = AL);
 
@@ -552,7 +554,7 @@
 
   void LoadPoolPointer();
 
-  void LoadObject(Register rd, const Object& object);
+  void LoadObject(Register rd, const Object& object, Condition cond = AL);
   void PushObject(const Object& object);
   void CompareObject(Register rn, const Object& object);
 
@@ -573,7 +575,7 @@
   void LoadClass(Register result, Register object, Register scratch);
   void CompareClassId(Register object, intptr_t class_id, Register scratch);
 
-  void LoadWordFromPoolOffset(Register rd, int32_t offset);
+  void LoadWordFromPoolOffset(Register rd, int32_t offset, Condition cond = AL);
   void LoadFromOffset(LoadOperandType type,
                       Register reg,
                       Register base,
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index 93955a8..a7e8f2b 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -616,7 +616,7 @@
 }
 
 
-ASSEMBLER_TEST_GENERATE(LongMultiply, assembler) {
+ASSEMBLER_TEST_GENERATE(Multiply64To64, assembler) {
   __ Push(R4);
   __ Mov(IP, R0);
   __ mul(R4, R2, R1);
@@ -628,10 +628,25 @@
 }
 
 
-ASSEMBLER_TEST_RUN(LongMultiply, test) {
+ASSEMBLER_TEST_RUN(Multiply64To64, test) {
   EXPECT(test != NULL);
-  typedef int64_t (*LongMultiply)(int64_t operand0, int64_t operand1);
-  EXPECT_EQ(6, EXECUTE_TEST_CODE_INT64_LL(LongMultiply, test->entry(), -3, -2));
+  typedef int64_t (*Multiply64To64)(int64_t operand0, int64_t operand1);
+  EXPECT_EQ(6,
+            EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) {
+  __ smull(R0, R1, R0, R2);
+  __ mov(PC, ShifterOperand(LR));
+}
+
+
+ASSEMBLER_TEST_RUN(Multiply32To64, test) {
+  EXPECT(test != NULL);
+  typedef int64_t (*Multiply32To64)(int64_t operand0, int64_t operand1);
+  EXPECT_EQ(6,
+            EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2));
 }
 
 
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index f293cb9..7442edc 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -8,7 +8,6 @@
 #include "vm/assembler.h"
 #include "vm/code_generator.h"
 #include "vm/heap.h"
-#include "vm/heap_trace.h"
 #include "vm/memory_region.h"
 #include "vm/runtime_entry.h"
 #include "vm/stub_code.h"
@@ -1911,7 +1910,6 @@
                                 Register value,
                                 bool can_value_be_smi) {
   ASSERT(object != value);
-  TraceStoreIntoObject(object, dest, value);
   movl(dest, value);
   Label done;
   if (can_value_be_smi) {
@@ -1933,7 +1931,6 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          Register value) {
-  TraceStoreIntoObject(object, dest, value);
   movl(dest, value);
 #if defined(DEBUG)
   Label done;
@@ -1953,7 +1950,6 @@
   if (value.IsSmi() || value.InVMHeap()) {
     movl(dest, Immediate(reinterpret_cast<int32_t>(value.raw())));
   } else {
-    // No heap trace for an old object store.
     ASSERT(value.IsOld());
     AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     EmitUint8(0xC7);
@@ -1964,23 +1960,6 @@
 }
 
 
-void Assembler::TraceStoreIntoObject(Register object,
-                                     const Address& dest,
-                                     Register value) {
-  if (HeapTrace::is_enabled()) {
-    pushal();
-    EnterCallRuntimeFrame(3 * kWordSize);
-    movl(Address(ESP, 0 * kWordSize), object);
-    leal(EAX, dest);
-    movl(Address(ESP, 1 * kWordSize), EAX);
-    movl(Address(ESP, 2 * kWordSize), value);
-    CallRuntime(kHeapTraceStoreRuntimeEntry);
-    LeaveCallRuntimeFrame();
-    popal();
-  }
-}
-
-
 void Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
   // TODO(5410843): Need to have a code constants table.
   int64_t constant = bit_cast<int64_t, double>(value);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index 4ed8c0e..d28f814 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -626,10 +626,6 @@
                                 const Address& dest,
                                 const Object& value);
 
-  void TraceStoreIntoObject(Register object,
-                            const Address& dest,
-                            Register value);
-
   void DoubleNegate(XmmRegister d);
   void FloatNegate(XmmRegister f);
 
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index e716dd5..bda9cd0 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -12,6 +12,7 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, trace_sim);
 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
 
 
@@ -330,9 +331,9 @@
     addiu(SP, SP, Immediate(-4 * kWordSize));
     sw(ZR, Address(SP, 3 * kWordSize));  // PC marker is 0 in stubs.
     sw(RA, Address(SP, 2 * kWordSize));
-    sw(PP, Address(SP, 1 * kWordSize));
-    sw(FP, Address(SP, 0 * kWordSize));
-    mov(FP, SP);
+    sw(FP, Address(SP, 1 * kWordSize));
+    sw(PP, Address(SP, 0 * kWordSize));
+    addiu(FP, SP, Immediate(1 * kWordSize));
     // Setup pool pointer for this stub.
     Label next;
     bal(&next);
@@ -355,13 +356,14 @@
 
 
 void Assembler::LeaveStubFrame(bool uses_pp) {
-  mov(SP, FP);
   if (uses_pp) {
+    addiu(SP, FP, Immediate(-1 * kWordSize));
     lw(RA, Address(SP, 2 * kWordSize));
-    lw(PP, Address(SP, 1 * kWordSize));
-    lw(FP, Address(SP, 0 * kWordSize));
+    lw(FP, Address(SP, 1 * kWordSize));
+    lw(PP, Address(SP, 0 * kWordSize));
     addiu(SP, SP, Immediate(4 * kWordSize));
   } else {
+    mov(SP, FP);
     lw(RA, Address(SP, 1 * kWordSize));
     lw(FP, Address(SP, 0 * kWordSize));
     addiu(SP, SP, Immediate(3 * kWordSize));
@@ -448,6 +450,8 @@
       2 * kWordSize +  // FP and RA.
       kDartVolatileFpuRegCount * kWordSize;
 
+  TraceSimMsg("EnterCallRuntimeFrame");
+
   if (prologue_offset_ == -1) {
     prologue_offset_ = CodeSize();
   }
@@ -490,6 +494,8 @@
       2 * kWordSize +  // FP and RA.
       kDartVolatileFpuRegCount * kWordSize;
 
+  TraceSimMsg("LeaveCallRuntimeFrame");
+
   // SP might have been modified to reserve space for arguments
   // and ensure proper alignment of the stack frame.
   // We need to restore it before restoring registers.
@@ -543,6 +549,18 @@
   break_(Instr::kStopMessageCode);
 }
 
+
+void Assembler::TraceSimMsg(const char* message) {
+  //  Don't bother adding in the messages unless tracing is enabled.
+  if (FLAG_trace_sim) {
+    Label msg;
+    b(&msg);
+    Emit(reinterpret_cast<int32_t>(message));
+    Bind(&msg);
+    break_(Instr::kMsgMessageCode);
+  }
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 0eca796..6402b6e 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -191,6 +191,10 @@
 
   // Debugging and bringup support.
   void Stop(const char* message);
+
+  // TODO(zra): TraceSimMsg enables printing of helpful messages when
+  // --trace_sim is given. Eventually these calls will be changed to Comment.
+  void TraceSimMsg(const char* message);
   void Unimplemented(const char* message);
   void Untested(const char* message);
   void Unreachable(const char* message);
@@ -682,87 +686,91 @@
   }
 
   void BranchEqual(Register rd, int32_t value, Label* l) {
-    LoadImmediate(TMP1, value);
-    beq(rd, TMP1, l);
+    ASSERT(rd != CMPRES);
+    LoadImmediate(CMPRES, value);
+    beq(rd, CMPRES, l);
   }
 
   void BranchEqual(Register rd, const Object& object, Label* l) {
-    LoadObject(TMP1, object);
-    beq(rd, TMP1, l);
+    ASSERT(rd != CMPRES);
+    LoadObject(CMPRES, object);
+    beq(rd, CMPRES, l);
   }
 
   void BranchNotEqual(Register rd, int32_t value, Label* l) {
-    LoadImmediate(TMP1, value);
-    bne(rd, TMP1, l);
+    ASSERT(rd != CMPRES);
+    LoadImmediate(CMPRES, value);
+    bne(rd, CMPRES, l);
   }
 
   void BranchNotEqual(Register rd, const Object& object, Label* l) {
-    LoadObject(TMP1, object);
-    bne(rd, TMP1, l);
+    ASSERT(rd != CMPRES);
+    LoadObject(CMPRES, object);
+    bne(rd, CMPRES, l);
   }
 
   void BranchGreater(Register rd, int32_t value, Label* l) {
     if (Utils::IsInt(kImmBits, -value)) {
-      addiu(TMP1, rd, Immediate(-value));
-      bgtz(TMP1, l);
+      addiu(CMPRES, rd, Immediate(-value));
+      bgtz(CMPRES, l);
     } else {
-      LoadImmediate(TMP1, value);
-      subu(TMP1, rd, TMP1);
-      bgtz(TMP1, l);
+      LoadImmediate(CMPRES, value);
+      subu(CMPRES, rd, CMPRES);
+      bgtz(CMPRES, l);
     }
   }
 
   void BranchGreater(Register rd, Register rs, Label* l) {
-    subu(TMP1, rd, rs);
-    bgtz(TMP1, l);
+    subu(CMPRES, rd, rs);
+    bgtz(CMPRES, l);
   }
 
   void BranchGreaterEqual(Register rd, int32_t value, Label* l) {
     if (Utils::IsInt(kImmBits, -value)) {
-      addiu(TMP1, rd, Immediate(-value));
-      bgez(TMP1, l);
+      addiu(CMPRES, rd, Immediate(-value));
+      bgez(CMPRES, l);
     } else {
-      LoadImmediate(TMP1, value);
-      subu(TMP1, rd, TMP1);
-      bgez(TMP1, l);
+      LoadImmediate(CMPRES, value);
+      subu(CMPRES, rd, CMPRES);
+      bgez(CMPRES, l);
     }
   }
 
   void BranchGreaterEqual(Register rd, Register rs, Label* l) {
-    subu(TMP1, rd, rs);
-    bgez(TMP1, l);
+    subu(CMPRES, rd, rs);
+    bgez(CMPRES, l);
   }
 
   void BranchLess(Register rd, int32_t value, Label* l) {
     if (Utils::IsInt(kImmBits, -value)) {
-      addiu(TMP1, rd, Immediate(-value));
-      bltz(TMP1, l);
+      addiu(CMPRES, rd, Immediate(-value));
+      bltz(CMPRES, l);
     } else {
-      LoadImmediate(TMP1, value);
-      subu(TMP1, rd, TMP1);
-      bltz(TMP1, l);
+      LoadImmediate(CMPRES, value);
+      subu(CMPRES, rd, CMPRES);
+      bltz(CMPRES, l);
     }
   }
 
   void BranchLess(Register rd, Register rs, Label* l) {
-    subu(TMP1, rd, rs);
-    bltz(TMP1, l);
+    subu(CMPRES, rd, rs);
+    bltz(CMPRES, l);
   }
 
   void BranchLessEqual(Register rd, int32_t value, Label* l) {
     if (Utils::IsInt(kImmBits, -value)) {
-      addiu(TMP1, rd, Immediate(-value));
-      blez(TMP1, l);
+      addiu(CMPRES, rd, Immediate(-value));
+      blez(CMPRES, l);
     } else {
-      LoadImmediate(TMP1, value);
-      subu(TMP1, rd, TMP1);
-      blez(TMP1, l);
+      LoadImmediate(CMPRES, value);
+      subu(CMPRES, rd, CMPRES);
+      blez(CMPRES, l);
     }
   }
 
   void BranchLessEqual(Register rd, Register rs, Label* l) {
-    subu(TMP1, rd, rs);
-    blez(TMP1, l);
+    subu(CMPRES, rd, rs);
+    blez(CMPRES, l);
   }
 
   void Push(Register rt) {
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index ef35ba4..837e74b 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -12,6 +12,8 @@
 #include "vm/stack_frame.h"
 #include "vm/unit_test.h"
 
+using dart::bin::File;
+
 namespace dart {
 
 Benchmark* Benchmark::first_ = NULL;
@@ -400,7 +402,7 @@
       "import 'dart:math';\n"
       "import 'dart:isolate';\n"
       "import 'dart:mirrors';\n"
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "\n";
 
   // Start an Isolate, load a script and create a full snapshot.
@@ -426,7 +428,7 @@
       "import 'dart:math';\n"
       "import 'dart:isolate';\n"
       "import 'dart:mirrors';\n"
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "import 'dart:uri';\n"
       "import 'dart:utf';\n"
       "import 'dart:json';\n"
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index d52fc5e..132478c 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -92,8 +92,8 @@
 
 
 RawScript* Bootstrap::LoadTypedDataScript(bool patch) {
-  const char* url = patch ? "dart:typeddata_patch" : "dart:typeddata";
-  const char* source = patch ? typeddata_patch_ : typeddata_source_;
+  const char* url = patch ? "dart:typed_data_patch" : "dart:typed_data";
+  const char* source = patch ? typed_data_patch_ : typed_data_source_;
   return LoadScript(url, source, patch);
 }
 
diff --git a/runtime/vm/bootstrap.h b/runtime/vm/bootstrap.h
index 020d819..93619a4 100644
--- a/runtime/vm/bootstrap.h
+++ b/runtime/vm/bootstrap.h
@@ -52,8 +52,8 @@
   static const char math_patch_[];
   static const char mirrors_source_[];
   static const char mirrors_patch_[];
-  static const char typeddata_source_[];
-  static const char typeddata_patch_[];
+  static const char typed_data_source_[];
+  static const char typed_data_patch_[];
   static const char uri_source_[];
   static const char utf_source_[];
 };
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index fe45457..0a460dd 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -170,6 +170,7 @@
   V(ByteData_ToEndianFloat32, 2)                                               \
   V(ByteData_ToEndianFloat64, 2)                                               \
   V(Float32x4_fromDoubles, 5)                                                  \
+  V(Float32x4_splat, 2)                                                        \
   V(Float32x4_zero, 1)                                                         \
   V(Float32x4_add, 2)                                                          \
   V(Float32x4_negate, 1)                                                       \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 283a09b..673df7a 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -38,10 +38,6 @@
     const GrowableArray<intptr_t>& added_subclasses_to_cids) {
   ASSERT(FLAG_use_cha);
   if (added_subclasses_to_cids.is_empty()) return;
-  // TODO(regis): Reenable this code for mips when possible.
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
   // Deoptimize all live frames.
   DeoptimizeIfOwner(added_subclasses_to_cids);
   // Switch all functions' code to unoptimized.
@@ -63,7 +59,6 @@
       }
     }
   }
-#endif
 }
 
 
@@ -1969,7 +1964,7 @@
     field ^= fields_array.At(0);
     ASSERT(field.Offset() == TypedDataView::data_offset());
     name ^= field.name();
-    expected_name ^= String::New("_typeddata");
+    expected_name ^= String::New("_typedData");
     ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
     field ^= fields_array.At(1);
     ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset());
@@ -1988,7 +1983,7 @@
   field ^= fields_array.At(0);
   ASSERT(field.Offset() == TypedDataView::data_offset());
   name ^= field.name();
-  expected_name ^= String::New("_typeddata");
+  expected_name ^= String::New("_typedData");
   ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
   field ^= fields_array.At(1);
   ASSERT(field.Offset() == TypedDataView::offset_in_bytes_offset());
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 2d14cec..3b34490 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -5,7 +5,6 @@
 #include "vm/class_table.h"
 #include "vm/flags.h"
 #include "vm/freelist.h"
-#include "vm/heap_trace.h"
 #include "vm/object.h"
 #include "vm/raw_object.h"
 #include "vm/visitor.h"
@@ -50,9 +49,6 @@
     ASSERT(table_[index] == 0);
     ASSERT(index < capacity_);
     table_[index] = cls.raw();
-    if (HeapTrace::is_enabled()) {
-      Isolate::Current()->heap()->trace()->TraceRegisterClass(cls);
-    }
     // Add the vtable for this predefined class into the static vtable registry
     // if it has not been setup yet.
     cpp_vtable cls_vtable = cls.handle_vtable();
@@ -76,9 +72,6 @@
     ASSERT(top_ < capacity_);
     cls.set_id(top_);
     table_[top_] = cls.raw();
-    if (HeapTrace::is_enabled()) {
-      Isolate::Current()->heap()->trace()->TraceRegisterClass(cls);
-    }
     top_++;  // Increment next index.
   }
 }
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 4391b4b..8fe8159 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -6,7 +6,6 @@
 #define VM_CLASS_TABLE_H_
 
 #include "platform/assert.h"
-#include "platform/globals.h"
 #include "vm/globals.h"
 
 namespace dart {
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index e4fc7b8..d9c5087 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -4,7 +4,6 @@
 
 #include "platform/assert.h"
 #include "vm/globals.h"
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
 
 #include "vm/ast.h"
 #include "vm/assembler.h"
@@ -284,4 +283,3 @@
 
 }  // namespace dart
 
-#endif  // defined TARGET_ARCH_IA32 || defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 6ae0afa..9df2cab 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -38,8 +38,14 @@
     "Trace IC miss in optimized code");
 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
 DEFINE_FLAG(int, optimization_counter_threshold, 3000,
     "Function's usage-counter value before it is optimized, -1 means never");
+#else
+// TODO(regis): Enable optimization on ARM and MIPS.
+DEFINE_FLAG(int, optimization_counter_threshold, -1,
+    "Function's usage-counter value before it is optimized, -1 means never");
+#endif
 DECLARE_FLAG(bool, enable_type_checks);
 DECLARE_FLAG(bool, trace_type_checks);
 DECLARE_FLAG(bool, report_usage_count);
@@ -92,9 +98,11 @@
   arguments.SetReturn(array);
   AbstractTypeArguments& element_type =
       AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1));
-  // An Array is raw or takes only one type argument.
+  // An Array is raw or takes one type argument. However, its type argument
+  // vector may be longer than 1 due to a type optimization reusing the type
+  // argument vector of the instantiator.
   ASSERT(element_type.IsNull() ||
-         ((element_type.Length() == 1) && element_type.IsInstantiated()));
+         ((element_type.Length() >= 1) && element_type.IsInstantiated()));
   array.SetTypeArguments(element_type);  // May be null.
 }
 
@@ -116,40 +124,29 @@
   }
   AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1));
-  ASSERT(type_arguments.IsNull() ||
-         (type_arguments.Length() == cls.NumTypeArguments()));
   // If no instantiator is provided, set the type arguments and return.
   if (Object::Handle(arguments.ArgAt(2)).IsSmi()) {
     ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() ==
            StubCode::kNoInstantiator);
+    // Unless null (for a raw type), the type argument vector may be longer than
+    // necessary due to a type optimization reusing the type argument vector of
+    // the instantiator.
+    ASSERT(type_arguments.IsNull() ||
+           (type_arguments.IsInstantiated() &&
+            (type_arguments.Length() >= cls.NumTypeArguments())));
     instance.SetTypeArguments(type_arguments);  // May be null.
     return;
   }
-  ASSERT(!type_arguments.IsInstantiated());
+  // A still uninstantiated type argument vector must have the correct length.
+  ASSERT(!type_arguments.IsInstantiated() &&
+         (type_arguments.Length() == cls.NumTypeArguments()));
   const AbstractTypeArguments& instantiator =
       AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2));
   ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
-  if (instantiator.IsNull()) {
-    type_arguments =
-        InstantiatedTypeArguments::New(type_arguments, instantiator);
-  } else if (instantiator.IsTypeArguments()) {
-    // Code inlined in the caller should have optimized the case where the
-    // instantiator is a TypeArguments and can be used as type argument vector.
-    ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
-           (instantiator.Length() != type_arguments.Length()));
-    type_arguments =
-        InstantiatedTypeArguments::New(type_arguments, instantiator);
-  } else {
-    // If possible, use the instantiator as the type argument vector.
-    if (type_arguments.IsUninstantiatedIdentity() &&
-        (instantiator.Length() == type_arguments.Length())) {
-      type_arguments = instantiator.raw();
-    } else {
-      type_arguments =
-          InstantiatedTypeArguments::New(type_arguments, instantiator);
-    }
-  }
-  ASSERT(type_arguments.IsInstantiated());
+  // Code inlined in the caller should have optimized the case where the
+  // instantiator can be reused as type argument vector.
+  ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
+  type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator);
   instance.SetTypeArguments(type_arguments);
 }
 
@@ -179,38 +176,28 @@
   ASSERT(cls.HasTypeArguments());
   AbstractTypeArguments& type_arguments =
       AbstractTypeArguments::CheckedHandle(arguments.ArgAt(1));
-  ASSERT(type_arguments.IsNull() ||
-         (type_arguments.Length() == cls.NumTypeArguments()));
   if (Object::Handle(arguments.ArgAt(2)).IsSmi()) {
     ASSERT(Smi::CheckedHandle(arguments.ArgAt(2)).Value() ==
            StubCode::kNoInstantiator);
+    // Unless null (for a raw type), the type argument vector may be longer than
+    // necessary due to a type optimization reusing the type argument vector of
+    // the instantiator.
+    ASSERT(type_arguments.IsNull() ||
+           (type_arguments.IsInstantiated() &&
+            (type_arguments.Length() >= cls.NumTypeArguments())));
   } else {
-    ASSERT(!type_arguments.IsInstantiated());
+    // A still uninstantiated type argument vector must have the correct length.
+    ASSERT(!type_arguments.IsInstantiated() &&
+           (type_arguments.Length() == cls.NumTypeArguments()));
     const AbstractTypeArguments& instantiator =
         AbstractTypeArguments::CheckedHandle(arguments.ArgAt(2));
     ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
     Error& malformed_error = Error::Handle();
-    if (instantiator.IsNull()) {
-      type_arguments = type_arguments.InstantiateFrom(instantiator,
-                                                      &malformed_error);
-    } else if (instantiator.IsTypeArguments()) {
-      // Code inlined in the caller should have optimized the case where the
-      // instantiator is a TypeArguments and can be used as type argument
-      // vector.
-      ASSERT(!type_arguments.IsUninstantiatedIdentity() ||
-             (instantiator.Length() != type_arguments.Length()));
-      type_arguments = type_arguments.InstantiateFrom(instantiator,
-                                                      &malformed_error);
-    } else {
-      // If possible, use the instantiator as the type argument vector.
-      if (type_arguments.IsUninstantiatedIdentity() &&
-          (instantiator.Length() == type_arguments.Length())) {
-        type_arguments = instantiator.raw();
-      } else {
-        type_arguments = type_arguments.InstantiateFrom(instantiator,
-                                                        &malformed_error);
-      }
-    }
+    // Code inlined in the caller should have optimized the case where the
+    // instantiator can be reused as type argument vector.
+  ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
+    type_arguments = type_arguments.InstantiateFrom(instantiator,
+                                                    &malformed_error);
     if (!malformed_error.IsNull()) {
       // Throw a dynamic type error.
       const intptr_t location = GetCallerLocation();
@@ -241,11 +228,8 @@
   ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated());
   ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
   // Code inlined in the caller should have optimized the case where the
-  // instantiator can be used as type argument vector.
-  ASSERT(instantiator.IsNull() ||
-         !type_arguments.IsUninstantiatedIdentity() ||
-         !instantiator.IsTypeArguments() ||
-         (instantiator.Length() != type_arguments.Length()));
+  // instantiator can be reused as type argument vector.
+  ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
   type_arguments = InstantiatedTypeArguments::New(type_arguments, instantiator);
   ASSERT(type_arguments.IsInstantiated());
   arguments.SetReturn(type_arguments);
@@ -1689,22 +1673,6 @@
 END_LEAF_RUNTIME_ENTRY
 
 
-DEFINE_LEAF_RUNTIME_ENTRY(void,
-                          HeapTraceStore,
-                          RawObject* object,
-                          uword field_addr,
-                          RawObject* value) {
-  if (!(object->IsHeapObject() && value->IsHeapObject())) {
-    return;
-  }
-  HeapTrace* heap_trace = Isolate::Current()->heap()->trace();
-  heap_trace->TraceStoreIntoObject(RawObject::ToAddr(object),
-                                   field_addr,
-                                   RawObject::ToAddr(value));
-}
-END_LEAF_RUNTIME_ENTRY
-
-
 double DartModulo(double left, double right) {
   double remainder = fmod_ieee(left, right);
   if (remainder == 0.0) {
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 82ecc2d..8b0a59c 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -30,7 +30,6 @@
 DECLARE_RUNTIME_ENTRY(CloneContext);
 DECLARE_RUNTIME_ENTRY(Deoptimize);
 DECLARE_RUNTIME_ENTRY(FixCallersTarget);
-DECLARE_LEAF_RUNTIME_ENTRY(void, HeapTraceStore, RawObject*, uword, RawObject*);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerOneArg);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerTwoArgs);
 DECLARE_RUNTIME_ENTRY(InlineCacheMissHandlerThreeArgs);
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index 86b5ff9..d88e130 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -43,11 +43,6 @@
 CODEGEN_TEST2_RUN(SimpleStaticCallCodegen, SmiReturnCodegen, Smi::New(3))
 
 
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
-
-
 // Helper to allocate and return a LocalVariable.
 static LocalVariable* NewTestLocalVariable(const char* name) {
   const String& variable_name = String::ZoneHandle(Symbols::New(name));
@@ -563,6 +558,4 @@
   EXPECT_EQ(cls.raw(), result.clazz());
 }
 
-#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
-
 }  // namespace dart
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index 1268dc7..d355a14 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -33,7 +33,8 @@
                                       const Code& code,
                                       uword new_target) {
   ASSERT(code.ContainsInstructionAt(return_address));
-  UNIMPLEMENTED();
+  CallPattern call(return_address, code);
+  call.SetTargetAddress(new_target);
 }
 
 
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index 198ab77..0668062 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -5,6 +5,8 @@
 #ifndef VM_CONSTANTS_MIPS_H_
 #define VM_CONSTANTS_MIPS_H_
 
+#include "platform/assert.h"
+
 namespace dart {
 
 enum Register {
@@ -152,11 +154,11 @@
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
-const Register kExceptionObjectReg = A0;
+const Register kExceptionObjectReg = V0;
 
 // Stack trace object is passed in this register to the catch handlers when
 // an exception is thrown.
-const Register kStackTraceObjectReg = A1;
+const Register kStackTraceObjectReg = V1;
 
 
 typedef uint32_t RegList;
@@ -400,6 +402,7 @@
   static const int32_t kNopInstruction = 0;
   static const int32_t kStopMessageCode = 1;
   static const int32_t kRedirectCode = 2;
+  static const int32_t kMsgMessageCode = 3;
 
   // Get the raw instruction bits.
   inline int32_t InstructionBits() const {
@@ -411,6 +414,25 @@
     *reinterpret_cast<int32_t*>(this) = value;
   }
 
+  inline void SetImmInstrBits(Opcode op, Register rs, Register rt,
+                              uint16_t imm) {
+    SetInstructionBits(
+        op << kOpcodeShift |
+        rs << kRsShift |
+        rt << kRtShift |
+        imm << kImmShift);
+  }
+
+  inline void SetSpecialInstrBits(SpecialFunction f,
+                                  Register rs, Register rt, Register rd) {
+    SetInstructionBits(
+        SPECIAL << kOpcodeShift |
+        f << kFunctionShift |
+        rs << kRsShift |
+        rt << kRtShift |
+        rd << kRdShift);
+  }
+
   // Read one particular bit out of the instruction bits.
   inline int32_t Bit(int nr) const {
     return (InstructionBits() >> nr) & 1;
@@ -501,6 +523,21 @@
   // Use the At(pc) function to create references to Instr.
   static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
 
+#if defined(DEBUG)
+  inline void AssertIsImmInstr(Opcode op, Register rs, Register rt,
+                              int32_t imm) {
+    ASSERT((OpcodeField() == op) && (RsField() == rs) && (RtField() == rt) &&
+           (SImmField() == imm));
+  }
+
+  inline void AssertIsSpecialInstr(SpecialFunction f, Register rs, Register rt,
+                                   Register rd) {
+    ASSERT((OpcodeField() == SPECIAL) && (FunctionField() == f) &&
+           (RsField() == rs) && (RtField() == rt) &&
+           (RdField() == rd));
+  }
+#endif  // defined(DEBUG)
+
  private:
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index 2064066..70fb4c7 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -15,11 +15,6 @@
 
 namespace dart {
 
-// Only ia32, x64, and arm can run execution tests.
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
-
 static void native_echo(Dart_NativeArguments args);
 static void CustomIsolateImpl_start(Dart_NativeArguments args);
 static Dart_NativeFunction NativeLookup(Dart_Handle name, int argc);
@@ -344,6 +339,4 @@
   delete event_queue;
 }
 
-#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
-
 }  // namespace dart
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 5f32e3f..1351152 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -27,7 +27,6 @@
 
 DEFINE_FLAG(bool, heap_profile_initialize, false,
             "Writes a heap profile on isolate initialization.");
-DECLARE_FLAG(bool, heap_trace);
 DECLARE_FLAG(bool, print_bootstrap);
 DECLARE_FLAG(bool, print_class_table);
 DECLARE_FLAG(bool, trace_isolates);
@@ -134,9 +133,6 @@
   Isolate::SetInterruptCallback(interrupt);
   Isolate::SetUnhandledExceptionCallback(unhandled);
   Isolate::SetShutdownCallback(shutdown);
-  if (FLAG_heap_trace) {
-    HeapTrace::InitOnce(file_open, file_write, file_close);
-  }
   return NULL;
 }
 
@@ -220,15 +216,8 @@
   Object::VerifyBuiltinVtables();
 
   StubCode::Init(isolate);
-  // TODO(regis): Reenable this code for mips when possible.
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
   isolate->megamorphic_cache_table()->InitMissHandler();
-#endif
-  if (FLAG_heap_trace) {
-    isolate->heap()->trace()->Init(isolate);
-  }
+
   isolate->heap()->EnableGrowthControl();
   isolate->set_init_callback_data(data);
   Api::SetupAcquiredError(isolate);
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 15958e4..be450c9 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2442,7 +2442,7 @@
                                          const String& constructor_name,
                                          intptr_t num_args) {
   const Library& lib =
-      Library::Handle(isolate->object_store()->typeddata_library());
+      Library::Handle(isolate->object_store()->typed_data_library());
   ASSERT(!lib.IsNull());
   const Class& cls =
       Class::Handle(isolate, lib.LookupClassAllowPrivate(Symbols::ByteData()));
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index a5c682e..1f939b5 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -17,8 +17,9 @@
 
 DECLARE_FLAG(bool, enable_type_checks);
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 TEST_CASE(ErrorHandleBasics) {
   const char* kScriptChars =
@@ -166,7 +167,7 @@
   EXPECT_SUBSTRING("myException", Dart_GetError(result));
 }
 
-#endif
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 
 TEST_CASE(Dart_Error) {
@@ -215,8 +216,9 @@
 }
 
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 TEST_CASE(ObjectEquals) {
   bool equal = false;
@@ -237,7 +239,7 @@
   EXPECT(!equal);
 }
 
-#endif
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 
 TEST_CASE(InstanceValues) {
@@ -336,8 +338,9 @@
 }
 
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 TEST_CASE(NumberValues) {
   // TODO(antonm): add various kinds of ints (smi, mint, bigint).
@@ -371,7 +374,7 @@
   EXPECT(!Dart_IsNumber(result));
 }
 
-#endif
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 
 TEST_CASE(IntegerValues) {
@@ -636,8 +639,9 @@
 }
 
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 static void ExternalStringCallbackFinalizer(void* peer) {
   *static_cast<int*>(peer) *= 2;
@@ -905,7 +909,7 @@
 
 TEST_CASE(ByteDataAccess) {
   const char* kScriptChars =
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "class Expect {\n"
       "  static equals(a, b) {\n"
       "    if (a != b) {\n"
@@ -967,7 +971,7 @@
   // TODO(asiva): Once we have getInt16LE and getInt16BE support use the
   // appropriate getter instead of the host endian format used now.
   const char* kScriptChars =
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "class Expect {\n"
       "  static equals(a, b) {\n"
       "    if (a != b) {\n"
@@ -1086,7 +1090,7 @@
 
 TEST_CASE(TypedDataDirectAccess1) {
   const char* kScriptChars =
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "class Expect {\n"
       "  static equals(a, b) {\n"
       "    if (a != b) {\n"
@@ -1133,7 +1137,7 @@
 
 TEST_CASE(TypedDataViewDirectAccess) {
   const char* kScriptChars =
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "class Expect {\n"
       "  static equals(a, b) {\n"
       "    if (a != b) {\n"
@@ -1172,7 +1176,7 @@
 
 TEST_CASE(ByteDataDirectAccess) {
   const char* kScriptChars =
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "class Expect {\n"
       "  static equals(a, b) {\n"
       "    if (a != b) {\n"
@@ -1377,7 +1381,7 @@
 
 TEST_CASE(Float32x4List) {
     const char* kScriptChars =
-      "import 'dart:typeddata';\n"
+      "import 'dart:typed_data';\n"
       "Float32x4List float32x4() {\n"
       "  return new Float32x4List(10);\n"
       "}\n";
@@ -1408,7 +1412,7 @@
 }
 
 
-#endif
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 
 // Unit test for entering a scope, creating a local handle and exiting
@@ -1543,8 +1547,9 @@
 };
 
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 TEST_CASE(WeakPersistentHandle) {
   Dart_Handle weak_new_ref = Dart_Null();
@@ -2409,7 +2414,7 @@
   EXPECT_EQ(7, global_epilogue_callback_status);
 }
 
-#endif
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 
 // Unit test for creating multiple scopes and local handles within them.
@@ -2581,8 +2586,9 @@
 }
 
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
 
 TEST_CASE(ClassTypedefsEtc) {
   const char* kScriptChars =
@@ -7645,6 +7651,6 @@
   EXPECT_EQ(260, value);
 }
 
-#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64).
+#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 5df30aa..c28bd7c 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -244,7 +244,7 @@
       object->cls->internal.as_class.library_url->value.as_string;
   char* class_name =
       object->cls->internal.as_class.class_name->value.as_string;
-  if (strcmp("dart:typeddata", library_url) != 0) {
+  if (strcmp("dart:typed_data", library_url) != 0) {
     return Dart_CObject::kNumberOfTypedDataTypes;
   }
   int i = 0;
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index a20a940..e1ac24e 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -733,7 +733,6 @@
 
  private:
   ApiZone zone_;
-  ThreadLocalKey key_;
 };
 
 
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 1aa299b..3b76466 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -8,6 +8,7 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/allocation.h"
+#include "vm/exceptions.h"
 #include "vm/globals.h"
 
 namespace dart {
@@ -148,7 +149,9 @@
     *buffer_ = reinterpret_cast<uint8_t*>(alloc_(NULL,
                                                  0,
                                                  initial_size_));
-    ASSERT(*buffer_ != NULL);
+    if (*buffer_ == NULL) {
+      Exceptions::ThrowOOM();
+    }
     current_ = *buffer_;
     current_size_ = initial_size_;
     end_ = *buffer_ + initial_size_;
@@ -243,7 +246,9 @@
     *buffer_ = reinterpret_cast<uint8_t*>(alloc_(*buffer_,
                                                  current_size_,
                                                  new_size));
-    ASSERT(*buffer_ != NULL);
+    if (*buffer_ == NULL) {
+      Exceptions::ThrowOOM();
+    }
     current_ = *buffer_ + position;
     current_size_ = new_size;
     end_ = *buffer_ + new_size;
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 6656ba2..43a80d4 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -111,47 +111,43 @@
   Isolate* isolate = Isolate::Current();
   ASSERT(isolate != NULL);
   ASSERT(isolate->debugger() != NULL);
+  Dart_EnterScope();
   Dart_IsolateId isolate_id = isolate->debugger()->GetIsolateId();
   if (event->type == Debugger::kBreakpointReached) {
     if (legacy_bp_handler != NULL) {
       Dart_StackTrace stack_trace =
           reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
       (*legacy_bp_handler)(isolate_id, NULL, stack_trace);
-      return;
+    } else if (paused_event_handler != NULL) {
+      Dart_CodeLocation location;
+      ActivationFrame* top_frame = event->top_frame;
+      location.script_url = Api::NewHandle(isolate, top_frame->SourceUrl());
+      const Library& lib = Library::Handle(top_frame->Library());
+      location.library_id = lib.index();
+      location.token_pos = top_frame->TokenPos();
+      (*paused_event_handler)(isolate_id, location);
     }
-    if (paused_event_handler == NULL) {
-      return;
-    }
-    Dart_CodeLocation location;
-    ActivationFrame* top_frame = event->top_frame;
-    location.script_url = Api::NewHandle(isolate, top_frame->SourceUrl());
-    const Library& lib = Library::Handle(top_frame->Library());
-    location.library_id = lib.index();
-    location.token_pos = top_frame->TokenPos();
-    (*paused_event_handler)(isolate_id, location);
   } else if (event->type == Debugger::kBreakpointResolved) {
-    if (bp_resolved_handler == NULL) {
-      return;
+    if (bp_resolved_handler != NULL) {
+      SourceBreakpoint* bpt = event->breakpoint;
+      ASSERT(bpt != NULL);
+      Dart_CodeLocation location;
+      Library& library = Library::Handle(isolate);
+      Script& script = Script::Handle(isolate);
+      intptr_t token_pos;
+      bpt->GetCodeLocation(&library, &script, &token_pos);
+      location.script_url = Api::NewHandle(isolate, script.url());
+      location.library_id = library.index();
+      location.token_pos = token_pos;
+      (*bp_resolved_handler)(isolate_id, bpt->id(), location);
     }
-    SourceBreakpoint* bpt = event->breakpoint;
-    ASSERT(bpt != NULL);
-    Dart_CodeLocation location;
-    Library& library = Library::Handle(isolate);
-    Script& script = Script::Handle(isolate);
-    intptr_t token_pos;
-    bpt->GetCodeLocation(&library, &script, &token_pos);
-    location.script_url = Api::NewHandle(isolate, script.url());
-    location.library_id = library.index();
-    location.token_pos = token_pos;
-    (*bp_resolved_handler)(isolate_id, bpt->id(), location);
   } else if (event->type == Debugger::kExceptionThrown) {
-    if (exc_thrown_handler == NULL) {
-      return;
+    if (exc_thrown_handler != NULL) {
+      Dart_Handle exception = Api::NewHandle(isolate, event->exception->raw());
+      Dart_StackTrace trace =
+      reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
+      (*exc_thrown_handler)(isolate_id, exception, trace);
     }
-    Dart_Handle exception = Api::NewHandle(isolate, event->exception->raw());
-    Dart_StackTrace trace =
-        reinterpret_cast<Dart_StackTrace>(isolate->debugger()->StackTrace());
-    (*exc_thrown_handler)(isolate_id, exception, trace);
   } else if (event->type == Debugger::kIsolateCreated) {
     if (isolate_event_handler != NULL) {
       (*isolate_event_handler)(event->isolate_id, kCreated);
@@ -167,6 +163,7 @@
   } else {
     UNIMPLEMENTED();
   }
+  Dart_ExitScope();
 }
 
 
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index ad61b39..a10bbeb 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -10,9 +10,6 @@
 
 namespace dart {
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
-
 static bool breakpoint_hit = false;
 static int  breakpoint_hit_counter = 0;
 static Dart_Handle script_lib = NULL;
@@ -1533,6 +1530,4 @@
   EXPECT_EQ(1, breakpoint_hit_counter);
 }
 
-#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64).
-
 }  // namespace dart
diff --git a/runtime/vm/debugger_arm.cc b/runtime/vm/debugger_arm.cc
index 6a4b45c..67a9e97 100644
--- a/runtime/vm/debugger_arm.cc
+++ b/runtime/vm/debugger_arm.cc
@@ -5,30 +5,58 @@
 #include "vm/globals.h"
 #if defined(TARGET_ARCH_ARM)
 
+#include "vm/cpu.h"
 #include "vm/debugger.h"
+#include "vm/instructions.h"
+#include "vm/stub_code.h"
 
 namespace dart {
 
+// TODO(hausner): Handle captured variables.
 RawInstance* ActivationFrame::GetLocalVarValue(intptr_t slot_index) {
-  UNIMPLEMENTED();
-  return NULL;
+  uword var_address = fp() + slot_index * kWordSize;
+  return reinterpret_cast<RawInstance*>(
+             *reinterpret_cast<uword*>(var_address));
 }
 
 
 RawInstance* ActivationFrame::GetInstanceCallReceiver(
                  intptr_t num_actual_args) {
-  UNIMPLEMENTED();
-  return NULL;
+  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
+  // Stack pointer points to last argument that was pushed on the stack.
+  uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
+  return reinterpret_cast<RawInstance*>(
+             *reinterpret_cast<uword*>(receiver_addr));
 }
 
 
 void CodeBreakpoint::PatchFunctionReturn() {
-  UNIMPLEMENTED();
+  uword* code = reinterpret_cast<uword*>(pc_ - 3 * Instr::kInstrSize);
+  ASSERT(code[0] == 0xe8bd4c00);  // ldmia sp!, {pp, fp, lr}
+  ASSERT(code[1] == 0xe28dd004);  // add sp, sp, #4
+  ASSERT(code[2] == 0xe12fff1e);  // bx lr
+
+  // Smash code with call instruction and target address.
+  uword stub_addr = StubCode::BreakpointReturnEntryPoint();
+  uint16_t target_lo = stub_addr & 0xffff;
+  uint16_t target_hi = stub_addr >> 16;
+  uword movw = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
+  uword movt = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
+  uword blx =  0xe12fff3c;
+  code[0] = movw;  // movw ip, #target_lo
+  code[1] = movt;  // movt ip, #target_hi
+  code[2] = blx;    // blx ip
+  CPU::FlushICache(pc_ - 3 * Instr::kInstrSize, 3 * Instr::kInstrSize);
 }
 
 
 void CodeBreakpoint::RestoreFunctionReturn() {
-  UNIMPLEMENTED();
+  uword* code = reinterpret_cast<uword*>(pc_ - 3 * Instr::kInstrSize);
+  ASSERT((code[0] & 0xfff0f000) == 0xe300c000);
+  code[0] = 0xe8bd4c00;  // ldmia sp!, {pp, fp, lr}
+  code[1] = 0xe28dd004;  // add sp, sp, #4
+  code[2] = 0xe12fff1e;  // bx lr
+  CPU::FlushICache(pc_ - 3 * Instr::kInstrSize, 3 * Instr::kInstrSize);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index bd3ccb4..bd443ef 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -46,7 +46,7 @@
   uword stub_addr = StubCode::BreakpointReturnEntryPoint();
   code[0] = 0xE8;
   *reinterpret_cast<uword*>(&code[1]) = stub_addr - pc_;
-  CPU::FlushICache(pc_, 5);
+  CPU::FlushICache(pc_ - 5, 5);
 }
 
 
@@ -58,7 +58,7 @@
   code[2] = 0x5D;  // pop ebp
   code[3] = 0xC3;  // ret
   code[4] = 0x90;  // nop
-  CPU::FlushICache(pc_, 5);
+  CPU::FlushICache(pc_ - 5, 5);
 }
 
 
diff --git a/runtime/vm/debugger_mips.cc b/runtime/vm/debugger_mips.cc
index 68acf9c..a234dcd 100644
--- a/runtime/vm/debugger_mips.cc
+++ b/runtime/vm/debugger_mips.cc
@@ -5,30 +5,86 @@
 #include "vm/globals.h"
 #if defined(TARGET_ARCH_MIPS)
 
+#include "vm/cpu.h"
 #include "vm/debugger.h"
+#include "vm/instructions.h"
+#include "vm/stub_code.h"
 
 namespace dart {
 
+// TODO(hausner): Handle captured variables.
 RawInstance* ActivationFrame::GetLocalVarValue(intptr_t slot_index) {
-  UNIMPLEMENTED();
-  return NULL;
+  uword var_address = fp() + slot_index * kWordSize;
+  return reinterpret_cast<RawInstance*>(
+             *reinterpret_cast<uword*>(var_address));
 }
 
 
 RawInstance* ActivationFrame::GetInstanceCallReceiver(
                  intptr_t num_actual_args) {
-  UNIMPLEMENTED();
-  return NULL;
+  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
+  // Stack pointer points to last argument that was pushed on the stack.
+  uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
+  return reinterpret_cast<RawInstance*>(
+             *reinterpret_cast<uword*>(receiver_addr));
 }
 
 
 void CodeBreakpoint::PatchFunctionReturn() {
-  UNIMPLEMENTED();
+  Instr* instr1 = Instr::At(pc_ - 6 * Instr::kInstrSize);
+  Instr* instr2 = Instr::At(pc_ - 5 * Instr::kInstrSize);
+  Instr* instr3 = Instr::At(pc_ - 4 * Instr::kInstrSize);
+  Instr* instr4 = Instr::At(pc_ - 3 * Instr::kInstrSize);
+  Instr* instr5 = Instr::At(pc_ - 2 * Instr::kInstrSize);
+  Instr* instr6 = Instr::At(pc_ - 1 * Instr::kInstrSize);
+
+#if defined(DEBUG)
+
+  instr1->AssertIsImmInstr(LW, SP, RA, 2 * kWordSize);
+  instr2->AssertIsImmInstr(LW, SP, FP, 1 * kWordSize);
+  instr3->AssertIsImmInstr(LW, SP, PP, 0 * kWordSize);
+  instr4->AssertIsImmInstr(ADDIU, SP, SP, 4 * kWordSize);
+  instr5->AssertIsSpecialInstr(JR, RA, ZR, ZR);
+  ASSERT(instr6->InstructionBits() == Instr::kNopInstruction);
+#endif  // defined(DEBUG)
+
+  // Smash code with call instruction and target address.
+  uword stub_addr = StubCode::BreakpointReturnEntryPoint();
+  uint16_t target_lo = stub_addr & 0xffff;
+  uint16_t target_hi = stub_addr >> 16;
+
+  // Unlike other architectures, the sequence we are patching in is shorter
+  // than the sequence we are replacing. We pad at the top with nops so that
+  // the end of the new sequence is lined up with the code descriptor.
+  instr1->SetInstructionBits(Instr::kNopInstruction);
+  instr2->SetInstructionBits(Instr::kNopInstruction);
+  instr3->SetImmInstrBits(LUI, ZR, TMP1, target_hi);
+  instr4->SetImmInstrBits(ORI, TMP1, TMP1, target_lo);
+  instr5->SetSpecialInstrBits(JALR, TMP1, ZR, RA);
+  instr6->SetInstructionBits(Instr::kNopInstruction);
+
+  CPU::FlushICache(pc_ - 6 * Instr::kInstrSize, 6 * Instr::kInstrSize);
 }
 
 
 void CodeBreakpoint::RestoreFunctionReturn() {
-  UNIMPLEMENTED();
+  Instr* instr1 = Instr::At(pc_ - 6 * Instr::kInstrSize);
+  Instr* instr2 = Instr::At(pc_ - 5 * Instr::kInstrSize);
+  Instr* instr3 = Instr::At(pc_ - 4 * Instr::kInstrSize);
+  Instr* instr4 = Instr::At(pc_ - 3 * Instr::kInstrSize);
+  Instr* instr5 = Instr::At(pc_ - 2 * Instr::kInstrSize);
+  Instr* instr6 = Instr::At(pc_ - 1 * Instr::kInstrSize);
+
+  ASSERT(instr3->OpcodeField() == LUI && instr3->RtField() == TMP1);
+
+  instr1->SetImmInstrBits(LW, SP, RA, 2 * kWordSize);
+  instr2->SetImmInstrBits(LW, SP, FP, 1 * kWordSize);
+  instr3->SetImmInstrBits(LW, SP, PP, 0 * kWordSize);
+  instr4->SetImmInstrBits(ADDIU, SP, SP, 4 * kWordSize);
+  instr5->SetSpecialInstrBits(JR, RA, ZR, ZR);
+  instr6->SetInstructionBits(Instr::kNopInstruction);
+
+  CPU::FlushICache(pc_ - 6 * Instr::kInstrSize, 6 * Instr::kInstrSize);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/debugger_x64.cc b/runtime/vm/debugger_x64.cc
index 6e64d85..c439640 100644
--- a/runtime/vm/debugger_x64.cc
+++ b/runtime/vm/debugger_x64.cc
@@ -49,7 +49,7 @@
   code[10] = 0x41;
   code[11] = 0xff;
   code[12] = 0xd3;
-  CPU::FlushICache(pc_, 5);
+  CPU::FlushICache(pc_ - 13, 13);
 }
 
 
@@ -69,7 +69,7 @@
   code[10] = 0x90;  // nop
   code[11] = 0x90;  // nop
   code[12] = 0x90;  // nop
-  CPU::FlushICache(pc_, 5);
+  CPU::FlushICache(pc_ - 13, 13);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 067f069..a9cc7f0 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -638,6 +638,11 @@
             Format(instr, "umull'cond's 'rd, 'rn, 'rm, 'rs");
             break;
           }
+          case 6: {
+            // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
+            Format(instr, "smull'cond's 'rd, 'rn, 'rm, 'rs");
+            break;
+          }
           default: {
             Unknown(instr);  // Not used.
             break;
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index bfa3438..81f35be 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -596,6 +596,10 @@
       Format(instr, "lh 'rt, 'imms('rs)");
       break;
     }
+    case LHU: {
+      Format(instr, "lhu 'rt, 'imms('rs)");
+      break;
+    }
     case LUI: {
       Format(instr, "lui 'rt, 'immu");
       break;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index a5086cf..280bd6e 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -535,6 +535,22 @@
 }
 
 
+void Exceptions::ThrowOOM() {
+  Isolate* isolate = Isolate::Current();
+  const Instance& oom = Instance::Handle(
+      isolate, isolate->object_store()->out_of_memory());
+  Throw(oom);
+}
+
+
+void Exceptions::ThrowStackOverflow() {
+  Isolate* isolate = Isolate::Current();
+  const Instance& stack_overflow = Instance::Handle(
+      isolate, isolate->object_store()->stack_overflow());
+  Throw(stack_overflow);
+}
+
+
 RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) {
   Library& library = Library::Handle();
   const String* class_name = NULL;
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 6015369..e74a0db 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -63,6 +63,9 @@
   };
 
   static void ThrowByType(ExceptionType type, const Array& arguments);
+  static void ThrowOOM();
+  static void ThrowStackOverflow();
+
   // Returns a RawInstance if the exception is successfully created,
   // otherwise returns a RawError.
   static RawObject* Create(ExceptionType type, const Array& arguments);
diff --git a/runtime/vm/exceptions_test.cc b/runtime/vm/exceptions_test.cc
index 5ccec16..6586435 100644
--- a/runtime/vm/exceptions_test.cc
+++ b/runtime/vm/exceptions_test.cc
@@ -9,11 +9,6 @@
 
 namespace dart {
 
-// Only ia32, x64, and arm can run execution tests.
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
-
 
 #define FUNCTION_NAME(name) UnhandledExcp_##name
 #define REGISTER_FUNCTION(name, count)                                         \
@@ -133,6 +128,5 @@
       reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
   EXPECT_VALID(Dart_Invoke(lib, NewString("testMain"), 0, NULL));
 }
-#endif  // TARGET_ARCH_IA32 || TARGET_ARCH_X64 || TARGET_ARCH_ARM
 
 }  // namespace dart
diff --git a/runtime/vm/flags.cc b/runtime/vm/flags.cc
index e18c43e..fdca04e 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -102,9 +102,12 @@
                           const char* name,
                           bool default_value,
                           const char* comment) {
-  ASSERT(Lookup(name) == NULL);
-
-  Flag* flag = new Flag(name, comment, addr, Flag::kBoolean);
+  Flag* flag = Lookup(name);
+  if (flag != NULL) {
+    ASSERT(flag->IsUnrecognized());
+    return default_value;
+  }
+  flag = new Flag(name, comment, addr, Flag::kBoolean);
   flag->next_ = Flags::flags_;
   Flags::flags_ = flag;
 
@@ -201,7 +204,7 @@
   if (flag == NULL) {
     // Collect unrecognized flags.
     char* new_flag = new char[name_len + 1];
-    strncpy(new_flag, name, name_len);
+    strncpy(new_flag, option, name_len);
     new_flag[name_len] = '\0';
     Flags::Register_bool(NULL, new_flag, true, NULL);
   } else {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index cf08e61..76f6469 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1917,6 +1917,7 @@
       case kTypedDataUint64ArrayCid:
       case kTypedDataFloat32ArrayCid:
       case kTypedDataFloat64ArrayCid:
+      case kTypedDataFloat32x4ArrayCid:
         return function_class.id();
       default:
         return kDynamicCid;  // Unknown.
@@ -2048,22 +2049,22 @@
 // List of recognized list factories in core lib:
 // (factory-name-symbol, result-cid, fingerprint).
 // TODO(srdjan): Store the values in the snapshot instead.
-// TODO(srdjan): Add Float32x4List.
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
   V(ObjectArrayFactory, kArrayCid, 97987288)                                   \
   V(GrowableObjectArrayWithData, kGrowableObjectArrayCid, 816132033)           \
   V(GrowableObjectArrayFactory, kGrowableObjectArrayCid, 552407276)            \
-  V(Int8ListFactory, kTypedDataInt8ArrayCid, 2066002614)                       \
-  V(Uint8ListFactory, kTypedDataUint8ArrayCid, 1883551322)                     \
-  V(Uint8ClampedListFactory, kTypedDataUint8ClampedArrayCid, 244333676)        \
-  V(Int16ListFactory, kTypedDataInt16ArrayCid, 335889889)                      \
-  V(Uint16ListFactory, kTypedDataUint16ArrayCid, 1552801708)                   \
-  V(Int32ListFactory, kTypedDataInt32ArrayCid, 1615677219)                     \
-  V(Uint32ListFactory, kTypedDataUint32ArrayCid, 1239540305)                   \
-  V(Int64ListFactory, kTypedDataInt64ArrayCid, 993438946)                      \
-  V(Uint64ListFactory, kTypedDataUint64ArrayCid, 1830907325)                   \
-  V(Float64ListFactory, kTypedDataFloat64ArrayCid, 1236037424)                 \
-  V(Float32ListFactory, kTypedDataFloat32ArrayCid, 570814412)                  \
+  V(Int8ListFactory, kTypedDataInt8ArrayCid, 1299195009)                       \
+  V(Uint8ListFactory, kTypedDataUint8ArrayCid, 1493118613)                     \
+  V(Uint8ClampedListFactory, kTypedDataUint8ClampedArrayCid, 642014193)        \
+  V(Int16ListFactory, kTypedDataInt16ArrayCid, 1346619471)                     \
+  V(Uint16ListFactory, kTypedDataUint16ArrayCid, 1374024153)                   \
+  V(Int32ListFactory, kTypedDataInt32ArrayCid, 1583592980)                     \
+  V(Uint32ListFactory, kTypedDataUint32ArrayCid, 1940214615)                   \
+  V(Int64ListFactory, kTypedDataInt64ArrayCid, 108181413)                      \
+  V(Uint64ListFactory, kTypedDataUint64ArrayCid, 375587484)                    \
+  V(Float64ListFactory, kTypedDataFloat64ArrayCid, 919047725)                  \
+  V(Float32ListFactory, kTypedDataFloat32ArrayCid, 1038684997)                 \
+  V(Float32x4ListFactory, kTypedDataFloat32x4ArrayCid, 801641591)              \
 
 
 // Class that recognizes factories and returns corresponding result cid.
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 5b0020b..acd4925 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -285,13 +285,86 @@
 }
 
 
+// Generates inlined check if 'type' is a type parameter or type itself
+// R0: instance (preserved).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
     intptr_t token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
-  UNIMPLEMENTED();
-  return NULL;
+  __ Comment("UninstantiatedTypeTest");
+  ASSERT(!type.IsInstantiated());
+  // Skip check if destination is a dynamic type.
+  if (type.IsTypeParameter()) {
+    const TypeParameter& type_param = TypeParameter::Cast(type);
+    // Load instantiator (or null) and instantiator type arguments on stack.
+    __ ldr(R1, Address(SP, 0));  // Get instantiator type arguments.
+    // R1: instantiator type arguments.
+    // Check if type argument is dynamic.
+    __ CompareImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
+    __ b(is_instance_lbl, EQ);
+    // Can handle only type arguments that are instances of TypeArguments.
+    // (runtime checks canonicalize type arguments).
+    Label fall_through;
+    __ CompareClassId(R1, kTypeArgumentsCid, R2);
+    __ b(&fall_through, NE);
+    __ ldr(R2,
+        FieldAddress(R1, TypeArguments::type_at_offset(type_param.index())));
+    // R2: concrete type of type.
+    // Check if type argument is dynamic.
+    __ CompareObject(R2, Type::ZoneHandle(Type::DynamicType()));
+    __ b(is_instance_lbl, EQ);
+    __ CompareImmediate(R2, reinterpret_cast<intptr_t>(Object::null()));
+    __ b(is_instance_lbl, EQ);
+    const Type& object_type = Type::ZoneHandle(Type::ObjectType());
+    __ CompareObject(R2, object_type);
+    __ b(is_instance_lbl, EQ);
+
+    // For Smi check quickly against int and num interfaces.
+    Label not_smi;
+    __ tst(R0, ShifterOperand(kSmiTagMask));  // Value is Smi?
+    __ b(&not_smi, NE);
+    __ CompareObject(R2, Type::ZoneHandle(Type::IntType()));
+    __ b(is_instance_lbl, EQ);
+    __ CompareObject(R2, Type::ZoneHandle(Type::Number()));
+    __ b(is_instance_lbl, EQ);
+    // Smi must be handled in runtime.
+    __ b(&fall_through);
+
+    __ Bind(&not_smi);
+    // R1: instantiator type arguments.
+    // R0: instance.
+    const Register kInstanceReg = R0;
+    const Register kTypeArgumentsReg = R1;
+    const Register kTempReg = kNoRegister;
+    const SubtypeTestCache& type_test_cache =
+        SubtypeTestCache::ZoneHandle(
+            GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
+                                        kInstanceReg,
+                                        kTypeArgumentsReg,
+                                        kTempReg,
+                                        is_instance_lbl,
+                                        is_not_instance_lbl));
+    __ Bind(&fall_through);
+    return type_test_cache.raw();
+  }
+  if (type.IsType()) {
+    const Register kInstanceReg = R0;
+    const Register kTypeArgumentsReg = R1;
+    __ tst(kInstanceReg, ShifterOperand(kSmiTagMask));  // Is instance Smi?
+    __ b(is_not_instance_lbl, EQ);
+    __ ldr(kTypeArgumentsReg, Address(SP, 0));  // Instantiator type args.
+    // Uninstantiated type class is known at compile time, but the type
+    // arguments are determined at runtime by the instantiator.
+    const Register kTempReg = kNoRegister;
+    return GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
+                                       kInstanceReg,
+                                       kTypeArgumentsReg,
+                                       kTempReg,
+                                       is_instance_lbl,
+                                       is_not_instance_lbl);
+  }
+  return SubtypeTestCache::null();
 }
 
 
@@ -394,7 +467,7 @@
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(dst_type.IsMalformed() ||
          (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
-  // Preserve instantiator and its type arguments.
+  // Preserve instantiator (R2) and its type arguments (R1).
   __ PushList((1 << R1) | (1 << R2));
   // A null object is always assignable and is returned as result.
   Label is_assignable, runtime_call;
@@ -425,7 +498,7 @@
     __ bkpt(0);
 
     __ Bind(&is_assignable);  // For a null object.
-    // Restore instantiator and its type arguments.
+    // Restore instantiator (R2) and its type arguments (R1).
     __ PopList((1 << R1) | (1 << R2));
     return;
   }
@@ -436,12 +509,12 @@
                                         &is_assignable, &runtime_call);
 
   __ Bind(&runtime_call);
-  // Load instantiator and its type arguments.
+  // Load instantiator (R2) and its type arguments (R1).
   __ ldm(IA, SP,  (1 << R1) | (1 << R2));
   __ PushObject(Object::ZoneHandle());  // Make room for the result.
   __ Push(R0);  // Push the source object.
   __ PushObject(dst_type);  // Push the type of the destination.
-  // Push instantiator and its type arguments.
+  // Push instantiator (R2) and its type arguments (R1).
   __ PushList((1 << R1) | (1 << R2));
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(R0, test_cache);
@@ -453,7 +526,7 @@
   __ Pop(R0);
 
   __ Bind(&is_assignable);
-  // Restore instantiator and its type arguments.
+  // Restore instantiator (R2) and its type arguments (R1).
   __ PopList((1 << R1) | (1 << R2));
 }
 
@@ -1000,7 +1073,21 @@
     intptr_t deopt_id,
     intptr_t token_pos,
     LocationSummary* locs) {
-  UNIMPLEMENTED();
+  // Each ICData propagated from unoptimized to optimized code contains the
+  // function that corresponds to the Dart function of that IC call. Due
+  // to inlining in optimized code, that function may not correspond to the
+  // top-level function (parsed_function().function()) which could be
+  // reoptimized and which counter needs to be incremented.
+  // Pass the function explicitly, it is used in IC stub.
+  __ LoadObject(R6, parsed_function().function());
+  __ LoadObject(R4, arguments_descriptor);
+  __ LoadObject(R5, ic_data);
+  GenerateDartCall(deopt_id,
+                   token_pos,
+                   target_label,
+                   PcDescriptors::kIcCall,
+                   locs);
+  __ Drop(argument_count);
 }
 
 
@@ -1055,7 +1142,17 @@
 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
                                                     const Object& obj,
                                                     bool needs_number_check) {
-  UNIMPLEMENTED();
+  if (needs_number_check &&
+      (obj.IsMint() || obj.IsDouble() || obj.IsBigint())) {
+    __ Push(reg);
+    __ PushObject(obj);
+    __ BranchLink(&StubCode::IdenticalWithNumberCheckLabel());
+    __ Drop(1);  // Discard constant.
+    __ Pop(reg);  // Restore 'reg'.
+    return;
+  }
+
+  __ CompareObject(reg, obj);
 }
 
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index dce40df..bc3d443 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -296,7 +296,7 @@
 }
 
 
-// Generates inlined check if 'type' is a type parameter or type itsef
+// Generates inlined check if 'type' is a type parameter or type itself
 // EAX: instance (preserved).
 // Clobbers EDX, EDI, ECX.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 75cf6b3..110bc96 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -66,6 +66,7 @@
 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
                                            Label* is_true,
                                            Label* is_false) {
+  __ TraceSimMsg("BoolToJump");
   Label fall_through;
   __ BranchEqual(bool_register, reinterpret_cast<intptr_t>(Object::null()),
                  &fall_through);
@@ -84,6 +85,7 @@
     Register temp_reg,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
+  __ TraceSimMsg("CallSubtypeTestStub");
   ASSERT(instance_reg == A0);
   ASSERT(temp_reg == kNoRegister);  // Unused on MIPS.
   const SubtypeTestCache& type_test_cache =
@@ -109,14 +111,67 @@
 }
 
 
+// Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
+// type test is conclusive, otherwise fallthrough if a type test could not
+// be completed.
+// A0: instance being type checked (preserved).
+// Clobbers T0.
 RawSubtypeTestCache*
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
     intptr_t token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
-  UNIMPLEMENTED();
-  return NULL;
+  __ Comment("InstantiatedTypeWithArgumentsTest");
+  ASSERT(type.IsInstantiated());
+  const Class& type_class = Class::ZoneHandle(type.type_class());
+  ASSERT(type_class.HasTypeArguments());
+  const Register kInstanceReg = A0;
+  // A Smi object cannot be the instance of a parameterized class.
+  __ andi(CMPRES, kInstanceReg, Immediate(kSmiTagMask));
+  __ beq(CMPRES, ZR, is_not_instance_lbl);
+  const AbstractTypeArguments& type_arguments =
+      AbstractTypeArguments::ZoneHandle(type.arguments());
+  const bool is_raw_type = type_arguments.IsNull() ||
+      type_arguments.IsRaw(type_arguments.Length());
+  if (is_raw_type) {
+    const Register kClassIdReg = T0;
+    // dynamic type argument, check only classes.
+    __ LoadClassId(kClassIdReg, kInstanceReg);
+    __ BranchEqual(kClassIdReg, type_class.id(), is_instance_lbl);
+    // List is a very common case.
+    if (type_class.IsListClass()) {
+      GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
+    }
+    return GenerateSubtype1TestCacheLookup(
+        token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+  }
+  // If one type argument only, check if type argument is Object or dynamic.
+  if (type_arguments.Length() == 1) {
+    const AbstractType& tp_argument = AbstractType::ZoneHandle(
+        type_arguments.TypeAt(0));
+    ASSERT(!tp_argument.IsMalformed());
+    if (tp_argument.IsType()) {
+      ASSERT(tp_argument.HasResolvedTypeClass());
+      // Check if type argument is dynamic or Object.
+      const Type& object_type = Type::Handle(Type::ObjectType());
+      if (object_type.IsSubtypeOf(tp_argument, NULL)) {
+        // Instance class test only necessary.
+        return GenerateSubtype1TestCacheLookup(
+            token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+      }
+    }
+  }
+  // Regular subtype test cache involving instance's type arguments.
+  const Register kTypeArgumentsReg = kNoRegister;
+  const Register kTempReg = kNoRegister;
+  // A0: instance (must be preserved).
+  return GenerateCallSubtypeTestStub(kTestTypeTwoArgs,
+                                     kInstanceReg,
+                                     kTypeArgumentsReg,
+                                     kTempReg,
+                                     is_instance_lbl,
+                                     is_not_instance_lbl);
 }
 
 
@@ -124,6 +179,7 @@
                                       const GrowableArray<intptr_t>& class_ids,
                                       Label* is_equal_lbl,
                                       Label* is_not_equal_lbl) {
+  __ TraceSimMsg("CheckClassIds");
   for (intptr_t i = 0; i < class_ids.length(); i++) {
     __ BranchEqual(class_id_reg, class_ids[i], is_equal_lbl);
   }
@@ -141,6 +197,7 @@
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
+  __ TraceSimMsg("InstantiatedTypeNoArgumentsTest");
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
   const Class& type_class = Class::Handle(type.type_class());
@@ -206,6 +263,7 @@
     const Class& type_class,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
+  __ TraceSimMsg("Subtype1TestCacheLookup");
   __ Comment("Subtype1TestCacheLookup");
   const Register kInstanceReg = A0;
   __ LoadClass(T0, kInstanceReg);
@@ -226,13 +284,83 @@
 }
 
 
+// Generates inlined check if 'type' is a type parameter or type itself
+// A0: instance (preserved).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
     intptr_t token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
-  UNIMPLEMENTED();
-  return NULL;
+  __ Comment("UninstantiatedTypeTest");
+  ASSERT(!type.IsInstantiated());
+  // Skip check if destination is a dynamic type.
+  if (type.IsTypeParameter()) {
+    const TypeParameter& type_param = TypeParameter::Cast(type);
+    // Load instantiator (or null) and instantiator type arguments on stack.
+    __ lw(A1, Address(SP, 0));  // Get instantiator type arguments.
+    // A1: instantiator type arguments.
+    // Check if type argument is dynamic.
+    __ BranchEqual(A1, reinterpret_cast<intptr_t>(Object::null()),
+                   is_instance_lbl);
+    // Can handle only type arguments that are instances of TypeArguments.
+    // (runtime checks canonicalize type arguments).
+    Label fall_through;
+    __ LoadClassId(T2, A1);
+    __ BranchNotEqual(T2, kTypeArgumentsCid, &fall_through);
+    __ lw(T2,
+        FieldAddress(A1, TypeArguments::type_at_offset(type_param.index())));
+    // R2: concrete type of type.
+    // Check if type argument is dynamic.
+    __ BranchEqual(T2, Type::ZoneHandle(Type::DynamicType()), is_instance_lbl);
+    __ BranchEqual(T2, reinterpret_cast<intptr_t>(Object::null()),
+                   is_instance_lbl);
+    const Type& object_type = Type::ZoneHandle(Type::ObjectType());
+    __ BranchEqual(T2, object_type, is_instance_lbl);
+
+    // For Smi check quickly against int and num interfaces.
+    Label not_smi;
+    __ andi(CMPRES, A0, Immediate(kSmiTagMask));
+    __ bne(CMPRES, ZR, &not_smi);  // Value is Smi?
+    __ BranchEqual(T2, Type::ZoneHandle(Type::IntType()), is_instance_lbl);
+    __ BranchEqual(T2, Type::ZoneHandle(Type::Number()), is_instance_lbl);
+
+    // Smi must be handled in runtime.
+    __ b(&fall_through);
+
+    __ Bind(&not_smi);
+    // T1: instantiator type arguments.
+    // A0: instance.
+    const Register kInstanceReg = A0;
+    const Register kTypeArgumentsReg = A1;
+    const Register kTempReg = kNoRegister;
+    const SubtypeTestCache& type_test_cache =
+        SubtypeTestCache::ZoneHandle(
+            GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
+                                        kInstanceReg,
+                                        kTypeArgumentsReg,
+                                        kTempReg,
+                                        is_instance_lbl,
+                                        is_not_instance_lbl));
+    __ Bind(&fall_through);
+    return type_test_cache.raw();
+  }
+  if (type.IsType()) {
+    const Register kInstanceReg = A0;
+    const Register kTypeArgumentsReg = A1;
+    __ andi(CMPRES, kInstanceReg, Immediate(kSmiTagMask));
+    __ beq(CMPRES, ZR, is_not_instance_lbl);  // Is instance Smi?
+    __ lw(kTypeArgumentsReg, Address(SP, 0));  // Instantiator type args.
+    // Uninstantiated type class is known at compile time, but the type
+    // arguments are determined at runtime by the instantiator.
+    const Register kTempReg = kNoRegister;
+    return GenerateCallSubtypeTestStub(kTestTypeThreeArgs,
+                                       kInstanceReg,
+                                       kTypeArgumentsReg,
+                                       kTempReg,
+                                       is_instance_lbl,
+                                       is_not_instance_lbl);
+  }
+  return SubtypeTestCache::null();
 }
 
 
@@ -250,6 +378,7 @@
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
+  __ TraceSimMsg("InlineInstanceof");
   __ Comment("InlineInstanceof");
   if (type.IsVoidType()) {
     // A non-null value is returned from a void function, which will result in a
@@ -330,6 +459,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
+  __ TraceSimMsg("AssertAssignable");
   ASSERT(token_pos >= 0);
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
@@ -355,10 +485,16 @@
     const Error& error = Error::Handle(dst_type.malformed_error());
     const String& error_message = String::ZoneHandle(
         Symbols::New(error.ToErrorCString()));
-    __ PushObject(Object::ZoneHandle());  // Make room for the result.
-    __ Push(A0);  // Push the source object.
-    __ PushObject(dst_name);  // Push the name of the destination.
-    __ PushObject(error_message);
+
+    __ addiu(SP, SP, Immediate(-4 * kWordSize));
+    __ LoadObject(TMP1, Object::ZoneHandle());
+    __ sw(TMP1, Address(SP, 3 * kWordSize));  // Make room for the result.
+    __ sw(A0, Address(SP, 2 * kWordSize));  // Push the source object.
+    __ LoadObject(TMP1, dst_name);
+    __ sw(TMP1, Address(SP, 1 * kWordSize));  // Push the destination name.
+    __ LoadObject(TMP1, error_message);
+    __ sw(TMP1, Address(SP, 0 * kWordSize));
+
     GenerateCallRuntime(token_pos,
                         deopt_id,
                         kMalformedTypeErrorRuntimeEntry,
@@ -380,25 +516,28 @@
                                         &is_assignable, &runtime_call);
 
   __ Bind(&runtime_call);
-  // Load instantiator and its type arguments.
+  // Load instantiator (A2) and its type arguments (A1).
   __ lw(A1, Address(SP, 0 * kWordSize));
   __ lw(A2, Address(SP, 1 * kWordSize));
-  __ addiu(SP, SP, Immediate(2 * kWordSize));
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
-  __ Push(A0);  // Push the source object.
-  __ PushObject(dst_type);  // Push the type of the destination.
-  // Push instantiator and its type arguments.
-  __ addiu(SP, SP, Immediate(-2 * kWordSize));
-  __ sw(A2, Address(SP, 1 * kWordSize));
-  __ sw(A1, Address(SP, 0 * kWordSize));
-  __ PushObject(dst_name);  // Push the name of the destination.
+
+  __ addiu(SP, SP, Immediate(-7 * kWordSize));
+  __ LoadObject(TMP1, Object::ZoneHandle());
+  __ sw(TMP1, Address(SP, 6 * kWordSize));  // Make room for the result.
+  __ sw(A0, Address(SP, 5 * kWordSize));  // Push the source object.
+  __ LoadObject(TMP1, dst_type);
+  __ sw(TMP1, Address(SP, 4 * kWordSize));  // Push the type of the destination.
+  __ sw(A2, Address(SP, 3 * kWordSize));  // Push instantiator.
+  __ sw(A1, Address(SP, 2 * kWordSize));  // Push type arguments.
+  __ LoadObject(TMP1, dst_name);
+  __ sw(TMP1, Address(SP, 1 * kWordSize));  // Push the name of the destination.
   __ LoadObject(T0, test_cache);
-  __ Push(T0);
+  __ sw(T0, Address(SP, 0 * kWordSize));
+
   GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs);
   // Pop the parameters supplied to the runtime entry. The result of the
   // type check runtime call is the checked value.
-  __ Drop(6);
-  __ Pop(A0);
+  __ lw(A0, Address(SP, 6 * kWordSize));
+  __ addiu(SP, SP, Immediate(7 * kWordSize));
 
   __ Bind(&is_assignable);
   // Restore instantiator and its type arguments.
@@ -442,6 +581,7 @@
 // Input parameters:
 //   S4: arguments descriptor array.
 void FlowGraphCompiler::CopyParameters() {
+  __ TraceSimMsg("CopyParameters");
   __ Comment("Copy parameters");
   const Function& function = parsed_function().function();
   LocalScope* scope = parsed_function().node_sequence()->scope();
@@ -482,12 +622,11 @@
   // Let T0 point to the last copied positional argument, i.e. to
   // fp[kFirstLocalSlotIndex - (num_pos_args - 1)].
   __ AddImmediate(T0, FP, (kFirstLocalSlotIndex + 1) * kWordSize);
-  __ sll(T3, T2, 1);  // T2 is a Smi.
-  __ subu(T0, T0, T3);
+  __ sll(T2, T2, 1);  // T2 is a Smi.
 
   Label loop, loop_condition;
   __ b(&loop_condition);
-  __ delay_slot()->SmiUntag(T2);
+  __ delay_slot()->subu(T0, T0, T2);
   // We do not use the final allocation index of the variable here, i.e.
   // scope->VariableAt(i)->index(), because captured variables still need
   // to be copied to the context that is not yet allocated.
@@ -573,7 +712,7 @@
     // Check that T0 now points to the null terminator in the array descriptor.
     __ lw(T3, Address(T0));
     __ BranchEqual(T3, reinterpret_cast<int32_t>(Object::null()),
-                &all_arguments_processed);
+                   &all_arguments_processed);
   } else {
     ASSERT(num_opt_pos_params > 0);
     __ lw(T2,
@@ -651,15 +790,18 @@
 
   // S4 : arguments descriptor array.
   __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(T2);
+  __ sll(T2, T2, 1);  // T2 is a Smi.
 
   __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
   Label null_args_loop, null_args_loop_condition;
+
   __ b(&null_args_loop_condition);
   __ delay_slot()->addiu(T1, FP, Immediate(kLastParamSlotIndex * kWordSize));
+
   __ Bind(&null_args_loop);
   __ addu(T3, T1, T2);
   __ sw(T0, Address(T3));
+
   __ Bind(&null_args_loop_condition);
   __ addiu(T2, T2, Immediate(-kWordSize));
   __ bgez(T2, &null_args_loop);
@@ -667,16 +809,30 @@
 
 
 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
-  UNIMPLEMENTED();
+  // RA: return address.
+  // SP: receiver.
+  // Sequence node has one return node, its input is load field node.
+  __ lw(V0, Address(SP, 0 * kWordSize));
+  __ lw(V0, Address(V0, offset - kHeapObjectTag));
+  __ Ret();
 }
 
 
 void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) {
-  UNIMPLEMENTED();
+  // RA: return address.
+  // SP+1: receiver.
+  // SP+0: value.
+  // Sequence node has one store node and one return NULL node.
+  __ lw(T0, Address(SP, 1 * kWordSize));  // Receiver.
+  __ lw(T1, Address(SP, 0 * kWordSize));  // Value.
+  __ StoreIntoObject(T0, FieldAddress(T0, offset), T1);
+  __ LoadImmediate(V0, reinterpret_cast<intptr_t>(Object::null()));
+  __ Ret();
 }
 
 
 void FlowGraphCompiler::EmitFrameEntry() {
+  __ TraceSimMsg("FrameEntry");
   const Function& function = parsed_function().function();
   if (CanOptimizeFunction() && function.is_optimizable()) {
     const bool can_optimize = !is_optimizing() || may_reoptimize();
@@ -786,6 +942,7 @@
     const bool check_arguments = function.IsClosureFunction();
 #endif
     if (check_arguments) {
+      __ TraceSimMsg("Check argument count");
       __ Comment("Check argument count");
       // Check that exactly num_fixed arguments are passed in.
       Label correct_num_arguments, wrong_num_arguments;
@@ -858,6 +1015,7 @@
   // In unoptimized code, initialize (non-argument) stack allocated slots to
   // null. This does not cover the saved_args_desc_var slot.
   if (!is_optimizing() && (num_locals > 0)) {
+    __ TraceSimMsg("Initialize spill slots");
     __ Comment("Initialize spill slots");
     const intptr_t slot_base = parsed_function().first_stack_local_index();
     __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
@@ -898,6 +1056,7 @@
                                      const ExternalLabel* label,
                                      PcDescriptors::Kind kind,
                                      LocationSummary* locs) {
+  __ TraceSimMsg("Call");
   __ BranchLinkPatchable(label);
   AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
@@ -909,6 +1068,7 @@
                                          const ExternalLabel* label,
                                          PcDescriptors::Kind kind,
                                          LocationSummary* locs) {
+  __ TraceSimMsg("DartCall");
   __ BranchLinkPatchable(label);
   AddCurrentDescriptor(kind, deopt_id, token_pos);
   RecordSafepoint(locs);
@@ -931,6 +1091,7 @@
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             LocationSummary* locs) {
+  __ TraceSimMsg("CallRuntime");
   __ CallRuntime(entry);
   AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
   RecordSafepoint(locs);
@@ -948,6 +1109,7 @@
                            token_pos);
     }
   }
+  __ TraceSimMsg("CallRuntime return");
 }
 
 
@@ -970,6 +1132,7 @@
                                          intptr_t deopt_id,
                                          intptr_t token_pos,
                                          LocationSummary* locs) {
+  __ TraceSimMsg("InstanceCall");
   __ LoadObject(S4, arguments_descriptor);
   __ LoadObject(S5, ic_data);
   GenerateDartCall(deopt_id,
@@ -977,6 +1140,7 @@
                    target_label,
                    PcDescriptors::kIcCall,
                    locs);
+  __ TraceSimMsg("InstanceCall return");
   __ Drop(argument_count);
 }
 
@@ -998,6 +1162,7 @@
                                        intptr_t deopt_id,
                                        intptr_t token_pos,
                                        LocationSummary* locs) {
+  __ TraceSimMsg("StaticCall");
   __ LoadObject(S4, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
   // we can record the outgoing edges to other code.
@@ -1021,13 +1186,17 @@
 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
                                                   Register right,
                                                   bool needs_number_check) {
+  __ TraceSimMsg("EqualityRegRegCompare");
   if (needs_number_check) {
-    __ Push(left);
-    __ Push(right);
+    __ addiu(SP, SP, Immediate(-2 * kWordSize));
+    __ sw(left, Address(SP, 1 * kWordSize));
+    __ sw(right, Address(SP, 0 * kWordSize));
     __ BranchLink(&StubCode::IdenticalWithNumberCheckLabel());
+    __ TraceSimMsg("EqualityRegRegCompare return");
     // Stub returns result in CMPRES. If it is 0, then left and right are equal.
-    __ Pop(right);
-    __ Pop(left);
+    __ lw(right, Address(SP, 0 * kWordSize));
+    __ lw(left, Address(SP, 1 * kWordSize));
+    __ addiu(SP, SP, Immediate(2 * kWordSize));
   } else {
     __ subu(CMPRES, left, right);
   }
@@ -1041,6 +1210,7 @@
 
 
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
+  __ TraceSimMsg("SaveLiveRegisters");
   // TODO(vegorov): consider saving only caller save (volatile) registers.
   const intptr_t fpu_registers = locs->live_registers()->fpu_registers();
   if (fpu_registers > 0) {
@@ -1068,6 +1238,7 @@
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
   // General purpose registers have the lowest register number at the
   // lowest address.
+  __ TraceSimMsg("RestoreLiveRegisters");
   const intptr_t cpu_registers = locs->live_registers()->cpu_registers();
   ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
   const int register_count = Utils::CountOneBits(cpu_registers);
@@ -1172,6 +1343,7 @@
 
 
 void ParallelMoveResolver::EmitMove(int index) {
+  __ TraceSimMsg("ParallelMoveResolver::EmitMove");
   MoveOperands* move = moves_[index];
   const Location source = move->src();
   const Location destination = move->dest();
@@ -1228,6 +1400,7 @@
 
 
 void ParallelMoveResolver::EmitSwap(int index) {
+  __ TraceSimMsg("ParallelMoveResolver::EmitSwap");
   MoveOperands* move = moves_[index];
   const Location source = move->src();
   const Location destination = move->dest();
@@ -1303,18 +1476,21 @@
 
 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst,
                                               const Address& src) {
+  __ TraceSimMsg("ParallelMoveResolver::MoveMemoryToMemory");
   __ lw(TMP1, src);
   __ sw(TMP1, dst);
 }
 
 
 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
+  __ TraceSimMsg("ParallelMoveResolver::StoreObject");
   __ LoadObject(TMP1, obj);
   __ sw(TMP1, dst);
 }
 
 
 void ParallelMoveResolver::Exchange(Register reg, const Address& mem) {
+  __ TraceSimMsg("ParallelMoveResolver::Exchange ra");
   ASSERT(reg != TMP1);
   __ mov(TMP1, reg);
   __ lw(reg, mem);
@@ -1323,6 +1499,7 @@
 
 
 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
+  __ TraceSimMsg("ParallelMoveResolver::Exchange aa");
   ScratchRegisterScope ensure_scratch(this, TMP1);
   __ lw(ensure_scratch.reg(), mem1);
   __ lw(TMP1, mem2);
@@ -1332,22 +1509,26 @@
 
 
 void ParallelMoveResolver::SpillScratch(Register reg) {
+  __ TraceSimMsg("ParallelMoveResolver::SpillScratch");
   __ Push(reg);
 }
 
 
 void ParallelMoveResolver::RestoreScratch(Register reg) {
+  __ TraceSimMsg("ParallelMoveResolver::RestoreScratch");
   __ Pop(reg);
 }
 
 
 void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) {
+  __ TraceSimMsg("ParallelMoveResolver::SpillFpuScratch");
   __ AddImmediate(SP, -kDoubleSize);
   __ sdc1(reg, Address(SP));
 }
 
 
 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
+  __ TraceSimMsg("ParallelMoveResolver::RestoreFpuScratch");
   __ ldc1(reg, Address(SP));
   __ AddImmediate(SP, kDoubleSize);
 }
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 48d2624..d566fa1 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -295,7 +295,7 @@
 }
 
 
-// Generates inlined check if 'type' is a type parameter or type itsef
+// Generates inlined check if 'type' is a type parameter or type itself
 // RAX: instance (preserved).
 // Clobbers RDI, RDX, R10.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index a021388..3170079 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1393,6 +1393,23 @@
 }
 
 
+bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
+                                               MethodRecognizer::Kind getter) {
+  AddCheckClass(call->ArgumentAt(0),
+                ICData::ZoneHandle(
+                    call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
+      getter,
+      new Value(call->ArgumentAt(0)),
+      call);
+  ReplaceCall(call, instr);
+  return true;
+}
+
+
 // Only unique implicit instance getters can be currently handled.
 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
   ASSERT(call->HasICData());
@@ -1454,6 +1471,19 @@
       }
       InlineStringIsEmptyGetter(call);
       return true;
+    case MethodRecognizer::kFloat32x4ShuffleXXXX:
+    case MethodRecognizer::kFloat32x4ShuffleYYYY:
+    case MethodRecognizer::kFloat32x4ShuffleZZZZ:
+    case MethodRecognizer::kFloat32x4ShuffleWWWW:
+    case MethodRecognizer::kFloat32x4ShuffleX:
+    case MethodRecognizer::kFloat32x4ShuffleY:
+    case MethodRecognizer::kFloat32x4ShuffleZ:
+    case MethodRecognizer::kFloat32x4ShuffleW:
+      if (!ic_data.HasReceiverClassId(kFloat32x4Cid) ||
+          !ic_data.HasOneTarget()) {
+        return false;
+      }
+      return InlineFloat32x4Getter(call, recognized_kind);
     default:
       ASSERT(recognized_kind == MethodRecognizer::kUnknown);
   }
@@ -2077,6 +2107,21 @@
     MathSqrtInstr* sqrt =
         new MathSqrtInstr(new Value(call->ArgumentAt(0)), call);
     ReplaceCall(call, sqrt);
+  } else if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
+    Float32x4ZeroInstr* zero = new Float32x4ZeroInstr(call);
+    ReplaceCall(call, zero);
+  } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) {
+    Float32x4SplatInstr* splat =
+        new Float32x4SplatInstr(new Value(call->ArgumentAt(1)), call);
+    ReplaceCall(call, splat);
+  } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) {
+    Float32x4ConstructorInstr* con =
+        new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)),
+                                      new Value(call->ArgumentAt(2)),
+                                      new Value(call->ArgumentAt(3)),
+                                      new Value(call->ArgumentAt(4)),
+                                      call);
+    ReplaceCall(call, con);
   }
 }
 
@@ -3063,52 +3108,216 @@
   // in the DominatorBasedCSE pass.
   // TODO(fschneider): Extend to other load instructions.
   return (def->IsLoadField() && def->AffectedBySideEffect())
-      || def->IsLoadIndexed();
+      || def->IsLoadIndexed()
+      || def->IsLoadStaticField()
+      || def->IsCurrentContext();
 }
 
 
-static intptr_t ComputeLoadOffsetInWords(Definition* defn) {
-  if (defn->IsLoadIndexed()) {
-    // We are assuming that LoadField is never used to load the first word.
-    return 0;
+// Alias represents a family of locations. It is used to capture aliasing
+// between stores and loads. Store can alias another load or store if and only
+// if they have the same alias.
+class Alias : public ValueObject {
+ public:
+  Alias(const Alias& other) : ValueObject(), alias_(other.alias_) { }
+
+  // All indexed load/stores alias each other.
+  // TODO(vegorov): incorporate type of array into alias to disambiguate
+  // different typed data and normal arrays.
+  static Alias Indexes() {
+    return Alias(kIndexesAlias);
   }
 
-  LoadFieldInstr* load_field = defn->AsLoadField();
-  if (load_field != NULL) {
-    const intptr_t idx = load_field->offset_in_bytes() / kWordSize;
-    ASSERT(idx > 0);
-    return idx;
+  // Field load/stores alias each other when field offset matches.
+  // TODO(vegorov): use field information to disambiguate load/stores into
+  // different fields that by accident share offset.
+  static Alias Field(intptr_t offset_in_bytes) {
+    const intptr_t idx = offset_in_bytes / kWordSize;
+    ASSERT(idx >= kFirstFieldAlias);
+    return Alias(idx * 2);
   }
 
-  UNREACHABLE();
-  return 0;
-}
-
-
-static bool IsInterferingStore(Instruction* instr,
-                               intptr_t* offset_in_words) {
-  if (instr->IsStoreIndexed()) {
-    // We are assuming that LoadField is never used to load the first word.
-    *offset_in_words = 0;
-    return true;
+  // Static field load/stores alias each other.
+  // AliasedSet assigns ids to static fields during optimization phase.
+  static Alias StaticField(intptr_t id) {
+    ASSERT(id >= kFirstFieldAlias);
+    return Alias(id * 2 + 1);
   }
 
-  StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField();
-  if (store_instance_field != NULL) {
-    ASSERT(store_instance_field->field().Offset() != 0);
-    *offset_in_words = store_instance_field->field().Offset() / kWordSize;
-    return true;
+  // Current context load/stores alias each other.
+  static Alias CurrentContext() {
+    return Alias(kCurrentContextAlias);
   }
 
-  StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
-  if (store_vm_field != NULL) {
-    ASSERT(store_vm_field->offset_in_bytes() != 0);
-    *offset_in_words = store_vm_field->offset_in_bytes() / kWordSize;
-    return true;
+  // Operation does not alias anything.
+  static Alias None() {
+    return Alias(kNoneAlias);
   }
 
-  return false;
-}
+  bool IsNone() const {
+    return alias_ == kNoneAlias;
+  }
+
+  // Convert this alias to a positive array index.
+  intptr_t ToIndex() const {
+    ASSERT(!IsNone());
+    return alias_ - kAliasBase;
+  }
+
+ private:
+  explicit Alias(intptr_t alias) : alias_(alias) { }
+
+  enum {
+    kNoneAlias = -2,
+    kCurrentContextAlias = -1,
+    kIndexesAlias = 0,
+    kFirstFieldAlias = kIndexesAlias + 1,
+    kAliasBase = kCurrentContextAlias
+  };
+
+  const intptr_t alias_;
+};
+
+
+// Set mapping alias to a list of loads sharing this alias.
+class AliasedSet : public ZoneAllocated {
+ public:
+  explicit AliasedSet(intptr_t max_expr_id)
+      : max_expr_id_(max_expr_id),
+        sets_(),
+        field_ids_(),
+        max_field_id_(0) { }
+
+  Alias ComputeAliasForLoad(Definition* defn) {
+    if (defn->IsLoadIndexed()) {
+      // We are assuming that LoadField is never used to load the first word.
+      return Alias::Indexes();
+    }
+
+    LoadFieldInstr* load_field = defn->AsLoadField();
+    if (load_field != NULL) {
+      return Alias::Field(load_field->offset_in_bytes());
+    }
+
+    if (defn->IsCurrentContext()) {
+      return Alias::CurrentContext();
+    }
+
+    LoadStaticFieldInstr* load_static_field = defn->AsLoadStaticField();
+    if (load_static_field != NULL) {
+      return Alias::StaticField(GetFieldId(load_static_field->field()));
+    }
+
+    UNREACHABLE();
+    return Alias::None();
+  }
+
+  Alias ComputeAliasForStore(Instruction* instr) {
+    if (instr->IsStoreIndexed()) {
+      return Alias::Indexes();
+    }
+
+    StoreInstanceFieldInstr* store_instance_field =
+        instr->AsStoreInstanceField();
+    if (store_instance_field != NULL) {
+      return Alias::Field(store_instance_field->field().Offset());
+    }
+
+    StoreVMFieldInstr* store_vm_field = instr->AsStoreVMField();
+    if (store_vm_field != NULL) {
+      return Alias::Field(store_vm_field->offset_in_bytes());
+    }
+
+    if (instr->IsStoreContext() || instr->IsChainContext()) {
+      return Alias::CurrentContext();
+    }
+
+    StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
+    if (store_static_field != NULL) {
+      return Alias::StaticField(GetFieldId(store_static_field->field()));
+    }
+
+    return Alias::None();
+  }
+
+  bool Contains(const Alias alias) {
+    const intptr_t idx = alias.ToIndex();
+    return (idx < sets_.length()) && (sets_[idx] != NULL);
+  }
+
+  BitVector* Get(const Alias alias) {
+    ASSERT(Contains(alias));
+    return sets_[alias.ToIndex()];
+  }
+
+  void Add(const Alias alias, intptr_t ssa_index) {
+    const intptr_t idx = alias.ToIndex();
+
+    while (sets_.length() <= idx) {
+      sets_.Add(NULL);
+    }
+
+    if (sets_[idx] == NULL) {
+      sets_[idx] = new BitVector(max_expr_id_);
+    }
+
+    sets_[idx]->Add(ssa_index);
+  }
+
+  intptr_t max_expr_id() const { return max_expr_id_; }
+  bool IsEmpty() const { return max_expr_id_ == 0; }
+
+ private:
+  const intptr_t max_expr_id_;
+
+  // Maps alias index to a set of ssa indexes corresponding to loads with the
+  // given alias.
+  GrowableArray<BitVector*> sets_;
+
+  // Get id assigned to the given field. Assign a new id if the field is seen
+  // for the first time.
+  intptr_t GetFieldId(const Field& field) {
+    intptr_t id = field_ids_.Lookup(&field);
+    if (id == 0) {
+      id = ++max_field_id_;
+      field_ids_.Insert(FieldIdPair(&field, id));
+    }
+    return id;
+  }
+
+  class FieldIdPair {
+   public:
+    typedef const Field* Key;
+    typedef intptr_t Value;
+    typedef FieldIdPair Pair;
+
+    FieldIdPair(Key key, Value value) : key_(key), value_(value) { }
+
+    static Key KeyOf(Pair kv) {
+      return kv.key_;
+    }
+
+    static Value ValueOf(Pair kv) {
+      return kv.value_;
+    }
+
+    static intptr_t Hashcode(Key key) {
+      return String::Handle(key->name()).Hash();
+    }
+
+    static inline bool IsKeyEqual(Pair kv, Key key) {
+      return KeyOf(kv)->raw() == key->raw();
+    }
+
+   private:
+    Key key_;
+    Value value_;
+  };
+
+  // Table mapping static field to their id used during optimization pass.
+  DirectChainedHashMap<FieldIdPair> field_ids_;
+  intptr_t max_field_id_;
+};
 
 
 static Definition* GetStoredValue(Instruction* instr) {
@@ -3126,6 +3335,15 @@
     return store_vm_field->value()->definition();
   }
 
+  StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
+  if (store_static_field != NULL) {
+    return store_static_field->value()->definition();
+  }
+
+  if (instr->IsStoreContext() || instr->IsChainContext()) {
+    return instr->InputAt(0)->definition();
+  }
+
   UNREACHABLE();  // Should only be called for supported store instructions.
   return NULL;
 }
@@ -3136,7 +3354,7 @@
 class LoadKeyValueTrait {
  public:
   typedef Definition* Value;
-  typedef Definition* Key;
+  typedef Instruction* Key;
   typedef Definition* Pair;
 
   static Key KeyOf(Pair kv) {
@@ -3171,6 +3389,16 @@
       StoreVMFieldInstr* store_field = key->AsStoreVMField();
       object = store_field->dest()->definition()->ssa_temp_index();
       location = store_field->offset_in_bytes();
+    } else if (key->IsLoadStaticField()) {
+      LoadStaticFieldInstr* load_static_field = key->AsLoadStaticField();
+      object = String::Handle(load_static_field->field().name()).Hash();
+    } else if (key->IsStoreStaticField()) {
+      StoreStaticFieldInstr* store_static_field = key->AsStoreStaticField();
+      object = String::Handle(store_static_field->field().name()).Hash();
+    } else {
+      ASSERT(key->IsStoreContext() ||
+             key->IsCurrentContext() ||
+             key->IsChainContext());
     }
 
     return object * 31 + location;
@@ -3189,6 +3417,20 @@
       return false;
     }
 
+    if (kv->IsLoadStaticField()) {
+      if (key->IsStoreStaticField()) {
+        LoadStaticFieldInstr* load_static_field = kv->AsLoadStaticField();
+        StoreStaticFieldInstr* store_static_field = key->AsStoreStaticField();
+        return load_static_field->field().raw() ==
+            store_static_field->field().raw();
+      }
+      return false;
+    }
+
+    if (kv->IsCurrentContext()) {
+      return key->IsStoreContext() || key->IsChainContext();
+    }
+
     ASSERT(kv->IsLoadField());
     LoadFieldInstr* load_field = kv->AsLoadField();
     if (key->IsStoreVMField()) {
@@ -3206,10 +3448,9 @@
 };
 
 
-static intptr_t NumberLoadExpressions(
+static AliasedSet* NumberLoadExpressions(
     FlowGraph* graph,
-    DirectChainedHashMap<LoadKeyValueTrait>* map,
-    GrowableArray<BitVector*>* kill_by_offs) {
+    DirectChainedHashMap<LoadKeyValueTrait>* map) {
   intptr_t expr_id = 0;
 
   // Loads representing different expression ids will be collected and
@@ -3238,35 +3479,24 @@
     }
   }
 
-  // Build per offset kill sets. Any store interferes only with loads from
-  // the same offset.
+  // Build aliasing sets mapping aliases to loads.
+  AliasedSet* aliased_set = new AliasedSet(expr_id);
   for (intptr_t i = 0; i < loads.length(); i++) {
     Definition* defn = loads[i];
-
-    const intptr_t offset_in_words = ComputeLoadOffsetInWords(defn);
-    while (kill_by_offs->length() <= offset_in_words) {
-      kill_by_offs->Add(NULL);
-    }
-    if ((*kill_by_offs)[offset_in_words] == NULL) {
-      (*kill_by_offs)[offset_in_words] = new BitVector(expr_id);
-    }
-    (*kill_by_offs)[offset_in_words]->Add(defn->expr_id());
+    aliased_set->Add(aliased_set->ComputeAliasForLoad(defn), defn->expr_id());
   }
-
-  return expr_id;
+  return aliased_set;
 }
 
 
 class LoadOptimizer : public ValueObject {
  public:
   LoadOptimizer(FlowGraph* graph,
-                intptr_t max_expr_id,
-                DirectChainedHashMap<LoadKeyValueTrait>* map,
-                const GrowableArray<BitVector*>& kill_by_offset)
+                AliasedSet* aliased_set,
+                DirectChainedHashMap<LoadKeyValueTrait>* map)
       : graph_(graph),
         map_(map),
-        max_expr_id_(max_expr_id),
-        kill_by_offset_(kill_by_offset),
+        aliased_set_(aliased_set),
         in_(graph_->preorder().length()),
         out_(graph_->preorder().length()),
         gen_(graph_->preorder().length()),
@@ -3275,24 +3505,26 @@
         out_values_(graph_->preorder().length()),
         phis_(5),
         worklist_(5),
-        in_worklist_(NULL) {
+        in_worklist_(NULL),
+        forwarded_(false) {
     const intptr_t num_blocks = graph_->preorder().length();
     for (intptr_t i = 0; i < num_blocks; i++) {
-      out_.Add(new BitVector(max_expr_id_));
-      gen_.Add(new BitVector(max_expr_id_));
-      kill_.Add(new BitVector(max_expr_id_));
-      in_.Add(new BitVector(max_expr_id_));
+      out_.Add(new BitVector(aliased_set_->max_expr_id()));
+      gen_.Add(new BitVector(aliased_set_->max_expr_id()));
+      kill_.Add(new BitVector(aliased_set_->max_expr_id()));
+      in_.Add(new BitVector(aliased_set_->max_expr_id()));
 
       exposed_values_.Add(NULL);
       out_values_.Add(NULL);
     }
   }
 
-  void Optimize() {
+  bool Optimize() {
     ComputeInitialSets();
     ComputeOutValues();
     ForwardLoads();
     EmitPhis();
+    return forwarded_;
   }
 
  private:
@@ -3320,16 +3552,16 @@
            instr_it.Advance()) {
         Instruction* instr = instr_it.Current();
 
-        intptr_t offset_in_words = 0;
-        if (IsInterferingStore(instr, &offset_in_words)) {
+        const Alias alias = aliased_set_->ComputeAliasForStore(instr);
+        if (!alias.IsNone()) {
           // Interfering stores kill only loads from the same offset.
-          if ((offset_in_words < kill_by_offset_.length()) &&
-              (kill_by_offset_[offset_in_words] != NULL)) {
-            kill->AddAll(kill_by_offset_[offset_in_words]);
+          if (aliased_set_->Contains(alias)) {
+            BitVector* killed = aliased_set_->Get(alias);
+            kill->AddAll(killed);
             // There is no need to clear out_values when clearing GEN set
             // because only those values that are in the GEN set
             // will ever be used.
-            gen->RemoveAll(kill_by_offset_[offset_in_words]);
+            gen->RemoveAll(killed);
 
             // Only forward stores to normal arrays and float64 arrays
             // to loads because other array stores (intXX/uintXX/float32)
@@ -3338,7 +3570,7 @@
             if (array_store == NULL ||
                 array_store->class_id() == kArrayCid ||
                 array_store->class_id() == kTypedDataFloat64ArrayCid) {
-              Definition* load = map_->Lookup(instr->AsDefinition());
+              Definition* load = map_->Lookup(instr);
               if (load != NULL) {
                 // Store has a corresponding numbered load. Try forwarding
                 // stored value to it.
@@ -3348,7 +3580,7 @@
               }
             }
           }
-          ASSERT(instr->IsDefinition() &&
+          ASSERT(!instr->IsDefinition() ||
                  !IsLoadEliminationCandidate(instr->AsDefinition()));
           continue;
         }
@@ -3383,6 +3615,7 @@
 
           defn->ReplaceUsesWith(replacement);
           instr_it.RemoveCurrentFromGraph();
+          forwarded_ = true;
           continue;
         } else if (!kill->Contains(expr_id)) {
           // This is an exposed load: it is the first representative of a
@@ -3391,7 +3624,8 @@
           if (exposed_values == NULL) {
             static const intptr_t kMaxExposedValuesInitialSize = 5;
             exposed_values = new ZoneGrowableArray<Definition*>(
-                Utils::Minimum(kMaxExposedValuesInitialSize, max_expr_id_));
+                Utils::Minimum(kMaxExposedValuesInitialSize,
+                               aliased_set_->max_expr_id()));
           }
 
           exposed_values->Add(defn);
@@ -3417,7 +3651,7 @@
   // These phis are not inserted at the graph immediately because some of them
   // might become redundant after load forwarding is done.
   void ComputeOutValues() {
-    BitVector* temp = new BitVector(max_expr_id_);
+    BitVector* temp = new BitVector(aliased_set_->max_expr_id());
 
     bool changed = true;
     while (changed) {
@@ -3591,6 +3825,7 @@
           load->ReplaceUsesWith(replacement);
           load->RemoveFromGraph();
           load->SetReplacement(replacement);
+          forwarded_ = true;
         }
       }
     }
@@ -3668,8 +3903,8 @@
 
   ZoneGrowableArray<Definition*>* CreateBlockOutValues() {
     ZoneGrowableArray<Definition*>* out =
-        new ZoneGrowableArray<Definition*>(max_expr_id_);
-    for (intptr_t i = 0; i < max_expr_id_; i++) {
+        new ZoneGrowableArray<Definition*>(aliased_set_->max_expr_id());
+    for (intptr_t i = 0; i < aliased_set_->max_expr_id(); i++) {
       out->Add(NULL);
     }
     return out;
@@ -3677,11 +3912,10 @@
 
   FlowGraph* graph_;
   DirectChainedHashMap<LoadKeyValueTrait>* map_;
-  const intptr_t max_expr_id_;
 
   // Mapping between field offsets in words and expression ids of loads from
   // that offset.
-  const GrowableArray<BitVector*>& kill_by_offset_;
+  AliasedSet* aliased_set_;
 
   // Per block sets of expression ids for loads that are: incoming (available
   // on the entry), outgoing (available on the exit), generated and killed.
@@ -3706,6 +3940,9 @@
   GrowableArray<PhiInstr*> worklist_;
   BitVector* in_worklist_;
 
+  // True if any load was eliminated.
+  bool forwarded_;
+
   DISALLOW_COPY_AND_ASSIGN(LoadOptimizer);
 };
 
@@ -3715,11 +3952,16 @@
   if (FLAG_load_cse) {
     GrowableArray<BitVector*> kill_by_offs(10);
     DirectChainedHashMap<LoadKeyValueTrait> map;
-    const intptr_t max_expr_id =
-        NumberLoadExpressions(graph, &map, &kill_by_offs);
-    if (max_expr_id > 0) {
-      LoadOptimizer load_optimizer(graph, max_expr_id, &map, kill_by_offs);
-      load_optimizer.Optimize();
+    AliasedSet* aliased_set = NumberLoadExpressions(graph, &map);
+    if (!aliased_set->IsEmpty()) {
+      // If any loads were forwarded return true from Optimize to run load
+      // forwarding again. This will allow to forward chains of loads.
+      // This is especially important for context variables as they are built
+      // as loads from loaded context.
+      // TODO(vegorov): renumber newly discovered congruences during the
+      // forwarding to forward chains without running whole pass twice.
+      LoadOptimizer load_optimizer(graph, aliased_set, &map);
+      changed = load_optimizer.Optimize() || changed;
     }
   }
 
@@ -4310,10 +4552,7 @@
       SetValue(instr, object);
       return;
     }
-    if (instr->type_arguments().IsUninstantiatedIdentity() &&
-        !object.IsNull() &&
-        object.IsTypeArguments() &&
-        (TypeArguments::Cast(object).Length() == len)) {
+    if (instr->type_arguments().IsUninstantiatedIdentity()) {
       SetValue(instr, object);
       return;
     }
@@ -4502,6 +4741,27 @@
 }
 
 
+void ConstantPropagator::VisitFloat32x4Constructor(
+    Float32x4ConstructorInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloat32x4Shuffle(Float32x4ShuffleInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
+void ConstantPropagator::VisitFloat32x4Splat(Float32x4SplatInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+
 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) {
   const Object& value = instr->value()->definition()->constant_value();
   if (IsNonConstant(value)) {
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 80c8e7f..4bc64c3 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -132,6 +132,9 @@
   bool InstanceCallNeedsClassCheck(InstanceCallInstr* call) const;
   bool MethodExtractorNeedsClassCheck(InstanceCallInstr* call) const;
 
+  bool InlineFloat32x4Getter(InstanceCallInstr* call,
+                             MethodRecognizer::Kind getter);
+
   void InlineImplicitInstanceGetter(InstanceCallInstr* call);
   void InlineArrayLengthGetter(InstanceCallInstr* call,
                                intptr_t length_offset,
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index ec1a880..f3f77f8 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -734,11 +734,9 @@
     return false;
   }
 
-  if (value_type->IsMoreSpecificThan(dst_type())) {
-    return UpdateType(*value_type);
-  }
-
-  return false;
+  return UpdateType(value_type->IsMoreSpecificThan(dst_type())
+      ? *value_type
+      : CompileType::FromAbstractType(dst_type()));
 }
 
 
@@ -967,6 +965,32 @@
 }
 
 
+CompileType Float32x4ShuffleInstr::ComputeType() const {
+  if ((op_kind() == MethodRecognizer::kFloat32x4ShuffleX) ||
+      (op_kind() == MethodRecognizer::kFloat32x4ShuffleY) ||
+      (op_kind() == MethodRecognizer::kFloat32x4ShuffleZ) ||
+      (op_kind() == MethodRecognizer::kFloat32x4ShuffleW)) {
+    return CompileType::FromCid(kDoubleCid);
+  }
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Float32x4ConstructorInstr::ComputeType() const {
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Float32x4ZeroInstr::ComputeType() const {
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
+CompileType Float32x4SplatInstr::ComputeType() const {
+  return CompileType::FromCid(kFloat32x4Cid);
+}
+
+
 CompileType MathSqrtInstr::ComputeType() const {
   return CompileType::FromCid(kDoubleCid);
 }
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 35d6c62..e15c532 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -187,10 +187,6 @@
     }
     marking_stack_->Push(raw_obj);
 
-    // Update the number of used bytes on this page for fast accounting.
-    HeapPage* page = PageSpace::PageFor(raw_obj);
-    page->AddUsed(raw_obj->Size());
-
     // TODO(iposva): Should we mark the classes early?
     MarkObject(raw_class, NULL);
   }
diff --git a/runtime/vm/gc_sweeper.cc b/runtime/vm/gc_sweeper.cc
index d87ea64..439cdd7 100644
--- a/runtime/vm/gc_sweeper.cc
+++ b/runtime/vm/gc_sweeper.cc
@@ -7,7 +7,6 @@
 #include "vm/freelist.h"
 #include "vm/globals.h"
 #include "vm/heap.h"
-#include "vm/heap_trace.h"
 #include "vm/pages.h"
 
 namespace dart {
@@ -15,47 +14,29 @@
 intptr_t GCSweeper::SweepPage(HeapPage* page, FreeList* freelist) {
   // Keep track of the discovered live object sizes to be able to finish
   // sweeping early. Reset the per page in_use count for the next marking phase.
-  intptr_t in_use_swept = 0;
-  intptr_t in_use = page->used();
-  page->set_used(0);
-
-  // Whole page is empty. Do not enter anything into the freelist.
-  if (in_use == 0) {
-    return 0;
-  }
+  intptr_t in_use = 0;
 
   bool is_executable = (page->type() == HeapPage::kExecutable);
-  uword current = page->object_start();
+  uword start = page->object_start();
   uword end = page->object_end();
+  uword current = start;
 
   while (current < end) {
     intptr_t obj_size;
-    if (in_use_swept == in_use && !HeapTrace::is_enabled()) {
-      // No more marked objects will be found on this page.
-      obj_size = end - current;
-      freelist->Free(current, obj_size);
-      break;
-    }
     RawObject* raw_obj = RawObject::FromAddr(current);
     if (raw_obj->IsMarked()) {
       // Found marked object. Clear the mark bit and update swept bytes.
       raw_obj->ClearMarkBit();
       obj_size = raw_obj->Size();
-      in_use_swept += obj_size;
+      in_use += obj_size;
     } else {
       uword free_end = current + raw_obj->Size();
-      if (HeapTrace::is_enabled()) {
-        heap_->trace()->TraceSweep(current);
-      }
       while (free_end < end) {
         RawObject* next_obj = RawObject::FromAddr(free_end);
         if (next_obj->IsMarked()) {
           // Reached the end of the free block.
           break;
         }
-        if (HeapTrace::is_enabled()) {
-          heap_->trace()->TraceSweep(free_end);
-        }
         // Expand the free block by the size of this object.
         free_end += next_obj->Size();
       }
@@ -63,21 +44,22 @@
       if (is_executable) {
         memset(reinterpret_cast<void*>(current), 0xcc, obj_size);
       }
-      freelist->Free(current, obj_size);
+      if ((current != start) || (free_end != end)) {
+        // Only add to the free list if not covering the whole page.
+        freelist->Free(current, obj_size);
+      }
     }
     current += obj_size;
   }
+  ASSERT(current == end);
 
-  return in_use_swept;
+  return in_use;
 }
 
 
 intptr_t GCSweeper::SweepLargePage(HeapPage* page) {
   RawObject* raw_obj = RawObject::FromAddr(page->object_start());
   if (!raw_obj->IsMarked()) {
-    if (HeapTrace::is_enabled()) {
-      heap_->trace()->TraceSweep(page->object_start());
-    }
     // The large object was not marked. Used size is zero, which also tells the
     // calling code that the large object page can be recycled.
     return 0;
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index a856638..95d7515 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -6,7 +6,6 @@
 #define VM_HANDLES_IMPL_H_
 
 #include "vm/heap.h"
-#include "vm/heap_trace.h"
 #include "vm/visitor.h"
 
 namespace dart {
@@ -116,10 +115,6 @@
   Handles* handles = isolate->current_zone()->handles();
   ASSERT(handles != NULL);
   uword address = handles->AllocateHandleInZone();
-  if (HeapTrace::is_enabled()) {
-    uword zone_addr = reinterpret_cast<uword>(isolate->current_zone());
-    isolate->heap()->trace()->TraceAllocateZoneHandle(address, zone_addr);
-  }
   return address;
 }
 
@@ -153,13 +148,6 @@
   zone_blocks_ = NULL;
 
   // Delete all the scoped handle blocks.
-  // Do not trace if there is no  current isolate. This can happen during
-  // isolate shutdown.
-  if (HeapTrace::is_enabled() && Isolate::Current() != NULL) {
-    Isolate::Current()->heap()->trace()->TraceDeleteScopedHandles();
-  }
-
-
   scoped_blocks_ = first_scoped_block_.next_block();
   DeleteHandleBlocks(scoped_blocks_);
   first_scoped_block_.ReInit();
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 22efc32..fefd788 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -57,9 +57,12 @@
 typename KeyValueTrait::Value
     DirectChainedHashMap<KeyValueTrait>::
         Lookup(typename KeyValueTrait::Key key) const {
+  const typename KeyValueTrait::Value kNoValue =
+      static_cast<typename KeyValueTrait::Value>(0);
+
   uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key));
   uword pos = Bound(hash);
-  if (KeyValueTrait::ValueOf(array_[pos].kv) != NULL) {
+  if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
     if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
       return KeyValueTrait::ValueOf(array_[pos].kv);
     }
@@ -72,7 +75,7 @@
       next = lists_[next].next;
     }
   }
-  return NULL;
+  return kNoValue;
 }
 
 
@@ -95,6 +98,9 @@
 
 template <typename KeyValueTrait>
 void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
+  const typename KeyValueTrait::Value kNoValue =
+      static_cast<typename KeyValueTrait::Value>(0);
+
   ASSERT(new_size > count_);
   // Hashing the values into the new array has no more collisions than in the
   // old hash map, so we can use the existing lists_ array, if we are careful.
@@ -119,7 +125,7 @@
   if (old_array != NULL) {
     // Iterate over all the elements in lists, rehashing them.
     for (intptr_t i = 0; i < old_size; ++i) {
-      if (KeyValueTrait::ValueOf(old_array[i].kv) != NULL) {
+      if (KeyValueTrait::ValueOf(old_array[i].kv) != kNoValue) {
         intptr_t current = old_array[i].next;
         while (current != kNil) {
           Insert(lists_[current].kv);
@@ -166,14 +172,17 @@
 template <typename KeyValueTrait>
 void DirectChainedHashMap<KeyValueTrait>::
     Insert(typename KeyValueTrait::Pair kv) {
-  ASSERT(KeyValueTrait::ValueOf(kv) != NULL);
+  const typename KeyValueTrait::Value kNoValue =
+      static_cast<typename KeyValueTrait::Value>(0);
+
+  ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue);
   // Resizing when half of the hashtable is filled up.
   if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
   ASSERT(count_ < array_size_);
   count_++;
   uword pos = Bound(
       static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv))));
-  if (KeyValueTrait::ValueOf(array_[pos].kv) == NULL) {
+  if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) {
     array_[pos].kv = kv;
     array_[pos].next = kNil;
   } else {
@@ -186,7 +195,7 @@
     lists_[new_element_pos].kv = kv;
     lists_[new_element_pos].next = array_[pos].next;
     ASSERT(array_[pos].next == kNil ||
-           KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != NULL);
+           KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != kNoValue);
     array_[pos].next = new_element_pos;
   }
 }
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 0809917..d36c847 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -8,7 +8,6 @@
 #include "platform/utils.h"
 #include "vm/flags.h"
 #include "vm/heap_profiler.h"
-#include "vm/heap_trace.h"
 #include "vm/isolate.h"
 #include "vm/object.h"
 #include "vm/object_set.h"
@@ -41,7 +40,6 @@
                              kNewObjectAlignmentOffset);
   old_space_ = new PageSpace(this, (FLAG_old_gen_heap_size * MB));
   stats_.num_ = 0;
-  heap_trace_ = new HeapTrace;
 }
 
 
@@ -61,9 +59,6 @@
       return AllocateOld(size, HeapPage::kData);
     }
   }
-  if (HeapTrace::is_enabled()) {
-    heap_trace_->TraceAllocation(addr, size);
-  }
   return addr;
 }
 
@@ -80,9 +75,6 @@
       return 0;
     }
   }
-  if (HeapTrace::is_enabled()) {
-    heap_trace_->TraceAllocation(addr, size);
-  }
   return addr;
 }
 
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index ab0f5db..b85d262 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -15,7 +15,6 @@
 namespace dart {
 
 // Forward declarations.
-class HeapTrace;
 class Isolate;
 class ObjectPointerVisitor;
 class ObjectSet;
@@ -59,7 +58,7 @@
     switch (space) {
       case kNew:
         // Do not attempt to allocate very large objects in new space.
-        if (!PageSpace::IsPageAllocatableSize(size)) {
+        if (!IsAllocatableInNewSpace(size)) {
           return AllocateOld(size, HeapPage::kData);
         }
         return AllocateNew(size);
@@ -151,10 +150,6 @@
   // Verify that all pointers in the heap point to the heap.
   bool Verify() const;
 
-  // Accessor function to get the HeapTrace used for tracing.  There
-  // should only ever be one of these per isolate
-  HeapTrace* trace() const { return heap_trace_; }
-
   // Print heap sizes.
   void PrintSizes() const;
 
@@ -197,6 +192,10 @@
 
   bool gc_in_progress() const { return gc_in_progress_; }
 
+  static bool IsAllocatableInNewSpace(intptr_t size) {
+    return size <= kNewAllocatableSize;
+  }
+
  private:
   class GCStats : public ValueObject {
    public:
@@ -229,6 +228,8 @@
     DISALLOW_COPY_AND_ASSIGN(GCStats);
   };
 
+  static const intptr_t kNewAllocatableSize = 256 * KB;
+
   Heap();
 
   uword AllocateNew(intptr_t size);
@@ -246,9 +247,6 @@
   // GC stats collection.
   GCStats stats_;
 
-  // The active heap trace.
-  HeapTrace* heap_trace_;
-
   // This heap is in read-only mode: No allocation is allowed.
   bool read_only_;
 
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index 0a487e5..54d0cd7 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -9,8 +9,6 @@
 
 namespace dart {
 
-// Only ia32 and x64 can run execution tests.
-#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
 TEST_CASE(OldGC) {
   const char* kScriptChars =
   "main() {\n"
@@ -48,6 +46,4 @@
   Dart_ExitScope();
   heap->CollectGarbage(Heap::kOld);
 }
-
-#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64).
 }
diff --git a/runtime/vm/heap_trace.cc b/runtime/vm/heap_trace.cc
deleted file mode 100644
index 56282c2..0000000
--- a/runtime/vm/heap_trace.cc
+++ /dev/null
@@ -1,488 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/heap_trace.h"
-
-#include "include/dart_api.h"
-#include "vm/dart_api_state.h"
-#include "vm/debugger.h"
-#include "vm/isolate.h"
-#include "vm/object.h"
-#include "vm/object_set.h"
-#include "vm/object_store.h"
-#include "vm/os.h"
-#include "vm/stack_frame.h"
-#include "vm/unicode.h"
-
-namespace dart {
-
-DEFINE_FLAG(bool, heap_trace, false, "Enable heap tracing.");
-
-Dart_FileOpenCallback HeapTrace::open_callback_ = NULL;
-Dart_FileWriteCallback HeapTrace::write_callback_ = NULL;
-Dart_FileCloseCallback HeapTrace::close_callback_ = NULL;
-bool HeapTrace::is_enabled_ = false;
-
-class HeapTraceVisitor : public ObjectPointerVisitor {
- public:
-  HeapTraceVisitor(Isolate* isolate,
-                   HeapTrace* heap_trace,
-                   ObjectSet* object_set)
-      : ObjectPointerVisitor(isolate),
-        heap_trace_(heap_trace),
-        vm_isolate_(Dart::vm_isolate()),
-        object_set_(object_set) {
-  }
-
-  void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; current++) {
-      RawObject* raw_obj = *current;
-
-      // We only care about objects in the heap
-      // Also, since this visitor will frequently be encountering redudant
-      // roots, we use an object_set to skip the duplicates.
-      if (raw_obj->IsHeapObject() &&
-          raw_obj != reinterpret_cast<RawObject*>(0x1) &&
-          raw_obj != reinterpret_cast<RawObject*>(0xabababab) &&
-          !object_set_->Contains(raw_obj) &&
-          !vm_isolate_->heap()->Contains(RawObject::ToAddr(raw_obj))) {
-        object_set_->Add(raw_obj);
-        uword addr = RawObject::ToAddr(raw_obj);
-        heap_trace_->TraceSingleRoot(addr);
-      }
-    }
-  }
-
- private:
-  HeapTrace* heap_trace_;
-  Isolate* vm_isolate_;
-  // TODO(cshapiro): replace with a sparse data structure.
-  ObjectSet* object_set_;
-  DISALLOW_COPY_AND_ASSIGN(HeapTraceVisitor);
-};
-
-
-class HeapTraceScopedHandleVisitor : public ObjectPointerVisitor {
- public:
-  HeapTraceScopedHandleVisitor(Isolate* isolate, HeapTrace* heap_trace)
-       : ObjectPointerVisitor(isolate), heap_trace_(heap_trace) {
-  }
-
-  void VisitPointers(RawObject**  first, RawObject** last) {
-    for (RawObject** current = first; current <= last; current++) {
-      RawObject* raw_obj = *current;
-      Heap* heap = isolate()->heap();
-
-      // We only care about objects in the heap
-      if (raw_obj->IsHeapObject() &&
-          raw_obj != reinterpret_cast<RawObject*>(0x1) &&
-          raw_obj != reinterpret_cast<RawObject*>(0xabababab) &&
-          heap->Contains(RawObject::ToAddr(raw_obj))) {
-        uword addr = RawObject::ToAddr(raw_obj);
-        heap_trace_->TraceScopedHandle(addr);
-     }
-    }
-  }
-
- private:
-  HeapTrace* heap_trace_;
-  DISALLOW_COPY_AND_ASSIGN(HeapTraceScopedHandleVisitor);
-};
-
-
-class HeapTraceObjectStoreVisitor : public ObjectPointerVisitor {
- public:
-  HeapTraceObjectStoreVisitor(Isolate* isolate, HeapTrace* heap_trace)
-        : ObjectPointerVisitor(isolate), heap_trace_(heap_trace) {
-  }
-
-  void VisitPointers(RawObject** first, RawObject** last) {
-    for (RawObject** current = first; current <= last; current++) {
-      RawObject* raw_obj = *current;
-
-      // We only care about obects in the heap.
-      if (raw_obj->IsHeapObject() &&
-          raw_obj != reinterpret_cast<RawObject*>(0x1) &&
-          raw_obj != reinterpret_cast<RawObject*>(0xabababab)) {
-        uword addr = RawObject::ToAddr(raw_obj);
-        heap_trace_->TraceObjectStorePointer(addr);
-      }
-    }
-  }
-
- private:
-  HeapTrace* heap_trace_;
-  DISALLOW_COPY_AND_ASSIGN(HeapTraceObjectStoreVisitor);
-};
-
-
-class HeapTraceInitialHeapVisitor : public ObjectVisitor {
- public:
-  HeapTraceInitialHeapVisitor(Isolate* isolate, HeapTrace* heap_trace)
-    : ObjectVisitor(isolate), heap_trace_(heap_trace) {}
-
-  void VisitObject(RawObject* raw_obj) {
-    heap_trace_->TraceSnapshotAlloc(raw_obj, raw_obj->Size());
-  }
-
- private:
-  HeapTrace* heap_trace_;
-  DISALLOW_COPY_AND_ASSIGN(HeapTraceInitialHeapVisitor);
-};
-
-
-HeapTrace::HeapTrace() : isolate_initialized_(false), output_stream_(NULL) {
-}
-
-
-HeapTrace::~HeapTrace() {
-  if (isolate_initialized_) {
-    (*close_callback_)(output_stream_);
-  }
-}
-
-
-void HeapTrace::InitOnce(Dart_FileOpenCallback open_callback,
-                         Dart_FileWriteCallback write_callback,
-                         Dart_FileCloseCallback close_callback) {
-  ASSERT(open_callback != NULL);
-  ASSERT(write_callback != NULL);
-  ASSERT(close_callback != NULL);
-  HeapTrace::open_callback_ = open_callback;
-  HeapTrace::write_callback_ = write_callback;
-  HeapTrace::close_callback_ = close_callback;
-  HeapTrace::is_enabled_ = true;
-}
-
-
-ObjectSet* HeapTrace::CreateEmptyObjectSet() const {
-  Isolate* isolate = Isolate::Current();
-  uword start, end;
-  isolate->heap()->StartEndAddress(&start, &end);
-
-  Isolate* vm_isolate = Dart::vm_isolate();
-  uword vm_start, vm_end;
-  vm_isolate->heap()->StartEndAddress(&vm_start, &vm_end);
-
-  ObjectSet* allocated_set = new ObjectSet(Utils::Minimum(start, vm_start),
-                                           Utils::Maximum(end, vm_end));
-
-  return allocated_set;
-}
-
-
-void HeapTrace::ResizeObjectSet() {
-  Isolate* isolate = Isolate::Current();
-  uword start, end;
-  isolate->heap()->StartEndAddress(&start, &end);
-  Isolate* vm_isolate = Dart::vm_isolate();
-  uword vm_start, vm_end;
-  vm_isolate->heap()->StartEndAddress(&vm_start, &vm_end);
-  object_set_.Resize(Utils::Minimum(start, vm_start),
-                     Utils::Maximum(end, vm_end));
-}
-
-
-void HeapTrace::Init(Isolate* isolate) {
-  // Do not trace the VM isolate
-  if (isolate == Dart::vm_isolate()) {
-    return;
-  }
-  ASSERT(isolate_initialized_ == false);
-  const char* format = "%s.htrace";
-  intptr_t len = OS::SNPrint(NULL, 0, format, isolate->name());
-  char* filename = new char[len + 1];
-  OS::SNPrint(filename, len + 1, format, isolate->name());
-  output_stream_ = (*open_callback_)(filename);
-  ASSERT(output_stream_ != NULL);
-  delete[] filename;
-  isolate_initialized_ = true;
-
-  HeapTraceObjectStoreVisitor object_store_visitor(isolate, this);
-  isolate->object_store()->VisitObjectPointers(&object_store_visitor);
-
-  // Visit any objects that may have been allocated during startup,
-  // before we started tracing.
-  HeapTraceInitialHeapVisitor heap_visitor(isolate, this);
-  isolate->heap()->IterateObjects(&heap_visitor);
-  TraceRoots(isolate);
-}
-
-
-// Allocation Record - 'A' (0x41)
-//
-// Format:
-// 'A'
-//  uword - address of allocated object
-//  uword - size of allocated object
-void HeapTrace::TraceAllocation(uword addr, intptr_t size) {
-  if (isolate_initialized_) {
-    {
-      AllocationRecord rec(this);
-      rec.Write(addr);
-      rec.Write(size);
-    }
-    TraceRoots(Isolate::Current());
-  }
-}
-
-
-// Snapshot Allocation Record - 'B' (0x41)
-//
-// Format:
-// 'B'
-//  uword - address of allocated object
-//  uword - size of allocated object
-void HeapTrace::TraceSnapshotAlloc(RawObject* obj, intptr_t size) {
-  if (isolate_initialized_) {
-    SnapshotAllocationRecord rec(this);
-    rec.Write(RawObject::ToAddr(obj));
-    rec.Write(static_cast<uword>(size));
-  }
-}
-
-
-// Allocate Zone Handle Record - 'Z' (0x5a)
-//
-// Format:
-//  'Z'
-//  uword - handle address (where the handle is pointing)
-//  uword - zone address (address of the zone the handle is in)
-void HeapTrace::TraceAllocateZoneHandle(uword handle, uword zone_addr) {
-  if (isolate_initialized_) {
-    AllocZoneHandleRecord rec(this);
-    rec.Write(handle);
-    rec.Write(zone_addr);
-  }
-}
-
-
-// Delete Zone Record - 'z' (0x7a)
-//
-// Format:
-//  'z'
-//  uword - zone address (all the handles in that zone are now gone)
-void HeapTrace::TraceDeleteZone(Zone* zone) {
-  if (isolate_initialized_) {
-    DeleteZoneRecord rec(this);
-    rec.Write(reinterpret_cast<uword>(zone));
-  }
-}
-
-
-// Delete Scoped Hanldes Record - 's' (0x73)
-//
-// Format:
-//  's'
-void HeapTrace::TraceDeleteScopedHandles() {
-  if (isolate_initialized_) {
-    DeleteScopedHandlesRecord rec(this);
-  }
-}
-
-
-//  Copy Record - 'C' (0x43)
-//
-//  Format:
-//   'C'
-//   uword - old address
-//   uword - new address
-void HeapTrace::TraceCopy(uword from_addr, uword to_addr) {
-    if (isolate_initialized_) {
-      CopyRecord rec(this);
-      rec.Write(from_addr);
-      rec.Write(to_addr);
-  }
-}
-
-
-// Object Store Recorda - 'O'(0x4f)
-//
-// Format:
-//  'O'
-//  uword - address
-void HeapTrace::TraceObjectStorePointer(uword addr) {
-  if (isolate_initialized_) {
-    ObjectStoreRecord rec(this);
-    rec.Write(addr);
-  }
-}
-
-
-// Promotion Records - 'P' (0x50)
-//
-// Format:
-//  'P'
-//  uword - old address
-//  uword - new address
-void HeapTrace::TracePromotion(uword old_addr, uword promoted_addr) {
-  if (isolate_initialized_) {
-    PromotionRecord rec(this);
-    rec.Write(old_addr);
-    rec.Write(promoted_addr);
-  }
-}
-
-
-// Death Range Record - 'L' (0x4c)
-//
-// Format:
-//  'L'
-//  uword - inclusive start address of the space being left
-//  uword - exclusive end address of the space being left
-void HeapTrace::TraceDeathRange(uword inclusive_start, uword exclusive_end) {
-  if (isolate_initialized_) {
-    DeathRangeRecord rec(this);
-    rec.Write(inclusive_start);
-    rec.Write(exclusive_end);
-  }
-}
-
-
-// Register Class Record - 'K' (0x4b)
-//
-// Format:
-//  'K'
-//  uword - address ( the address of the class)
-void HeapTrace::TraceRegisterClass(const Class& cls) {
-  if (isolate_initialized_) {
-    RegisterClassRecord rec(this);
-    rec.Write(RawObject::ToAddr(cls.raw()));
-  }
-}
-
-
-// Scoped Handle Record - 'H' (0x48)
-//
-// Format:
-//  'H'
-//  uword - adress of the scoped handle (where it is pointing)
-void HeapTrace::TraceScopedHandle(uword handle) {
-  if (isolate_initialized_) {
-    AllocScopedHandleRecord rec(this);
-    rec.Write(handle);
-  }
-}
-
-
-// Root Record - 'R' (0x52)
-//
-// Format:
-// 'R'
-// uword - address
-void HeapTrace::TraceSingleRoot(uword root_addr) {
-  if (isolate_initialized_) {
-    RootRecord rec(this);
-    rec.Write(root_addr);
-  }
-}
-
-
-// Sweep Record - 'S'
-//
-// Format:
-// 'S'
-// uword - address
-void HeapTrace::TraceSweep(uword sweept_addr) {
-  if (isolate_initialized_) {
-    SweepRecord rec(this);
-    rec.Write(sweept_addr);
-  }
-}
-
-
-// Does not output any records directly,
-// but does call TraceSingleRoot
-void HeapTrace::TraceRoots(Isolate* isolate) {
-  if (isolate_initialized_) {
-    ResizeObjectSet();
-    HeapTraceVisitor visitor(isolate, this, &object_set_);
-    HeapTraceScopedHandleVisitor handle_visitor(isolate, this);
-
-    bool visit_prologue_weak_handles = true;
-    bool validate_frames = false;
-
-    // Visit objects in per isolate stubs.
-    StubCode::VisitObjectPointers(&visitor);
-
-    // stack
-    StackFrameIterator frames_iterator(validate_frames);
-    StackFrame* frame = frames_iterator.NextFrame();
-    while (frame != NULL) {
-      frame->VisitObjectPointers(&visitor);
-      frame = frames_iterator.NextFrame();
-    }
-
-    if (isolate->api_state() != NULL) {
-      isolate->api_state()->VisitObjectPointers(&visitor,
-                                                visit_prologue_weak_handles);
-    }
-
-    // Visit the top context which is stored in the isolate.
-    RawContext* top_context = isolate->top_context();
-    visitor.VisitPointer(reinterpret_cast<RawObject**>(&top_context));
-
-    // Visit the currently active IC data array.
-    RawArray* ic_data_array = isolate->ic_data_array();
-    visitor.VisitPointer(reinterpret_cast<RawObject**>(&ic_data_array));
-
-    // Visit objects in the debugger.
-    isolate->debugger()->VisitObjectPointers(&visitor);
-
-    isolate->current_zone()->handles()->
-        VisitUnvisitedScopedHandles(&handle_visitor);
-
-    object_set_.FastClear();
-  }
-}
-
-
-// Store Record - 'U' (0x55)
-//
-// Format:
-//  'U'
-//  uword - originating object address (where a pointer is being stored)
-//  uword - byte offset into origin where the pointer is being stored
-//  uword - value of the pointer being stored
-void HeapTrace::TraceStoreIntoObject(uword object,
-                                     uword field_addr,
-                                     uword value) {
-  if (isolate_initialized_) {
-    // We don't care about pointers into the VM_Islate heap, so skip them.
-    // There should not be any pointers /out/ of the VM isolate; so we
-    // do not check object.
-    if (Isolate::Current()->heap()->Contains(value)) {
-      StoreRecord rec(this);
-      uword slot_offset =  field_addr - object;
-
-      rec.Write(object);
-      rec.Write(slot_offset);
-      rec.Write(value);
-    }
-  }
-}
-
-
-// Mark Sweep Start Record - '{' (0x7b)
-//
-// Format:
-//  '{'
-void HeapTrace::TraceMarkSweepStart() {
-  if (isolate_initialized_) {
-    MarkSweepStartRecord rec(this);
-  }
-}
-
-
-// Mark Sweep Finish Record - '}' (0x7d)
-//
-// Format:
-//  '}'
-void HeapTrace::TraceMarkSweepFinish() {
-  if (isolate_initialized_) {
-    MarkSweepFinishRecord rec(this);
-  }
-}
-
-}  // namespace dart
diff --git a/runtime/vm/heap_trace.h b/runtime/vm/heap_trace.h
deleted file mode 100644
index 983f7df..0000000
--- a/runtime/vm/heap_trace.h
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_HEAP_TRACE_H_
-#define VM_HEAP_TRACE_H_
-
-#include "include/dart_api.h"
-#include "vm/globals.h"
-#include "vm/object_set.h"
-
-namespace dart {
-
-// Forward declarations.
-class HeapTraceVisitor;
-class Isolate;
-class RawClass;
-class RawObject;
-class RawString;
-class BaseZone;
-
-class HeapTrace {
- public:
-  enum RecordSize {
-    kRootSize = 5,
-    kAllocSize = 9,
-    kSnapshotAllocSize = 9,
-    kCopySize = 9,
-    kStoreSize = 13,
-    kSweepSize = 5,
-    kDeathRangeSize = 9,
-    kPromotionSize = 9,
-    kAllocZoneHandleSize = 9,
-    kDeleteZoneSize = 5,
-    kRegisterClassSize = 5,
-    kAllocScopedHandleSize = 5,
-    kDeleteScopedHandlesSize = 1,
-    kMarkSweepStartSize = 1,
-    kMarkSweepFinishSize = 1,
-    kObjectStoreSize = 5
-  };
-
-  enum RecordType {
-    kRootType = 'R',
-    kAllocType = 'A',
-    kSnapshotAllocType = 'B',
-    kCopyType = 'C',
-    kStoreType = 'U',
-    kSweepType = 'S',
-    kDeathRangeType = 'L',
-    kPromotionType = 'P',
-    kAllocZoneHandleType = 'Z',
-    kDeleteZoneType = 'z',
-    kRegisterClassType = 'K',
-    kAllocScopedHandleType = 'H',
-    kDeleteScopedHandlesType = 'h',
-    kMarkSweepStartType = '{',
-    kMarkSweepFinishType = '}',
-    kObjectStoreType = 'O'
-  };
-
-  template <RecordType T, RecordSize N>
-  class Record {
-   public:
-    explicit Record(HeapTrace* trace): cursor_(0), trace_(trace) {
-      ASSERT(N >= 1);
-      buffer_[0] = T;
-      ++cursor_;
-    }
-    ~Record() {
-      (*trace_->write_callback_)(Buffer(), Length(), trace_->output_stream_);
-    }
-
-    void Write(uword word) {
-      ASSERT(cursor_ + sizeof(word) <= N);
-      memmove(&buffer_[cursor_], &word, sizeof(word));
-      cursor_ += sizeof(word);
-    }
-
-    intptr_t Length() const { return cursor_; }
-
-    const uint8_t* Buffer() const {
-      ASSERT(cursor_ == N);
-      return buffer_;
-    }
-
-   private:
-    uint8_t buffer_[N];
-    intptr_t cursor_;
-    HeapTrace* trace_;
-    DISALLOW_COPY_AND_ASSIGN(Record);
-  };
-
-  typedef Record<kRootType, kRootSize> RootRecord;
-  typedef Record<kAllocType, kAllocSize> AllocationRecord;
-  typedef Record<kSnapshotAllocType, kSnapshotAllocSize>
-  SnapshotAllocationRecord;
-  typedef Record<kCopyType, kCopySize> CopyRecord;
-  typedef Record<kStoreType, kStoreSize> StoreRecord;
-  typedef Record<kSweepType, kSweepSize> SweepRecord;
-  typedef Record<kDeathRangeType, kDeathRangeSize> DeathRangeRecord;
-  typedef Record<kPromotionType, kPromotionSize> PromotionRecord;
-  typedef Record<kAllocZoneHandleType, kAllocZoneHandleSize>
-  AllocZoneHandleRecord;
-  typedef Record<kDeleteZoneType, kDeleteZoneSize>
-  DeleteZoneRecord;
-  typedef Record<kRegisterClassType, kRegisterClassSize> RegisterClassRecord;
-  typedef Record<kAllocScopedHandleType, kAllocScopedHandleSize>
-  AllocScopedHandleRecord;
-  typedef Record<kDeleteScopedHandlesType, kDeleteScopedHandlesSize>
-  DeleteScopedHandlesRecord;
-  typedef Record<kMarkSweepStartType, kMarkSweepStartSize> MarkSweepStartRecord;
-  typedef Record<kMarkSweepFinishType, kMarkSweepFinishSize>
-  MarkSweepFinishRecord;
-  typedef Record<kObjectStoreType, kObjectStoreSize> ObjectStoreRecord;
-
-  HeapTrace();
-  ~HeapTrace();
-
-  // Called by the isolate just before EnableGrowthControl.  Indicates
-  // the Isolate is initialized and enables tracing.
-  void Init(Isolate* isolate);
-
-  // Called when an object is allocated in the heap.
-  void TraceAllocation(uword addr, intptr_t size);
-
-  // Invoked after the snapshot is loaded at Isolate startup time.
-  void TraceSnapshotAlloc(RawObject* obj, intptr_t size);
-
-  // Rename to something like TraceAllocateZoneHandle (or whatever)
-  void TraceAllocateZoneHandle(uword handle, uword zone_addr);
-
-  // Invoked when a Zone block is deleted.
-  void TraceDeleteZone(Zone* zone);
-
-  // Invoked whenever the scoped handles are delelted.
-  void TraceDeleteScopedHandles();
-
-  // Invoked when objects are coped from the from space to the to space
-  // by the scavenger.
-  void TraceCopy(uword from_addr, uword to_addr);
-
-  // Invoked on each pointer in the object store.
-  void TraceObjectStorePointer(uword addr);
-
-  // Invoked when an object is promoted from the new space to the old space.
-  void TracePromotion(uword old_addr, uword promoted_addr);
-
-  // Invoked after a scavenge with the addressed range of from-space
-  void TraceDeathRange(uword inclusive_start, uword exclusive_end);
-
-  // Invoked whenever a class is registered in the class table.
-  void TraceRegisterClass(const Class& cls);
-
-  // Invoked when an address is swept.
-  void TraceSweep(uword sweept_addr);
-
-  // Invoked when storing value into origin, and value is an object.
-  void TraceStoreIntoObject(uword origin_object_addr,
-                            uword slot_addr,
-                            uword value);
-
-  // Invoked when starting a mark-sweep collection on old space
-  void TraceMarkSweepStart();
-
-  // Invoked after finishing a mark sweep collection on old space.
-  void TraceMarkSweepFinish();
-
-  // Initialize tracing globablly across the VM. Invidual isolates
-  // will still have to initialized themselves when they are started.
-  static void InitOnce(Dart_FileOpenCallback open_callback,
-                       Dart_FileWriteCallback write_callback,
-                       Dart_FileCloseCallback close_callback);
-
-  // Returns true if tracign is enabled for the VM.
-  static bool is_enabled() { return is_enabled_; }
-
- private:
-  ObjectSet* CreateEmptyObjectSet() const;
-  void ResizeObjectSet();
-
-  void TraceScopedHandle(uword handle);
-
-  // A helper for PutRoots, called by HeapTraceVisitor.
-  void TraceSingleRoot(uword root);
-
-  // Invoked while tracing an allocation.
-  void TraceRoots(Isolate* isolate);
-
-  // Is the isolate we are tracing initialized?
-  bool isolate_initialized_;
-
-  void* output_stream_;
-
-  ObjectSet object_set_;
-
-  static Dart_FileOpenCallback open_callback_;
-  static Dart_FileWriteCallback write_callback_;
-  static Dart_FileCloseCallback close_callback_;
-
-  static bool is_enabled_;
-
-  friend class HeapTraceVisitor;
-  friend class HeapTraceScopedHandleVisitor;
-  friend class HeapTraceObjectStoreVisitor;
-  friend class HeapTraceDebugObjectVisitor;
-
-  DISALLOW_COPY_AND_ASSIGN(HeapTrace);
-};
-
-}  // namespace dart
-
-#endif  // VM_HEAP_TRACE_H_
diff --git a/runtime/vm/heap_trace_test.cc b/runtime/vm/heap_trace_test.cc
deleted file mode 100644
index eb0ca6b..0000000
--- a/runtime/vm/heap_trace_test.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <iostream>
-#include <sstream>
-#include <string>
-#include "vm/dart_api_impl.h"
-#include "vm/growable_array.h"
-#include "vm/heap.h"
-#include "vm/heap_trace.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-// only ia32 can run heap trace tests.
-#if defined(TARGET_ARCH_IA32)
-static std::stringstream* global_stream;
-
-static void* OpenTraceFile(const char* name) {
-  ASSERT(global_stream == NULL);
-  global_stream = new std::stringstream;
-  return reinterpret_cast<void*>(global_stream);
-}
-
-
-static void WriteToTraceFile(const void* data, intptr_t length, void* stream) {
-  ASSERT(stream == global_stream);
-  std::stringstream* sstream = reinterpret_cast<std::stringstream*>(stream);
-  sstream->write(reinterpret_cast<const char*>(data), length);
-}
-
-
-static void CloseTraceFile(void *stream) {
-  ASSERT(stream == global_stream);
-  global_stream = NULL;
-  delete reinterpret_cast<std::stringstream*>(stream);
-}
-
-
-bool DoesAllocationRecordExist(uword addr, const std::string& trace_string) {
-  const char* raw_trace = trace_string.c_str();
-  for (size_t i = 0; i < trace_string.length(); ++i) {
-    if ((raw_trace[i] == 'A') && (i + 4 < trace_string.length())) {
-      const uword candidate_address =
-          *(reinterpret_cast<const uword*>(raw_trace + i + 1));
-      if (candidate_address == addr) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-
-bool DoesSweepRecordExist(uword addr, const std::string& trace_string) {
-  const char* raw_trace = trace_string.c_str();
-  for (size_t i = 0; i < trace_string.length(); ++i) {
-    if ((raw_trace[i] == 'S') && (i + 4 < trace_string.length())) {
-      const uword candidate_address =
-          *(reinterpret_cast<const uword*>(raw_trace + i + 1));
-      if (candidate_address == addr) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-
-TEST_CASE(GCTraceAllocate) {
-  HeapTrace::InitOnce(OpenTraceFile,
-                      WriteToTraceFile,
-                      CloseTraceFile);
-
-  Isolate* isolate = Isolate::Current();
-  isolate->heap()->trace()->Init(isolate);
-
-  const int kArrayLen = 5;
-  RawArray* raw_arr = Array::New(kArrayLen);
-  uword addr = RawObject::ToAddr(raw_arr);
-
-  ASSERT(DoesAllocationRecordExist(addr, global_stream->str()));
-}
-
-
-TEST_CASE(GCTraceSweep) {
-  HeapTrace::InitOnce(OpenTraceFile,
-                      WriteToTraceFile,
-                      CloseTraceFile);
-
-  Isolate* isolate = Isolate::Current();
-  isolate->heap()->trace()->Init(isolate);
-
-  const int kArrayLen = 5;
-  RawArray* raw_arr = Array::New(kArrayLen, Heap::kOld);
-  uword addr = RawObject::ToAddr(raw_arr);
-
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  DoesSweepRecordExist(addr, global_stream->str());
-}
-#endif
-
-}  // namespace dart
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index ce75a13..c0dffcc 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -603,6 +603,37 @@
 }
 
 
+void Float32x4ShuffleInstr::PrintOperandsTo(BufferFormatter* f) const {
+  // TODO(johnmccutchan): Add proper string enumeration of shuffle.
+  f->Print("SHUFFLE ");
+  value()->PrintTo(f);
+}
+
+
+void Float32x4ZeroInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("ZERO ");
+}
+
+
+void Float32x4SplatInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("SPLAT ");
+  value()->PrintTo(f);
+}
+
+
+void Float32x4ConstructorInstr::PrintOperandsTo(BufferFormatter* f) const {
+  f->Print("Float32x4(");
+  value0()->PrintTo(f);
+  f->Print(", ");
+  value1()->PrintTo(f);
+  f->Print(", ");
+  value2()->PrintTo(f);
+  f->Print(", ");
+  value3()->PrintTo(f);
+  f->Print(")");
+}
+
+
 void BinaryMintOpInstr::PrintOperandsTo(BufferFormatter* f) const {
   f->Print("%s, ", Token::Str(op_kind()));
   left()->PrintTo(f);
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index 69e99c2..41648b1 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -73,7 +73,7 @@
   instr = Instr::At(reinterpret_cast<uword>(&i));
   ASSERT(instr->OpcodeField() == LUI);
   ASSERT(instr->RtField() == *reg);
-  imm |= instr->UImmField();
+  imm |= (instr->UImmField() << 16);
   *value = imm;
   return end;
 }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 55de520..ea389c7 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1166,6 +1166,7 @@
     case kTypedDataUint64ArrayCid:
     case kTypedDataFloat32ArrayCid:
     case kTypedDataFloat64ArrayCid:
+    case kTypedDataFloat32x4ArrayCid:
       return true;
     default:
       return false;
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 05b0a21..c8110bb 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -37,25 +37,25 @@
 #define RECOGNIZED_LIST(V)                                                     \
   V(_ObjectArray, get:length, ObjectArrayLength, 405297088)                    \
   V(_ImmutableArray, get:length, ImmutableArrayLength, 433698233)              \
-  V(_TypedList, get:length, TypedDataLength, 231908172)                        \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 380843687)                     \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 380843687)                   \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 380843687)                   \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 380843687)                 \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 380843687)                   \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 380843687)                 \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 979971573)               \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 979971573)               \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 690339584)           \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 287047804)                     \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 287047804)                   \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 287047804)                   \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 287047804)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 287047804)                   \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 287047804)                 \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1032541114)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1032541114)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1016704782)          \
+  V(_TypedList, get:length, TypedDataLength, 1004567191)                       \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 728842615)                     \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 728842615)                   \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 728842615)                   \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 728842615)                 \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 728842615)                   \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 728842615)                 \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1067360925)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1067360925)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 279982060)           \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 427754869)                     \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 427754869)                   \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 427754869)                   \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 427754869)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 427754869)                   \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 427754869)                 \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 637235443)               \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 637235443)               \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 780994886)           \
   V(_GrowableObjectArray, get:length, GrowableArrayLength, 725548050)          \
   V(_GrowableObjectArray, get:_capacity, GrowableArrayCapacity, 725548050)     \
   V(_StringBase, get:length, StringBaseLength, 320803993)                      \
@@ -71,6 +71,17 @@
   V(_Double, pow, DoublePow, 631903778)                                        \
   V(_Double, _modulo, DoubleMod, 437099337)                                    \
   V(::, sqrt, MathSqrt, 1662640002)                                            \
+  V(Float32x4, Float32x4., Float32x4Constructor, 1327837070)                   \
+  V(Float32x4, Float32x4.zero, Float32x4Zero, 927169529)                       \
+  V(Float32x4, Float32x4.splat, Float32x4Splat, 1778587275)                    \
+  V(_Float32x4, get:xxxx, Float32x4ShuffleXXXX, 42621627)                      \
+  V(_Float32x4, get:yyyy, Float32x4ShuffleYYYY, 42621627)                      \
+  V(_Float32x4, get:zzzz, Float32x4ShuffleZZZZ, 42621627)                      \
+  V(_Float32x4, get:wwww, Float32x4ShuffleWWWW, 42621627)                      \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 211144022)                           \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 211144022)                           \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 211144022)                           \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 211144022)                           \
 
 // Class that recognizes the name and owner of a function and returns the
 // corresponding enum. See RECOGNIZED_LIST above for list of recognizable
@@ -505,6 +516,11 @@
   M(GuardField)                                                                \
   M(IfThenElse)                                                                \
   M(BinaryFloat32x4Op)                                                         \
+  M(Float32x4Shuffle)                                                          \
+  M(Float32x4Constructor)                                                      \
+  M(Float32x4Zero)                                                             \
+  M(Float32x4Splat)                                                            \
+
 
 #define FORWARD_DECLARATION(type) class type##Instr;
 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
@@ -755,6 +771,10 @@
   friend class UnboxFloat32x4Instr;
   friend class BinaryDoubleOpInstr;
   friend class BinaryFloat32x4OpInstr;
+  friend class Float32x4ZeroInstr;
+  friend class Float32x4SplatInstr;
+  friend class Float32x4ShuffleInstr;
+  friend class Float32x4ConstructorInstr;
   friend class BinaryMintOpInstr;
   friend class BinarySmiOpInstr;
   friend class UnarySmiOpInstr;
@@ -1073,7 +1093,7 @@
 class ForwardInstructionIterator : public ValueObject {
  public:
   explicit ForwardInstructionIterator(BlockEntryInstr* block_entry)
-      : block_entry_(block_entry), current_(block_entry) {
+      : current_(block_entry) {
     Advance();
   }
 
@@ -1090,7 +1110,6 @@
   Instruction* Current() const { return current_; }
 
  private:
-  BlockEntryInstr* block_entry_;
   Instruction* current_;
 };
 
@@ -2319,6 +2338,8 @@
 
   virtual bool HasSideEffect() const { return false; }
 
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(CurrentContextInstr);
 };
@@ -4139,6 +4160,194 @@
 };
 
 
+class Float32x4ShuffleInstr : public TemplateDefinition<1> {
+ public:
+  Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
+                        InstanceCallInstr* instance_call)
+      : op_kind_(op_kind) {
+    SetInputAt(0, value);
+    deopt_id_ = instance_call->deopt_id();
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  MethodRecognizer::Kind op_kind() const { return op_kind_; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual bool HasSideEffect() const { return false; }
+
+  virtual bool AffectedBySideEffect() const { return false; }
+
+  virtual bool AttributesEqual(Instruction* other) const {
+    return op_kind() == other->AsFloat32x4Shuffle()->op_kind();
+  }
+
+  virtual Representation representation() const {
+    if ((op_kind_ == MethodRecognizer::kFloat32x4ShuffleX) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4ShuffleY) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4ShuffleZ) ||
+        (op_kind_ == MethodRecognizer::kFloat32x4ShuffleW)) {
+      return kUnboxedDouble;
+    }
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedFloat32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4Shuffle)
+  virtual CompileType ComputeType() const;
+
+ private:
+  const MethodRecognizer::Kind op_kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr);
+};
+
+
+class Float32x4ConstructorInstr : public TemplateDefinition<4> {
+ public:
+  Float32x4ConstructorInstr(Value* value0, Value* value1, Value* value2,
+                            Value* value3, StaticCallInstr* static_call) {
+    SetInputAt(0, value0);
+    SetInputAt(1, value1);
+    SetInputAt(2, value2);
+    SetInputAt(3, value3);
+    deopt_id_ = static_call->deopt_id();
+  }
+
+  Value* value0() const { return inputs_[0]; }
+  Value* value1() const { return inputs_[1]; }
+  Value* value2() const { return inputs_[2]; }
+  Value* value3() const { return inputs_[3]; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual bool HasSideEffect() const { return false; }
+
+  virtual bool AffectedBySideEffect() const { return false; }
+
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx >= 0 && idx < 4);
+    return kUnboxedDouble;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4Constructor)
+  virtual CompileType ComputeType() const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Float32x4ConstructorInstr);
+};
+
+
+class Float32x4SplatInstr : public TemplateDefinition<1> {
+ public:
+  Float32x4SplatInstr(Value* value, StaticCallInstr* static_call) {
+    SetInputAt(0, value);
+    deopt_id_ = static_call->deopt_id();
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual bool HasSideEffect() const { return false; }
+
+  virtual bool AffectedBySideEffect() const { return false; }
+
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    ASSERT(idx == 0);
+    return kUnboxedDouble;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4Splat)
+  virtual CompileType ComputeType() const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Float32x4SplatInstr);
+};
+
+
+class Float32x4ZeroInstr : public TemplateDefinition<0> {
+ public:
+  explicit Float32x4ZeroInstr(StaticCallInstr* static_call) {
+    deopt_id_ = static_call->deopt_id();
+  }
+
+  Value* value() const { return inputs_[0]; }
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  virtual bool CanDeoptimize() const { return false; }
+
+  virtual bool HasSideEffect() const { return false; }
+
+  virtual bool AffectedBySideEffect() const { return false; }
+
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  virtual Representation representation() const {
+    return kUnboxedFloat32x4;
+  }
+
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    UNIMPLEMENTED();
+    return kUnboxedFloat32x4;
+  }
+
+  virtual intptr_t DeoptimizationTarget() const {
+    // Direct access since this instruction cannot deoptimize, and the deopt-id
+    // was inherited from another instruction that could deoptimize.
+    return deopt_id_;
+  }
+
+  DECLARE_INSTRUCTION(Float32x4Zero)
+  virtual CompileType ComputeType() const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Float32x4ZeroInstr);
+};
+
+
 class BinaryMintOpInstr : public TemplateDefinition<2> {
  public:
   BinaryMintOpInstr(Token::Kind op_kind,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 64e8e39..43043a5 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -95,10 +95,9 @@
   __ LeaveDartFrame();
   __ Ret();
 
-  // Generate 2 NOP instructions so that the debugger can patch the return
-  // pattern (1 instruction) with a call to the debug stub (3 instructions).
-  __ nop();
-  __ nop();
+  // No need to generate NOP instructions so that the debugger can patch the
+  // return pattern (3 instructions) with a call to the debug stub (also 3
+  // instructions).
   compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
                                  Isolate::kNoDeoptId,
                                  token_pos());
@@ -208,8 +207,8 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(R0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(R1));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(R2));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(R2));  // Instantiator.
+  summary->set_in(2, Location::RegisterLocation(R1));  // Type arguments.
   summary->set_out(Location::RegisterLocation(R0));
   return summary;
 }
@@ -344,7 +343,7 @@
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
   locs->set_in(0, Location::RegisterLocation(R1));
   locs->set_in(1, Location::RegisterLocation(R0));
-  locs->set_temp(0, Location::RegisterLocation(R6));
+  locs->set_temp(0, Location::RegisterLocation(R5));
   locs->set_out(Location::RegisterLocation(R0));
   return locs;
 }
@@ -352,7 +351,7 @@
 
 // R1: left.
 // R0: right.
-// Uses R6 to load ic_call_data.
+// Uses R5 to load ic_call_data.
 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
                                        intptr_t deopt_id,
                                        intptr_t token_pos,
@@ -405,13 +404,9 @@
   Label equality_done;
   if (compiler->is_optimizing()) {
     // No need to update IC data.
-    Label is_true;
     __ cmp(R0, ShifterOperand(R1));
-    __ b(&is_true, EQ);
-    __ LoadObject(R0, (kind == Token::kEQ) ? Bool::False() : Bool::True());
-    __ b(&equality_done);
-    __ Bind(&is_true);
-    __ LoadObject(R0, (kind == Token::kEQ) ? Bool::True() : Bool::False());
+    __ LoadObject(R0, (kind == Token::kEQ) ? Bool::False() : Bool::True(), NE);
+    __ LoadObject(R0, (kind == Token::kEQ) ? Bool::True() : Bool::False(), EQ);
     if (kind == Token::kNE) {
       // Skip not-equal result conversion.
       __ b(&equality_done);
@@ -420,7 +415,7 @@
     // Call stub, load IC data in register. The stub will update ICData if
     // necessary.
     Register ic_data_reg = locs->temp(0).reg();
-    ASSERT(ic_data_reg == R6);  // Stub depends on it.
+    ASSERT(ic_data_reg == R5);  // Stub depends on it.
     __ LoadObject(ic_data_reg, equality_ic_data);
     // Pass left in R1 and right in R0.
     compiler->GenerateCall(token_pos,
@@ -430,15 +425,10 @@
   }
   __ Bind(&check_ne);
   if (kind == Token::kNE) {
-    Label true_label, done;
     // Negate the condition: true label returns false and vice versa.
     __ CompareObject(R0, Bool::True());
-    __ b(&true_label, EQ);
-    __ LoadObject(R0, Bool::True());
-    __ b(&done);
-    __ Bind(&true_label);
-    __ LoadObject(R0, Bool::False());
-    __ Bind(&done);
+    __ LoadObject(R0, Bool::True(), NE);
+    __ LoadObject(R0, Bool::False(), EQ);
   }
   __ Bind(&equality_done);
 }
@@ -488,6 +478,25 @@
 }
 
 
+static Condition NegateCondition(Condition condition) {
+  switch (condition) {
+    case EQ: return NE;
+    case NE: return EQ;
+    case LT: return GE;
+    case LE: return GT;
+    case GT: return LE;
+    case GE: return LT;
+    case CC: return CS;
+    case LS: return HI;
+    case HI: return LS;
+    case CS: return CC;
+    default:
+      UNIMPLEMENTED();
+      return EQ;
+  }
+}
+
+
 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
                                 const LocationSummary& locs,
                                 Token::Kind kind,
@@ -511,13 +520,8 @@
     branch->EmitBranchOnCondition(compiler, true_condition);
   } else {
     Register result = locs.out().reg();
-    Label done, is_true;
-    __ b(&is_true, true_condition);
-    __ LoadObject(result, Bool::False());
-    __ b(&done);
-    __ Bind(&is_true);
-    __ LoadObject(result, Bool::True());
-    __ Bind(&done);
+    __ LoadObject(result, Bool::True(), true_condition);
+    __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
   }
 }
 
@@ -837,25 +841,192 @@
 
 
 CompileType LoadIndexedInstr::ComputeType() const {
-  UNIMPLEMENTED();
-  return CompileType::Dynamic();
+  switch (class_id_) {
+    case kArrayCid:
+    case kImmutableArrayCid:
+      return CompileType::Dynamic();
+
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+      return CompileType::FromCid(kDoubleCid);
+    case kTypedDataFloat32x4ArrayCid:
+      return CompileType::FromCid(kFloat32x4Cid);
+
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kOneByteStringCid:
+    case kTwoByteStringCid:
+      return CompileType::FromCid(kSmiCid);
+
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+      // Result can be Smi or Mint when boxed.
+      // Instruction can deoptimize if we optimistically assumed that the result
+      // fits into Smi.
+      return CanDeoptimize() ? CompileType::FromCid(kSmiCid)
+                             : CompileType::Int();
+
+    default:
+      UNIMPLEMENTED();
+      return CompileType::Dynamic();
+  }
 }
 
 
 Representation LoadIndexedInstr::representation() const {
-  UNIMPLEMENTED();
-  return kTagged;
+  switch (class_id_) {
+    case kArrayCid:
+    case kImmutableArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kOneByteStringCid:
+    case kTwoByteStringCid:
+      return kTagged;
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+      // Instruction can deoptimize if we optimistically assumed that the result
+      // fits into Smi.
+      return CanDeoptimize() ? kTagged : kUnboxedMint;
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+      return kUnboxedDouble;
+    case kTypedDataFloat32x4ArrayCid:
+      return kUnboxedFloat32x4;
+    default:
+      UNIMPLEMENTED();
+      return kTagged;
+  }
 }
 
 
 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(0, Location::RequiresRegister());
+  // The smi index is either untagged (element size == 1), or it is left smi
+  // tagged (for all element sizes > 1).
+  // TODO(regis): Revisit and see if the index can be immediate.
+  locs->set_in(1, Location::WritableRegister());
+  if (representation() == kUnboxedDouble) {
+    locs->set_out(Location::RequiresFpuRegister());
+  } else {
+    locs->set_out(Location::RequiresRegister());
+  }
+  return locs;
 }
 
 
 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Register array = locs()->in(0).reg();
+  Location index = locs()->in(1);
+
+  Address element_address(kNoRegister, 0);
+  if (IsExternal()) {
+    UNIMPLEMENTED();
+  } else {
+    ASSERT(this->array()->definition()->representation() == kTagged);
+    ASSERT(index.IsRegister());  // TODO(regis): Revisit.
+    // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
+    // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
+    // index is expected to be untagged before accessing.
+    ASSERT(kSmiTagShift == 1);
+    switch (index_scale()) {
+      case 1: {
+        __ SmiUntag(index.reg());
+        break;
+      }
+      case 2: {
+        break;
+      }
+      case 4: {
+        __ mov(index.reg(), ShifterOperand(index.reg(), LSL, 1));
+        break;
+      }
+      case 8: {
+        __ mov(index.reg(), ShifterOperand(index.reg(), LSL, 2));
+        break;
+      }
+      case 16: {
+        __ mov(index.reg(), ShifterOperand(index.reg(), LSL, 3));
+        break;
+      }
+      default:
+        UNREACHABLE();
+    }
+    __ AddImmediate(index.reg(),
+        FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
+    element_address = Address(array, index.reg(), LSL, 0);
+  }
+
+  if ((representation() == kUnboxedDouble) ||
+      (representation() == kUnboxedMint) ||
+      (representation() == kUnboxedFloat32x4)) {
+    UNIMPLEMENTED();
+  }
+
+  Register result = locs()->out().reg();
+  if ((index_scale() == 1) && index.IsRegister()) {
+    __ SmiUntag(index.reg());
+  }
+  switch (class_id()) {
+    case kTypedDataInt8ArrayCid:
+      ASSERT(index_scale() == 1);
+      __ ldrsb(result, element_address);
+      __ SmiTag(result);
+      break;
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kOneByteStringCid:
+      ASSERT(index_scale() == 1);
+      __ ldrb(result, element_address);
+      __ SmiTag(result);
+      break;
+    case kTypedDataInt16ArrayCid:
+      __ ldrsh(result, element_address);
+      __ SmiTag(result);
+      break;
+    case kTypedDataUint16ArrayCid:
+    case kTwoByteStringCid:
+      __ ldrh(result, element_address);
+      __ SmiTag(result);
+      break;
+    case kTypedDataInt32ArrayCid: {
+        Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptInt32Load);
+        __ ldr(result, element_address);
+        // Verify that the signed value in 'result' can fit inside a Smi.
+        __ CompareImmediate(result, 0xC0000000);
+        __ b(deopt, MI);
+        __ SmiTag(result);
+      }
+      break;
+    case kTypedDataUint32ArrayCid: {
+        Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptUint32Load);
+        __ ldr(result, element_address);
+        // Verify that the unsigned value in 'result' can fit inside a Smi.
+        __ tst(result, ShifterOperand(0xC0000000));
+        __ b(deopt, NE);
+        __ SmiTag(result);
+      }
+      break;
+    default:
+      ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
+      __ ldr(result, element_address);
+      break;
+  }
 }
 
 
@@ -1039,28 +1210,25 @@
     FieldAddress field_nullability_operand(
         field_reg, Field::is_nullable_offset());
 
+    if (value_cid_reg == kNoRegister) {
+      ASSERT(!compiler->is_optimizing());
+      value_cid_reg = R3;
+      ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+    }
+
     if (value_cid == kDynamicCid) {
-      if (value_cid_reg == kNoRegister) {
-        ASSERT(!compiler->is_optimizing());
-        value_cid_reg = R3;
-        ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
-      }
-
       LoadValueCid(compiler, value_cid_reg, value_reg);
-
       __ ldr(IP, field_cid_operand);
       __ cmp(value_cid_reg, ShifterOperand(IP));
       __ b(&ok, EQ);
       __ ldr(IP, field_nullability_operand);
       __ cmp(value_cid_reg, ShifterOperand(IP));
     } else if (value_cid == kNullCid) {
-      // TODO(regis): IP may conflict. Revisit.
-      __ ldr(IP, field_nullability_operand);
-      __ CompareImmediate(IP, value_cid);
+      __ ldr(value_cid_reg, field_nullability_operand);
+      __ CompareImmediate(value_cid_reg, value_cid);
     } else {
-      // TODO(regis): IP may conflict. Revisit.
-      __ ldr(IP, field_cid_operand);
-      __ CompareImmediate(IP, value_cid);
+      __ ldr(value_cid_reg, field_cid_operand);
+      __ CompareImmediate(value_cid_reg, value_cid);
     }
     __ b(&ok, EQ);
 
@@ -1274,11 +1442,10 @@
 
 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
   locs->set_in(0, Location::RegisterLocation(R0));
-  locs->set_temp(0, Location::RegisterLocation(R1));
   locs->set_out(Location::RegisterLocation(R0));
   return locs;
 }
@@ -1287,48 +1454,34 @@
 void InstantiateTypeArgumentsInstr::EmitNativeCode(
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
-  Register temp = locs()->temp(0).reg();
   Register result_reg = locs()->out().reg();
 
   // 'instantiator_reg' is the instantiator AbstractTypeArguments object
   // (or null).
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  const intptr_t len = type_arguments().Length();
-  if (type_arguments().IsRawInstantiatedRaw(len)) {
-    __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
-    __ cmp(instantiator_reg, ShifterOperand(IP));
-    __ b(&type_arguments_instantiated, EQ);
+  if (!type_arguments().IsUninstantiatedIdentity()) {
+    // If the instantiator is null and if the type argument vector
+    // instantiated from null becomes a vector of dynamic, then use null as
+    // the type arguments.
+    Label type_arguments_instantiated;
+    const intptr_t len = type_arguments().Length();
+    if (type_arguments().IsRawInstantiatedRaw(len)) {
+      __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
+      __ cmp(instantiator_reg, ShifterOperand(IP));
+      __ b(&type_arguments_instantiated, EQ);
+    }
+    // Instantiate non-null type arguments.
+    // A runtime call to instantiate the type arguments is required.
+    __ PushObject(Object::ZoneHandle());  // Make room for the result.
+    __ PushObject(type_arguments());
+    __ Push(instantiator_reg);  // Push instantiator type arguments.
+    compiler->GenerateCallRuntime(token_pos(),
+                                  deopt_id(),
+                                  kInstantiateTypeArgumentsRuntimeEntry,
+                                  locs());
+    __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
+    __ Pop(result_reg);  // Pop instantiated type arguments.
+    __ Bind(&type_arguments_instantiated);
   }
-  // Instantiate non-null type arguments.
-  if (type_arguments().IsUninstantiatedIdentity()) {
-    // Check if the instantiator type argument vector is a TypeArguments of a
-    // matching length and, if so, use it as the instantiated type_arguments.
-    // No need to check the instantiator ('instantiator_reg') for null here,
-    // because a null instantiator will have the wrong class (Null instead of
-    // TypeArguments).
-    Label type_arguments_uninstantiated;
-    __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp);
-    __ b(&type_arguments_uninstantiated, NE);
-    __ ldr(temp,
-           FieldAddress(instantiator_reg, TypeArguments::length_offset()));
-    __ CompareImmediate(temp, Smi::RawValue(len));
-    __ b(&type_arguments_instantiated, EQ);
-    __ Bind(&type_arguments_uninstantiated);
-  }
-  // A runtime call to instantiate the type arguments is required.
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
-  __ PushObject(type_arguments());
-  __ Push(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
-                                deopt_id(),
-                                kInstantiateTypeArgumentsRuntimeEntry,
-                                locs());
-  __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
-  __ Pop(result_reg);  // Pop instantiated type arguments.
-  __ Bind(&type_arguments_instantiated);
   ASSERT(instantiator_reg == result_reg);
   // 'result_reg': Instantiated type arguments.
 }
@@ -1337,12 +1490,11 @@
 LocationSummary*
 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   locs->set_in(0, Location::RequiresRegister());
   locs->set_out(Location::SameAsFirstInput());
-  locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
 
@@ -1352,40 +1504,28 @@
   Register instantiator_reg = locs()->in(0).reg();
   Register result_reg = locs()->out().reg();
   ASSERT(instantiator_reg == result_reg);
-  Register temp_reg = locs()->temp(0).reg();
 
   // instantiator_reg is the instantiator type argument vector, i.e. an
   // AbstractTypeArguments object (or null).
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  const intptr_t len = type_arguments().Length();
-  if (type_arguments().IsRawInstantiatedRaw(len)) {
-    __ CompareImmediate(instantiator_reg,
-                        reinterpret_cast<intptr_t>(Object::null()));
-    __ b(&type_arguments_instantiated, EQ);
+  if (!type_arguments().IsUninstantiatedIdentity()) {
+    // If the instantiator is null and if the type argument vector
+    // instantiated from null becomes a vector of dynamic, then use null as
+    // the type arguments.
+    Label type_arguments_instantiated;
+    const intptr_t len = type_arguments().Length();
+    if (type_arguments().IsRawInstantiatedRaw(len)) {
+      __ CompareImmediate(instantiator_reg,
+                          reinterpret_cast<intptr_t>(Object::null()));
+      __ b(&type_arguments_instantiated, EQ);
+    }
+    // Instantiate non-null type arguments.
+    // In the non-factory case, we rely on the allocation stub to
+    // instantiate the type arguments.
+    __ LoadObject(result_reg, type_arguments());
+    // result_reg: uninstantiated type arguments.
+    __ Bind(&type_arguments_instantiated);
   }
-  // Instantiate non-null type arguments.
-  if (type_arguments().IsUninstantiatedIdentity()) {
-    // Check if the instantiator type argument vector is a TypeArguments of a
-    // matching length and, if so, use it as the instantiated type_arguments.
-    // No need to check instantiator_reg for null here, because a null
-    // instantiator will have the wrong class (Null instead of TypeArguments).
-    Label type_arguments_uninstantiated;
-    __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
-    __ b(&type_arguments_uninstantiated, NE);
-    __ ldr(temp_reg,
-           FieldAddress(instantiator_reg, TypeArguments::length_offset()));
-    __ CompareImmediate(temp_reg, Smi::RawValue(type_arguments().Length()));
-    __ b(&type_arguments_instantiated, EQ);
-    __ Bind(&type_arguments_uninstantiated);
-  }
-  // In the non-factory case, we rely on the allocation stub to
-  // instantiate the type arguments.
-  __ LoadObject(result_reg, type_arguments());
-  // result_reg: uninstantiated type arguments.
-  __ Bind(&type_arguments_instantiated);
+  ASSERT(instantiator_reg == result_reg);
   // result_reg: uninstantiated or instantiated type arguments.
 }
 
@@ -1393,12 +1533,11 @@
 LocationSummary*
 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   locs->set_in(0, Location::RequiresRegister());
   locs->set_out(Location::SameAsFirstInput());
-  locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
 
@@ -1407,51 +1546,31 @@
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
   ASSERT(locs()->out().reg() == instantiator_reg);
-  Register temp_reg = locs()->temp(0).reg();
 
   // instantiator_reg is the instantiator AbstractTypeArguments object
-  // (or null).  If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments and do not pass the instantiator.
-  Label done;
-  const intptr_t len = type_arguments().Length();
-  if (type_arguments().IsRawInstantiatedRaw(len)) {
-    Label instantiator_not_null;
-    __ CompareImmediate(instantiator_reg,
-                        reinterpret_cast<intptr_t>(Object::null()));
-    __ b(&instantiator_not_null, NE);
-    // Null was used in VisitExtractConstructorTypeArguments as the
-    // instantiated type arguments, no proper instantiator needed.
-    __ LoadImmediate(instantiator_reg,
-                     Smi::RawValue(StubCode::kNoInstantiator));
-    __ b(&done);
-    __ Bind(&instantiator_not_null);
-  }
-  // Instantiate non-null type arguments.
+  // (or null).
   if (type_arguments().IsUninstantiatedIdentity()) {
-    // TODO(regis): The following emitted code is duplicated in
-    // VisitExtractConstructorTypeArguments above. The reason is that the code
-    // is split between two computations, so that each one produces a
-    // single value, rather than producing a pair of values.
-    // If this becomes an issue, we should expose these tests at the IL level.
-
-    // Check if the instantiator type argument vector is a TypeArguments of a
-    // matching length and, if so, use it as the instantiated type_arguments.
-    // No need to check the instantiator ('instantiator_reg') for null here,
-    // because a null instantiator will have the wrong class (Null instead of
-    // TypeArguments).
-    __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
-    __ b(&done, NE);
-    __ ldr(temp_reg,
-           FieldAddress(instantiator_reg, TypeArguments::length_offset()));
-    __ CompareImmediate(temp_reg, Smi::RawValue(type_arguments().Length()));
-    __ b(&done, NE);
     // The instantiator was used in VisitExtractConstructorTypeArguments as the
     // instantiated type arguments, no proper instantiator needed.
     __ LoadImmediate(instantiator_reg,
                      Smi::RawValue(StubCode::kNoInstantiator));
+  } else {
+    // If the instantiator is null and if the type argument vector
+    // instantiated from null becomes a vector of dynamic, then use null as
+    // the type arguments and do not pass the instantiator.
+    const intptr_t len = type_arguments().Length();
+    if (type_arguments().IsRawInstantiatedRaw(len)) {
+      Label instantiator_not_null;
+      __ CompareImmediate(instantiator_reg,
+                          reinterpret_cast<intptr_t>(Object::null()));
+      __ b(&instantiator_not_null, NE);
+      // Null was used in VisitExtractConstructorTypeArguments as the
+      // instantiated type arguments, no proper instantiator needed.
+      __ LoadImmediate(instantiator_reg,
+                       Smi::RawValue(StubCode::kNoInstantiator));
+      __ Bind(&instantiator_not_null);
+    }
   }
-  __ Bind(&done);
   // instantiator_reg: instantiator or kNoInstantiator.
 }
 
@@ -1625,14 +1744,24 @@
       case Token::kMUL: {
         // Keep left value tagged and untag right value.
         const intptr_t value = Smi::Cast(constant).Value();
-        if (value == 2) {
-          __ mov(result, ShifterOperand(left, LSL, 1));
+        if (deopt == NULL) {
+          if (value == 2) {
+            __ mov(result, ShifterOperand(left, LSL, 1));
+          } else {
+            __ LoadImmediate(IP, value);
+            __ mul(result, left, IP);
+          }
         } else {
-          __ LoadImmediate(IP, value);
-          __ mul(result, left, IP);
-        }
-        if (deopt != NULL) {
-          UNIMPLEMENTED();
+          if (value == 2) {
+            __ mov(IP, ShifterOperand(left, ASR, 31));  // IP = sign of left.
+            __ mov(result, ShifterOperand(left, LSL, 1));
+          } else {
+            __ LoadImmediate(IP, value);
+            __ smull(result, IP, left, IP);
+          }
+          // IP: result bits 32..63.
+          __ cmp(IP, ShifterOperand(result, ASR, 31));
+          __ b(deopt, NE);
         }
         break;
       }
@@ -1840,6 +1969,50 @@
 }
 
 
+LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
+LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+
+void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  UNIMPLEMENTED();
+}
+
+
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
   UNIMPLEMENTED();
   return NULL;
@@ -1971,13 +2144,56 @@
 
 
 LocationSummary* CheckClassInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  if (!null_check()) {
+    summary->AddTemp(Location::RequiresRegister());
+  }
+  return summary;
 }
 
 
 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  if (null_check()) {
+    Label* deopt = compiler->AddDeoptStub(deopt_id(),
+                                          kDeoptCheckClass);
+    __ CompareImmediate(locs()->in(0).reg(),
+                        reinterpret_cast<intptr_t>(Object::null()));
+    __ b(deopt, EQ);
+    return;
+  }
+
+  ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
+         (unary_checks().NumberOfChecks() > 1));
+  Register value = locs()->in(0).reg();
+  Register temp = locs()->temp(0).reg();
+  Label* deopt = compiler->AddDeoptStub(deopt_id(),
+                                        kDeoptCheckClass);
+  Label is_ok;
+  intptr_t cix = 0;
+  if (unary_checks().GetReceiverClassIdAt(cix) == kSmiCid) {
+    __ tst(value, ShifterOperand(kSmiTagMask));
+    __ b(&is_ok, EQ);
+    cix++;  // Skip first check.
+  } else {
+    __ tst(value, ShifterOperand(kSmiTagMask));
+    __ b(deopt, EQ);
+  }
+  __ LoadClassId(temp, value);
+  const intptr_t num_checks = unary_checks().NumberOfChecks();
+  for (intptr_t i = cix; i < num_checks; i++) {
+    ASSERT(unary_checks().GetReceiverClassIdAt(i) != kSmiCid);
+    __ CompareImmediate(temp, unary_checks().GetReceiverClassIdAt(i));
+    if (i == (num_checks - 1)) {
+      __ b(deopt, NE);
+    } else {
+      __ b(&is_ok, EQ);
+    }
+  }
+  __ Bind(&is_ok);
 }
 
 
@@ -2001,13 +2217,44 @@
 
 
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(0, Location::RegisterOrSmiConstant(length()));
+  locs->set_in(1, Location::RegisterOrSmiConstant(index()));
+  return locs;
 }
 
 
 void CheckArrayBoundInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Label* deopt = compiler->AddDeoptStub(deopt_id(),
+                                        kDeoptCheckArrayBound);
+  if (locs()->in(0).IsConstant() && locs()->in(1).IsConstant()) {
+    // Unconditionally deoptimize for constant bounds checks because they
+    // only occur only when index is out-of-bounds.
+    __ b(deopt);
+    return;
+  }
+
+  if (locs()->in(1).IsConstant()) {
+    Register length = locs()->in(0).reg();
+    const Object& constant = locs()->in(1).constant();
+    ASSERT(constant.IsSmi());
+    __ CompareImmediate(length, reinterpret_cast<int32_t>(constant.raw()));
+    __ b(deopt, LS);
+  } else if (locs()->in(0).IsConstant()) {
+    ASSERT(locs()->in(0).constant().IsSmi());
+    const Smi& smi_const = Smi::Cast(locs()->in(0).constant());
+    Register index = locs()->in(1).reg();
+    __ CompareImmediate(index, reinterpret_cast<int32_t>(smi_const.raw()));
+    __ b(deopt, CS);
+  } else {
+    Register length = locs()->in(0).reg();
+    Register index = locs()->in(1).reg();
+    __ cmp(index, ShifterOperand(length));
+    __ b(deopt, CS);
+  }
 }
 
 
@@ -2120,26 +2367,6 @@
 }
 
 
-static Condition NegateCondition(Condition condition) {
-  switch (condition) {
-    case EQ: return NE;
-    case NE: return EQ;
-    case LT: return GE;
-    case LE: return GT;
-    case GT: return LE;
-    case GE: return LT;
-    case CC: return CS;
-    case LS: return HI;
-    case HI: return LS;
-    case CS: return CC;
-    default:
-      OS::Print("Error %d\n", condition);
-      UNIMPLEMENTED();
-      return EQ;
-  }
-}
-
-
 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
                                            bool value) {
   if (value && !compiler->CanFallThroughTo(true_successor())) {
@@ -2221,14 +2448,9 @@
   }
 
   Register result = locs()->out().reg();
-  Label load_true, done;
   Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
-  __ b(&load_true, true_condition);
-  __ LoadObject(result, Bool::False());
-  __ b(&done);
-  __ Bind(&load_true);
-  __ LoadObject(result, Bool::True());
-  __ Bind(&done);
+  __ LoadObject(result, Bool::True(), true_condition);
+  __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
 }
 
 
@@ -2275,34 +2497,54 @@
   Register value = locs()->in(0).reg();
   Register result = locs()->out().reg();
 
-  Label done;
   __ LoadObject(result, Bool::True());
   __ cmp(result, ShifterOperand(value));
-  __ b(&done, NE);
-  __ LoadObject(result, Bool::False());
-  __ Bind(&done);
+  __ LoadObject(result, Bool::False(), EQ);
 }
 
 
 LocationSummary* ChainContextInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  return LocationSummary::Make(1,
+                               Location::NoLocation(),
+                               LocationSummary::kNoCall);
 }
 
 
 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Register context_value = locs()->in(0).reg();
+
+  // Chain the new context in context_value to its parent in CTX.
+  __ StoreIntoObject(context_value,
+                     FieldAddress(context_value, Context::parent_offset()),
+                     CTX);
+  // Set new context as current context.
+  __ mov(CTX, ShifterOperand(context_value));
 }
 
 
 LocationSummary* StoreVMFieldInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(0, value()->NeedsStoreBuffer() ? Location::WritableRegister()
+                                              : Location::RequiresRegister());
+  locs->set_in(1, Location::RequiresRegister());
+  return locs;
 }
 
 
 void StoreVMFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Register value_reg = locs()->in(0).reg();
+  Register dest_reg = locs()->in(1).reg();
+
+  if (value()->NeedsStoreBuffer()) {
+    __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
+                       value_reg);
+  } else {
+    __ StoreIntoObjectNoBarrier(
+        dest_reg, FieldAddress(dest_reg, offset_in_bytes()), value_reg);
+  }
 }
 
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index ad46c62..00cd501 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1859,11 +1859,10 @@
 
 LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
   locs->set_in(0, Location::RegisterLocation(EAX));
-  locs->set_temp(0, Location::RegisterLocation(ECX));
   locs->set_out(Location::RegisterLocation(EAX));
   return locs;
 }
@@ -1872,48 +1871,35 @@
 void InstantiateTypeArgumentsInstr::EmitNativeCode(
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
-  Register temp = locs()->temp(0).reg();
   Register result_reg = locs()->out().reg();
 
   // 'instantiator_reg' is the instantiator AbstractTypeArguments object
   // (or null).
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  const intptr_t len = type_arguments().Length();
-  if (type_arguments().IsRawInstantiatedRaw(len)) {
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ cmpl(instantiator_reg, raw_null);
-    __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
+  if (!type_arguments().IsUninstantiatedIdentity()) {
+    // If the instantiator is null and if the type argument vector
+    // instantiated from null becomes a vector of dynamic, then use null as
+    // the type arguments.
+    Label type_arguments_instantiated;
+    const intptr_t len = type_arguments().Length();
+    if (type_arguments().IsRawInstantiatedRaw(len)) {
+      const Immediate& raw_null =
+          Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      __ cmpl(instantiator_reg, raw_null);
+      __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
+    }
+    // Instantiate non-null type arguments.
+    // A runtime call to instantiate the type arguments is required.
+    __ PushObject(Object::ZoneHandle());  // Make room for the result.
+    __ PushObject(type_arguments());
+    __ pushl(instantiator_reg);  // Push instantiator type arguments.
+    compiler->GenerateCallRuntime(token_pos(),
+                                  deopt_id(),
+                                  kInstantiateTypeArgumentsRuntimeEntry,
+                                  locs());
+    __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
+    __ popl(result_reg);  // Pop instantiated type arguments.
+    __ Bind(&type_arguments_instantiated);
   }
-  // Instantiate non-null type arguments.
-  if (type_arguments().IsUninstantiatedIdentity()) {
-    // Check if the instantiator type argument vector is a TypeArguments of a
-    // matching length and, if so, use it as the instantiated type_arguments.
-    // No need to check the instantiator ('instantiator_reg') for null here,
-    // because a null instantiator will have the wrong class (Null instead of
-    // TypeArguments).
-    Label type_arguments_uninstantiated;
-    __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp);
-    __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
-    __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
-            Immediate(Smi::RawValue(len)));
-    __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
-    __ Bind(&type_arguments_uninstantiated);
-  }
-  // A runtime call to instantiate the type arguments is required.
-  __ PushObject(Object::ZoneHandle());  // Make room for the result.
-  __ PushObject(type_arguments());
-  __ pushl(instantiator_reg);  // Push instantiator type arguments.
-  compiler->GenerateCallRuntime(token_pos(),
-                                deopt_id(),
-                                kInstantiateTypeArgumentsRuntimeEntry,
-                                locs());
-  __ Drop(2);  // Drop instantiator and uninstantiated type arguments.
-  __ popl(result_reg);  // Pop instantiated type arguments.
-  __ Bind(&type_arguments_instantiated);
   ASSERT(instantiator_reg == result_reg);
   // 'result_reg': Instantiated type arguments.
 }
@@ -1922,12 +1908,11 @@
 LocationSummary*
 ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   locs->set_in(0, Location::RequiresRegister());
   locs->set_out(Location::SameAsFirstInput());
-  locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
 
@@ -1937,42 +1922,29 @@
   Register instantiator_reg = locs()->in(0).reg();
   Register result_reg = locs()->out().reg();
   ASSERT(instantiator_reg == result_reg);
-  Register temp_reg = locs()->temp(0).reg();
 
   // instantiator_reg is the instantiator type argument vector, i.e. an
   // AbstractTypeArguments object (or null).
-  // If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments.
-  Label type_arguments_instantiated;
-  const intptr_t len = type_arguments().Length();
-  if (type_arguments().IsRawInstantiatedRaw(len)) {
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ cmpl(instantiator_reg, raw_null);
-    __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
+  if (!type_arguments().IsUninstantiatedIdentity()) {
+    // If the instantiator is null and if the type argument vector
+    // instantiated from null becomes a vector of dynamic, then use null as
+    // the type arguments.
+    Label type_arguments_instantiated;
+    const intptr_t len = type_arguments().Length();
+    if (type_arguments().IsRawInstantiatedRaw(len)) {
+      const Immediate& raw_null =
+          Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      __ cmpl(instantiator_reg, raw_null);
+      __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
+    }
+    // Instantiate non-null type arguments.
+    // In the non-factory case, we rely on the allocation stub to
+    // instantiate the type arguments.
+    __ LoadObject(result_reg, type_arguments());
+    // result_reg: uninstantiated type arguments.
+    __ Bind(&type_arguments_instantiated);
   }
-  // Instantiate non-null type arguments.
-  if (type_arguments().IsUninstantiatedIdentity()) {
-    // Check if the instantiator type argument vector is a TypeArguments of a
-    // matching length and, if so, use it as the instantiated type_arguments.
-    // No need to check instantiator_reg for null here, because a null
-    // instantiator will have the wrong class (Null instead of TypeArguments).
-    Label type_arguments_uninstantiated;
-    __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
-    __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
-    const Immediate& arguments_length =
-        Immediate(Smi::RawValue(type_arguments().Length()));
-    __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
-        arguments_length);
-    __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
-    __ Bind(&type_arguments_uninstantiated);
-  }
-  // In the non-factory case, we rely on the allocation stub to
-  // instantiate the type arguments.
-  __ LoadObject(result_reg, type_arguments());
-  // result_reg: uninstantiated type arguments.
-  __ Bind(&type_arguments_instantiated);
+  ASSERT(instantiator_reg == result_reg);
   // result_reg: uninstantiated or instantiated type arguments.
 }
 
@@ -1980,12 +1952,11 @@
 LocationSummary*
 ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* locs =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   locs->set_in(0, Location::RequiresRegister());
   locs->set_out(Location::SameAsFirstInput());
-  locs->set_temp(0, Location::RequiresRegister());
   return locs;
 }
 
@@ -1994,52 +1965,32 @@
     FlowGraphCompiler* compiler) {
   Register instantiator_reg = locs()->in(0).reg();
   ASSERT(locs()->out().reg() == instantiator_reg);
-  Register temp_reg = locs()->temp(0).reg();
 
   // instantiator_reg is the instantiator AbstractTypeArguments object
-  // (or null).  If the instantiator is null and if the type argument vector
-  // instantiated from null becomes a vector of dynamic, then use null as
-  // the type arguments and do not pass the instantiator.
-  Label done;
-  const intptr_t len = type_arguments().Length();
-  if (type_arguments().IsRawInstantiatedRaw(len)) {
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    Label instantiator_not_null;
-    __ cmpl(instantiator_reg, raw_null);
-    __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
-    // Null was used in VisitExtractConstructorTypeArguments as the
-    // instantiated type arguments, no proper instantiator needed.
-    __ movl(instantiator_reg,
-            Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
-    __ jmp(&done);
-    __ Bind(&instantiator_not_null);
-  }
-  // Instantiate non-null type arguments.
+  // (or null).
   if (type_arguments().IsUninstantiatedIdentity()) {
-    // TODO(regis): The following emitted code is duplicated in
-    // VisitExtractConstructorTypeArguments above. The reason is that the code
-    // is split between two computations, so that each one produces a
-    // single value, rather than producing a pair of values.
-    // If this becomes an issue, we should expose these tests at the IL level.
-
-    // Check if the instantiator type argument vector is a TypeArguments of a
-    // matching length and, if so, use it as the instantiated type_arguments.
-    // No need to check the instantiator for null here, because a null
-    // instantiator will have the wrong class (Null instead of TypeArguments).
-    __ CompareClassId(instantiator_reg, kTypeArgumentsCid, temp_reg);
-    __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-    const Immediate& arguments_length =
-        Immediate(Smi::RawValue(type_arguments().Length()));
-    __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
-        arguments_length);
-    __ j(NOT_EQUAL, &done, Assembler::kNearJump);
     // The instantiator was used in VisitExtractConstructorTypeArguments as the
     // instantiated type arguments, no proper instantiator needed.
     __ movl(instantiator_reg,
             Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
+  } else {
+    // If the instantiator is null and if the type argument vector
+    // instantiated from null becomes a vector of dynamic, then use null as
+    // the type arguments and do not pass the instantiator.
+    const intptr_t len = type_arguments().Length();
+    if (type_arguments().IsRawInstantiatedRaw(len)) {
+      const Immediate& raw_null =
+          Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      Label instantiator_not_null;
+      __ cmpl(instantiator_reg, raw_null);
+      __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
+      // Null was used in VisitExtractConstructorTypeArguments as the
+      // instantiated type arguments, no proper instantiator needed.
+      __ movl(instantiator_reg,
+              Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
+      __ Bind(&instantiator_not_null);
+    }
   }
-  __ Bind(&done);
   // instantiator_reg: instantiator or kNoInstantiator.
 }
 
@@ -2843,6 +2794,132 @@
   }
 }
 
+
+LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister value = locs()->in(0).fpu_reg();
+
+  ASSERT(locs()->out().fpu_reg() == value);
+
+  switch (op_kind()) {
+    case MethodRecognizer::kFloat32x4ShuffleXXXX:
+      __ shufps(value, value, Immediate(0x00));
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleYYYY:
+      __ shufps(value, value, Immediate(0x55));
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleZZZZ:
+      __ shufps(value, value, Immediate(0xAA));
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleWWWW:
+      __ shufps(value, value, Immediate(0xFF));
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleX:
+      __ shufps(value, value, Immediate(0x00));
+      __ cvtss2sd(value, value);
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleY:
+      __ shufps(value, value, Immediate(0x55));
+      __ cvtss2sd(value, value);
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleZ:
+      __ shufps(value, value, Immediate(0xAA));
+      __ cvtss2sd(value, value);
+      break;
+    case MethodRecognizer::kFloat32x4ShuffleW:
+      __ shufps(value, value, Immediate(0xFF));
+      __ cvtss2sd(value, value);
+      break;
+
+    default: UNREACHABLE();
+  }
+}
+
+
+LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 4;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_in(1, Location::RequiresFpuRegister());
+  summary->set_in(2, Location::RequiresFpuRegister());
+  summary->set_in(3, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister v0 = locs()->in(0).fpu_reg();
+  XmmRegister v1 = locs()->in(1).fpu_reg();
+  XmmRegister v2 = locs()->in(2).fpu_reg();
+  XmmRegister v3 = locs()->in(3).fpu_reg();
+  ASSERT(v0 == locs()->out().fpu_reg());
+  __ subl(ESP, Immediate(16));
+  __ cvtsd2ss(v0, v0);
+  __ movss(Address(ESP, -16), v0);
+  __ movsd(v0, v1);
+  __ cvtsd2ss(v0, v0);
+  __ movss(Address(ESP, -12), v0);
+  __ movsd(v0, v2);
+  __ cvtsd2ss(v0, v0);
+  __ movss(Address(ESP, -8), v0);
+  __ movsd(v0, v3);
+  __ cvtsd2ss(v0, v0);
+  __ movss(Address(ESP, -4), v0);
+  __ movups(v0, Address(ESP, -16));
+  __ addl(ESP, Immediate(16));
+}
+
+
+LocationSummary* Float32x4ZeroInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_out(Location::RequiresFpuRegister());
+  return summary;
+}
+
+
+void Float32x4ZeroInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister value = locs()->out().fpu_reg();
+  __ xorps(value, value);
+}
+
+
+LocationSummary* Float32x4SplatInstr::MakeLocationSummary() const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresFpuRegister());
+  summary->set_out(Location::SameAsFirstInput());
+  return summary;
+}
+
+
+void Float32x4SplatInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  XmmRegister value = locs()->out().fpu_reg();
+  ASSERT(locs()->in(0).fpu_reg() == locs()->out().fpu_reg());
+  // Convert to Float32.
+  __ cvtsd2ss(value, value);
+  // Splat across all lanes.
+  __ shufps(value, value, Immediate(0x00));
+}
+
+
 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -3599,7 +3676,6 @@
     case ABOVE:         return BELOW_EQUAL;
     case ABOVE_EQUAL:   return BELOW;
     default:
-      OS::Print("Error %d\n", condition);
       UNIMPLEMENTED();
       return EQUAL;
   }
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 03b08cf..fa66db3 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -46,6 +46,7 @@
 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode
   // where PushArgument is handled by BindInstr::EmitNativeCode.
+  __ TraceSimMsg("PushArgumentInstr");
   if (compiler->is_optimizing()) {
     Location value = locs()->in(0);
     if (value.IsRegister()) {
@@ -75,6 +76,7 @@
 // The entry needs to be patchable, no inlined objects are allowed in the area
 // that will be overwritten by the patch instructions: a branch macro sequence.
 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ TraceSimMsg("ReturnInstr");
   Register result = locs()->in(0).reg();
   ASSERT(result == V0);
 #if defined(DEBUG)
@@ -85,6 +87,7 @@
   if (!compiler->HasFinally()) {
     Label stack_ok;
     __ Comment("Stack Check");
+    __ TraceSimMsg("Stack Check");
     const intptr_t fp_sp_dist =
         (kFirstLocalSlotIndex + 1 - compiler->StackSize()) * kWordSize;
     ASSERT(fp_sp_dist <= 0);
@@ -96,13 +99,11 @@
     __ Bind(&stack_ok);
   }
 #endif
+  // This sequence is patched by a debugger breakpoint. There is no need for
+  // extra NOP instructions here because the sequence patched in for a
+  // breakpoint is shorter than the sequence here.
   __ LeaveDartFrame();
   __ Ret();
-
-  // Generate 2 NOP instructions so that the debugger can patch the return
-  // pattern (1 instruction) with a call to the debug stub (3 instructions).
-  __ nop();
-  __ nop();
   compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
                                  Isolate::kNoDeoptId,
                                  token_pos());
@@ -134,8 +135,31 @@
 
 
 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* result =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+  result->set_out(Location::RegisterLocation(V0));
+  result->set_temp(0, Location::RegisterLocation(S4));  // Arg. descriptor.
+  return result;
+}
+
+
+void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  // The arguments to the stub include the closure, as does the arguments
+  // descriptor.
+  Register temp_reg = locs()->temp(0).reg();
+  int argument_count = ArgumentCount();
+  const Array& arguments_descriptor =
+      Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
+                                                 argument_names()));
+  __ LoadObject(temp_reg, arguments_descriptor);
+  compiler->GenerateDartCall(deopt_id(),
+                             token_pos(),
+                             &StubCode::CallClosureFunctionLabel(),
+                             PcDescriptors::kOther,
+                             locs());
+  __ Drop(argument_count);
 }
 
 
@@ -147,6 +171,7 @@
 
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ TraceSimMsg("LoadLocalInstr");
   Register result = locs()->out().reg();
   __ lw(result, Address(FP, local().index() * kWordSize));
 }
@@ -160,6 +185,7 @@
 
 
 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ TraceSimMsg("StoreLocalInstr");
   Register value = locs()->in(0).reg();
   Register result = locs()->out().reg();
   ASSERT(result == value);  // Assert that register assignment is correct.
@@ -177,6 +203,7 @@
 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // The register allocator drops constant definitions that have no uses.
   if (!locs()->out().IsInvalid()) {
+    __ TraceSimMsg("ConstantInstr");
     Register result = locs()->out().reg();
     __ LoadObject(result, value());
   }
@@ -189,8 +216,8 @@
   LocationSummary* summary =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(A0));  // Value.
-  summary->set_in(1, Location::RegisterLocation(A1));  // Instantiator.
-  summary->set_in(2, Location::RegisterLocation(A2));  // Type arguments.
+  summary->set_in(1, Location::RegisterLocation(A2));  // Instantiator.
+  summary->set_in(2, Location::RegisterLocation(A1));  // Type arguments.
   summary->set_out(Location::RegisterLocation(A0));
   return summary;
 }
@@ -234,6 +261,7 @@
   Register obj = locs()->in(0).reg();
   Register result = locs()->out().reg();
 
+  __ TraceSimMsg("AssertBooleanInstr");
   EmitAssertBoolean(obj, token_pos(), deopt_id(), locs(), compiler);
   ASSERT(obj == result);
 }
@@ -324,6 +352,7 @@
                                        Token::Kind kind,
                                        LocationSummary* locs,
                                        const ICData& original_ic_data) {
+  __ TraceSimMsg("EmitEqualityAsInstanceCall");
   if (!compiler->is_optimizing()) {
     compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
                                    deopt_id,
@@ -411,6 +440,7 @@
                          Register value_cid_reg,
                          Register value_reg,
                          Label* value_is_smi = NULL) {
+  __ TraceSimMsg("LoadValueCid");
   Label done;
   if (value_is_smi == NULL) {
     __ LoadImmediate(value_cid_reg, kSmiCid);
@@ -470,6 +500,7 @@
                                 const LocationSummary& locs,
                                 Token::Kind kind,
                                 BranchInstr* branch) {
+  __ TraceSimMsg("EmitSmiComparisonOp");
   Location left = locs.in(0);
   Location right = locs.in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
@@ -577,6 +608,7 @@
 
 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                           BranchInstr* branch) {
+  __ TraceSimMsg("EqualityCompareInstr");
   ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
   if (receiver_class_id() == kSmiCid) {
     // Deoptimizes if both arguments not Smi.
@@ -666,6 +698,7 @@
 
 
 void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ TraceSimMsg("RelationalOpInstr");
   if (operands_class_id() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
     return;
@@ -684,8 +717,9 @@
   // explicitly pushing arguments to the call here.
   Register left = locs()->in(0).reg();
   Register right = locs()->in(1).reg();
-  __ Push(left);
-  __ Push(right);
+  __ addiu(SP, SP, Immediate(-2 * kWordSize));
+  __ sw(left, Address(SP, 1 * kWordSize));
+  __ sw(right, Address(SP, 0 * kWordSize));
   if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
     Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp);
     // Load class into A2.
@@ -737,6 +771,7 @@
 
 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
                                        BranchInstr* branch) {
+  __ TraceSimMsg("RelationalOpInstr");
   if (operands_class_id() == kSmiCid) {
     EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
     return;
@@ -769,6 +804,7 @@
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  __ TraceSimMsg("NativeCallInstr");
   ASSERT(locs()->temp(0).reg() == A1);
   ASSERT(locs()->temp(1).reg() == A2);
   ASSERT(locs()->temp(2).reg() == T5);
@@ -853,57 +889,350 @@
 
 
 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 3;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(0, Location::RequiresRegister());
+  // The smi index is either untagged (element size == 1), or it is left smi
+  // tagged (for all element sizes > 1).
+  // TODO(regis): Revisit and see if the index can be immediate.
+  locs->set_in(1, Location::WritableRegister());
+  switch (class_id()) {
+    case kArrayCid:
+      locs->set_in(2, ShouldEmitStoreBarrier()
+                        ? Location::WritableRegister()
+                        : Location::RegisterOrConstant(value()));
+      break;
+    case kExternalTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+    case kTypedDataFloat32x4ArrayCid:
+      UNIMPLEMENTED();
+      break;
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+  return locs;
 }
 
 
 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  __ TraceSimMsg("StoreIndexedInstr");
+  Register array = locs()->in(0).reg();
+  Location index = locs()->in(1);
+
+  Address element_address(kNoRegister, 0);
+  if (IsExternal()) {
+    UNIMPLEMENTED();
+  } else {
+    ASSERT(this->array()->definition()->representation() == kTagged);
+    ASSERT(index.IsRegister());  // TODO(regis): Revisit.
+    // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
+    // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
+    // index is expected to be untagged before accessing.
+    ASSERT(kSmiTagShift == 1);
+    switch (index_scale()) {
+      case 1: {
+        __ SmiUntag(index.reg());
+        break;
+      }
+      case 2: {
+        break;
+      }
+      case 4: {
+        __ sll(index.reg(), index.reg(), 1);
+        break;
+      }
+      case 8: {
+        __ sll(index.reg(), index.reg(), 2);
+        break;
+      }
+      case 16: {
+        __ sll(index.reg(), index.reg(), 3);
+        break;
+      }
+      default:
+        UNREACHABLE();
+    }
+    __ AddImmediate(index.reg(),
+        FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
+    __ addu(TMP1, array, index.reg());
+    element_address = Address(TMP1);
+  }
+
+  switch (class_id()) {
+    case kArrayCid:
+      if (ShouldEmitStoreBarrier()) {
+        Register value = locs()->in(2).reg();
+        __ StoreIntoObject(array, element_address, value);
+      } else if (locs()->in(2).IsConstant()) {
+        const Object& constant = locs()->in(2).constant();
+        __ StoreIntoObjectNoBarrier(array, element_address, constant);
+      } else {
+        Register value = locs()->in(2).reg();
+        __ StoreIntoObjectNoBarrier(array, element_address, value);
+      }
+      break;
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+    case kTypedDataFloat32x4ArrayCid:
+      UNIMPLEMENTED();
+      break;
+    default:
+      UNREACHABLE();
+  }
 }
 
 
 LocationSummary* GuardFieldInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  if ((value()->Type()->ToCid() == kDynamicCid) &&
+      (field().guarded_cid() != kSmiCid)) {
+    summary->AddTemp(Location::RequiresRegister());
+  }
+  if (field().guarded_cid() == kIllegalCid) {
+    summary->AddTemp(Location::RequiresRegister());
+  }
+  return summary;
 }
 
 
 void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  __ TraceSimMsg("GuardFieldInstr");
+  const intptr_t field_cid = field().guarded_cid();
+  const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
+
+  if (field_cid == kDynamicCid) {
+    ASSERT(!compiler->is_optimizing());
+    return;  // Nothing to emit.
+  }
+
+  const intptr_t value_cid = value()->Type()->ToCid();
+
+  Register value_reg = locs()->in(0).reg();
+
+  Register value_cid_reg = ((value_cid == kDynamicCid) &&
+      (field_cid != kSmiCid)) ? locs()->temp(0).reg() : kNoRegister;
+
+  Register field_reg = (field_cid == kIllegalCid) ?
+      locs()->temp(locs()->temp_count() - 1).reg() : kNoRegister;
+
+  Label ok, fail_label;
+
+  Label* deopt = compiler->is_optimizing() ?
+      compiler->AddDeoptStub(deopt_id(), kDeoptGuardField) : NULL;
+
+  Label* fail = (deopt != NULL) ? deopt : &fail_label;
+
+  const bool ok_is_fall_through = (deopt != NULL);
+
+  if (!compiler->is_optimizing() || (field_cid == kIllegalCid)) {
+    if (!compiler->is_optimizing()) {
+      // Currently we can't have different location summaries for optimized
+      // and non-optimized code. So instead we manually pick up a register
+      // that is known to be free because we know how non-optimizing compiler
+      // allocates registers.
+      field_reg = A0;
+      ASSERT((field_reg != value_reg) && (field_reg != value_cid_reg));
+    }
+
+    __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
+
+    FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
+    FieldAddress field_nullability_operand(
+        field_reg, Field::is_nullable_offset());
+
+    if (value_cid == kDynamicCid) {
+      if (value_cid_reg == kNoRegister) {
+        ASSERT(!compiler->is_optimizing());
+        value_cid_reg = A1;
+        ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
+      }
+
+      LoadValueCid(compiler, value_cid_reg, value_reg);
+
+      __ lw(TMP1, field_cid_operand);
+      __ beq(value_cid_reg, TMP1, &ok);
+      __ lw(TMP1, field_nullability_operand);
+      __ subu(CMPRES, value_cid_reg, TMP1);
+    } else if (value_cid == kNullCid) {
+      // TODO(regis): TMP1 may conflict. Revisit.
+      __ lw(TMP1, field_nullability_operand);
+      __ LoadImmediate(TMP2, value_cid);
+      __ subu(CMPRES, TMP1, TMP2);
+    } else {
+      // TODO(regis): TMP1 may conflict. Revisit.
+      __ lw(TMP1, field_cid_operand);
+      __ LoadImmediate(TMP2, value_cid);
+      __ subu(CMPRES, TMP1, TMP2);
+    }
+    __ beq(CMPRES, ZR, &ok);
+
+    __ lw(TMP1, field_cid_operand);
+    __ BranchNotEqual(TMP1, kIllegalCid, fail);
+
+    if (value_cid == kDynamicCid) {
+      __ sw(value_cid_reg, field_cid_operand);
+      __ sw(value_cid_reg, field_nullability_operand);
+    } else {
+      __ LoadImmediate(TMP1, value_cid);
+      __ sw(TMP1, field_cid_operand);
+      __ sw(TMP1, field_nullability_operand);
+    }
+
+    if (!ok_is_fall_through) {
+      __ b(&ok);
+    }
+  } else {
+    if (value_cid == kDynamicCid) {
+      // Field's guarded class id is fixed by value's class id is not known.
+      __ andi(CMPRES, value_reg, Immediate(kSmiTagMask));
+
+      if (field_cid != kSmiCid) {
+        __ beq(CMPRES, ZR, fail);
+        __ LoadClassId(value_cid_reg, value_reg);
+        __ LoadImmediate(TMP1, field_cid);
+        __ subu(CMPRES, value_cid_reg, TMP1);
+      }
+
+      if (field().is_nullable() && (field_cid != kNullCid)) {
+        __ beq(CMPRES, ZR, &ok);
+        __ LoadImmediate(TMP1, reinterpret_cast<intptr_t>(Object::null()));
+        __ subu(CMPRES, value_reg, TMP1);
+      }
+
+      if (ok_is_fall_through) {
+        __ bne(CMPRES, ZR, fail);
+      } else {
+        __ beq(CMPRES, ZR, &ok);
+      }
+    } else {
+      // Both value's and field's class id is known.
+      if ((value_cid != field_cid) && (value_cid != nullability)) {
+        if (ok_is_fall_through) {
+          __ b(fail);
+        }
+      } else {
+        // Nothing to emit.
+        ASSERT(!compiler->is_optimizing());
+        return;
+      }
+    }
+  }
+
+  if (deopt == NULL) {
+    ASSERT(!compiler->is_optimizing());
+    __ Bind(fail);
+
+    __ lw(TMP1, FieldAddress(field_reg, Field::guarded_cid_offset()));
+    __ BranchEqual(TMP1, kDynamicCid, &ok);
+
+    __ addiu(SP, SP, Immediate(-2 * kWordSize));
+    __ sw(field_reg, Address(SP, 1 * kWordSize));
+    __ sw(value_reg, Address(SP, 0 * kWordSize));
+    __ CallRuntime(kUpdateFieldCidRuntimeEntry);
+    __ Drop(2);  // Drop the field and the value.
+  }
+
+  __ Bind(&ok);
 }
 
 
 LocationSummary* StoreInstanceFieldInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 2;
+  const intptr_t num_temps =  0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs, num_temps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  summary->set_in(1, ShouldEmitStoreBarrier()
+                       ? Location::WritableRegister()
+                       : Location::RegisterOrConstant(value()));
+  return summary;
 }
 
 
 void StoreInstanceFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  Register instance_reg = locs()->in(0).reg();
+  if (ShouldEmitStoreBarrier()) {
+    Register value_reg = locs()->in(1).reg();
+    __ StoreIntoObject(instance_reg,
+                       FieldAddress(instance_reg, field().Offset()),
+                       value_reg,
+                       CanValueBeSmi());
+  } else {
+    if (locs()->in(1).IsConstant()) {
+      __ StoreIntoObjectNoBarrier(
+          instance_reg,