Version 1.12.0-dev.5.1

Cherry-pick 0a35f7be3bc2d6dd598374c8abed6bff768c72cc to dev
Cherry-pick 7f375e3ec19b1f36cec77a2c94e1696e47804f89 to dev
Cherry-pick 13335ebf97cbdabe3b3b0c9b3a13f4ffa6fb49d4 to dev
Cherry-pick 60c7a3d0abb5df3e833e15b279a0c0ff0fd39083 to dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index feb8c48..e8827b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@
 ### Core library changes
 
 * `dart:async`
-  * `StreamController`  added setters for the `onListen`, `onPause`, `onResume`
+  * `StreamController` added setters for the `onListen`, `onPause`, `onResume`
     and `onCancel` callbacks.
 
 * `dart:convert`
@@ -14,6 +14,7 @@
     This removes most `..` and `.` sequences from the URI path.
     Purely relative paths (no scheme or authority) are allowed to retain
     some leading "dot" segments.
+    Also added `hasAbsolutePath`, `hasEmptyPath`, and `hasScheme` properties.
 
 * `dart:html`
   * `NodeTreeSanitizer` added the `const trusted` field. It can be used
diff --git a/DEPS b/DEPS
index e6693ff..56677bd 100644
--- a/DEPS
+++ b/DEPS
@@ -49,7 +49,7 @@
   "collection_rev": "@1da9a07f32efa2ba0c391b289e2037391e31da0e",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
-  "dartdoc_tag" : "@v0.1.0+5",
+  "dartdoc_tag" : "@v0.4.0",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.0",
   "dev_compiler_rev": "@0.1.3",
@@ -196,9 +196,9 @@
   Var("dart_root") + "/third_party/pkg_tested/dart_style":
       (Var("github_mirror") % "dart_style") + Var("dart_style_tag"),
   Var("dart_root") + "/third_party/pkg/dartdoc":
-      "https://github.com/dart-lang/dartdoc.git" + Var("dartdoc_tag"),
+      (Var("github_mirror") % "dartdoc") + Var("dartdoc_tag"),
   Var("dart_root") + "/third_party/pkg/dev_compiler":
-      "https://github.com/dart-lang/dev_compiler.git" + Var("dev_compiler_rev"),
+      (Var("github_mirror") % "dev_compiler") + Var("dev_compiler_rev"),
   Var("dart_root") + "/third_party/pkg/glob":
       (Var("github_mirror") % "glob") + Var("glob_rev"),
   Var("dart_root") + "/third_party/pkg/html":
@@ -261,13 +261,11 @@
       + "/external/github.com/google/quiver-dart.git"
       + Var("quiver_tag"),
   Var("dart_root") + "/third_party/pkg/scheduled_test":
