Version 0.4.4.2

svn merge -r 20688:20748  https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@20761 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index 4c4eed1..b46dc45 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -183,7 +183,7 @@
 
 export 'package:unittest/matcher.dart' hide completes, completion;
 export 'package:unittest/unittest.dart' show
-    config, configure, Configuration, logMessage, expectThrow;
+    Configuration, logMessage, expectThrow;
 
 export 'src/schedule.dart';
 export 'src/schedule_error.dart';
@@ -344,3 +344,10 @@
 
   return currentSchedule.wrapFuture(future, description);
 }
+
+// TODO(nweiz): re-export these once issue 9535 is fixed.
+unittest.Configuration get unittestConfiguration =>
+  unittest.unittestConfiguration;
+void set unittestConfiguration(unittest.Configuration value) {
+  unittest.unittestConfiguration = value;
+}
diff --git a/pkg/scheduled_test/test/descriptor_test.dart b/pkg/scheduled_test/test/descriptor_test.dart
index baca328..f43e159 100644
--- a/pkg/scheduled_test/test/descriptor_test.dart
+++ b/pkg/scheduled_test/test/descriptor_test.dart
@@ -17,6 +17,12 @@
 String sandbox;
 
 void main() {
+  metaSetUp(() {
+    // The windows bots are very slow, so we increase the default timeout.
+    if (Platform.operatingSystem != "windows") return;
+    currentSchedule.timeout = new Duration(seconds: 10);
+  });
+
   expectTestsPass('file().create() creates a file', () {
     test('test', () {
       scheduleSandbox();
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 0771ff4..71ad421 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -15,6 +15,7 @@
 
 import 'package:pathos/path.dart' as path;
 import 'package:unittest/unittest.dart';
+import 'package:scheduled_test/scheduled_test.dart' as scheduled_test;
 
 import 'utils.dart';
 
@@ -71,6 +72,14 @@
   });
 }
 
+/// Runs [setUpFn] before every metatest. Note that [setUpFn] will be
+/// overwritten if the test itself calls [setUp].
+void metaSetUp(void setUpFn()) {
+  _inChildIsolate.then((inIsolate) {
+    if (inIsolate) scheduled_test.setUp(setUpFn);
+  });
+}
+
 /// Sets up a test with the given [description] and [body]. After the test runs,
 /// calls [validate] with the result map.
 void _setUpTest(String description, void body(), void validate(Map)) {
diff --git a/pkg/scheduled_test/test/scheduled_process_test.dart b/pkg/scheduled_test/test/scheduled_process_test.dart
index 9742947..4b89da1 100644
--- a/pkg/scheduled_test/test/scheduled_process_test.dart
+++ b/pkg/scheduled_test/test/scheduled_process_test.dart
@@ -16,6 +16,12 @@
 import 'utils.dart';
 
 void main() {
+  metaSetUp(() {
+    // The windows bots are very slow, so we increase the default timeout.
+    if (Platform.operatingSystem != "windows") return;
+    currentSchedule.timeout = new Duration(seconds: 10);
+  });
+
   expectTestsPass("a process must have kill() or shouldExit() called", () {
     var errors;
     test('test 1', () {
diff --git a/pkg/scheduled_test/test/scheduled_server_test.dart b/pkg/scheduled_test/test/scheduled_server_test.dart
index 19135e0..b34765c 100644
--- a/pkg/scheduled_test/test/scheduled_server_test.dart
+++ b/pkg/scheduled_test/test/scheduled_server_test.dart
@@ -16,6 +16,12 @@
 import 'utils.dart';
 
 void main() {
+  metaSetUp(() {
+    // The windows bots are very slow, so we increase the default timeout.
+    if (Platform.operatingSystem != "windows") return;
+    currentSchedule.timeout = new Duration(seconds: 10);
+  });
+
   expectTestsPass("a server with no handlers does nothing", () {
     test('test', () => new ScheduledServer());
   });
diff --git a/pkg/scheduled_test/test/scheduled_test_test.dart b/pkg/scheduled_test/test/scheduled_test_test.dart
index b3c8477..b1c0acb 100644
--- a/pkg/scheduled_test/test/scheduled_test_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test_test.dart
@@ -5,6 +5,7 @@
 library scheduled_test_test;
 
 import 'dart:async';
+import 'dart:io';
 
 import 'package:scheduled_test/scheduled_test.dart';
 import 'package:scheduled_test/src/mock_clock.dart' as mock_clock;
@@ -13,6 +14,12 @@
 import 'utils.dart';
 
 void main() {
+  metaSetUp(() {
+    // The windows bots are very slow, so we increase the default timeout.
+    if (Platform.operatingSystem != "windows") return;
+    currentSchedule.timeout = new Duration(seconds: 10);
+  });
+
   expectTestsPass('a scheduled test with a correct synchronous expectation '
       'should pass', () {
     test('test', () {
diff --git a/pkg/stack_trace/lib/src/frame.dart b/pkg/stack_trace/lib/src/frame.dart
index fdf4fe0..5f0777c 100644
--- a/pkg/stack_trace/lib/src/frame.dart
+++ b/pkg/stack_trace/lib/src/frame.dart
@@ -9,6 +9,7 @@
 import 'package:pathos/path.dart' as path;
 
 import 'trace.dart';
+import 'utils.dart';
 
 final _nativeFrameRegExp = new RegExp(
     r'^#\d+\s+([^\s].*) \((.+):(\d+):(\d+)\)$');
@@ -42,7 +43,7 @@
   String get library {
     // TODO(nweiz): handle relative URIs here as well once pathos supports that.
     if (uri.scheme != 'file') return uri.toString();
-    return path.relative(uri.path);
+    return path.relative(fileUriToPath(uri));
   }
 
   /// A human-friendly description of the code location.
diff --git a/pkg/stack_trace/lib/src/utils.dart b/pkg/stack_trace/lib/src/utils.dart
new file mode 100644
index 0000000..790dec8
--- /dev/null
+++ b/pkg/stack_trace/lib/src/utils.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library utils;
+
+import 'dart:io';
+import 'dart:uri';
+
+import 'package:pathos/path.dart' as path;
+
+/// Converts a `file:` [Uri] to a local path string.
+String fileUriToPath(Uri uri) {
+  if (uri.scheme != 'file') {
+    throw new ArgumentError("Uri $uri must have scheme 'file:'.");
+  }
+  if (Platform.operatingSystem != 'windows') return uri.path;
+  return uri.path.replaceFirst("/", "").replaceAll("/", "\\");
+}
+
+/// Converts a local path string to a `file:` [Uri].
+Uri pathToFileUri(String pathString) {
+  pathString = path.absolute(pathString);
+  if (Platform.operatingSystem != 'windows') {
+    return Uri.parse('file://$pathString');
+  } else {
+    return Uri.parse('file:///${pathString.replaceAll("\\", "/")}');
+  }
+}
diff --git a/pkg/stack_trace/test/frame_test.dart b/pkg/stack_trace/test/frame_test.dart
index 5c5a32e..c65f395 100644
--- a/pkg/stack_trace/test/frame_test.dart
+++ b/pkg/stack_trace/test/frame_test.dart
@@ -8,6 +8,7 @@
 import 'dart:uri';
 
 import 'package:pathos/path.dart' as path;
+import 'package:stack_trace/src/utils.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:unittest/unittest.dart';
 
@@ -42,7 +43,7 @@
     // TODO(nweiz): use URL-style paths when such a thing exists.
     var builder = new path.Builder(style: path.Style.posix);
     expect(builder.basename(frame.uri.path), equals('frame_test.dart'));
-    expect(frame.line, equals(16));
+    expect(frame.line, equals(17));
     expect(frame.column, equals(5));
     expect(frame.member, equals('getStackFrame'));
   });
@@ -113,7 +114,7 @@
     });
 
     test('returns the relative path for file URIs', () {
-      var uri = _pathToFileUri(path.join('foo', 'bar.dart'));
+      var uri = pathToFileUri(path.join('foo', 'bar.dart'));
       expect(new Frame.parse('#0 Foo ($uri:0:0)').library,
           equals(path.join('foo', 'bar.dart')));
     });
@@ -125,7 +126,7 @@
       expect(new Frame.parse('#0 Foo '
               '(http://dartlang.org/thing.dart:5:10)').location,
           equals('http://dartlang.org/thing.dart 5:10'));
-      var uri = _pathToFileUri(path.join('foo', 'bar.dart'));
+      var uri = pathToFileUri(path.join('foo', 'bar.dart'));
       expect(new Frame.parse('#0 Foo ($uri:1:2)').location,
           equals('${path.join('foo', 'bar.dart')} 1:2'));
     });
@@ -158,9 +159,3 @@
     });
   });
 }
-
-String _pathToFileUri(String pathString) {
-  pathString = path.absolute(pathString);
-  if (Platform.operatingSystem != 'windows') return 'file://$pathString';
-  return 'file:///${pathString.replaceAll("\\", "/")}';
-}
diff --git a/pkg/stack_trace/test/trace_test.dart b/pkg/stack_trace/test/trace_test.dart
index 2cbe48d..ed8fa6b 100644
--- a/pkg/stack_trace/test/trace_test.dart
+++ b/pkg/stack_trace/test/trace_test.dart
@@ -8,6 +8,7 @@
 import 'dart:uri';
 
 import 'package:pathos/path.dart' as path;
+import 'package:stack_trace/src/utils.dart';
 import 'package:stack_trace/stack_trace.dart';
 import 'package:unittest/unittest.dart';
 
@@ -91,7 +92,7 @@
   });
 
   test('.toString() nicely formats the stack trace', () {
-    var uri = _pathToFileUri(path.join('foo', 'bar.dart'));
+    var uri = pathToFileUri(path.join('foo', 'bar.dart'));
     var trace = new Trace.parse('''
 #0      Foo._bar ($uri:42:21)
 #1      zip.<anonymous closure>.zap (dart:async:0:2)
@@ -133,9 +134,3 @@
 '''));
   });
 }
-
-String _pathToFileUri(String pathString) {
-  pathString = path.absolute(pathString);
-  if (Platform.operatingSystem != 'windows') return 'file://$pathString';
-  return 'file:///${pathString.replaceAll("\\", "/")}';
-}
diff --git a/pkg/unittest/test/unittest_test.dart b/pkg/unittest/test/unittest_test.dart
index 9621d92..7f62c50 100644
--- a/pkg/unittest/test/unittest_test.dart
+++ b/pkg/unittest/test/unittest_test.dart
@@ -14,6 +14,10 @@
 import 'dart:async';
 import 'package:unittest/unittest.dart';
 
+var tests; // array of test names
+var expected; // array of test expected results (from buildStatusString)
+var actual; // actual test results (from buildStatusString in config.onDone)
+
 Future _defer(void fn()) {
   return new Future.of(fn);
 }