-      (Var("github_mirror") % "scheduled_test") +
-      Var("scheduled_test_tag"),
+      (Var("github_mirror") % "scheduled_test") + Var("scheduled_test_tag"),
   Var("dart_root") + "/third_party/pkg/shelf":
       (Var("github_mirror") % "shelf") + Var("shelf_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_static":
-      "https://github.com/dart-lang/shelf_static.git" +
-      Var("shelf_static_rev"),
+      (Var("github_mirror") % "shelf_static") + Var("shelf_static_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_web_socket":
       (Var("github_mirror") % "shelf_web_socket") +
       Var("shelf_web_socket_rev"),
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 6eb737e..7c9ee75 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1305,7 +1305,7 @@
 }
 
 /**
- * A subscritption on events from a [Stream].
+ * A subscription on events from a [Stream].
  *
  * When you listen on a [Stream] using [Stream.listen],
  * a [StreamSubscription] object is returned.
diff --git a/tests/language/async_star_await_pauses_test.dart b/tests/language/async_star_await_pauses_test.dart
new file mode 100644
index 0000000..c16fbdd
--- /dev/null
+++ b/tests/language/async_star_await_pauses_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() {
+  var sc;
+  var i = 0;
+  void send() {
+    if (i == 5) {
+      sc.close();
+    } else {
+      sc.add(i++);
+    }
+  }
+  sc = new StreamController(onListen: send, onResume: send);
+
+  f(s) async {
+    var r = 0;
+    await for (var i in s) {
+      r += await new Future.delayed(new Duration(milliseconds: 10), () => i);
+    }
+    return r;
+  }
+
+  asyncStart();
+  f(sc.stream).then((v) {
+    Expect.equals(10, v);
+    asyncEnd();
+  });
+}
diff --git a/tests/language/async_star_cancel_while_paused_test.dart b/tests/language/async_star_cancel_while_paused_test.dart
new file mode 100644
index 0000000..633769f
--- /dev/null
+++ b/tests/language/async_star_cancel_while_paused_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is a regression test for issue 22853.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() {
+  var list = [];
+  var sync = new Sync();
+  f() async* {
+    list.add("*1");
+    yield 1;
+    await sync.wait();
+    sync.release();
+    list.add("*2");
+    yield 2;
+    list.add("*3");
+  };
+  var stream = f();
+  var sub = stream.listen(list.add);
+
+  asyncStart();
+  return sync.wait().whenComplete(() {
+    Expect.listEquals(list, ["*1", 1]);
+    sub.pause();
+    return sync.wait();
+  }).whenComplete(() {
+    Expect.listEquals(list, ["*1", 1, "*2"]);
+    sub.cancel();
+    new Future.delayed(new Duration(milliseconds: 200), () {
+      // Should not have yielded 2 or added *3 while paused.
+      Expect.listEquals(list, ["*1", 1, "*2"]);
+      asyncEnd();
+    });
+  });
+}
+
+/**
+ * Allows two asynchronous executions to synchronize.
+ *
+ * Calling [wait] and waiting for the returned future to complete will
+ * wait for the other executions to call [wait] again. At that point,
+ * the waiting execution is allowed to continue (the returned future completes),
+ * and the more recent call to [wait] is now the waiting execution.
+ */
+class Sync {
+  Completer _completer = null;
+  // Release whoever is currently waiting and start waiting yourself.
+  Future wait([v]) {
+    if (_completer != null) _completer.complete(v);
+    _completer = new Completer();
+    return _completer.future;
+  }
+
+  // Release whoever is currently waiting.
+  void release([v]) {
+    if (_completer != null) {
+      _completer.complete(v);
+      _completer = null;
+    }
+  }
+}
diff --git a/tests/language/async_star_regression_2238_test.dart b/tests/language/async_star_regression_2238_test.dart
new file mode 100644
index 0000000..b73a61a
--- /dev/null
+++ b/tests/language/async_star_regression_2238_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is a regression test for issue 2238
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() {
+  f() async* {
+    label1: label2: yield 0;
+  }
+
+  asyncStart();
+  f().toList().then((list) {
+    Expect.listEquals([0], list);
+    asyncEnd();
+  });
+}
diff --git a/tests/language/async_star_regression_fisk_test.dart b/tests/language/async_star_regression_fisk_test.dart
new file mode 100644
index 0000000..b05356a9
--- /dev/null
+++ b/tests/language/async_star_regression_fisk_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test may crash dart2js.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+main() {
+  var res = [];
+  fisk() async* {
+    res.add("+fisk");
+    try {
+      for (int i = 0; i < 2; i++) {
+        yield await new Future.microtask(() => i);
+      }
+    } finally {
+      res.add("-fisk");
+    }
+  }
+
+  fugl(int count) async {
+    res.add("fisk $count");
+    try {
+      await for(int i in fisk().take(count)) res.add(i);
+    } finally {
+      res.add("done");
+    }
+  }
+
+  asyncStart();
+  fugl(3).whenComplete(() => fugl(2))
+      .whenComplete(() => fugl(1))
+      .whenComplete(() {
+    Expect.listEquals(res,
+        ["fisk 3", "+fisk", 0, 1, "-fisk", "done",
+         "fisk 2", "+fisk", 0, 1, "-fisk", "done",
+         "fisk 1", "+fisk", 0, "done", "-fisk", ]);
+    asyncEnd();
+  });
+}
diff --git a/tests/language/async_star_stream_take_test.dart b/tests/language/async_star_stream_take_test.dart
new file mode 100644
index 0000000..095082b
--- /dev/null
+++ b/tests/language/async_star_stream_take_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+Stream makeStream(int n) async* {
+  for (int i = 0; i < n; i++) yield i;
+}
+
+main() {
+  f(Stream s) async {
+    var r = 0;
+    await for(var v in s.take(5)) r += v;
+    return r;
+  }
+
+  asyncStart();
+  f(makeStream(10)).then((v) {
+    Expect.equals(10, v);
+    asyncEnd();
+  });
+}
+
diff --git a/tests/language/async_star_take_reyield_test.dart b/tests/language/async_star_take_reyield_test.dart
new file mode 100644
index 0000000..f2e8737
--- /dev/null
+++ b/tests/language/async_star_take_reyield_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+expectList(stream, list) {
+  return stream.toList().then((v) {
+    Expect.listEquals(v, list);
+  });
+}
+
+Stream makeStream(int n) async* {
+  for (int i = 0; i < n; i++) yield i;
+}
+
+main() {
+  fivePartialSums(Stream s) async* {
+    var r = 0;
+    await for(var v in s.take(5)) yield r += v;
+  }
+  asyncStart();
+  expectList(fivePartialSums(makeStream(10)), [0, 1, 3, 6, 10])
+      .then(asyncSuccess);
+}
diff --git a/tests/language/async_star_test.dart b/tests/language/async_star_test.dart
index 94a7523..c30f50e 100644
--- a/tests/language/async_star_test.dart
+++ b/tests/language/async_star_test.dart
@@ -143,14 +143,6 @@
       return expectList(f(), [0]);
     });
 
-    // VM issue 2238
-    test("labeled 2", () {          /// 01: ok
-      f() async* {                  /// 01: continued
-        label1: label2: yield 0;    /// 01: continued
-      }                             /// 01: continued
-      return expectList(f(), [0]);  /// 01: continued
-    });                             /// 01: continued
-
     test("for-loop", () {
       f() async* {
         for (int i = 0; i < 3; i++) yield i;
@@ -583,39 +575,6 @@
         return expectList(f().take(0), []);
       });
     });
-
-    // Crashes dart2js.
-    // test("regression-fugl/fisk", () {
-    //   var res = [];
-    //   fisk() async* {
-    //     res.add("+fisk");
-    //     try {
-    //       for (int i = 0; i < 2; i++) {
-    //         yield await new Future.microtask(() => i);
-    //       }
-    //     } finally {
-    //       res.add("-fisk");
-    //     }
-    //   }
-
-    //   fugl(int count) async {
-    //     res.add("fisk $count");
-    //     try {
-    //       await for(int i in fisk().take(count)) res.add(i);
-    //     } finally {
-    //       res.add("done");
-    //     }
-    //   }
-
-    //   return fugl(3).whenComplete(() => fugl(2))
-    //                 .whenComplete(() => fugl(1))
-    //                 .whenComplete(() {
-    //     expect(res, ["fisk 3", "+fisk", 0, 1, "-fisk", "done",
-    //                  "fisk 2", "+fisk", 0, 1, "-fisk", "done",
-    //                  "fisk 1", "+fisk", 0, "done", "-fisk", ]);
-    //   });
-    // });
-
   });
 
   group("pausing", () {
@@ -703,34 +662,6 @@
         expect(list.length == 18 || list.length == 19, isTrue);
       });
     });
-
-    test("canceling while paused at yield", () {                  /// 02: ok
-      var list = [];                                              /// 02: continued
-      var sync = new Sync();                                      /// 02: continued
-      f() async* {                                                /// 02: continued
-        list.add("*1");                                           /// 02: continued
-        yield 1;                                                  /// 02: continued
-        await sync.wait();                                        /// 02: continued
-        sync.release();                                           /// 02: continued
-        list.add("*2");                                           /// 02: continued
-        yield 2;                                                  /// 02: continued
-        list.add("*3");                                           /// 02: continued
-      };                                                          /// 02: continued
-      var stream = f();                                           /// 02: continued
-      var sub = stream.listen(list.add);                          /// 02: continued
-      return sync.wait().whenComplete(() {                        /// 02: continued
-        expect(list, equals(["*1", 1]));                          /// 02: continued
-        sub.pause();                                              /// 02: continued
-        return sync.wait();                                       /// 02: continued
-      }).whenComplete(() {                                        /// 02: continued
-        expect(list, equals(["*1", 1, "*2"]));                    /// 02: continued
-        sub.cancel();                                             /// 02: continued
-        return new Future.delayed(MS * 200, () {                  /// 02: continued
-          // Should not have yielded 2 or added *3 while paused.  /// 02: continued
-          expect(list, equals(["*1", 1, "*2"]));                  /// 02: continued
-        });                                                       /// 02: continued
-      });                                                         /// 02: continued
-    });                                                           /// 02: continued
   });
 
   group("await for", () {
@@ -760,17 +691,6 @@
       });
     });
 