@@ -67,7 +71,7 @@
 }
 
 runTest() {
-  port.receive((String testName, sendport) {
+  port.receive((testName, sendport) {
     var _testconfig= new TestConfiguration(sendport);
     unittestConfiguration = _testconfig;
 
@@ -299,34 +303,63 @@
   });
 }
 
+void nextTest(int testNum) {
+  SendPort sport = spawnFunction(runTest);
+  sport.call(tests[testNum]).then((msg) {
+    actual.add(msg);
+    if (actual.length == expected.length) {
+      for (var i = 0; i < tests.length; i++) {
+        test(tests[i], () => expect(actual[i].trim(), equals(expected[i])));
+      }
+    } else {
+      nextTest(testNum+1);
+    }
+  });
+}
+
 main() {
-  var tests = {
-    'single correct test': buildStatusString(1, 0, 0, 'single correct test'),
-    'single failing test': buildStatusString(0, 1, 0, 'single failing test',
+  tests = [
+    'single correct test',
+    'single failing test',
+    'exception test',
+    'group name test',
+    'setup test',
+    'teardown test',
+    'setup and teardown test',
+    'correct callback test',
+    'excess callback test',
+    'completion test',
+    'async exception test',
+    'late exception test',
+    'middle exception test',
+    'async setup/teardown test',
+    'test returning future',
+    'test returning future using Timer',
+    'testCases immutable'
+  ];
+
+  expected = [
+    buildStatusString(1, 0, 0, tests[0]),
+    buildStatusString(0, 1, 0, tests[1],
         message: 'Expected: <5> but: was <4>.'),
-    'exception test': buildStatusString(0, 1, 0, 'exception test',
-        message: 'Caught Exception: Fail.'),
-    'group name test': buildStatusString(2, 0, 0, 'a a::a b b'),
-    'setup test': buildStatusString(1, 0, 0, 'a setup test',
-        count: 0, setup: 'setup'),
-    'teardown test': buildStatusString(1, 0, 0, 'a teardown test',
-        count: 0, setup: '', teardown: 'teardown'),
-    'setup and teardown test': buildStatusString(1, 0, 0,
-        'a setup and teardown test', count: 0, setup: 'setup',
+    buildStatusString(0, 1, 0, tests[2], message: 'Caught Exception: Fail.'),
+    buildStatusString(2, 0, 0, 'a a::a b b'),
+    buildStatusString(1, 0, 0, 'a ${tests[4]}', count: 0, setup: 'setup'),
+    buildStatusString(1, 0, 0, 'a ${tests[5]}', count: 0, setup: '',
         teardown: 'teardown'),
-    'correct callback test': buildStatusString(1, 0, 0, 'correct callback test',
-        count: 1),
-    'excess callback test': buildStatusString(0, 1, 0, 'excess callback test',
-        count: 1, message: 'Callback called more times than expected (1).'),
-    'completion test': buildStatusString(1, 0, 0, 'completion test', count: 10),
-    'async exception test': buildStatusString(0, 1, 0, 'async exception test',
-        message: 'Caught error!'),
-    'late exception test': buildStatusString(1, 0, 1, 'testOne',
+    buildStatusString(1, 0, 0, 'a ${tests[6]}', count: 0,
+        setup: 'setup', teardown: 'teardown'),
+    buildStatusString(1, 0, 0, tests[7], count: 1),
+    buildStatusString(0, 1, 0, tests[8], count: 1,
+        message: 'Callback called more times than expected (1).'),
+    buildStatusString(1, 0, 0, tests[9], count: 10),
+    buildStatusString(0, 1, 0, tests[10], message: 'Caught error!'),
+    buildStatusString(1, 0, 1, 'testOne',
         message: 'Callback called (2) after test case testOne has already '
                  'been marked as pass.:testTwo:'),
-    'middle exception test': buildStatusString(2, 1, 0,
+    buildStatusString(2, 1, 0,
         'testOne::testTwo:Expected: false but: was <true>.:testThree'),
-    'async setup/teardown test': buildStatusString(2, 0, 3,
+    buildStatusString(2, 0, 3,
         'good setup/good teardown foo1::'
         'good setup/bad teardown foo2:good setup/bad teardown '
         'foo2: Test teardown failed: Failed to complete tearDown:'
@@ -335,28 +368,25 @@
         'bad setup/bad teardown foo4:bad setup/bad teardown '
         'foo4: Test teardown failed: Failed to complete tearDown:'
         'post groups'),
-    'test returning future': buildStatusString(2, 4, 0,
+    buildStatusString(2, 4, 0,
         'successful::'
         'error1:Callback called more times than expected (1).:'
         'fail1:Expected: <false> but: was <true>.:'
         'error2:Callback called more times than expected (1).:'
         'fail2:failure:'
         'foo5'),
-    'test returning future using Timer': buildStatusString(2, 4, 0,
+    buildStatusString(2, 4, 0,
         'successful::'
         'fail1:Expected: <false> but: was <true>.:'
         'error1:Callback called more times than expected (1).:'
         'fail2:failure:'
         'error2:Callback called more times than expected (1).:'
         'foo6'),
-    'testCases immutable':
-        buildStatusString(1, 0, 0, 'testCases immutable'),
-  };
+    buildStatusString(1, 0, 0, 'testCases immutable'),
+  ];
 
-  tests.forEach((String name, String expected) {
-    test(name, () => spawnFunction(runTest)
-        .call(name)
-        .then((String msg) => expect(msg.trim(), equals(expected))));
-    });
+  actual = [];
+
+  nextTest(0);
 }
 
diff --git a/runtime/embedders/openglui/android/android_input_handler.h b/runtime/embedders/openglui/android/android_input_handler.h
index d1e8d2a..420e459 100644
--- a/runtime/embedders/openglui/android/android_input_handler.h
+++ b/runtime/embedders/openglui/android/android_input_handler.h
@@ -5,7 +5,6 @@
 #ifndef EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
 #define EMBEDDERS_OPENGLUI_ANDROID_ANDROID_INPUT_HANDLER_H_
 
-#include "embedders/openglui/android/android_sensor.h"
 #include "embedders/openglui/common/graphics_handler.h"
 #include "embedders/openglui/common/input_handler.h"
 
diff --git a/runtime/embedders/openglui/android/android_sound_handler.cc b/runtime/embedders/openglui/android/android_sound_handler.cc
index a40c1ba..de9e977 100644
--- a/runtime/embedders/openglui/android/android_sound_handler.cc
+++ b/runtime/embedders/openglui/android/android_sound_handler.cc
@@ -19,7 +19,6 @@
       sample_player_(NULL),
       sample_player_if_(NULL),
       sample_player_queue_(NULL) {
-  SoundHandler::instance_ = this;
 }
 
 int32_t AndroidSoundHandler::Start() {
diff --git a/runtime/embedders/openglui/android/main.cc b/runtime/embedders/openglui/android/main.cc
index 4844a3d..c0c386b 100644
--- a/runtime/embedders/openglui/android/main.cc
+++ b/runtime/embedders/openglui/android/main.cc
@@ -5,7 +5,6 @@
 #include "embedders/openglui/android/android_graphics_handler.h"
 #include "embedders/openglui/android/android_input_handler.h"
 #include "embedders/openglui/android/android_resource.h"
-#include "embedders/openglui/android/android_sensor.h"
 #include "embedders/openglui/android/android_sound_handler.h"
 #include "embedders/openglui/android/eventloop.h"
 #include "embedders/openglui/common/context.h"
diff --git a/runtime/embedders/openglui/common/gl.dart b/runtime/embedders/openglui/common/gl.dart
index 084338c..f709000 100644
--- a/runtime/embedders/openglui/common/gl.dart
+++ b/runtime/embedders/openglui/common/gl.dart
@@ -576,143 +576,143 @@
 //------------------------------------------------------------------
 // 2D canvas support
 
-int SetWidth(int handle, int width)
-    native "CanvasSetWidth";
-int SetHeight(int handle, int height)
-    native "CanvasSetHeight";
+int _SetWidth(int handle, int width)
+    native "C2DSetWidth";
+int _SetHeight(int handle, int height)
+    native "C2DSetHeight";
 
-double SetGlobalAlpha(int handle, double globalAlpha)
-    native "CanvasSetGlobalAlpha";
-void SetFillStyle(int handle, fs)
-    native "CanvasSetFillStyle";
-String SetFont(int handle, String font)
-    native "CanvasSetFont";
-void SetGlobalCompositeOperation(int handle, String op)
-    native "CanvasSetGlobalCompositeOperation";
-SetLineCap(int handle, String lc)
-    native "CanvasSetLineCap";
-SetLineJoin(int handle, String lj)
-    native "CanvasSetLineJoin";
-SetLineWidth(int handle, double w)
-    native "CanvasSetLineWidth";
-SetMiterLimit(int handle, double limit)
-    native "CanvasSetMiterLimit";
-SetShadowBlur(int handle, double blur)
-    native "CanvasSetShadowBlur";
-SetShadowColor(int handle, String color)
-    native "CanvasSetShadowColor";
-SetShadowOffsetX(int handle, double offset)
-    native "CanvasSetShadowOffsetX";
-SetShadowOffsetY(int handle, double offset)
-    native "CanvasSetShadowOffsetY";
-void SetStrokeStyle(int handle, ss)
-    native "CanvasSetStrokeStyle";
-String SetTextAlign(int handle, String align)
-    native "CanvasSetTextAlign";
-String SetTextBaseline(int handle, String baseline)
-    native "CanvasSetTextBaseline";
-GetBackingStorePixelRatio(int handle)
-    native "CanvasGetBackingStorePixelRatio";
-void SetImageSmoothingEnabled(int handle, bool ise)
-    native "CanvasSetImageSmoothingEnabled";    
-void SetLineDash(int handle, List v)
-    native "CanvasSetLineDash";
-SetLineDashOffset(int handle, int v)
-    native "CanvasSetLineDashOffset";
-void Arc(int handle, double x, double y, double radius,
+double _SetGlobalAlpha(int handle, double globalAlpha)
+    native "C2DSetGlobalAlpha";
+void _SetFillStyle(int handle, fs)
+    native "C2DSetFillStyle";
+String _SetFont(int handle, String font)
+    native "C2DSetFont";
+void _SetGlobalCompositeOperation(int handle, String op)
+    native "C2DSetGlobalCompositeOperation";
+_SetLineCap(int handle, String lc)
+    native "C2DSetLineCap";
+_SetLineJoin(int handle, String lj)
+    native "C2DSetLineJoin";
+_SetLineWidth(int handle, double w)
+    native "C2DSetLineWidth";
+_SetMiterLimit(int handle, double limit)
+    native "C2DSetMiterLimit";
+_SetShadowBlur(int handle, double blur)
+    native "C2DSetShadowBlur";
+_SetShadowColor(int handle, String color)
+    native "C2DSetShadowColor";
+_SetShadowOffsetX(int handle, double offset)
+    native "C2DSetShadowOffsetX";
+_SetShadowOffsetY(int handle, double offset)
+    native "C2DSetShadowOffsetY";
+void _SetStrokeStyle(int handle, ss)
+    native "C2DSetStrokeStyle";
+String _SetTextAlign(int handle, String align)
+    native "C2DSetTextAlign";
+String _SetTextBaseline(int handle, String baseline)
+    native "C2DSetTextBaseline";
+_GetBackingStorePixelRatio(int handle)
+    native "C2DGetBackingStorePixelRatio";
+void _SetImageSmoothingEnabled(int handle, bool ise)
+    native "C2DSetImageSmoothingEnabled";    
+void _SetLineDash(int handle, List v)
+    native "C2DSetLineDash";
+_SetLineDashOffset(int handle, int v)
+    native "C2DSetLineDashOffset";
+void _Arc(int handle, double x, double y, double radius,
     double startAngle, double endAngle, [bool anticlockwise = false])
-    native "CanvasArc";
-void ArcTo(int handle, double x1, double y1,
+    native "C2DArc";
+void _ArcTo(int handle, double x1, double y1,
               double x2, double y2, double radius)
-    native "CanvasArcTo"; 
-void ArcTo2(int handle, double x1, double y1,
+    native "C2DArcTo"; 
+void _ArcTo2(int handle, double x1, double y1,
                double x2, double y2, double radiusX,
     double radiusY, double rotation)
-    native "CanvasArcTo2"; 
-void BeginPath(int handle)
-    native "CanvasBeginPath";
-void BezierCurveTo(int handle, double cp1x, double cp1y,
+    native "C2DArcTo2"; 
+void _BeginPath(int handle)
+    native "C2DBeginPath";
+void _BezierCurveTo(int handle, double cp1x, double cp1y,
                       double cp2x, double cp2y, double x, double y)
-    native "CanvasBezierCurveTo";
-void ClearRect(int handle, double x, double y, double w, double h)
-    native "CanvasClearRect";
-void Clip(int handle)
-    native "CanvasClip";
-void ClosePath(int handle)
-    native "CanvasClosePath";
-ImageData CreateImageDataFromDimensions(int handle, num w, num h)
-    native "CanvasCreateImageDataFromDimensions";
-void DrawImage(int handle, String src_url,
+    native "C2DBezierCurveTo";
+void _ClearRect(int handle, double x, double y, double w, double h)
+    native "C2DClearRect";
+void _Clip(int handle)
+    native "C2DClip";
+void _ClosePath(int handle)
+    native "C2DClosePath";
+ImageData _CreateImageDataFromDimensions(int handle, num w, num h)
+    native "C2DCreateImageDataFromDimensions";
+void _DrawImage(int handle, String src_url,
                   int sx, int sy,
                   bool has_src_dimensions, int sw, int sh,
                   int dx, int dy,
                   bool has_dst_dimensions, int dw, int dh)
-    native "CanvasDrawImage";
-void Fill(int handle)
-    native "CanvasFill";
-void FillRect(int handle, double x, double y, double w, double h)
-    native "CanvasFillRect";
-void FillText(int handle, String text, double x, double y, double maxWidth)
-    native "CanvasFillText";
-ImageData GetImageData(num sx, num sy, num sw, num sh)
-    native "CanvasGetImageData";    
-void LineTo(int handle, double x, double y)
-    native "CanvasLineTo";
-double MeasureText(int handle, String text)
-    native "CanvasMeasureText";
-void MoveTo(int handle, double x, double y)
-    native "CanvasMoveTo";
-void PutImageData(int handle, ImageData imagedata, double dx, double dy)
-    native "CanvasPutImageData";    
-void QuadraticCurveTo(int handle, double cpx, double cpy,
+    native "C2DDrawImage";
+void _Fill(int handle)
+    native "C2DFill";
+void _FillRect(int handle, double x, double y, double w, double h)
+    native "C2DFillRect";
+void _FillText(int handle, String text, double x, double y, double maxWidth)
+    native "C2DFillText";
+ImageData _GetImageData(num sx, num sy, num sw, num sh)
+    native "C2DGetImageData";    
+void _LineTo(int handle, double x, double y)
+    native "C2DLineTo";
+double _MeasureText(int handle, String text)
+    native "C2DMeasureText";
+void _MoveTo(int handle, double x, double y)
+    native "C2DMoveTo";
+void _PutImageData(int handle, ImageData imagedata, double dx, double dy)
+    native "C2DPutImageData";    
+void _QuadraticCurveTo(int handle, double cpx, double cpy,
     double x, double y)
-        native "CanvasQuadraticCurveTo";
-void Rect(int handle, double x, double y, double w, double h)
-    native "CanvasRect";
-void Restore(int handle)
-    native "CanvasRestore";
-void Rotate(int handle, double a)
-    native "CanvasRotate";
-void Save(int handle)
-    native "CanvasSave";
-void Scale(int handle, double sx, double sy)
-    native "CanvasScale";
-void SetTransform(int handle, double m11, double m12,
+        native "C2DQuadraticCurveTo";
+void _Rect(int handle, double x, double y, double w, double h)
+    native "C2DRect";
+void _Restore(int handle)
+    native "C2DRestore";
+void _Rotate(int handle, double a)
+    native "C2DRotate";
+void _Save(int handle)
+    native "C2DSave";
+void _Scale(int handle, double sx, double sy)
+    native "C2DScale";
+void _SetTransform(int handle, double m11, double m12,
                      double m21, double m22, double dx, double dy)
-    native "CanvasSetTransform";
-void Stroke(int handle)
-    native "CanvasStroke";
-void StrokeRect(int handle, double x, double y, double w, double h)
-    native "CanvasStrokeRect";    
-void StrokeText(int handle, String text, double x, double y,
+    native "C2DSetTransform";
+void _Stroke(int handle)
+    native "C2DStroke";
+void _StrokeRect(int handle, double x, double y, double w, double h)
+    native "C2DStrokeRect";    
+void _StrokeText(int handle, String text, double x, double y,
     double maxWidth)
-        native "CanvasStrokeText";
-void Transform(int handle, double m11, double m12,
+        native "C2DStrokeText";
+void _Transform(int handle, double m11, double m12,
                   double m21, double m22, double dx, double dy)
-    native "CanvasTransform";
-void Translate(int handle, double x, double y)
-    native "CanvasTranslate";
+    native "C2DTransform";
+void _Translate(int handle, double x, double y)
+    native "C2DTranslate";
 
-void CreateNativeContext(int handle, int width, int height)
-    native "CanvasCreateNativeContext";
+void _CreateNativeContext(int handle, int width, int height)
+    native "C2DCreateNativeContext";
 
-void SetFillGradient(int handle, bool isRadial,
+void _SetFillGradient(int handle, bool isRadial,
         double x0, double y0, double r0,
         double x1, double y1, double r1,
         List<double> positions, List<String> colors)
-    native "CanvasSetFillGradient";
+    native "C2DSetFillGradient";
 
-void SetStrokeGradient(int handle, bool isRadial,
+void _SetStrokeGradient(int handle, bool isRadial,
         double x0, double y0, double r0,
         double x1, double y1, double r1,
         List<double> positions, List<String> colors)
-    native "CanvasSetStrokeGradient";
+    native "C2DSetStrokeGradient";
 
-int GetImageWidth(String url)
-    native "CanvasGetImageWidth";
+int _GetImageWidth(String url)
+    native "C2DGetImageWidth";
 
-int GetImageHeight(String url)
-    native "CanvasGetImageHeight";
+int _GetImageHeight(String url)
+    native "C2DGetImageHeight";
 
 class CanvasGradient {
   num _x0, _y0, _r0 = 0, _x1, _y1, _r1 = 0;
@@ -733,14 +733,14 @@
       : _isRadial = true;
 
   void setAsFillStyle(_handle) {
-    SetFillGradient(_handle, _isRadial,
+    _SetFillGradient(_handle, _isRadial,
         _x0.toDouble(), _y0.toDouble(), _r0.toDouble(),
         _x1.toDouble(), _y1.toDouble(), _r1.toDouble(),
         _colorStopPositions, _colorStopColors);
   }
 
   void setAsStrokeStyle(_handle) {
-    SetStrokeGradient(_handle, _isRadial,
+    _SetStrokeGradient(_handle, _isRadial,
         _x0.toDouble(), _y0.toDouble(), _r0.toDouble(),
         _x1.toDouble(), _y1.toDouble(), _r1.toDouble(),
         _colorStopPositions, _colorStopColors);
@@ -772,8 +772,8 @@
     }
   }
 
-  get width => _width == null ? _width = GetImageWidth(_src) : _width;
-  get height => _height == null ? _height = GetImageHeight(_src) : _height;
+  get width => _width == null ? _width = _GetImageWidth(_src) : _width;
+  get height => _height == null ? _height = _GetImageHeight(_src) : _height;
   set width(int widthp) => _width = widthp;
   set height(int heightp) => _height = heightp;
 
@@ -782,8 +782,8 @@
       _width = widthp,
       _height = heightp {
     if (_src != null) {
-      if (_width == null) _width = GetImageWidth(_src);
-      if (_height == null) _height = GetImageHeight(_src);
+      if (_width == null) _width = _GetImageWidth(_src);
+      if (_height == null) _height = _GetImageHeight(_src);
     }
   }
 }
@@ -826,12 +826,12 @@
   CanvasRenderingContext2D(canvas, width, height) : super(canvas) {
     _width = width;
     _height = height;
-    CreateNativeContext(_handle = next_handle++, width, height);
+    _CreateNativeContext(_handle = next_handle++, width, height);
   }
 
   double _alpha = 1.0;
   set globalAlpha(num a) {
-    _alpha = SetGlobalAlpha(_handle, a.toDouble());
+    _alpha = _SetGlobalAlpha(_handle, a.toDouble());
   }
   get globalAlpha => _alpha;
 
@@ -844,46 +844,46 @@
     if (fs is CanvasGradient) {
       fs.setAsFillStyle(_handle);
     } else {
-      SetFillStyle(_handle, fs);
+      _SetFillStyle(_handle, fs);
     }
   }
   get fillStyle => _fillStyle;
 
   String _font = "10px sans-serif";
-  set font(String f) { _font = SetFont(_handle, f); }
+  set font(String f) { _font = _SetFont(_handle, f); }
   get font => _font;
 
   String _globalCompositeOperation = "source-over";
   set globalCompositeOperation(String o) =>
-      SetGlobalCompositeOperation(_handle, _globalCompositeOperation = o);
+      _SetGlobalCompositeOperation(_handle, _globalCompositeOperation = o);
   get globalCompositeOperation => _globalCompositeOperation;
 
   String _lineCap = "butt"; // "butt", "round", "square"
   get lineCap => _lineCap;
-  set lineCap(String lc) => SetLineCap(_handle, _lineCap = lc);
+  set lineCap(String lc) => _SetLineCap(_handle, _lineCap = lc);
 
   int _lineDashOffset = 0;
   get lineDashOffset => _lineDashOffset;
   set lineDashOffset(num v) {
     _lineDashOffset = v.toInt();
-    SetLineDashOffset(_handle, _lineDashOffset);
+    _SetLineDashOffset(_handle, _lineDashOffset);
   }
 
   String _lineJoin = "miter"; // "round", "bevel", "miter"
   get lineJoin => _lineJoin;
-  set lineJoin(String lj) =>  SetLineJoin(_handle, _lineJoin = lj);
+  set lineJoin(String lj) =>  _SetLineJoin(_handle, _lineJoin = lj);
 
   num _lineWidth = 1.0;
   get lineWidth => _lineWidth;
   set lineWidth(num w) {
-    SetLineWidth(_handle, w.toDouble());
+    _SetLineWidth(_handle, w.toDouble());
     _lineWidth = w;
   }
 
   num _miterLimit = 10.0; // (default 10)
   get miterLimit => _miterLimit;
   set miterLimit(num limit) {
-    SetMiterLimit(_handle, limit.toDouble());
+    _SetMiterLimit(_handle, limit.toDouble());
     _miterLimit = limit;
   }
 
@@ -891,26 +891,26 @@
   get shadowBlur =>  _shadowBlur;
   set shadowBlur(num blur) {
     _shadowBlur = blur;
-    SetShadowBlur(_handle, blur.toDouble());
+    _SetShadowBlur(_handle, blur.toDouble());
   }
 
   String _shadowColor;
   get shadowColor => _shadowColor;
   set shadowColor(String color) =>
-      SetShadowColor(_handle, _shadowColor = color);
+      _SetShadowColor(_handle, _shadowColor = color);
   
   num _shadowOffsetX;
   get shadowOffsetX => _shadowOffsetX;
   set shadowOffsetX(num offset) {
     _shadowOffsetX = offset;
-    SetShadowOffsetX(_handle, offset.toDouble());
+    _SetShadowOffsetX(_handle, offset.toDouble());
   }
 
   num _shadowOffsetY;
   get shadowOffsetY => _shadowOffsetY;
   set shadowOffsetY(num offset) {
     _shadowOffsetY = offset;
-    SetShadowOffsetY(_handle, offset.toDouble());
+    _SetShadowOffsetY(_handle, offset.toDouble());
   }
 
   var _strokeStyle = "#000";
@@ -921,24 +921,24 @@
     if (ss is CanvasGradient) {
       ss.setAsStrokeStyle(_handle);
     } else {
-      SetStrokeStyle(_handle, ss);
+      _SetStrokeStyle(_handle, ss);
     }
   }
 
   String _textAlign = "start";
   get textAlign => _textAlign;
-  set textAlign(String a) { _textAlign = SetTextAlign(_handle, a); }
+  set textAlign(String a) { _textAlign = _SetTextAlign(_handle, a); }
 
   String _textBaseline = "alphabetic";
   get textBaseline => _textBaseline;
-  set textBaseline(String b) { _textBaseline = SetTextBaseline(_handle, b); }
+  set textBaseline(String b) { _textBaseline = _SetTextBaseline(_handle, b); }
 
-  get webkitBackingStorePixelRatio => GetBackingStorePixelRatio(_handle);
+  get webkitBackingStorePixelRatio => _GetBackingStorePixelRatio(_handle);
 
   bool _webkitImageSmoothingEnabled;
   get webkitImageSmoothingEnabled => _webkitImageSmoothingEnabled;
   set webkitImageSmoothingEnabled(bool v) =>
-     SetImageSmoothingEnabled(_webkitImageSmoothingEnabled = v);
+     _SetImageSmoothingEnabled(_webkitImageSmoothingEnabled = v);
 
   get webkitLineDash => lineDash;
   set webkitLineDash(List v) => lineDash = v;
@@ -952,7 +952,7 @@
     if (radius < 0) {
       // throw IndexSizeError
     } else {
-      Arc(_handle, x.toDouble(), y.toDouble(), radius.toDouble(),
+      _Arc(_handle, x.toDouble(), y.toDouble(), radius.toDouble(),
           a1.toDouble(), a2.toDouble(), anticlockwise);
     }
   }
@@ -962,37 +962,37 @@
   void arcTo(num x1, num y1, num x2, num y2,
     num radiusX, [num radiusY, num rotation]) {
     if (radiusY == null) {
-      ArcTo(_handle, x1.toDouble(), y1.toDouble(),
+      _ArcTo(_handle, x1.toDouble(), y1.toDouble(),
                         x2.toDouble(), y2.toDouble(), radiusX.toDouble());
     } else {
-      ArcTo2(_handle, x1.toDouble(), y1.toDouble(),
+      _ArcTo2(_handle, x1.toDouble(), y1.toDouble(),
                          x2.toDouble(), y2.toDouble(),
                          radiusX.toDouble(), radiusY.toDouble(),
                          rotation.toDouble());
     }
   }
 
-  void beginPath() => BeginPath(_handle);
+  void beginPath() => _BeginPath(_handle);
 
   void bezierCurveTo(num cp1x, num cp1y, num cp2x, num cp2y,
     num x, num y) =>
-    BezierCurveTo(_handle, cp1x.toDouble(), cp1y.toDouble(),
+    _BezierCurveTo(_handle, cp1x.toDouble(), cp1y.toDouble(),
                               cp2x.toDouble(), cp2y.toDouble(),
                               x.toDouble(), y.toDouble());
 
   void clearRect(num x, num y, num w, num h) =>
-    ClearRect(_handle, x.toDouble(), y.toDouble(),
+    _ClearRect(_handle, x.toDouble(), y.toDouble(),
         w.toDouble(), h.toDouble());
 
-  void clip() => Clip(_handle);
+  void clip() => _Clip(_handle);
 
-  void closePath() => ClosePath(_handle);
+  void closePath() => _ClosePath(_handle);
 
   ImageData createImageData(var imagedata_OR_sw, [num sh = null]) {
     if (sh == null) {
       throw new Exception('Unimplemented createImageData(imagedata)');
     } else {
-      return CreateImageDataFromDimensions(_handle, imagedata_OR_sw, sh);
+      return _CreateImageDataFromDimensions(_handle, imagedata_OR_sw, sh);
     }
   }
 
@@ -1009,7 +1009,7 @@
     return new CanvasGradient.radial(x0, y0, r0, x1, y1, r1);
   }
 
-  void drawImage(element, num x1, num y1,
+  void _drawImage(element, num x1, num y1,
                 [num w1, num h1, num x2, num y2, num w2, num h2]) {
     if (element == null || element.src == null || element.src.length == 0) {
       throw "drawImage called with no valid src";
@@ -1019,40 +1019,56 @@
     var w = (element.width == null) ? 0 : element.width;
     var h = (element.height == null) ?  0 : element.height;
     if (!?w1) { // drawImage(element, dx, dy)
-      DrawImage(_handle, element.src, 0, 0, false, w, h,
+      _DrawImage(_handle, element.src, 0, 0, false, w, h,
                    x1.toInt(), y1.toInt(), false, 0, 0);
     } else if (!?x2) {  // drawImage(element, dx, dy, dw, dh)
-      DrawImage(_handle, element.src, 0, 0, false, w, h,
+      _DrawImage(_handle, element.src, 0, 0, false, w, h,
                    x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt());
     } else {  // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
-      DrawImage(_handle, element.src, 
+      _DrawImage(_handle, element.src, 
                    x1.toInt(), y1.toInt(), true, w1.toInt(), h1.toInt(),
                    x2.toInt(), y2.toInt(), true, w2.toInt(), h2.toInt());
     }
   }
 
-  void drawImageAtScale(element, Rect dest, {Rect sourceRect}) {
+  void drawImage(source, num destX, num destY) {
+    _drawImage(source, destX, destY);
+  }
+
+  void drawImageScaled(source,
+      num destX, num destY, num destWidth, num destHeight) {
+    _drawImage(source, destX,  destY, destWidth, destHeight);
+  }
+
+  void drawImageScaledFromSource(source,
+      num sourceX, num sourceY, num sourceWidth, num sourceHeight,
+      num destX, num destY, num destWidth, num destHeight) {
+    _drawImage(source, sourceX, sourceY, sourceWidth, sourceHeight,
+        destX, destY, destWidth, destHeight);
+  }
+
+  void drawImageToRect(source, Rect dest, {Rect sourceRect}) {
     if (sourceRect == null) {
-      drawImage(element, dest.left, dest.top, dest.width, dest.height);
+      _drawImage(source, dest.left, dest.top, dest.width, dest.height);
     } else {
-      drawImage(element,
+      _drawImage(source,
          sourceRect.left, sourceRect.top, sourceRect.width, sourceRect.height,
          dest.left, dest.top, dest.width, dest.height);
     }
   }
 
-  void fill() => Fill(_handle);
+  void fill() => _Fill(_handle);
 
   void fillRect(num x, num y, num w, num h) =>
-    FillRect(_handle, x.toDouble(), y.toDouble(),
+    _FillRect(_handle, x.toDouble(), y.toDouble(),
                          w.toDouble(), h.toDouble());
 
   void fillText(String text, num x, num y, [num maxWidth = -1]) =>
-      FillText(_handle, text, x.toDouble(), y.toDouble(),
+    _FillText(_handle, text, x.toDouble(), y.toDouble(),
                                  maxWidth.toDouble());
 
   ImageData getImageData(num sx, num sy, num sw, num sh) =>
-    GetImageData(sx, sy, sw, sh);
+    _GetImageData(sx, sy, sw, sh);
 
   List<double> _lineDash = null;
   List<num> getLineDash() {
@@ -1065,40 +1081,40 @@
   }
 
   void lineTo(num x, num y) {
-    LineTo(_handle, x.toDouble(), y.toDouble());
+    _LineTo(_handle, x.toDouble(), y.toDouble());
   }
 
   TextMetrics measureText(String text) {
-    double w = MeasureText(_handle, text);
+    double w = _MeasureText(_handle, text);
     return new TextMetrics(w);
   }
 
   void moveTo(num x, num y) =>
-    MoveTo(_handle, x.toDouble(), y.toDouble());
+    _MoveTo(_handle, x.toDouble(), y.toDouble());
 
   void putImageData(ImageData imagedata, num dx, num dy,
                    [num dirtyX, num dirtyY, num dirtyWidth, num dirtyHeight]) {
     if (dirtyX != null || dirtyY != null) {
       throw new Exception('Unimplemented putImageData');
     } else {
-      PutImageData(_handle, imagedata, dx, dy);
+      _PutImageData(_handle, imagedata, dx, dy);
     }
   }
 
   void quadraticCurveTo(num cpx, num cpy, num x, num y) =>
-    QuadraticCurveTo(_handle, cpx.toDouble(), cpy.toDouble(),
+    _QuadraticCurveTo(_handle, cpx.toDouble(), cpy.toDouble(),
                         x.toDouble(), y.toDouble());
 
   void rect(num x, num y, num w, num h) =>
-    Rect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
+    _Rect(_handle, x.toDouble(), y.toDouble(), w.toDouble(), h.toDouble());
 
-  void restore() => Restore(_handle);
+  void restore() => _Restore(_handle);
 
-  void rotate(num angle) => Rotate(_handle, angle.toDouble());
+  void rotate(num angle) => _Rotate(_handle, angle.toDouble());
 
-  void save() => Save(_handle);
+  void save() => _Save(_handle);
 
-  void scale(num x, num y) => Scale(_handle, x.toDouble(), y.toDouble());
+  void scale(num x, num y) => _Scale(_handle, x.toDouble(), y.toDouble());
 
   void setFillColorHsl(int h, num s, num l, [num a = 1]) {
     throw new Exception('Unimplemented setFillColorHsl');
@@ -1133,7 +1149,7 @@
       }
     }
     if (valid) {
-      SetLineDash(_handle, _lineDash = new_dash);
+      _SetLineDash(_handle, _lineDash = new_dash);
     }
   }
 
@@ -1146,27 +1162,27 @@
   }
 
   void setTransform(num m11, num m12, num m21, num m22, num dx, num dy) =>
-          SetTransform(_handle, m11.toDouble(), m12.toDouble(),
-                                   m21.toDouble(), m22.toDouble(),
-                                   dx.toDouble(), dy.toDouble());
+    _SetTransform(_handle, m11.toDouble(), m12.toDouble(),
+                           m21.toDouble(), m22.toDouble(),
+                           dx.toDouble(), dy.toDouble());
 
-  void stroke() => Stroke(_handle);
+  void stroke() => _Stroke(_handle);
 
   void strokeRect(num x, num y, num w, num h, [num lineWidth]) =>
-    StrokeRect(_handle, x.toDouble(), y.toDouble(),
+    _StrokeRect(_handle, x.toDouble(), y.toDouble(),
         w.toDouble(), h.toDouble());
 
   void strokeText(String text, num x, num y, [num maxWidth = -1]) =>
-      StrokeText(_handle, text, x.toDouble(), y.toDouble(),
-                                 maxWidth.toDouble());
+    _StrokeText(_handle, text, x.toDouble(), y.toDouble(),
+        maxWidth.toDouble());
 
   void transform(num m11, num m12, num m21, num m22, num dx, num dy) =>
-          Transform(_handle, m11.toDouble(), m12.toDouble(),
-                       m21.toDouble(), m22.toDouble(),
-                       dx.toDouble(), dy.toDouble());
+    _Transform(_handle, m11.toDouble(), m12.toDouble(),
+                        m21.toDouble(), m22.toDouble(),
+                        dx.toDouble(), dy.toDouble());
 
   void translate(num x, num y) =>
-      Translate(_handle, x.toDouble(), y.toDouble());
+    _Translate(_handle, x.toDouble(), y.toDouble());
 
   ImageData webkitGetImageDataHD(num sx, num sy, num sw, num sh) {
     throw new Exception('Unimplemented webkitGetImageDataHD');
@@ -1184,5 +1200,6 @@
   }
 }
 
+var sfx_extension = 'raw';
 int _loadSample(String s) native "LoadSample";
 int _playSample(String s) native "PlaySample";
diff --git a/runtime/embedders/openglui/common/image_cache.cc b/runtime/embedders/openglui/common/image_cache.cc
index f6c1be5..957f7ea 100644
--- a/runtime/embedders/openglui/common/image_cache.cc
+++ b/runtime/embedders/openglui/common/image_cache.cc
@@ -18,7 +18,6 @@
 }
 
 const SkBitmap* ImageCache::GetImage_(const char* src_url) {
-fprintf(stderr, "ImageCache::GetImage(%s)\n", src_url);
   if (strncmp(src_url, "context2d://", 12) == 0) {
     int handle = atoi(src_url + 12);
     CanvasContext* otherContext = Context2D(handle);
@@ -35,21 +34,18 @@
 }
 
 int ImageCache::GetWidth_(const char* src_url) {
-fprintf(stderr, "ImageCache::GetWidth(%s)\n", src_url);
   const SkBitmap* image = GetImage(src_url);
   if (image == NULL) return 0;
   return image->width();
 }
 
 int ImageCache::GetHeight_(const char* src_url) {
-fprintf(stderr, "ImageCache::GetHeight(%s)\n", src_url);
   const SkBitmap* image = GetImage(src_url);
   if (image == NULL) return 0;
   return image->height();
 }
 
 SkBitmap* ImageCache::Load(const char* src_url) {
-fprintf(stderr, "ImageCache::Load(%s)\n", src_url);
   SkBitmap *bm = NULL;
   const char* filepath;
   if (strncmp(src_url, "file://", 7) == 0) {
diff --git a/runtime/embedders/openglui/common/vm_glue.cc b/runtime/embedders/openglui/common/vm_glue.cc
index 4b7bccd..77564e54 100644
--- a/runtime/embedders/openglui/common/vm_glue.cc
+++ b/runtime/embedders/openglui/common/vm_glue.cc
@@ -24,14 +24,16 @@
 VMGlue::VMGlue(ISized* surface,
                const char* script_path,
                const char* extension_script,
-               const char* main_script)
+               const char* main_script,
+               int setup_flag)
     : surface_(surface),
       isolate_(NULL),
       initialized_script_(false),
       x_(0.0),
       y_(0.0),
       z_(0.0),
-      accelerometer_changed_(false) {
+      accelerometer_changed_(false),
+      setup_flag_(setup_flag) {
   LOGI("Creating VMGlue");
   if (main_script == NULL) {
     main_script = "main.dart";
@@ -207,14 +209,16 @@
   // we can eliminate it along with the need for the force parameter.
   if (!initialized_script_ || force) {
     initialized_script_ = true;
-    LOGI("Invoking setup(NULL, %d,%d)", surface_->width(), surface_->height());
+    LOGI("Invoking setup(null, %d,%d,%d)",
+        surface_->width(), surface_->height(), setup_flag_);
     Dart_EnterIsolate(isolate_);
     Dart_EnterScope();
-    Dart_Handle args[3];
+    Dart_Handle args[4];
     args[0] = CheckError(Dart_Null());
     args[1] = CheckError(Dart_NewInteger(surface_->width()));
     args[2] = CheckError(Dart_NewInteger(surface_->height()));
-    int rtn = Invoke("setup", 3, args);
+    args[3] = CheckError(Dart_NewInteger(setup_flag_));
+    int rtn = Invoke("setup", 4, args);
 
     if (rtn == 0) {
       // Plug in the print handler. It would be nice if we could do this
diff --git a/runtime/embedders/openglui/common/vm_glue.h b/runtime/embedders/openglui/common/vm_glue.h
index cf7788f..f340b56 100644
--- a/runtime/embedders/openglui/common/vm_glue.h
+++ b/runtime/embedders/openglui/common/vm_glue.h
@@ -16,7 +16,8 @@
   explicit VMGlue(ISized* surface,
                   const char* script_path,
                   const char* extension_script = NULL,
-                  const char* main_script = NULL);
+                  const char* main_script = NULL,
+                  int setup_flag = 0);
   ~VMGlue() {
     delete[] main_script_;
     delete[] extension_script_;
@@ -70,6 +71,7 @@
   char* main_script_;
   float x_, y_, z_;  // Last values from accelerometer.
   bool accelerometer_changed_;
+  int setup_flag_;
 };
 
 #endif  // EMBEDDERS_OPENGLUI_COMMON_VM_GLUE_H_
diff --git a/runtime/embedders/openglui/emulator/emulator_embedder.cc b/runtime/embedders/openglui/emulator/emulator_embedder.cc
index 904a60f..de01870 100644
--- a/runtime/embedders/openglui/emulator/emulator_embedder.cc
+++ b/runtime/embedders/openglui/emulator/emulator_embedder.cc
@@ -104,7 +104,7 @@
       script = argv[i];
     }
   }
-  VMGlue vm_glue(&graphics_handler, ".", "gl.dart", script);
+  VMGlue vm_glue(&graphics_handler, ".", "gl.dart", script, 1);
   InputHandler input_handler(&vm_glue);
   input_handler_ptr = &input_handler;
   SoundHandler sound_handler;
diff --git a/runtime/embedders/openglui/openglui_embedder.gypi b/runtime/embedders/openglui/openglui_embedder.gypi
index 2893fbe..dc66642 100644
--- a/runtime/embedders/openglui/openglui_embedder.gypi
+++ b/runtime/embedders/openglui/openglui_embedder.gypi
@@ -247,16 +247,16 @@
                 '-Wall',
                 '<(skia_libs_location_desktop)',
                 '-Wl,--start-group',
-                '-lskia_effects',
-                '-lskia_images',
                 '-lskia_core',
+                '-lskia_effects',
+                '-lskia_gr',
+                '-lskia_images',
                 '-lskia_opts',
                 '-lskia_opts_ssse3',
                 '-lskia_ports',
                 '-lskia_sfnt',
-                '-lskia_utils',
-                '-lskia_gr',
                 '-lskia_skgr',
+                '-lskia_utils',
                 '-Wl,--end-group',
                 '-lfreetype',
               ],
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 8bc87cc..b98cc4b 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -76,6 +76,27 @@
 }
 
 
+void Assembler::LoadObject(Register rd, const Object& object) {
+  // Smi's and VM heap objects are never relocated; do not use object pool.
+  if (object.IsSmi()) {
+    LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()));
+  } else if (object.InVMHeap()) {
+    // Make sure that class CallPattern is able to decode this load immediate.
+    int32_t object_raw = reinterpret_cast<int32_t>(object.raw());
+    const uint16_t object_low = Utils::Low16Bits(object_raw);
+    const uint16_t object_high = Utils::High16Bits(object_raw);
+    lui(rd, Immediate(object_high));
+    ori(rd, rd, Immediate(object_low));
+  } 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);
+  }
+}
+
+
 int32_t Assembler::AddObject(const Object& obj) {
   ASSERT(obj.IsNotTemporaryScopedHandle());
   ASSERT(obj.IsOld());
@@ -94,6 +115,92 @@
 }
 
 
+void Assembler::PushObject(const Object& object) {
+  LoadObject(TMP, object);
+  Push(TMP);
+}
+
+
+void Assembler::CompareObject(Register rd, Register rn, const Object& object) {
+  ASSERT(rn != TMP);
+  LoadObject(TMP, object);
+  subu(rd, rn, TMP);
+}
+
+
+void Assembler::EnterStubFrame() {
+  addiu(SP, SP, Immediate(-3 * kWordSize));
+  sw(ZR, Address(SP, 2 * kWordSize));  // PC marker is 0 in stubs.
+  sw(RA, Address(SP, 1 * kWordSize));
+  sw(FP, Address(SP, 0 * kWordSize));
+  mov(FP, SP);
+}
+
+
+void Assembler::LeaveStubFrame() {
+  mov(SP, FP);
+  lw(RA, Address(SP, 1 * kWordSize));
+  lw(FP, Address(SP, 0 * kWordSize));
+  addiu(SP, SP, Immediate(3 * kWordSize));
+}
+
+
+void Assembler::EnterDartFrame(intptr_t frame_size) {
+  const intptr_t offset = CodeSize();
+
+  addiu(SP, SP, Immediate(-4 * kWordSize));
+  sw(RA, Address(SP, 2 * kWordSize));
+  sw(FP, Address(SP, 1 * kWordSize));
+  sw(PP, Address(SP, 0 * kWordSize));
+
+  Label next;
+  // Branch and link to the instruction after the delay slot to get the PC.
+  bal(&next);
+
+  // RA is the address of the sw instruction below. Save it in T0.
+  delay_slot()->mov(T0, RA);
+
+  // Calculate the offset of the pool pointer from the PC.
+  const intptr_t object_pool_pc_dist =
+      Instructions::HeaderSize() - Instructions::object_pool_offset() +
+      CodeSize();
+
+  // This sw instruction is the return address for the bal, so T0 holds
+  // the PC at this sw instruction.
+  Bind(&next);
+
+  if (offset != 0) {
+    // Adjust PC for any intrinsic code that could have been generated
+    // before a frame is created.
+    addiu(T0, T0, Immediate(-offset));
+  }
+
+  // Save PC in frame for fast identification of corresponding code.
+  sw(T0, Address(SP, 3 * kWordSize));
+
+  // Set FP to the saved previous FP.
+  addiu(FP, SP, Immediate(kWordSize));
+
+  // Load the pool pointer.
+  lw(PP, Address(T0, -object_pool_pc_dist));
+
+  // Reserve space for locals.
+  addiu(SP, SP, Immediate(-frame_size));
+}
+
+
+void Assembler::LeaveDartFrame() {
+  addiu(SP, FP, Immediate(-kWordSize));
+
+  lw(RA, Address(SP, 2 * kWordSize));
+  lw(FP, Address(SP, 1 * kWordSize));
+  lw(PP, Address(SP, 0 * kWordSize));
+
+  // Adjust SP for PC pushed in EnterDartFrame.
+  addiu(SP, SP, Immediate(4 * kWordSize));
+}
+
+
 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) {
   if (object_pool_.IsNull()) {
     // The object pool cannot be used in the vm isolate.
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 81f9810..68cc734 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -162,18 +162,10 @@
     buffer_.FinalizeInstructions(region);
   }
 
-  // Set up a Dart frame on entry with a frame pointer and PC information to
-  // enable easy access to the RawInstruction object of code corresponding
-  // to this frame.
-  void EnterDartFrame(intptr_t frame_size) {
-    UNIMPLEMENTED();
-  }
-
   // Set up a stub frame so that the stack traversal code can easily identify
   // a stub frame.
-  void EnterStubFrame() {
-    UNIMPLEMENTED();
-  }
+  void EnterStubFrame();
+  void LeaveStubFrame();
 
   // Instruction pattern from entrypoint is used in dart frame prologs
   // to set up the frame and save a PC which can be used to figure out the
@@ -250,6 +242,12 @@
     beq(R0, R0, l);
   }
 
+  void bal(Label *l) {
+    ASSERT(!in_delay_slot_);
+    EmitRegImmBranch(BGEZAL, R0, l);
+    EmitBranchDelayNop();
+  }
+
   // Branch if equal.
   void beq(Register rs, Register rt, Label* l) {
     ASSERT(!in_delay_slot_);
@@ -546,6 +544,18 @@
     jr(TMP);
   }
 
+  // If the signed value in rs is less than value, rd is 1, and 0 otherwise.
+  void LessThanSImmediate(Register rd, Register rs, int32_t value) {
+    LoadImmediate(TMP, value);
+    slt(rd, rs, TMP);
+  }
+
+  // If the unsigned value in rs is less than value, rd is 1, and 0 otherwise.
+  void LessThanUImmediate(Register rd, Register rs, uint32_t value) {
+    LoadImmediate(TMP, value);
+    sltu(rd, rs, TMP);
+  }
+
   void Drop(intptr_t stack_elements) {
     ASSERT(stack_elements >= 0);
     if (stack_elements > 0) {
@@ -578,6 +588,14 @@
     jr(RA);
   }
 
+  void SmiTag(Register reg) {
+    sll(reg, reg, kSmiTagSize);
+  }
+
+  void SmiUntag(Register reg) {
+    sra(reg, reg, kSmiTagSize);
+  }
+
   void LoadWordFromPoolOffset(Register rd, int32_t offset);
   void LoadObject(Register rd, const Object& object);
   void PushObject(const Object& object);
@@ -586,6 +604,12 @@
   // set to non-zero otherwise.
   void CompareObject(Register rd, Register rn, const Object& object);
 
+  // Set up a Dart frame on entry with a frame pointer and PC information to
+  // enable easy access to the RawInstruction object of code corresponding
+  // to this frame.
+  void EnterDartFrame(intptr_t frame_size);
+  void LeaveDartFrame();
+
  private:
   AssemblerBuffer buffer_;
   GrowableObjectArray& object_pool_;  // Objects and patchable jump targets.
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index cb86ed0..27beef2 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -4,10 +4,6 @@
 
 #include "platform/assert.h"
 #include "vm/globals.h"
-#if defined(TARGET_ARCH_IA32) ||                                               \
-    defined(TARGET_ARCH_X64) ||                                                \
-    defined(TARGET_ARCH_ARM)
-
 #include "vm/ast.h"
 #include "vm/assembler.h"
 #include "vm/class_finalizer.h"
@@ -38,6 +34,11 @@
 CODEGEN_TEST_RUN(SmiReturnCodegen, Smi::New(3))
 
 
+#if defined(TARGET_ARCH_IA32) ||                                               \
+    defined(TARGET_ARCH_X64) ||                                                \
+    defined(TARGET_ARCH_ARM)
+
+
 CODEGEN_TEST2_GENERATE(SimpleStaticCallCodegen, function, test) {
   // Wrap the SmiReturnCodegen test above as a static function and call it.
   ArgumentListNode* no_arguments = new ArgumentListNode(kPos);
@@ -567,6 +568,6 @@
 
 #endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
 
-}  // namespace dart
-
 #endif  // defined(TARGET_ARCH_IA32) || ..._ARCH_X64) || ..._ARCH_ARM)
+
+}  // namespace dart
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index db01e25..8b0a266 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -141,6 +141,18 @@
 const Register FPREG = FP;  // Frame pointer register.
 
 
+typedef uint32_t RegList;
+const RegList kAllCpuRegistersList = 0xFFFFFFFF;
+
+
+const RegList kAbiArgumentCpuRegs =
+    (1 << A0) | (1 << A1) | (1 << A2) | (1 << A3);
+const RegList kAbiPreservedCpuRegs =
+    (1 << S0) | (1 << S1) | (1 << S2) | (1 << S3) |
+    (1 << S4) | (1 << S5) | (1 << S6) | (1 << S7);
+const int kAbiPreservedCpuRegCount = 8;
+
+
 // Dart stack frame layout.
 static const int kLastParamSlotIndex = 3;
 static const int kFirstLocalSlotIndex = -2;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index e5d97ed..1045708 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -229,6 +229,7 @@
   }
   isolate->heap()->EnableGrowthControl();
   isolate->set_init_callback_data(data);
+  Api::SetupAcquiredError(isolate);
   if (FLAG_print_class_table) {
     isolate->class_table()->Print();
   }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 50900ac..1ef5060 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -200,20 +200,20 @@
 }
 
 
-void Api::SetupCallbackError(Isolate* isolate) {
+void Api::SetupAcquiredError(Isolate* isolate) {
   ASSERT(isolate != NULL);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
-  state->SetupCallbackError();
+  state->SetupAcquiredError();
 }
 
 
-Dart_Handle Api::CallbackError(Isolate* isolate) {
+Dart_Handle Api::AcquiredError(Isolate* isolate) {
   ASSERT(isolate != NULL);
   ApiState* state = isolate->api_state();
   ASSERT(state != NULL);
-  PersistentHandle* callback_error_handle = state->CallbackError();
-  return reinterpret_cast<Dart_Handle>(callback_error_handle);
+  PersistentHandle* acquired_error_handle = state->AcquiredError();
+  return reinterpret_cast<Dart_Handle>(acquired_error_handle);
 }
 
 
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 32f36bc..b5e89da 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -106,15 +106,15 @@
   // Gets the handle used to designate successful return.
   static Dart_Handle Success(Isolate* isolate);
 
-  // Sets up the callback error object after initializing an Isolate. This
+  // Sets up the acquired error object after initializing an Isolate. This
   // object is pre-created because we will not be able to allocate this
   // object when the error actually occurs. When the error occurs there will
   // be outstanding acquires to internal data pointers making it unsafe to
   // allocate objects on the dart heap.
-  static void SetupCallbackError(Isolate* isolate);
+  static void SetupAcquiredError(Isolate* isolate);
 
-  // Gets the handle which holds the pre-created callback error object.
-  static Dart_Handle CallbackError(Isolate* isolate);
+  // Gets the handle which holds the pre-created acquired error object.
+  static Dart_Handle AcquiredError(Isolate* isolate);
 
   // Returns true if the handle holds a Smi.
   static bool IsSmi(Dart_Handle handle) {
@@ -192,7 +192,7 @@
 
 #define CHECK_CALLBACK_STATE(isolate)                                          \
   if (isolate->no_callback_scope_depth() != 0) {                               \
-    return reinterpret_cast<Dart_Handle>(Api::CallbackError(isolate));         \
+    return reinterpret_cast<Dart_Handle>(Api::AcquiredError(isolate));         \
   }                                                                            \
 
 }  // namespace dart.
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index b66ede1..61c4dbc 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1413,7 +1413,7 @@
     }
   }
   EXPECT(scope == state->top_scope());
-  EXPECT_EQ(2000, state->CountPersistentHandles());
+  EXPECT_EQ(2001, state->CountPersistentHandles());
   Dart_ShutdownIsolate();
 }
 
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index 57e62c0..9b27ecd 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -527,7 +527,7 @@
  public:
   ApiState() : top_scope_(NULL), delayed_weak_reference_sets_(NULL),
                null_(NULL), true_(NULL), false_(NULL),
-               callback_error_(NULL) {}
+               acquired_error_(NULL) {}
   ~ApiState() {
     while (top_scope_ != NULL) {
       ApiLocalScope* scope = top_scope_;
@@ -546,6 +546,10 @@
       persistent_handles().FreeHandle(false_);
       false_ = NULL;
     }
+    if (acquired_error_ != NULL) {
+      persistent_handles().FreeHandle(acquired_error_);
+      acquired_error_ = NULL;
+    }
   }
 
   // Accessors.
@@ -651,18 +655,13 @@
   }
   PersistentHandle* Null() {
     if (null_ == NULL) {
-      DARTSCOPE(Isolate::Current());
-
-      Object& null_object = Object::Handle();
       null_ = persistent_handles().AllocateHandle();
-      null_->set_raw(null_object);
+      null_->set_raw(Object::null());
     }
     return null_;
   }
   PersistentHandle* True() {
     if (true_ == NULL) {
-      DARTSCOPE(Isolate::Current());
-
       true_ = persistent_handles().AllocateHandle();
       true_->set_raw(Bool::True());
     }
@@ -670,25 +669,23 @@
   }
   PersistentHandle* False() {
     if (false_ == NULL) {
-      DARTSCOPE(Isolate::Current());
-
       false_ = persistent_handles().AllocateHandle();
       false_->set_raw(Bool::False());
     }
     return false_;
   }
 
-  void SetupCallbackError() {
-    ASSERT(callback_error_ == NULL);
-    callback_error_ = persistent_handles().AllocateHandle();
-    callback_error_->set_raw(
+  void SetupAcquiredError() {
+    ASSERT(acquired_error_ == NULL);
+    acquired_error_ = persistent_handles().AllocateHandle();
+    acquired_error_->set_raw(
         String::New("Internal Dart data pointers have been acquired, "
-                    "please release them using Dart_ByteArrayReleaseData."));
+                    "please release them using Dart_TypedDataReleaseData."));
   }
 
-  PersistentHandle* CallbackError() const {
-    ASSERT(callback_error_ != NULL);
-    return callback_error_;
+  PersistentHandle* AcquiredError() const {
+    ASSERT(acquired_error_ != NULL);
+    return acquired_error_;
   }
 
   void DelayWeakReferenceSet(WeakReferenceSet* reference_set) {
@@ -706,7 +703,7 @@
   PersistentHandle* null_;
   PersistentHandle* true_;
   PersistentHandle* false_;
-  PersistentHandle* callback_error_;
+  PersistentHandle* acquired_error_;
 
   DISALLOW_COPY_AND_ASSIGN(ApiState);
 };
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index ff74333..0c30e3b 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -141,7 +141,8 @@
     case 'd': {
       ASSERT(STRING_STARTS_WITH(format, "dest"));
       int off = instr->SImmField() << 2;
-      uword destination = reinterpret_cast<uword>(instr) + off;
+      uword destination =
+          reinterpret_cast<uword>(instr) + off + Instr::kInstrSize;
       buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
                                  remaining_size_in_buffer(),
                                  "%#"Px"",
@@ -377,6 +378,10 @@
       Format(instr, "bgez 'rs, 'dest");
       break;
     }
+    case BGEZAL: {
+      Format(instr, "bgezal 'rs, 'dest");
+      break;
+    }
     case BGEZL: {
       Format(instr, "bgezl 'rs, 'dest");
       break;
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index b455448..1a88c4d 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -7,10 +7,24 @@
 
 #include "vm/flow_graph_compiler.h"
 
-#include "vm/longjump.h"
+#include "lib/error.h"
+#include "vm/ast_printer.h"
+#include "vm/dart_entry.h"
+#include "vm/il_printer.h"
+#include "vm/locations.h"
+#include "vm/object_store.h"
+#include "vm/parser.h"
+#include "vm/stub_code.h"
+#include "vm/symbols.h"
 
 namespace dart {
 
+DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, print_ast);
+DECLARE_FLAG(bool, print_scopes);
+DECLARE_FLAG(bool, enable_type_checks);
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -31,6 +45,9 @@
 }
 
 
+#define __ assembler()->
+
+
 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
                                            Label* is_true,
                                            Label* is_false) {
@@ -128,12 +145,24 @@
 
 
 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
-  UNIMPLEMENTED();
+  if (!is_optimizing()) {
+    if (FLAG_enable_type_checks && instr->IsAssertAssignable()) {
+      AssertAssignableInstr* assert = instr->AsAssertAssignable();
+      AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
+                           assert->deopt_id(),
+                           assert->token_pos());
+    }
+    AllocateRegistersLocally(instr);
+  }
 }
 
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
-  UNIMPLEMENTED();
+  if (is_optimizing()) return;
+  Definition* defn = instr->AsDefinition();
+  if ((defn != NULL) && defn->is_used()) {
+    __ Push(defn->locs()->out().reg());
+  }
 }
 
 
@@ -153,12 +182,221 @@
 
 
 void FlowGraphCompiler::EmitFrameEntry() {
-  UNIMPLEMENTED();
+  const Function& function = parsed_function().function();
+  if (CanOptimizeFunction() && function.is_optimizable()) {
+    const bool can_optimize = !is_optimizing() || may_reoptimize();
+    const Register function_reg = T0;
+    if (can_optimize) {
+      Label next;
+      // The pool pointer is not setup before entering the Dart frame.
+
+      __ mov(TMP, RA);  // Save RA.
+      __ bal(&next);  // Branch and link to next instruction to get PC in RA.
+      __ delay_slot()->mov(T2, RA);  // Save PC of the following mov.
+
+      // Calculate offset of pool pointer from the PC.
+      const intptr_t object_pool_pc_dist =
+         Instructions::HeaderSize() - Instructions::object_pool_offset() +
+         assembler()->CodeSize();
+
+      __ Bind(&next);
+      __ mov(RA, TMP);  // Restore RA.
+
+      // Preserve PP of caller.
+      __ mov(T1, PP);
+
+      // Temporarily setup pool pointer for this dart function.
+      __ lw(PP, Address(T2, -object_pool_pc_dist));
+
+      // Load function object from object pool.
+      __ LoadObject(function_reg, function);  // Uses PP.
+
+      // Restore PP of caller.
+      __ mov(PP, T1);
+    }
+    // Patch point is after the eventually inlined function object.
+    AddCurrentDescriptor(PcDescriptors::kEntryPatch,
+                         Isolate::kNoDeoptId,
+                         0);  // No token position.
+    if (can_optimize) {
+      // Reoptimization of optimized function is triggered by counting in
+      // IC stubs, but not at the entry of the function.
+      if (!is_optimizing()) {
+        __ lw(T1, FieldAddress(function_reg,
+                               Function::usage_counter_offset()));
+        __ addiu(T1, T1, Immediate(1));
+        __ sw(T1, FieldAddress(function_reg,
+                               Function::usage_counter_offset()));
+      } else {
+        __ lw(T1, FieldAddress(function_reg,
+                               Function::usage_counter_offset()));
+      }
+
+      // Skip Branch if T1 is less than the threshold.
+      Label dont_branch;
+      __ LoadImmediate(T2, FLAG_optimization_counter_threshold);
+      __ sltu(T2, T1, T2);
+      __ bgtz(T2, &dont_branch);
+
+      ASSERT(function_reg == T0);
+      __ Branch(&StubCode::OptimizeFunctionLabel());
+
+      __ Bind(&dont_branch);
+    }
+  } else {
+    AddCurrentDescriptor(PcDescriptors::kEntryPatch,
+                         Isolate::kNoDeoptId,
+                         0);  // No token position.
+  }
+  __ Comment("Enter frame");
+  __ EnterDartFrame((StackSize() * kWordSize));
 }
 
-
+// Input parameters:
+//   RA: return address.
+//   SP: address of last argument.
+//   FP: caller's frame pointer.
+//   PP: caller's pool pointer.
+//   S5: ic-data.
+//   S4: arguments descriptor array.
 void FlowGraphCompiler::CompileGraph() {
-  UNIMPLEMENTED();
+  InitCompiler();
+  if (TryIntrinsify()) {
+    // Although this intrinsified code will never be patched, it must satisfy
+    // CodePatcher::CodeIsPatchable, which verifies that this code has a minimum
+    // code size.
+    __ break_(0);
+    __ Branch(&StubCode::FixCallersTargetLabel());
+    return;
+  }
+
+  EmitFrameEntry();
+
+  const Function& function = parsed_function().function();
+
+  const int num_fixed_params = function.num_fixed_parameters();
+  const int num_copied_params = parsed_function().num_copied_params();
+  const int num_locals = parsed_function().num_stack_locals();
+
+  // We check the number of passed arguments when we have to copy them due to
+  // the presence of optional parameters.
+  // No such checking code is generated if only fixed parameters are declared,
+  // unless we are in debug mode or unless we are compiling a closure.
+  LocalVariable* saved_args_desc_var =
+      parsed_function().GetSavedArgumentsDescriptorVar();
+  if (num_copied_params == 0) {
+#ifdef DEBUG
+    ASSERT(!parsed_function().function().HasOptionalParameters());
+    const bool check_arguments = true;
+#else
+    const bool check_arguments = function.IsClosureFunction();
+#endif
+    if (check_arguments) {
+      __ Comment("Check argument count");
+      // Check that exactly num_fixed arguments are passed in.
+      Label correct_num_arguments, wrong_num_arguments;
+      __ lw(T0, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
+      __ LoadImmediate(T1, Smi::RawValue(num_fixed_params));
+      __ bne(T0, T1, &wrong_num_arguments);
+
+      __ lw(T1, FieldAddress(S4,
+                             ArgumentsDescriptor::positional_count_offset()));
+      __ beq(T0, T1, &correct_num_arguments);
+      __ Bind(&wrong_num_arguments);
+      if (function.IsClosureFunction()) {
+        if (StackSize() != 0) {
+          // We need to unwind the space we reserved for locals and copied
+          // parameters. The NoSuchMethodFunction stub does not expect to see
+          // that area on the stack.
+          __ addiu(SP, SP, Immediate(StackSize() * kWordSize));
+        }
+        // The call below has an empty stackmap because we have just
+        // dropped the spill slots.
+        BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
+
+        // Invoke noSuchMethod function passing "call" as the function name.
+        const int kNumArgsChecked = 1;
+        const ICData& ic_data = ICData::ZoneHandle(
+            ICData::New(function, Symbols::Call(),
+                        Isolate::kNoDeoptId, kNumArgsChecked));
+        __ LoadObject(S5, ic_data);
+        // FP - 4 : saved PP, object pool pointer of caller.
+        // FP + 0 : previous frame pointer.
+        // FP + 4 : return address.
+        // FP + 8 : PC marker, for easy identification of RawInstruction obj.
+        // FP + 12: last argument (arg n-1).
+        // SP + 0 : saved PP.
+        // SP + 16 + 4*(n-1) : first argument (arg 0).
+        // S5 : ic-data.
+        // S4 : arguments descriptor array.
+        __ BranchLink(&StubCode::CallNoSuchMethodFunctionLabel());
+        if (is_optimizing()) {
+          stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
+                                            empty_stack_bitmap,
+                                            0);  // No registers.
+        }
+        // The noSuchMethod call may return.
+        __ LeaveDartFrame();
+        __ Ret();
+      } else {
+        __ Stop("Wrong number of arguments");
+      }
+      __ Bind(&correct_num_arguments);
+    }
+    // The arguments descriptor is never saved in the absence of optional
+    // parameters, since any argument definition test would always yield true.
+    ASSERT(saved_args_desc_var == NULL);
+  } else {
+    if (saved_args_desc_var != NULL) {
+      __ Comment("Save arguments descriptor");
+      const Register kArgumentsDescriptorReg = S4;
+      // The saved_args_desc_var is allocated one slot before the first local.
+      const intptr_t slot = parsed_function().first_stack_local_index() + 1;
+      // If the saved_args_desc_var is captured, it is first moved to the stack
+      // and later to the context, once the context is allocated.
+      ASSERT(saved_args_desc_var->is_captured() ||
+             (saved_args_desc_var->index() == slot));
+      __ sw(kArgumentsDescriptorReg, Address(FP, slot * kWordSize));
+    }
+    CopyParameters();
+  }
+
+  // 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)) {
+    __ Comment("Initialize spill slots");
+    const intptr_t slot_base = parsed_function().first_stack_local_index();
+    __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null()));
+    for (intptr_t i = 0; i < num_locals; ++i) {
+      // Subtract index i (locals lie at lower addresses than FP).
+      __ sw(T0, Address(FP, (slot_base - i) * kWordSize));
+    }
+  }
+
+  if (FLAG_print_scopes) {
+    // Print the function scope (again) after generating the prologue in order
+    // to see annotations such as allocation indices of locals.
+    if (FLAG_print_ast) {
+      // Second printing.
+      OS::Print("Annotated ");
+    }
+    AstPrinter::PrintFunctionScope(parsed_function());
+  }
+
+  VisitBlocks();
+
+  __ break_(0);
+  GenerateDeferredCode();
+  // Emit function patching code. This will be swapped with the first 5 bytes
+  // at entry point.
+  AddCurrentDescriptor(PcDescriptors::kPatchCode,
+                       Isolate::kNoDeoptId,
+                       0);  // No token position.
+  __ Branch(&StubCode::FixCallersTargetLabel());
+  AddCurrentDescriptor(PcDescriptors::kLazyDeoptJump,
+                       Isolate::kNoDeoptId,
+                       0);  // No token position.
+  __ Branch(&StubCode::DeoptimizeLazyLabel());
 }
 
 
@@ -183,7 +421,7 @@
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             LocationSummary* locs) {
-  UNIMPLEMENTED();
+  __ Unimplemented("call runtime");
 }
 
 
@@ -252,12 +490,51 @@
 
 
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
-  UNIMPLEMENTED();
+  // TODO(vegorov): consider saving only caller save (volatile) registers.
+  const intptr_t fpu_registers = locs->live_registers()->fpu_registers();
+  if (fpu_registers > 0) {
+    UNIMPLEMENTED();
+  }
+
+  // Store general purpose registers with the lowest register number at the
+  // lowest address.
+  const intptr_t cpu_registers = locs->live_registers()->cpu_registers();
+  ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
+  const int register_count = Utils::CountOneBits(cpu_registers);
+  int registers_pushed = 0;
+
+  __ addiu(SP, SP, Immediate(-register_count * kWordSize));
+  for (int i = 0; i < kNumberOfCpuRegisters; i++) {
+    Register r = static_cast<Register>(i);
+    if (locs->live_registers()->ContainsRegister(r)) {
+      __ sw(r, Address(SP, registers_pushed * kWordSize));
+      registers_pushed++;
+    }
+  }
 }
 
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
-  UNIMPLEMENTED();
+  // General purpose registers have the lowest register number at the
+  // lowest address.
+  const intptr_t cpu_registers = locs->live_registers()->cpu_registers();
+  ASSERT((cpu_registers & ~kAllCpuRegistersList) == 0);
+  const int register_count = Utils::CountOneBits(cpu_registers);
+  int registers_popped = 0;
+
+  for (int i = 0; i < kNumberOfCpuRegisters; i++) {
+    Register r = static_cast<Register>(i);
+    if (locs->live_registers()->ContainsRegister(r)) {
+      __ lw(r, Address(SP, registers_popped * kWordSize));
+      registers_popped++;
+    }
+  }
+  __ addiu(SP, SP, Immediate(register_count * kWordSize));
+
+  const intptr_t fpu_registers = locs->live_registers()->fpu_registers();
+  if (fpu_registers > 0) {
+    UNIMPLEMENTED();
+  }
 }
 
 
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 45c00d8..7df257b 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1768,7 +1768,18 @@
   ASSERT(ic_data.num_args_tested() == 1);  // Unary checks only.
   if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null();
   const Class& type_class = Class::Handle(type.type_class());
-  if (type_class.HasTypeArguments()) return Bool::null();
+  if (type_class.HasTypeArguments()) {
+    // Only raw types can be directly compared, thus disregarding type
+    // arguments.
+    const AbstractTypeArguments& type_arguments =
+        AbstractTypeArguments::Handle(type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(type_arguments.Length());
+    if (!is_raw_type) {
+      // Unknown result.
+      return Bool::null();
+    }
+  }
   const ClassTable& class_table = *Isolate::Current()->class_table();
   Bool& prev = Bool::Handle();
   Class& cls = Class::Handle();
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index bfc7f1d..a0bc6d4 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -15,16 +15,16 @@
     : end_(reinterpret_cast<uword*>(pc)),
       target_address_pool_index_(-1),
       args_desc_load_end_(-1),
-      args_desc_pool_index_(-1),
+      args_desc_(Array::Handle()),
       ic_data_load_end_(-1),
-      ic_data_pool_index_(-1),
+      ic_data_(ICData::Handle()),
       object_pool_(Array::Handle(code.ObjectPool())) {
   ASSERT(code.ContainsInstructionAt(pc));
   ASSERT(Back(2) == 0x0020f809);  // Last instruction: jalr RA, TMP(=R1)
   Register reg;
   // First end is 0 so that we begin from the delay slot of the jalr.
-  args_desc_load_end_ =
-     DecodeLoadWordFromPool(2, &reg, &target_address_pool_index_);
+  ic_data_load_end_ =
+      DecodeLoadWordFromPool(2, &reg, &target_address_pool_index_);
   ASSERT(reg == TMP);
 }
 
@@ -35,6 +35,54 @@
 }
 
 
+// Decodes a load sequence ending at end. Returns the register being loaded and
+// the loaded object.
+// Returns the location of the load sequence, counting the number of
+// instructions back from the end of the call pattern.
+int CallPattern::DecodeLoadObject(int end, Register* reg, Object* obj) {
+  ASSERT(end > 0);
+  uword i = Back(end + 1);
+  Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
+  if (instr->OpcodeField() == LW) {
+    int index = 0;
+    end = DecodeLoadWordFromPool(end, reg, &index);
+    *obj = object_pool_.At(index);
+  } else {
+    int value = 0;
+    end = DecodeLoadWordImmediate(end, reg, &value);
+    *obj = reinterpret_cast<RawObject*>(value);
+  }
+  return end;
+}
+
+
+// Decodes a load sequence ending at end. Returns the register being loaded and
+// the loaded immediate value.
+// Returns the location of the load sequence, counting the number of
+// instructions back from the end of the call pattern.
+int CallPattern::DecodeLoadWordImmediate(int end, Register* reg, int* value) {
+  ASSERT(end > 0);
+  int imm = 0;
+  uword i = Back(++end);
+  Instr* instr = Instr::At(reinterpret_cast<uword>(&i));
+  ASSERT(instr->OpcodeField() == ORI);
+  imm = instr->UImmField();
+  *reg = instr->RtField();
+
+  i = Back(++end);
+  instr = Instr::At(reinterpret_cast<uword>(&i));
+  ASSERT(instr->OpcodeField() == LUI);
+  ASSERT(instr->RtField() == *reg);
+  imm |= instr->UImmField();
+  *value = imm;
+  return end;
+}
+
+
+// Decodes a load sequence ending at end. Returns the register being loaded and
+// the index in the pool being read from.
+// Returns the location of the load sequence, counting the number of
+// instructions back from the end of the call pattern.
 int CallPattern::DecodeLoadWordFromPool(int end, Register* reg, int* index) {
   ASSERT(end > 0);
   uword i = Back(++end);
@@ -58,6 +106,7 @@
 
     i = Back(++end);
     instr = Instr::At(reinterpret_cast<uword>(&i));
+    ASSERT(instr->OpcodeField() == LUI);
     ASSERT(instr->RtField() == *reg);
     // Offset is signed, so add the upper 16 bits.
     offset += (instr->UImmField() << 16);
@@ -70,14 +119,23 @@
 
 
 RawICData* CallPattern::IcData() {
-  UNIMPLEMENTED();
-  return NULL;
+  if (ic_data_.IsNull()) {
+    Register reg;
+    args_desc_load_end_ = DecodeLoadObject(ic_data_load_end_, &reg, &ic_data_);
+    ASSERT(reg == S5);
+  }
+  return ic_data_.raw();
 }
 
 
 RawArray* CallPattern::ArgumentsDescriptor() {
-  UNIMPLEMENTED();
-  return NULL;
+  if (args_desc_.IsNull()) {
+    IcData();  // Loading of the ic_data must be decoded first, if not already.
+    Register reg;
+    DecodeLoadObject(args_desc_load_end_, &reg, &args_desc_);
+    ASSERT(reg == S4);
+  }
+  return args_desc_.raw();
 }
 
 
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index 1a71dc6..4035a3b 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -27,13 +27,15 @@
 
  private:
   uword Back(int n) const;
+  int DecodeLoadObject(int end, Register* reg, Object* obj);
+  int DecodeLoadWordImmediate(int end, Register* reg, int* value);
   int DecodeLoadWordFromPool(int end, Register* reg, int* index);
   const uword* end_;
   int target_address_pool_index_;
   int args_desc_load_end_;
-  int args_desc_pool_index_;
+  Array& args_desc_;
   int ic_data_load_end_;
-  int ic_data_pool_index_;
+  ICData& ic_data_;
   const Array& object_pool_;
 
   DISALLOW_COPY_AND_ASSIGN(CallPattern);
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index de9556f..6adbda5 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -16,6 +16,8 @@
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 
+#define __ compiler->assembler()->
+
 namespace dart {
 
 DECLARE_FLAG(int, optimization_counter_threshold);
@@ -39,13 +41,49 @@
 
 
 LocationSummary* ReturnInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs =
+      new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+  locs->set_in(0, Location::RegisterLocation(V0));
+  return locs;
 }
 
 
+// Attempt optimized compilation at return instruction instead of at the entry.
+// 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) {
-  UNIMPLEMENTED();
+  Register result = locs()->in(0).reg();
+  ASSERT(result == V0);
+#if defined(DEBUG)
+  // TODO(srdjan): Fix for functions with finally clause.
+  // A finally clause may leave a previously pushed return value if it
+  // has its own return instruction. Method that have finally are currently
+  // not optimized.
+  if (!compiler->HasFinally()) {
+    Label stack_ok;
+    __ Comment("Stack Check");
+    const int sp_fp_dist = compiler->StackSize() + (-kFirstLocalSlotIndex - 1);
+    __ subu(T2, FP, SP);
+
+    __ addiu(T2, T2, Immediate(-sp_fp_dist * kWordSize));
+    __ beq(T2, ZR, &stack_ok);
+    __ break_(0);
+
+    __ Bind(&stack_ok);
+  }
+#endif
+  __ 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());
 }
 
 
@@ -78,13 +116,18 @@
 
 
 LocationSummary* ConstantInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  return LocationSummary::Make(0,
+                               Location::RequiresRegister(),
+                               LocationSummary::kNoCall);
 }
 
 
 void ConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  // The register allocator drops constant definitions that have no uses.
+  if (!locs()->out().IsInvalid()) {
+    Register result = locs()->out().reg();
+    __ LoadObject(result, value());
+  }
 }
 
 
@@ -386,13 +429,54 @@
 
 
 LocationSummary* CheckStackOverflowInstr::MakeLocationSummary() const {
-  UNIMPLEMENTED();
-  return NULL;
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary =
+      new LocationSummary(kNumInputs,
+                          kNumTemps,
+                          LocationSummary::kCallOnSlowPath);
+  return summary;
 }
 
 
+class CheckStackOverflowSlowPath : public SlowPathCode {
+ public:
+  explicit CheckStackOverflowSlowPath(CheckStackOverflowInstr* instruction)
+      : instruction_(instruction) { }
+
+  virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    __ Comment("CheckStackOverflowSlowPath");
+    __ Bind(entry_label());
+    compiler->SaveLiveRegisters(instruction_->locs());
+    // pending_deoptimization_env_ is needed to generate a runtime call that
+    // may throw an exception.
+    ASSERT(compiler->pending_deoptimization_env_ == NULL);
+    compiler->pending_deoptimization_env_ = instruction_->env();
+    compiler->GenerateCallRuntime(instruction_->token_pos(),
+                                  instruction_->deopt_id(),
+                                  kStackOverflowRuntimeEntry,
+                                  instruction_->locs());
+    compiler->pending_deoptimization_env_ = NULL;
+    compiler->RestoreLiveRegisters(instruction_->locs());
+    __ b(exit_label());
+  }
+
+ private:
+  CheckStackOverflowInstr* instruction_;
+};
+
+
 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
+  compiler->AddSlowPathCode(slow_path);
+
+  __ LoadImmediate(TMP, Isolate::Current()->stack_limit_address());
+
+  __ lw(TMP, Address(TMP));
+  __ subu(TMP, SP, TMP);
+  __ blez(TMP, slow_path->entry_label());
+
+  __ Bind(slow_path->exit_label());
 }
 
 
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index 24d9fd9..f76ea9d 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -379,8 +379,8 @@
 class RegisterSet : public ValueObject {
  public:
   RegisterSet() : cpu_registers_(0), fpu_registers_(0) {
-    ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte));
-    ASSERT(kNumberOfFpuRegisters < (kWordSize * kBitsPerByte));
+    ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte));
+    ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte));
   }
 
 
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index a9bf83d..d78a1e1 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1030,6 +1030,13 @@
       DoBranch(instr, rs_val >= 0, false);
       break;
     }
+    case BGEZAL: {
+      int32_t rs_val = get_register(instr->RsField());
+      // Return address is one after the delay slot.
+      set_register(RA, pc_ + (2*Instr::kInstrSize));
+      DoBranch(instr, rs_val >= 0, false);
+      break;
+    }
     case BGEZL: {
       // Format(instr, "bgezl 'rs, 'dest");
       int32_t rs_val = get_register(instr->RsField());
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index a782ec5..9cb6525 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -5,6 +5,11 @@
 #include "vm/globals.h"
 #if defined(TARGET_ARCH_MIPS)
 
+#include "vm/assembler.h"
+#include "vm/code_generator.h"
+#include "vm/dart_entry.h"
+#include "vm/instructions.h"
+#include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 
 #define __ assembler->
@@ -66,8 +71,123 @@
 }
 
 
+// Called when invoking Dart code from C++ (VM code).
+// Input parameters:
+//   RA : points to return address.
+//   A0 : entrypoint of the Dart function to call.
+//   A1 : arguments descriptor array.
+//   A2 : arguments array.
+//   A3 : new context containing the current isolate pointer.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
-  __ Unimplemented("InvokeDartCode stub");
+  // Save frame pointer coming in.
+  __ EnterStubFrame();
+
+  // Save new context and C++ ABI callee-saved registers.
+  const intptr_t kNewContextOffset =
+      -(1 + kAbiPreservedCpuRegCount) * kWordSize;
+
+  __ addiu(SP, SP, Immediate(-(3 + kAbiPreservedCpuRegCount) * kWordSize));
+  for (int i = S0; i <= S7; i++) {
+    Register r = static_cast<Register>(i);
+    __ sw(r, Address(SP, (i - S0 + 3) * kWordSize));
+  }
+  __ sw(A3, Address(SP, 2 * kWordSize));
+
+  // The new Context structure contains a pointer to the current Isolate
+  // structure. Cache the Context pointer in the CTX register so that it is
+  // available in generated code and calls to Isolate::Current() need not be
+  // done. The assumption is that this register will never be clobbered by
+  // compiled or runtime stub code.
+
+  // Cache the new Context pointer into CTX while executing Dart code.
+  __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle));
+
+  // Load Isolate pointer from Context structure into temporary register R8.
+  __ lw(T2, FieldAddress(CTX, Context::isolate_offset()));
+
+  // Save the top exit frame info. Use R5 as a temporary register.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ lw(S5, Address(T2, Isolate::top_exit_frame_info_offset()));
+  __ LoadImmediate(T0, 0);
+  __ sw(T0, Address(T2, Isolate::top_exit_frame_info_offset()));
+
+  // Save the old Context pointer. Use S4 as a temporary register.
+  // Note that VisitObjectPointers will find this saved Context pointer during
+  // GC marking, since it traverses any information between SP and
+  // FP - kExitLinkOffsetInEntryFrame.
+  // EntryFrame::SavedContext reads the context saved in this frame.
+  __ lw(S4, Address(T2, Isolate::top_context_offset()));
+
+  // The constants kSavedContextOffsetInEntryFrame and
+  // kExitLinkOffsetInEntryFrame must be kept in sync with the code below.
+  __ sw(S5, Address(SP, 1 * kWordSize));
+  __ sw(S4, Address(SP, 0 * kWordSize));
+
+  // after the call, The stack pointer is restored to this location.
+  // Pushed A3, S0-7, S4, S5 = 11.
+  const intptr_t kSavedContextOffsetInEntryFrame = -11 * kWordSize;
+
+  // Load arguments descriptor array into S4, which is passed to Dart code.
+  __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle));
+
+  // Load number of arguments into S5.
+  __ lw(S5, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(S5);
+
+  // Compute address of 'arguments array' data area into A2.
+  __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle));
+  __ addiu(A2, A2, Immediate(Array::data_offset() - kHeapObjectTag));
+
+  // Set up arguments for the Dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+
+  __ beq(S5, ZR, &done_push_arguments);  // check if there are arguments.
+  __ LoadImmediate(A1, 0);
+  __ Bind(&push_arguments);
+  __ lw(A3, Address(A2));
+  __ Push(A3);
+  __ addiu(A2, A2, Immediate(kWordSize));
+  __ addiu(A1, A1, Immediate(1));
+  __ subu(T0, A1, S5);
+  __ bltz(T0, &push_arguments);
+
+  __ Bind(&done_push_arguments);
+
+
+  // Call the Dart code entrypoint.
+  __ jalr(A0);  // S4 is the arguments descriptor array.
+
+  // Read the saved new Context pointer.
+  __ lw(CTX, Address(FP, kNewContextOffset));
+  __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle));
+
+  // Get rid of arguments pushed on the stack.
+  __ addiu(SP, FP, Immediate(kSavedContextOffsetInEntryFrame));
+
+  // Load Isolate pointer from Context structure into CTX. Drop Context.
+  __ lw(CTX, FieldAddress(CTX, Context::isolate_offset()));
+
+  // Restore the saved Context pointer into the Isolate structure.
+  // Uses S4 as a temporary register for this.
+  // Restore the saved top exit frame info back into the Isolate structure.
+  // Uses S5 as a temporary register for this.
+  __ lw(S4, Address(SP, 0 * kWordSize));
+  __ lw(S5, Address(SP, 1 * kWordSize));
+  __ sw(S4, Address(CTX, Isolate::top_context_offset()));
+  __ sw(S5, Address(CTX, Isolate::top_exit_frame_info_offset()));
+
+  // Restore C++ ABI callee-saved registers.
+  for (int i = S0; i <= S7; i++) {
+    Register r = static_cast<Register>(i);
+    __ lw(r, Address(SP, (i - S0 + 3) * kWordSize));
+  }
+  __ lw(A3, Address(SP));
+  __ addiu(SP, SP, Immediate((3 + kAbiPreservedCpuRegCount) * kWordSize));
+
+  // Restore the frame pointer and return.
+  __ LeaveStubFrame();
+  __ Ret();
 }
 
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
index f0552e8..5fe4cb1 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/variable_allocator.dart
@@ -626,7 +626,9 @@
     return instructionInterval.diesAt(start);
   }
 