-    test("simple stream - take", () {           /// 03: ok
-      f(s) async {                              /// 03: continued
-        var r = 0;                              /// 03: continued
-        await for(var v in s.take(5)) r += v;   /// 03: continued
-        return r;                               /// 03: continued
-      }                                         /// 03: continued
-      return f(mkStream(10)).then((v) {         /// 03: continued
-        expect(v, equals(10));                  /// 03: continued
-      });                                       /// 03: continued
-    });                                         /// 03: continued
-
     test("simple stream reyield", () {
       f(s) async* {
         var r = 0;
@@ -787,14 +707,6 @@
       return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
     });
 
-    test("simple stream - take, reyield", () {                /// 04: ok
-      f(s) async* {                                           /// 04: continued
-        var r = 0;                                            /// 04: continued
-        await for(var v in s.take(5)) yield r += v;           /// 04: continued
-      }                                                       /// 04: continued
-      return expectList(f(mkStream(10)), [0, 1, 3, 6, 10]);   /// 04: continued
-    });                                                       /// 04: continued
-
     test("nested", () {
       f() async {
         var r = 0;
@@ -840,29 +752,6 @@
         expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
       });
     });
-
-    test("await pauses loop", () {                                   /// 05: ok
-      var sc;                                                        /// 05: continued
-      var i = 0;                                                     /// 05: continued
-      void send() {                                                  /// 05: continued
-        if (i == 5) {                                                /// 05: continued
-          sc.close();                                                /// 05: continued
-        } else {                                                     /// 05: continued
-          sc.add(i++);                                               /// 05: continued
-        }                                                            /// 05: continued
-      }                                                              /// 05: continued
-      sc = new StreamController(onListen: send, onResume: send);     /// 05: continued
-      f(s) async {                                                   /// 05: continued
-        var r = 0;                                                   /// 05: continued
-        await for (var i in s) {                                     /// 05: continued
-          r += await new Future.delayed(MS * 10, () => i);           /// 05: continued
-        }                                                            /// 05: continued
-        return r;                                                    /// 05: continued
-      }                                                              /// 05: continued
-      return f(sc.stream).then((v) {                                 /// 05: continued
-        expect(v, equals(10));                                       /// 05: continued
-      });                                                            /// 05: continued
-    });                                                              /// 05: continued
   });
 }
 
@@ -894,29 +783,3 @@
     fail("Not implementing Stream.");
   }
 }
-
-/**
- * Allows two asynchronous executions to synchronize.
- *
- * Calling [wait] and waiting for the returned future to complete will
- * wait for the other executions to call [wait] again. At that point,
- * the waiting execution is allowed to continue (the returned future completes),
- * and the more resent call to [wait] is now the waiting execution.
- */
-class Sync {
-  Completer _completer = null;
-  // Release whoever is currently waiting and start waiting yourself.
-  Future wait([v]) {
-    if (_completer != null) _completer.complete(v);
-    _completer = new Completer();
-    return _completer.future;
-  }
-
-  // Release whoever is currently waiting.
-  void release([v]) {
-    if (_completer != null) {
-      _completer.complete(v);
-      _completer = null;
-    }
-  }
-}
diff --git a/tests/language/language.status b/tests/language/language.status
index 2f58a23..55e186d 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -27,9 +27,10 @@
 cyclic_type2_test: Fail, OK
 least_upper_bound_expansive_test/*: Fail, OK
 
-async_star_test/01: CompileTimeError, RuntimeError # drt only runtime-errs.
-async_star_test/02: RuntimeError
-async_star_test/05: Timeout, RuntimeError
+async_star_regression_2238_test: CompileTimeError, RuntimeError # drt only runtime-errs.
+async_star_cancel_while_paused_test: RuntimeError
+async_star_await_pauses_test: Skip # Times out. Issue 23996
+async_star_regression_fisk_test: RuntimeError # Issue 23994
 
 [ $compiler == none && $runtime == vm ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 00d35b0..4740960 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -8,8 +8,8 @@
 sync_generator2_test/10: MissingCompileTimeError # Issue 22324
 getter_setter_in_lib_test: Fail # Issue 23288
 
-async_star_test/02: RuntimeError # 22853
-async_star_test/05: RuntimeError, Timeout
+async_star_cancel_while_paused_test: RuntimeError # Issue 22853
+async_star_await_pauses_test: Fail, Timeout # Issue 22853
 tearoff_basic_test: Skip # Tear-off not supported
 tearoff_constructor_basic_test: Skip # Tear-off not supported
 
@@ -382,12 +382,12 @@
 async_return_types_test/wrongTypeParameter: Crash # (test()async{Expect....  cannot handle async/sync*/async* functions
 async_star_cancel_and_throw_in_finally_test: Crash # (test()async{var com...  cannot handle async/sync*/async* functions
 async_star_regression_23116_test: Crash # (test()async{Complet...  cannot handle async/sync*/async* functions
-async_star_test/01: Crash # (f()async*{}): cannot handle async/sync*/async* functions
-async_star_test/02: Crash # (f()async*{}): cannot handle async/sync*/async* functions
-async_star_test/03: Crash # (f()async*{}): cannot handle async/sync*/async* functions
-async_star_test/04: Crash # (f()async*{}): cannot handle async/sync*/async* functions
-async_star_test/05: Crash # (f()async*{}): cannot handle async/sync*/async* functions
-async_star_test/none: Crash # (f()async*{}): cannot handle async/sync*/async* functions
+async_star_regression_2238_test: Crash # (f()async*{}): cannot handle async/sync*/async* functions
+async_star_cancel_while_paused_test: Crash # (f()async*{}): cannot handle async/sync*/async* functions
+async_star_stream_take_test: Crash # (f()async*{}): cannot handle async/sync*/async* functions
+async_star_take_reyield_test: Crash # (f()async*{}): cannot handle async/sync*/async* functions
+async_star_await_pauses_test: Crash # (f()async*{}): cannot handle async/sync*/async* functions
+async_star_test: Crash # (f()async*{}): cannot handle async/sync*/async* functions
 async_switch_test/none: Crash # (test()async{Expect....  cannot handle async/sync*/async* functions
 async_switch_test/withDefault: Crash # (test()async{Expect....  cannot handle async/sync*/async* functions
 async_test/none: Crash # (bar(int p1,p2)async{var z=8;return p2+z+foo;}): cannot handle async/sync*/async* functions
diff --git a/tests/lib/async/stream_controller_test.dart b/tests/lib/async/stream_controller_test.dart
index c03dc4a..c9ef021 100644
--- a/tests/lib/async/stream_controller_test.dart
+++ b/tests/lib/async/stream_controller_test.dart
@@ -481,17 +481,17 @@
   Expect.equals(c.stream, c.stream);
   c = new StreamController(sync: true);
   Expect.equals(c.stream, c.stream);
-  c = new StreamController(sync: false, onListen:(){});
+  c = new StreamController(sync: false, onListen: () {});
   Expect.equals(c.stream, c.stream);
-  c = new StreamController(sync: true, onListen:(){});
+  c = new StreamController(sync: true, onListen: () {});
   Expect.equals(c.stream, c.stream);
   c = new StreamController.broadcast(sync: false);
   Expect.equals(c.stream, c.stream);
   c = new StreamController.broadcast(sync: true);
   Expect.equals(c.stream, c.stream);
-  c = new StreamController.broadcast(sync: false, onListen:(){});
+  c = new StreamController.broadcast(sync: false, onListen: () {});
   Expect.equals(c.stream, c.stream);
-  c = new StreamController.broadcast(sync: true, onListen:(){});
+  c = new StreamController.broadcast(sync: true, onListen: () {});
   Expect.equals(c.stream, c.stream);
 }
 
@@ -811,9 +811,9 @@
   var stream = controller.stream;
   var state = initial;
 
-  Expect.throws(() { controller.onPause = (){}; },
+  Expect.throws(() { controller.onPause = () {}; },
                 (e) => e is UnsupportedError);
-  Expect.throws(() { controller.onResume = (){}; },
+  Expect.throws(() { controller.onResume = () {}; },
                 (e) => e is UnsupportedError);
 
   controller..onListen = () { state = running; }
diff --git a/tools/VERSION b/tools/VERSION
index 1800f31..6dd51cf 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 12
 PATCH 0
 PRERELEASE 5
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1