-  void handleInstruction(HInstruction instruction, VariableNamer namer) {
+  void freeUsedNamesAt(HInstruction instruction,
+                       HInstruction at,
+                       VariableNamer namer) {
     // TODO(ager): We cannot perform this check to free names for
     // HCheck instructions because they are special cased to have the
     // same live intervals as the instruction they are checking. This
@@ -635,16 +637,26 @@
     // end up checking that otherInput dies not here, but at the
     // location of checkedInput. We should preserve the start id for
     // the check instruction.
-    if (instruction is! HCheck) {
+    if (at is HCheck) return;
+    if (needsName(instruction)) {
+      if (diesAt(instruction, at)) {
+        namer.freeName(instruction);
+      }
+    } else if (generateAtUseSite.contains(instruction)) {
+      // If the instruction is generated at use site, then all its
+      // inputs may also die at [at].
       for (int i = 0, len = instruction.inputs.length; i < len; i++) {
         HInstruction input = instruction.inputs[i];
-        // If [input] has a name, and its use here is the last use, free
-        // its name.
-        if (needsName(input) && diesAt(input, instruction)) {
-          namer.freeName(input);
-        }
+        freeUsedNamesAt(input, at, namer);
       }
     }
+  }
+
+  void handleInstruction(HInstruction instruction, VariableNamer namer) {
+    for (int i = 0, len = instruction.inputs.length; i < len; i++) {
+      HInstruction input = instruction.inputs[i];
+      freeUsedNamesAt(input, instruction, namer);
+    }
 
     if (needsName(instruction)) {
       namer.allocateName(instruction);
diff --git a/tests/compiler/dart2js/ssa_phi_codegen_test.dart b/tests/compiler/dart2js/ssa_phi_codegen_test.dart
index 7cfdcc2..96c9372 100644
--- a/tests/compiler/dart2js/ssa_phi_codegen_test.dart
+++ b/tests/compiler/dart2js/ssa_phi_codegen_test.dart
@@ -55,6 +55,17 @@
 }
 """;
 
+const String TEST_FIVE = r"""
+void main() {
+  var hash = 0;
+  for (var i = 0; i == 0; i = i + 1) {
+    hash = hash + 10;
+    hash = hash + 42;
+  }
+  print(t);
+}
+""";
+
 main() {
   compileAndMatchFuzzy(TEST_ONE, 'foo', "var x = x === true \\? 2 : 3;");
   compileAndMatchFuzzy(TEST_ONE, 'foo', "print\\(x\\);");
@@ -69,6 +80,7 @@
   // only generates one instruction.
   compileAndMatchFuzzy(TEST_THREE, 'foo', 'x = 42');
 
-  var generated = compile(TEST_FOUR, entry: 'foo');
   compileAndDoNotMatchFuzzy(TEST_FOUR, 'foo', '(x) = \1;');
+
+  compileAndDoNotMatch(TEST_FIVE, 'main', new RegExp('hash0'));
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index 0d45af0..f8c058d 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -26,6 +26,9 @@
 [ $runtime == chrome ]
 touchevent_test/supported: Fail
 
+[ $runtime == chrome && $system == windows ]
+audiocontext_test: Skip # Issue 9566
+
 [$runtime == drt || $runtime == dartium || $runtime == chrome]
 webgl_1_test: Pass, Fail # Issue 8219
 
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 9f7e85a..5ac2302 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -8,6 +8,7 @@
 count_test: Fail, Crash # Bug in v8, http://dartbug.com/9407
 count_stream_test: Fail, Crash # Bug in v8, http://dartbug.com/9407
 mandel_isolate_test: Fail, Crash # Bug in v8, http://dartbug.com/9407
+message_test: Fail, Crash # Bug in v8, http://dartbug.com/9407
 mint_maker_test: Fail, Crash # Bug in v8, http://dartbug.com/9407
 
 
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 84436a5..8ef5e6e 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -20,7 +20,7 @@
 async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9002
 async/run_async4_test: Pass, Fail # no global exception handler in isolates. http://dartbug.com/9012
 
-[ $compiler == dart2js && $runtime == chrome && $system == macos]
+[ $compiler == dart2js && $runtime == chrome && ($system == macos || $system == windows)]
 crypto/hmac_sha1_test: Fail # Issue 9471
 
 [ $compiler == dart2js && $checked ]
diff --git a/tools/VERSION b/tools/VERSION
index 217a1a6..f09938c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 4
 BUILD 4
-PATCH 0
+PATCH 2
diff --git a/utils/pub/command_cache.dart b/utils/pub/command_cache.dart
index 056f383..c3a3a3d 100644
--- a/utils/pub/command_cache.dart
+++ b/utils/pub/command_cache.dart
@@ -33,18 +33,17 @@
     }
     
     // TODO(keertip): Add flag to list packages from non default sources
-    return cache.sources.defaultSource.getCachedPackages().then((packages){
-      var packagesObj = <String, Map>{};
-      for (var package in packages){
-        packagesObj[package.name] = {
-          'version': package.version.toString(),
-          'location': package.dir
-        };
-      }
-      // TODO(keertip): Add support for non-JSON format 
-      // and check for --format flag
-      log.message( json.stringify({'packages': packagesObj}));
-    });
+    var packagesObj = <String, Map>{};
+    for (var package in cache.sources.defaultSource.getCachedPackages()) {
+      packagesObj[package.name] = {
+        'version': package.version.toString(),
+        'location': package.dir
+      };
+    }
+
+    // TODO(keertip): Add support for non-JSON format
+    // and check for --format flag
+    log.message(json.stringify({'packages': packagesObj}));
   }  
 }
 
diff --git a/utils/pub/command_lish.dart b/utils/pub/command_lish.dart
index c2f2529..1948ba1 100644
--- a/utils/pub/command_lish.dart
+++ b/utils/pub/command_lish.dart
@@ -146,11 +146,9 @@
                         "--exclude-standard"]);
       }
 
-      return listDir(rootDir, recursive: true).then((entries) {
-        return entries
-            .where(fileExists) // Skip directories and broken symlinks.
-            .map((entry) => path.relative(entry, from: rootDir));
-      });
+      return listDir(rootDir, recursive: true)
+          .where(fileExists) // Skip directories and broken symlinks.
+          .map((entry) => path.relative(entry, from: rootDir));
     }).then((files) => files.where(_shouldPublish).toList());
   }
 
diff --git a/utils/pub/command_uploader.dart b/utils/pub/command_uploader.dart
index 977415b..673a4bd 100644
--- a/utils/pub/command_uploader.dart
+++ b/utils/pub/command_uploader.dart
@@ -59,7 +59,7 @@
       exit(exit_codes.USAGE);
     }
 
-    return defer(() {
+    return new Future.of(() {
       var package = commandOptions['package'];
       if (package != null) return package;
       return new Entrypoint(path.current, cache).root.name;
diff --git a/utils/pub/entrypoint.dart b/utils/pub/entrypoint.dart
index 95790d3..db6ad47 100644
--- a/utils/pub/entrypoint.dart
+++ b/utils/pub/entrypoint.dart
@@ -71,7 +71,7 @@
     if (pendingOrCompleted != null) return pendingOrCompleted;
 
     var packageDir = path.join(packagesDir, id.name);
-    var future = defer(() {
+    var future = new Future.of(() {
       ensureDir(path.dirname(packageDir));
 
       if (entryExists(packageDir)) {
@@ -102,7 +102,7 @@
   /// directory, respecting the [LockFile] if present. Returns a [Future] that
   /// completes when all dependencies are installed.
   Future installDependencies() {
-    return defer(() {
+    return new Future.of(() {
       return resolveVersions(cache.sources, root, loadLockFile());
     }).then(_installDependencies);
   }
@@ -119,7 +119,7 @@
   /// other dependencies as specified by the [LockFile] if possible. Returns a
   /// [Future] that completes when all dependencies are installed.
   Future updateDependencies(List<String> dependencies) {
-    return defer(() {
+    return new Future.of(() {
       var solver = new VersionSolver(cache.sources, root, loadLockFile());
       for (var dependency in dependencies) {
         solver.useLatestVersion(dependency);
@@ -137,16 +137,18 @@
         if (id.isRoot) return new Future.immediate(id);
         return install(id);
       }).toList());
-    }).then(_saveLockFile)
-      .then(_installSelfReference)
-      .then(_linkSecondaryPackageDirs);
+    }).then((ids) {
+      _saveLockFile(ids);
+      _installSelfReference();
+      _linkSecondaryPackageDirs();
+    });
   }
 
   /// Traverses the root's package dependency graph and loads each of the
   /// reached packages. This should only be called after the lockfile has been
   /// successfully generated.
   Future<List<Pubspec>> walkDependencies() {
-    return defer(() {
+    return new Future.of(() {
       var lockFile = loadLockFile();
       var group = new FutureGroup<Pubspec>();
       var visited = new Set<String>();
@@ -227,79 +229,59 @@
 
   /// Installs a self-referential symlink in the `packages` directory that will
   /// allow a package to import its own files using `package:`.
-  Future _installSelfReference(_) {
-    return defer(() {
-      var linkPath = path.join(packagesDir, root.name);
-      // Create the symlink if it doesn't exist.
-      if (entryExists(linkPath)) return;
-      ensureDir(packagesDir);
-      return createPackageSymlink(root.name, root.dir, linkPath,
-          isSelfLink: true, relative: true);
-    });
+  void _installSelfReference() {
+    var linkPath = path.join(packagesDir, root.name);
+    // Create the symlink if it doesn't exist.
+    if (entryExists(linkPath)) return;
+    ensureDir(packagesDir);
+    createPackageSymlink(root.name, root.dir, linkPath,
+        isSelfLink: true, relative: true);
   }
 
   /// If `bin/`, `test/`, or `example/` directories exist, symlink `packages/`
   /// into them so that their entrypoints can be run. Do the same for any
   /// subdirectories of `test/` and `example/`.
-  Future _linkSecondaryPackageDirs(_) {
+  void _linkSecondaryPackageDirs() {
     var binDir = path.join(root.dir, 'bin');
     var exampleDir = path.join(root.dir, 'example');
     var testDir = path.join(root.dir, 'test');
     var toolDir = path.join(root.dir, 'tool');
     var webDir = path.join(root.dir, 'web');
-    return defer(() {
-      if (!dirExists(binDir)) return;
-      return _linkSecondaryPackageDir(binDir);
-    }).then((_) => _linkSecondaryPackageDirsRecursively(exampleDir))
-      .then((_) => _linkSecondaryPackageDirsRecursively(testDir))
-      .then((_) => _linkSecondaryPackageDirsRecursively(toolDir))
-      .then((_) => _linkSecondaryPackageDirsRecursively(webDir));
-  }
+
+    if (dirExists(binDir)) _linkSecondaryPackageDir(binDir);
+    for (var dir in ['example', 'test', 'tool', 'web']) {
+      _linkSecondaryPackageDirsRecursively(path.join(root.dir, dir));
+    }
+ }
 
   /// Creates a symlink to the `packages` directory in [dir] and all its
   /// subdirectories.
-  Future _linkSecondaryPackageDirsRecursively(String dir) {
-    return defer(() {
-      if (!dirExists(dir)) return;
-      return _linkSecondaryPackageDir(dir)
-          .then((_) => _listDirWithoutPackages(dir))
-          .then((files) {
-        return Future.wait(files.map((file) {
-          return defer(() {
-            if (!dirExists(file)) return;
-            return _linkSecondaryPackageDir(file);
-          });
-        }).toList());
-      });
-    });
+  void _linkSecondaryPackageDirsRecursively(String dir) {
+    if (!dirExists(dir)) return;
+    _linkSecondaryPackageDir(dir);
+    _listDirWithoutPackages(dir)
+        .where(dirExists)
+        .forEach(_linkSecondaryPackageDir);
   }
 
   // TODO(nweiz): roll this into [listDir] in io.dart once issue 4775 is fixed.
   /// Recursively lists the contents of [dir], excluding hidden `.DS_Store`
   /// files and `package` files.
-  Future<List<String>> _listDirWithoutPackages(dir) {
-    return listDir(dir).then((files) {
-      return Future.wait(files.map((file) {
-        if (path.basename(file) == 'packages') return new Future.immediate([]);
-        return defer(() {
-          if (!dirExists(file)) return [];
-          return _listDirWithoutPackages(file);
-        }).then((subfiles) {
-          var fileAndSubfiles = [file];
-          fileAndSubfiles.addAll(subfiles);
-          return fileAndSubfiles;
-        });
-      }).toList());
-    }).then(flatten);
+  List<String> _listDirWithoutPackages(dir) {
+    return flatten(listDir(dir).map((file) {
+      if (path.basename(file) == 'packages') return [];
+      if (!dirExists(file)) return [];
+      var fileAndSubfiles = [file];
+      fileAndSubfiles.addAll(_listDirWithoutPackages(file));
+      return fileAndSubfiles;
+    }));
   }
 
   /// Creates a symlink to the `packages` directory in [dir]. Will replace one
   /// if already there.
-  Future _linkSecondaryPackageDir(String dir) {
-    return defer(() {
-      var symlink = path.join(dir, 'packages');
-      if (entryExists(symlink)) deleteEntry(symlink);
-      return createSymlink(packagesDir, symlink, relative: true);
-    });
+  void _linkSecondaryPackageDir(String dir) {
+    var symlink = path.join(dir, 'packages');
+    if (entryExists(symlink)) deleteEntry(symlink);
+    createSymlink(packagesDir, symlink, relative: true);
   }
 }
diff --git a/utils/pub/error_group.dart b/utils/pub/error_group.dart
index 5e6baf8..f579d8e 100644
--- a/utils/pub/error_group.dart
+++ b/utils/pub/error_group.dart
@@ -264,7 +264,7 @@
     if (_isDone) return;
     _subscription.cancel();
     // Call these asynchronously to work around issue 7913.
-    defer(() {
+    new Future.immediate(null).then((_) {
       _controller.addError(e.error, e.stackTrace);
       _controller.close();
     });
diff --git a/utils/pub/git_source.dart b/utils/pub/git_source.dart
index 1193892..cea2bac 100644
--- a/utils/pub/git_source.dart
+++ b/utils/pub/git_source.dart
@@ -123,7 +123,7 @@
   /// future that completes once this is finished and throws an exception if it
   /// fails.
   Future _ensureRepoCache(PackageId id) {
-    return defer(() {
+    return new Future.of(() {
       var path = _repoCachePath(id);
       if (!entryExists(path)) return _clone(_getUrl(id), path, mirror: true);
       return git.run(["fetch"], workingDir: path).then((result) => null);
@@ -143,7 +143,7 @@
   /// the working tree, but instead makes the repository a local mirror of the
   /// remote repository. See the manpage for `git clone` for more information.
   Future _clone(String from, String to, {bool mirror: false}) {
-    return defer(() {
+    return new Future.of(() {
       // Git on Windows does not seem to automatically create the destination
       // directory.
       ensureDir(to);
diff --git a/utils/pub/hosted_source.dart b/utils/pub/hosted_source.dart
index 4d6626f..0ed4e0c 100644
--- a/utils/pub/hosted_source.dart
+++ b/utils/pub/hosted_source.dart
@@ -63,7 +63,7 @@
 
   /// Downloads a package from the site and unpacks it.
   Future<bool> install(PackageId id, String destPath) {
-    return defer(() {
+    return new Future.of(() {
       var url = _makeVersionUrl(id, (server, package, version) =>
           "$server/packages/$package/versions/$version.tar.gz");
       log.io("Install package from $url.");
@@ -118,17 +118,13 @@
     return description;
   }
 
-  Future<List<Package>> getCachedPackages() {
-    return defer(() {
-      var cacheDir = path.join(systemCacheRoot, 
-                               _getSourceDirectory(_defaultUrl)); 
-      if (!dirExists(cacheDir)) return [];
-    
-      return listDir(path.join(cacheDir)).then((entries) {
-        return entries.map((entry) => 
-          new Package.load(null, entry, systemCache.sources));
-      });  
-    });
+  List<Package> getCachedPackages() {
+    var cacheDir = path.join(systemCacheRoot,
+                             _getSourceDirectory(_defaultUrl));
+    if (!dirExists(cacheDir)) return [];
+  
+    return listDir(path.join(cacheDir)).map((entry) =>
+        new Package.load(null, entry, systemCache.sources)).toList();
   }
   
   /// When an error occurs trying to read something about [package] from [url],
diff --git a/utils/pub/io.dart b/utils/pub/io.dart
index 4dcbf5d..a0e69a9 100644
--- a/utils/pub/io.dart
+++ b/utils/pub/io.dart
@@ -33,7 +33,7 @@
 
 /// Returns whether [link] exists on the file system. This will return `true`
 /// for any symlink, regardless of what it points at or whether it's broken.
-bool linkExists(String path) => new Link(path).existsSync();
+bool linkExists(String link) => new Link(link).existsSync();
 
 /// Returns whether [file] exists on the file system. This will return `true`
 /// for a symlink only if that symlink is unbroken and points to a file.
@@ -125,68 +125,55 @@
   return tempDir.path;
 }
 
-/// Asynchronously lists the contents of [dir]. If [recursive] is `true`, lists
-/// subdirectory contents (defaults to `false`). If [includeHiddenFiles] is
-/// `true`, includes files and directories beginning with `.` (defaults to
-/// `false`).
+/// Lists the contents of [dir]. If [recursive] is `true`, lists subdirectory
+/// contents (defaults to `false`). If [includeHidden] is `true`, includes files
+/// and directories beginning with `.` (defaults to `false`).
 ///
-/// If [dir] is a string, the returned paths are guaranteed to begin with it.
-Future<List<String>> listDir(String dir,
-    {bool recursive: false, bool includeHiddenFiles: false}) {
-  Future<List<String>> doList(String dir, Set<String> listedDirectories) {
+/// The returned paths are guaranteed to begin with [dir].
+List<String> listDir(String dir, {bool recursive: false,
+    bool includeHidden: false}) {
+  List<String> doList(String dir, Set<String> listedDirectories) {
     var contents = <String>[];
-    var completer = new Completer<List<String>>();
 
     // Avoid recursive symlinks.
     var resolvedPath = new File(dir).fullPathSync();
-    if (listedDirectories.contains(resolvedPath)) {
-      return new Future.immediate([]);
-    }
+    if (listedDirectories.contains(resolvedPath)) return [];
 
     listedDirectories = new Set<String>.from(listedDirectories);
     listedDirectories.add(resolvedPath);
 
     log.io("Listing directory $dir.");
-    var lister = new Directory(dir).list();
 
     var children = [];
-    lister.listen(
-        (entity) {
-          if (entity is File) {
-            var file = entity.path;
-            if (!includeHiddenFiles && path.basename(file).startsWith('.')) {
-              return;
-            }
-            contents.add(file);
-          } else if (entity is Directory) {
-            var file = entity.path;
-            if (!includeHiddenFiles && path.basename(file).startsWith('.')) {
-              return;
-            }
-            contents.add(file);
-            // TODO(nweiz): don't manually recurse once issue 4794 is fixed.
-            // Note that once we remove the manual recursion, we'll need to
-            // explicitly filter out files in hidden directories.
-            if (recursive) {
-              children.add(doList(file, listedDirectories));
-            }
-          }
-        },
-        onDone: () {
-          // TODO(rnystrom): May need to sort here if it turns out
-          // onDir and onFile aren't guaranteed to be called in a
-          // certain order. So far, they seem to.
-          log.fine("Listed directory $dir:\n${contents.join('\n')}");
-          completer.complete(contents);
-        },
-        onError: (error) => completer.completeError(error));
+    for (var entity in new Directory(dir).listSync(followLinks: false)) {
+      var entityPath = entity.path;
+      if (!includeHidden && path.basename(entityPath).startsWith('.')) continue;
 
-    return completer.future.then((contents) {
-      return Future.wait(children).then((childContents) {
-        contents.addAll(flatten(childContents));
-        return contents;
-      });
-    });
+      // TODO(nweiz): remove this when issue 4928 is fixed.
+      if (entity is Link) {
+        // We treat broken symlinks as files, in that we don't want to recurse
+        // into them.
+        entity = dirExists(entityPath)
+            ? new Directory(entityPath)
+            : new File(entityPath);
+      }
+
+      if (entity is File) {
+        contents.add(entityPath);
+      } else if (entity is Directory) {
+        contents.add(entityPath);
+        // TODO(nweiz): don't manually recurse once issue 4794 is fixed.
+        // Note that once we remove the manual recursion, we'll need to
+        // explicitly filter out files in hidden directories.
+        if (recursive) {
+          children.addAll(doList(entityPath, listedDirectories));
+        }
+      }
+    }
+
+    log.fine("Listed directory $dir:\n${contents.join('\n')}");
+    contents.addAll(children);
+    return contents;
   }
 
   return doList(dir, new Set<String>());
@@ -210,7 +197,7 @@
   } else if (dirExists(path)) {
     log.io("Deleting directory $path.");
     new Directory(path).deleteSync(recursive: true);
-  } else {
+  } else if (fileExists(path)) {
     log.io("Deleting file $path.");
     new File(path).deleteSync();
   }
@@ -236,7 +223,7 @@
 /// symlink to the target. Otherwise, uses the [target] path unmodified.
 ///
 /// Note that on Windows, only directories may be symlinked to.
-Future<String> createSymlink(String target, String symlink,
+void createSymlink(String target, String symlink,
     {bool relative: false}) {
   if (relative) {
     // Relative junction points are not supported on Windows. Instead, just
@@ -252,51 +239,32 @@
   }
 
   log.fine("Creating $symlink pointing to $target");
-
-  var command = 'ln';
-  var args = ['-s', target, symlink];
-
-  if (Platform.operatingSystem == 'windows') {
-    // Call mklink on Windows to create an NTFS junction point. Only works on
-    // Vista or later. (Junction points are available earlier, but the "mklink"
-    // command is not.) I'm using a junction point (/j) here instead of a soft
-    // link (/d) because the latter requires some privilege shenanigans that
-    // I'm not sure how to specify from the command line.
-    command = 'mklink';
-    args = ['/j', symlink, target];
-  }
-
-  // TODO(rnystrom): Check exit code and output?
-  return runProcess(command, args).then((result) => symlink);
+  new Link(symlink).createSync(target);
 }
 
 /// Creates a new symlink that creates an alias at [symlink] that points to the
-/// `lib` directory of package [target]. Returns a [Future] which completes to
-/// the path to the symlink file. If [target] does not have a `lib` directory,
-/// this shows a warning if appropriate and then does nothing.
+/// `lib` directory of package [target]. If [target] does not have a `lib`
+/// directory, this shows a warning if appropriate and then does nothing.
 ///
 /// If [relative] is true, creates a symlink with a relative path from the
 /// symlink to the target. Otherwise, uses the [target] path unmodified.
-Future<String> createPackageSymlink(String name, String target, String symlink,
+void createPackageSymlink(String name, String target, String symlink,
     {bool isSelfLink: false, bool relative: false}) {
-  return defer(() {
-    // See if the package has a "lib" directory.
-    target = path.join(target, 'lib');
-    log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'.");
-    if (dirExists(target)) {
-      return createSymlink(target, symlink, relative: relative);
-    }
+  // See if the package has a "lib" directory.
+  target = path.join(target, 'lib');
+  log.fine("Creating ${isSelfLink ? "self" : ""}link for package '$name'.");
+  if (dirExists(target)) {
+    createSymlink(target, symlink, relative: relative);
+    return;
+  }
 
-    // It's OK for the self link (i.e. the root package) to not have a lib
-    // directory since it may just be a leaf application that only has
-    // code in bin or web.
-    if (!isSelfLink) {
-      log.warning('Warning: Package "$name" does not have a "lib" directory so '
-                  'you will not be able to import any libraries from it.');
-    }
-
-    return symlink;
-  });
+  // It's OK for the self link (i.e. the root package) to not have a lib
+  // directory since it may just be a leaf application that only has
+  // code in bin or web.
+  if (!isSelfLink) {
+    log.warning('Warning: Package "$name" does not have a "lib" directory so '
+                'you will not be able to import any libraries from it.');
+  }
 }
 
 /// Resolves [target] relative to the location of pub.dart.
@@ -585,7 +553,7 @@
 /// Returns a future that completes to the value that the future returned from
 /// [fn] completes to.
 Future withTempDir(Future fn(String path)) {
-  return defer(() {
+  return new Future.of(() {
     var tempDir = createTempDir();
     return new Future.of(() => fn(tempDir))
         .whenComplete(() => deleteEntry(tempDir));
@@ -651,18 +619,13 @@
             '${result.stdout.join("\n")}\n'
             '${result.stderr.join("\n")}';
       }
-      // Find the tar file we just created since we don't know its name.
-      return listDir(tempDir);
-    }).then((files) {
-      var tarFile;
-      for (var file in files) {
-        if (path.extension(file) == '.tar') {
-          tarFile = file;
-          break;
-        }
-      }
 
-      if (tarFile == null) throw 'The gzip file did not contain a tar file.';
+      // Find the tar file we just created since we don't know its name.
+      var tarFile = listDir(tempDir).firstWhere(
+          (file) => path.extension(file) == '.tar',
+          orElse: () {
+        throw 'The gzip file did not contain a tar file.';
+      });
 
       // Untar the archive into the destination directory.
       return runProcess(command, ['x', tarFile], workingDir: destination);
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index ced3ed4..85bfed7 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -104,7 +104,7 @@
 /// Gets a new OAuth2 client. If saved credentials are available, those are
 /// used; otherwise, the user is prompted to authorize the pub client.
 Future<Client> _getClient(SystemCache cache) {
-  return defer(() {
+  return new Future.of(() {
     var credentials = _loadCredentials(cache);
     if (credentials == null) return _authorize();
 
diff --git a/utils/pub/package.dart b/utils/pub/package.dart
index 1bc7445..d3d9819 100644
--- a/utils/pub/package.dart
+++ b/utils/pub/package.dart
@@ -43,20 +43,18 @@
   /// same conventions as pub.dartlang.org for choosing the primary one: the
   /// README with the fewest extensions that is lexically ordered first is
   /// chosen.
-  Future<String> get readmePath {
-    return listDir(dir).then((entries) {
-      var readmes = entries.map(path.basename).
-          where((entry) => entry.contains(_README_REGEXP));
-      if (readmes.isEmpty) return;
+  String get readmePath {
+    var readmes = listDir(dir).map(path.basename).
+        where((entry) => entry.contains(_README_REGEXP));
+    if (readmes.isEmpty) return;
 
-      return path.join(dir, readmes.min((readme1, readme2) {
-        var extensions1 = ".".allMatches(readme1).length;
-        var extensions2 = ".".allMatches(readme2).length;
-        var comparison = extensions1.compareTo(extensions2);
-        if (comparison != 0) return comparison;
-        return readme1.compareTo(readme2);
-      }));
-    });
+    return path.join(dir, readmes.min((readme1, readme2) {
+      var extensions1 = ".".allMatches(readme1).length;
+      var extensions2 = ".".allMatches(readme2).length;
+      var comparison = extensions1.compareTo(extensions2);
+      if (comparison != 0) return comparison;
+      return readme1.compareTo(readme2);
+    }));
   }
 
   /// Loads the package whose root directory is [packageDir]. [name] is the
diff --git a/utils/pub/path_source.dart b/utils/pub/path_source.dart
index 3b433a1..e849b6f 100644
--- a/utils/pub/path_source.dart
+++ b/utils/pub/path_source.dart
@@ -25,7 +25,7 @@
   final shouldCache = false;
 
   Future<Pubspec> describe(PackageId id) {
-    return defer(() {
+    return new Future.of(() {
       _validatePath(id.name, id.description);
       return new Pubspec.load(id.name, id.description["path"],
           systemCache.sources);
@@ -40,16 +40,17 @@
   }
 
   Future<bool> install(PackageId id, String destination) {
-    return defer(() {
+    return new Future.of(() {
       try {
         _validatePath(id.name, id.description);
       } on FormatException catch(err) {
         return false;
       }
 
-      return createPackageSymlink(id.name, id.description["path"], destination,
+      createPackageSymlink(id.name, id.description["path"], destination,
           relative: id.description["relative"]);
-    }).then((_) => true);
+      return true;
+    });
   }
 
   /// Parses a path dependency. This takes in a path string and returns a map.
diff --git a/utils/pub/pub.dart b/utils/pub/pub.dart
index 5f52a53..811c198 100644
--- a/utils/pub/pub.dart
+++ b/utils/pub/pub.dart
@@ -145,7 +145,7 @@
 /// Checks that pub is running on a supported platform. If it isn't, it prints
 /// an error message and exits. Completes when the validation is done.
 Future validatePlatform() {
-  return defer(() {
+  return new Future.of(() {
     if (Platform.operatingSystem != 'windows') return;
 
     return runProcess('ver', []).then((result) {
@@ -265,7 +265,7 @@
       exit(_chooseExitCode(error));
     }
 
-    defer(() {
+    new Future.of(() {
       if (requiresEntrypoint) {
         // TODO(rnystrom): Will eventually need better logic to walk up
         // subdirectories until we hit one that looks package-like. For now,
diff --git a/utils/pub/source.dart b/utils/pub/source.dart
index 109b5b2..adb9571 100644
--- a/utils/pub/source.dart
+++ b/utils/pub/source.dart
@@ -113,17 +113,12 @@
       packageDir = p;
 
       // See if it's already cached.
-      if (!dirExists(packageDir)) return false;
-
-      return _isCachedPackageCorrupted(packageDir).then((isCorrupted) {
-        if (!isCorrupted) return true;
-
+      if (dirExists(packageDir)) {
+        if (!_isCachedPackageCorrupted(packageDir)) return true;
         // Busted, so wipe out the package and reinstall.
         deleteEntry(packageDir);
-        return false;
-      });
-    }).then((isInstalled) {
-      if (isInstalled) return true;
+      }
+
       ensureDir(path.dirname(packageDir));
       return install(id, packageDir);
     }).then((found) {
@@ -143,18 +138,14 @@
   ///
   ///   * It has an empty "lib" directory.
   ///   * It has no pubspec.
-  Future<bool> _isCachedPackageCorrupted(String packageDir) {
-    return defer(() {
-      if (!fileExists(path.join(packageDir, "pubspec.yaml"))) return true;
+  bool _isCachedPackageCorrupted(String packageDir) {
+    if (!fileExists(path.join(packageDir, "pubspec.yaml"))) return true;
 
-      var libDir = path.join(packageDir, "lib");
-      if (dirExists(libDir)) {
-        return listDir(libDir).then((contents) => contents.length == 0);
-      }
+    var libDir = path.join(packageDir, "lib");
+    if (dirExists(libDir)) return listDir(libDir).length == 0;
 
-      // If we got here, it's OK.
-      return false;
-    });
+    // If we got here, it's OK.
+    return false;
   }
 
   /// Returns the directory in the system cache that the package identified by
@@ -218,7 +209,7 @@
   Future<PackageId> resolveId(PackageId id) => new Future.immediate(id);
   
   /// Returns the [Package]s that have been installed in the system cache.
-  Future<List<Package>> getCachedPackages() {
+  List<Package> getCachedPackages() {
     if (shouldCache) throw "Source $name must implement this.";
   }
 
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart
index d354e68..cb316cbe 100644
--- a/utils/pub/utils.dart
+++ b/utils/pub/utils.dart
@@ -145,16 +145,6 @@
   return CryptoUtils.bytesToHex(sha.close());
 }
 
-/// Invokes the given callback asynchronously. Returns a [Future] that completes
-/// to the result of [callback].
-///
-/// This is also used to wrap synchronous code that may thrown an exception to
-/// ensure that methods that have both sync and async code only report errors
-/// asynchronously.
-Future defer(callback()) {
-  return new Future.immediate(null).then((_) => callback());
-}
-
 /// Returns a [Future] that completes in [milliseconds].
 Future sleep(int milliseconds) {
   var completer = new Completer();
diff --git a/utils/pub/validator/compiled_dartdoc.dart b/utils/pub/validator/compiled_dartdoc.dart
index b139869..1998c47 100644
--- a/utils/pub/validator/compiled_dartdoc.dart
+++ b/utils/pub/validator/compiled_dartdoc.dart
@@ -20,8 +20,8 @@
     : super(entrypoint);
 
   Future validate() {
-    return listDir(entrypoint.root.dir, recursive: true).then((entries) {
-      for (var entry in entries) {
+    return new Future.of(() {
+      for (var entry in listDir(entrypoint.root.dir, recursive: true)) {
         if (path.basename(entry) != "nav.json") continue;
         var dir = path.dirname(entry);
 
diff --git a/utils/pub/validator/directory.dart b/utils/pub/validator/directory.dart
index 032c0d1..5d6628d 100644
--- a/utils/pub/validator/directory.dart
+++ b/utils/pub/validator/directory.dart
@@ -21,8 +21,8 @@
   static final _PLURAL_NAMES = ["tools", "tests", "docs", "examples"];
 
   Future validate() {
-    return listDir(entrypoint.root.dir).then((dirs) {
-      for (var dir in dirs) {
+    return new Future.of(() {
+      for (var dir in listDir(entrypoint.root.dir)) {
         if (!dirExists(dir)) continue;
 
         dir = path.basename(dir);
diff --git a/utils/pub/validator/lib.dart b/utils/pub/validator/lib.dart
index c31b071..7ff06fc 100644
--- a/utils/pub/validator/lib.dart
+++ b/utils/pub/validator/lib.dart
@@ -23,26 +23,26 @@
     : super(entrypoint);
 
   Future validate() {
-    var libDir = path.join(entrypoint.root.dir, "lib");
+    return new Future.of(() {
+      var libDir = path.join(entrypoint.root.dir, "lib");
 
-    return defer(() {
       if (!dirExists(libDir)) {
         errors.add('You must have a "lib" directory.\n'
             "Without that, users cannot import any code from your package.");
         return;
       }
 
-      return listDir(libDir).then((files) {
-        files = files.map((file) => path.relative(file, from: libDir)).toList();
-        if (files.isEmpty) {
-          errors.add('You must have a non-empty "lib" directory.\n'
-              "Without that, users cannot import any code from your package.");
-        } else if (files.length == 1 && files.first == "src") {
-          errors.add('The "lib" directory must contain something other than '
-              '"src".\n'
-              "Otherwise, users cannot import any code from your package.");
-        }
-      });
+      var files = listDir(libDir)
+          .map((file) => path.relative(file, from: libDir))
+          .toList();
+      if (files.isEmpty) {
+        errors.add('You must have a non-empty "lib" directory.\n'
+            "Without that, users cannot import any code from your package.");
+      } else if (files.length == 1 && files.first == "src") {
+        errors.add('The "lib" directory must contain something other than '
+            '"src".\n'
+            "Otherwise, users cannot import any code from your package.");
+      }
     });
   }
 }
diff --git a/utils/pub/validator/license.dart b/utils/pub/validator/license.dart
index 6cd623b..ffcbd10 100644
--- a/utils/pub/validator/license.dart
+++ b/utils/pub/validator/license.dart
@@ -19,10 +19,14 @@
     : super(entrypoint);
 
   Future validate() {
-    return listDir(entrypoint.root.dir).then((files) {
+    return new Future.of(() {
       var licenseLike = new RegExp(
           r"^([a-zA-Z0-9]+[-_])?(LICENSE|COPYING)(\..*)?$");
-      if (files.map(path.basename).any(licenseLike.hasMatch)) return;
+      if (listDir(entrypoint.root.dir)
+          .map(path.basename)
+          .any(licenseLike.hasMatch)) {
+        return;
+      }
 
       errors.add(
           "You must have a COPYING or LICENSE file in the root directory.\n"
diff --git a/utils/pub/validator/name.dart b/utils/pub/validator/name.dart
index 2dc93e5..412d6c3 100644
--- a/utils/pub/validator/name.dart
+++ b/utils/pub/validator/name.dart
@@ -28,10 +28,11 @@
     : super(entrypoint);
 
   Future validate() {
-    _checkName(entrypoint.root.name, 'Package name "${entrypoint.root.name}"',
-        isPackage: true);
+    return new Future.of(() {
+      _checkName(entrypoint.root.name, 'Package name "${entrypoint.root.name}"',
+          isPackage: true);
 
-    return _libraries.then((libraries) {
+      var libraries = _libraries;
       for (var library in libraries) {
         var libName = path.basenameWithoutExtension(library);
         _checkName(libName, 'The name of "$library", "$libName",',
@@ -50,18 +51,14 @@
 
   /// Returns a list of all libraries in the current package as paths relative
   /// to the package's root directory.
-  Future<List<String>> get _libraries {
+  List<String> get _libraries {
     var libDir = path.join(entrypoint.root.dir, "lib");
-    return defer(() {
-      if (!dirExists(libDir)) return [];
-      return listDir(libDir, recursive: true);
-    }).then((files) {
-      return files
-          .map((file) => path.relative(file, from: path.dirname(libDir)))
-          .where((file) => !path.split(file).contains("src") &&
-                           path.extension(file) == '.dart')
-          .toList();
-    });
+    if (!dirExists(libDir)) return [];
+    return listDir(libDir, recursive: true)
+        .map((file) => path.relative(file, from: path.dirname(libDir)))
+        .where((file) => !path.split(file).contains("src") &&
+                         path.extension(file) == '.dart')
+        .toList();
   }
 
   void _checkName(String name, String description, {bool isPackage}) {
diff --git a/utils/pub/validator/utf8_readme.dart b/utils/pub/validator/utf8_readme.dart
index 145ac86..8bf52a9 100644
--- a/utils/pub/validator/utf8_readme.dart
+++ b/utils/pub/validator/utf8_readme.dart
@@ -20,7 +20,8 @@
     : super(entrypoint);
 
   Future validate() {
-    return entrypoint.root.readmePath.then((readme) {
+    return new Future.of(() {
+      var readme = entrypoint.root.readmePath;
       if (readme == null) return;
       var bytes = readBinaryFile(readme);
       try {
diff --git a/utils/tests/pub/descriptor/tar.dart b/utils/tests/pub/descriptor/tar.dart
index 18af2b3..453793d 100644
--- a/utils/tests/pub/descriptor/tar.dart
+++ b/utils/tests/pub/descriptor/tar.dart
@@ -27,8 +27,9 @@
       return Future.wait(contents.map((entry) {
         return entry.create(tempDir);
       })).then((_) {
-        return listDir(tempDir, recursive: true, includeHiddenFiles: true);
-      }).then((createdContents) {
+        var createdContents = listDir(tempDir,
+            recursive: true,
+            includeHidden: true);
         return createTarGz(createdContents, baseDir: tempDir).toBytes();
       }).then((bytes) {
         var file = path.join(parent, name);
diff --git a/utils/tests/pub/io_test.dart b/utils/tests/pub/io_test.dart
index 585d068..54e165f 100644
--- a/utils/tests/pub/io_test.dart
+++ b/utils/tests/pub/io_test.dart
@@ -19,120 +19,118 @@
   group('listDir', () {
     test('lists a simple directory non-recursively', () {
       expect(withTempDir((temp) {
-        var future = defer(() {
-          writeTextFile(path.join(temp, 'file1.txt'), '');
-          writeTextFile(path.join(temp, 'file2.txt'), '');
-          createDir(path.join(temp, 'subdir'));
-          writeTextFile(path.join(temp, 'subdir', 'file3.txt'), '');
-          return listDir(temp);
-        });
-        expect(future, completion(unorderedEquals([
+        writeTextFile(path.join(temp, 'file1.txt'), '');
+        writeTextFile(path.join(temp, 'file2.txt'), '');
+        createDir(path.join(temp, 'subdir'));
+        writeTextFile(path.join(temp, 'subdir', 'file3.txt'), '');
+
+        expect(listDir(temp), unorderedEquals([
           path.join(temp, 'file1.txt'),
           path.join(temp, 'file2.txt'),
           path.join(temp, 'subdir')
-        ])));
-        return future;
+        ]));
       }), completes);
     });
 
     test('lists a simple directory recursively', () {
       expect(withTempDir((temp) {
-        var future = defer(() {
-          writeTextFile(path.join(temp, 'file1.txt'), '');
-          writeTextFile(path.join(temp, 'file2.txt'), '');
-          createDir(path.join(temp, 'subdir'));
-          writeTextFile(path.join(temp, 'subdir', 'file3.txt'), '');
-          return listDir(temp, recursive: true);
-        });
+        writeTextFile(path.join(temp, 'file1.txt'), '');
+        writeTextFile(path.join(temp, 'file2.txt'), '');
+        createDir(path.join(temp, 'subdir'));
+        writeTextFile(path.join(temp, 'subdir', 'file3.txt'), '');
 
-        expect(future, completion(unorderedEquals([
+        expect(listDir(temp, recursive: true), unorderedEquals([
           path.join(temp, 'file1.txt'),
           path.join(temp, 'file2.txt'),
           path.join(temp, 'subdir'),
           path.join(temp, 'subdir', 'file3.txt'),
-        ])));
-        return future;
+        ]));
       }), completes);
     });
 
     test('ignores hidden files by default', () {
       expect(withTempDir((temp) {
-        var future = defer(() {
-          writeTextFile(path.join(temp, 'file1.txt'), '');
-          writeTextFile(path.join(temp, 'file2.txt'), '');
-          writeTextFile(path.join(temp, '.file3.txt'), '');
-          createDir(path.join(temp, '.subdir'));
-          writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');
-          return listDir(temp, recursive: true);
-        });
-        expect(future, completion(unorderedEquals([
+        writeTextFile(path.join(temp, 'file1.txt'), '');
+        writeTextFile(path.join(temp, 'file2.txt'), '');
+        writeTextFile(path.join(temp, '.file3.txt'), '');
+        createDir(path.join(temp, '.subdir'));
+        writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');
+
+        expect(listDir(temp, recursive: true), unorderedEquals([
           path.join(temp, 'file1.txt'),
           path.join(temp, 'file2.txt')
-        ])));
-        return future;
+        ]));
       }), completes);
     });
 
     test('includes hidden files when told to', () {
       expect(withTempDir((temp) {
-        var future = defer(() {
-          writeTextFile(path.join(temp, 'file1.txt'), '');
-          writeTextFile(path.join(temp, 'file2.txt'), '');
-          writeTextFile(path.join(temp, '.file3.txt'), '');
-          createDir(path.join(temp, '.subdir'));
-          writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');
-          return listDir(temp, recursive: true, includeHiddenFiles: true);
-        });
-        expect(future, completion(unorderedEquals([
+        writeTextFile(path.join(temp, 'file1.txt'), '');
+        writeTextFile(path.join(temp, 'file2.txt'), '');
+        writeTextFile(path.join(temp, '.file3.txt'), '');
+        createDir(path.join(temp, '.subdir'));
+        writeTextFile(path.join(temp, '.subdir', 'file3.txt'), '');
+
+        expect(listDir(temp, recursive: true, includeHidden: true),
+            unorderedEquals([
           path.join(temp, 'file1.txt'),
           path.join(temp, 'file2.txt'),
           path.join(temp, '.file3.txt'),
           path.join(temp, '.subdir'),
           path.join(temp, '.subdir', 'file3.txt')
-        ])));
-        return future;
+        ]));
       }), completes);
     });
 
     test('returns the unresolved paths for symlinks', () {
       expect(withTempDir((temp) {
         var dirToList = path.join(temp, 'dir-to-list');
-        var future = defer(() {
-          createDir(path.join(temp, 'dir1'));
-          writeTextFile(path.join(temp, 'dir1', 'file1.txt'), '');
-          createDir(path.join(temp, 'dir2'));
-          writeTextFile(path.join(temp, 'dir2', 'file2.txt'), '');
-          createDir(dirToList);
-          return createSymlink(path.join(temp, 'dir1'),
-                               path.join(dirToList, 'linked-dir1'));
-        }).then((_) {
-          createDir(path.join(dirToList, 'subdir'));
-          return createSymlink(
-                  path.join(temp, 'dir2'),
-                  path.join(dirToList, 'subdir', 'linked-dir2'));
-        }).then((_) => listDir(dirToList, recursive: true));
-        expect(future, completion(unorderedEquals([
+        createDir(path.join(temp, 'dir1'));
+        writeTextFile(path.join(temp, 'dir1', 'file1.txt'), '');
+        createDir(path.join(temp, 'dir2'));
+        writeTextFile(path.join(temp, 'dir2', 'file2.txt'), '');
+        createDir(dirToList);
+        createSymlink(
+            path.join(temp, 'dir1'),
+            path.join(dirToList, 'linked-dir1'));
+        createDir(path.join(dirToList, 'subdir'));
+        createSymlink(
+            path.join(temp, 'dir2'),
+            path.join(dirToList, 'subdir', 'linked-dir2'));
+
+        expect(listDir(dirToList, recursive: true), unorderedEquals([
           path.join(dirToList, 'linked-dir1'),
           path.join(dirToList, 'linked-dir1', 'file1.txt'),
           path.join(dirToList, 'subdir'),
           path.join(dirToList, 'subdir', 'linked-dir2'),
           path.join(dirToList, 'subdir', 'linked-dir2', 'file2.txt'),
-        ])));
-        return future;
+        ]));
       }), completes);
     });
 
     test('works with recursive symlinks', () {
       expect(withTempDir((temp) {
-        var future = defer(() {
-          writeTextFile(path.join(temp, 'file1.txt'), '');
-          return createSymlink(temp, path.join(temp, 'linkdir'));
-        }).then((_) => listDir(temp, recursive: true));
-        expect(future, completion(unorderedEquals([
+        writeTextFile(path.join(temp, 'file1.txt'), '');
+        createSymlink(temp, path.join(temp, 'linkdir'));
+
+        expect(listDir(temp, recursive: true), unorderedEquals([
           path.join(temp, 'file1.txt'),
           path.join(temp, 'linkdir')
-        ])));
-        return future;
+        ]));
+      }), completes);
+    });
+
+    test('treats a broken symlink as a file', () {
+      expect(withTempDir((temp) {
+        writeTextFile(path.join(temp, 'file1.txt'), '');
+        createDir(path.join(temp, 'dir'));
+        createSymlink(path.join(temp, 'dir'), path.join(temp, 'linkdir'));
+        deleteEntry(path.join(temp, 'dir'));
+
+        expect(listDir(temp, recursive: true), unorderedEquals([
+          path.join(temp, 'file1.txt'),
+          path.join(temp, 'linkdir')
+        ]));
       }), completes);
     });
   });
@@ -190,17 +188,17 @@
   group(name, () {
     test('returns $forFile for a file', () {
       expect(withTempDir((temp) {
-        var path = path.join(temp, "test.txt");
-        writeTextFile(path, "contents");
-        expect(predicate(path), equals(forFile));
+        var file = path.join(temp, "test.txt");
+        writeTextFile(file, "contents");
+        expect(predicate(file), equals(forFile));
       }), completes);
     });
 
     test('returns $forDirectory for a directory', () {
       expect(withTempDir((temp) {
-        var path = path.join(temp, "dir");
-        createDir(path);
-        expect(predicate(path), equals(forDirectory));
+        var file = path.join(temp, "dir");
+        createDir(file);
+        expect(predicate(file), equals(forDirectory));
       }), completes);
     });
 
@@ -209,9 +207,8 @@
         var targetPath = path.join(temp, "dir");
         var symlinkPath = path.join(temp, "linkdir");
         createDir(targetPath);
-        return createSymlink(targetPath, symlinkPath).then((_) {
-          expect(predicate(symlinkPath), equals(forDirectorySymlink));
-        });
+        createSymlink(targetPath, symlinkPath);
+        expect(predicate(symlinkPath), equals(forDirectorySymlink));
       }), completes);
     });
 
@@ -222,12 +219,10 @@
         var symlink1Path = path.join(temp, "link1dir");
         var symlink2Path = path.join(temp, "link2dir");
         createDir(targetPath);
-        return createSymlink(targetPath, symlink1Path)
-            .then((_) => createSymlink(symlink1Path, symlink2Path))
-            .then((_) {
-          expect(predicate(symlink2Path),
+        createSymlink(targetPath, symlink1Path);
+        createSymlink(symlink1Path, symlink2Path);
+        expect(predicate(symlink2Path),
               equals(forMultiLevelDirectorySymlink));
-        });
       }), completes);
     });
 
@@ -236,10 +231,9 @@
         var targetPath = path.join(temp, "dir");
         var symlinkPath = path.join(temp, "linkdir");
         createDir(targetPath);
-        return createSymlink(targetPath, symlinkPath).then((_) {
-          deleteEntry(targetPath);
-          expect(predicate(symlinkPath), equals(forBrokenSymlink));
-        });
+        createSymlink(targetPath, symlinkPath);
+        deleteEntry(targetPath);
+        expect(predicate(symlinkPath), equals(forBrokenSymlink));
       }), completes);
     });
 
@@ -250,12 +244,10 @@
         var symlink1Path = path.join(temp, "link1dir");
         var symlink2Path = path.join(temp, "link2dir");
         createDir(targetPath);
-        return createSymlink(targetPath, symlink1Path)
-            .then((_) => createSymlink(symlink1Path, symlink2Path))
-            .then((_) {
-          deleteEntry(targetPath);
-          expect(predicate(symlink2Path), equals(forMultiLevelBrokenSymlink));
-        });
+        createSymlink(targetPath, symlink1Path);
+        createSymlink(symlink1Path, symlink2Path);
+        deleteEntry(targetPath);
+        expect(predicate(symlink2Path), equals(forMultiLevelBrokenSymlink));
       }), completes);
     });
 
@@ -266,9 +258,8 @@
           var targetPath = path.join(temp, "test.txt");
           var symlinkPath = path.join(temp, "link.txt");
           writeTextFile(targetPath, "contents");
-          return createSymlink(targetPath, symlinkPath).then((_) {
-            expect(predicate(symlinkPath), equals(forFileSymlink));
-          });
+          createSymlink(targetPath, symlinkPath);
+          expect(predicate(symlinkPath), equals(forFileSymlink));
         }), completes);
       });
 
@@ -279,11 +270,9 @@
           var symlink1Path = path.join(temp, "link1.txt");
           var symlink2Path = path.join(temp, "link2.txt");
           writeTextFile(targetPath, "contents");
-          return createSymlink(targetPath, symlink1Path)
-              .then((_) => createSymlink(symlink1Path, symlink2Path))
-              .then((_) {
-            expect(predicate(symlink2Path), equals(forMultiLevelFileSymlink));
-          });
+          createSymlink(targetPath, symlink1Path);
+          createSymlink(symlink1Path, symlink2Path);
+          expect(predicate(symlink2Path), equals(forMultiLevelFileSymlink));
         }), completes);
       });
     }
diff --git a/utils/tests/pub/test_pub.dart b/utils/tests/pub/test_pub.dart
index 156f616..e2dc335 100644
--- a/utils/tests/pub/test_pub.dart
+++ b/utils/tests/pub/test_pub.dart
@@ -45,11 +45,15 @@
 /// test configuration for the machine running the tests.
 initConfig() {
   // If we aren't running on the bots, use the human-friendly config.
-  if (new Options().arguments.contains('--human')) {
-    configure(new CommandLineConfiguration());
+  if (!runningOnBuildbot) {
+    unittestConfiguration = new CommandLineConfiguration();
   }
 }
 
+/// Returns whether we're running on a Dart build bot.
+bool get runningOnBuildbot =>
+  Platform.environment.containsKey('BUILDBOT_BUILDERNAME');
+
 /// The current [HttpServer] created using [serve].
 var _server;
 
@@ -212,10 +216,6 @@
 /// Set to true when the current batch of scheduled events should be aborted.
 bool _abortScheduled = false;
 
-/// The time (in milliseconds) to wait for the entire scheduled test to
-/// complete.
-final _TIMEOUT = 30000;
-
 /// Defines an integration test. The [body] should schedule a series of
 /// operations which will be run asynchronously.
 void integration(String description, void body()) =>
@@ -227,6 +227,11 @@
 
 void _integration(String description, void body(), [Function testFn]) {
   testFn(description, () {
+    // The windows bots are very slow, so we increase the default timeout.
+    if (Platform.operatingSystem == "windows") {
+      currentSchedule.timeout = new Duration(seconds: 10);
+    }
+
     // Ensure the SDK version is always available.
     d.dir(sdkPath, [
       d.file('version', '0.1.2.3')
@@ -398,7 +403,7 @@
   schedule(() {
     return gitlib.isInstalled.then((installed) {
       if (installed) return;
-      if (Platform.environment.containsKey('BUILDBOT_BUILDERNAME')) return;
+      if (runningOnBuildbot) return;
       currentSchedule.abort();
     });
   }, 'ensuring that Git is installed');
@@ -578,7 +583,7 @@
   return schedule(() {
     var cache = new SystemCache.withSources(path.join(sandboxDir, cachePath));
 
-    return defer(() {
+    return new Future.of(() {
       var validator = fn(new Entrypoint(path.join(sandboxDir, appPath), cache));
       return validator.validate().then((_) {
         return new Pair(validator.errors, validator.warnings);
diff --git a/utils/tests/pub/version_solver_test.dart b/utils/tests/pub/version_solver_test.dart
index 835139a3..94a7c58 100644
--- a/utils/tests/pub/version_solver_test.dart
+++ b/utils/tests/pub/version_solver_test.dart
@@ -481,13 +481,11 @@
       : _packages = <String, Map<Version, Package>>{};
 
   Future<List<Version>> getVersions(String name, String description) {
-    return defer(() => _packages[description].keys.toList());
+    return new Future.of(() => _packages[description].keys.toList());
   }
 
   Future<Pubspec> describe(PackageId id) {
-    return defer(() {
-      return _packages[id.name][id.version].pubspec;
-    });
+    return new Future.of(() => _packages[id.name][id.version].pubspec);
   }
 
   Future<bool> install(PackageId id, String path) {