Version 1.8.0-dev.4.1

svn merge -c 41704 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 41705 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 41711 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@41762 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index f874056..fd49c22 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -1672,34 +1672,6 @@
         ..add(assembledCode)
         ..close();
     compiler.assembledCode = assembledCode;
-
-    if (!compiler.useContentSecurityPolicy) {
-      CodeBuffer cspBuffer = new CodeBuffer();
-      cspBuffer.add(mainBuffer);
-      cspBuffer.write("""
-{
-  var message =
-      'Deprecation: Automatic generation of output for Content Security\\n' +
-      'Policy is deprecated and will be removed with the next development\\n' +
-      'release. Use the --csp option to generate CSP restricted output.';
-  if (typeof dartPrint == "function") {
-    dartPrint(message);
-  } else if (typeof console == "object" && typeof console.log == "function") {
-    console.log(message);
-  } else if (typeof print == "function") {
-    print(message);
-  }
-}\n""");
-
-      cspBuffer.write(
-          jsAst.prettyPrint(
-              precompiledFunctionAst, compiler,
-              allowVariableMinification: false).getText());
-
-      compiler.outputProvider('', 'precompiled.js')
-          ..add(cspBuffer.getText())
-          ..close();
-    }
   }
 
   /// Returns a map from OutputUnit to a hash of its content. The hash uniquely
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index b65ae30..5f9bd9f 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -3,12 +3,17 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:mirrors' show MirrorSystem;
+import 'dart:convert' show JSON;
 
 patch class Error {
   /* patch */ static String _objectToString(Object object) {
     return Object._toString(object);
   }
 
+  /* patch */ static String _stringToSafeString(String string) {
+    return JSON.encode(string);
+  }
+
   /* patch */ StackTrace get stackTrace => _stackTrace;
 
   StackTrace _stackTrace;
diff --git a/sdk/lib/_internal/compiler/js_lib/core_patch.dart b/sdk/lib/_internal/compiler/js_lib/core_patch.dart
index 77098e1..2e2bab9 100644
--- a/sdk/lib/_internal/compiler/js_lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/js_lib/core_patch.dart
@@ -8,6 +8,7 @@
 import 'dart:_js_helper' show patch,
                               checkInt,
                               getRuntimeType,
+                              jsonEncodeNative,
                               JSSyntaxRegExp,
                               Primitives,
                               stringJoinUnchecked,
@@ -141,6 +142,11 @@
   }
 
   @patch
+  static String _stringToSafeString(String string) {
+    return jsonEncodeNative(string);
+  }
+
+  @patch
   StackTrace get stackTrace => Primitives.extractStackTrace(this);
 }
 
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
index 9f1c892..ae5c853 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
@@ -3238,6 +3238,10 @@
   return int32a + int32b * 0x100000000;
 }
 
+String jsonEncodeNative(String string) {
+  return JS("String", "JSON.stringify(#)", string);
+}
+
 /**
  * Returns a property name for placing data on JavaScript objects shared between
  * DOM isolates.  This happens when multiple programs are loaded in the same
diff --git a/sdk/lib/_internal/pub/test/build/copies_browser_js_next_to_entrypoints_test.dart b/sdk/lib/_internal/pub/test/build/copies_browser_js_next_to_entrypoints_test.dart
index 5178021..99e4e64 100644
--- a/sdk/lib/_internal/pub/test/build/copies_browser_js_next_to_entrypoints_test.dart
+++ b/sdk/lib/_internal/pub/test/build/copies_browser_js_next_to_entrypoints_test.dart
@@ -37,7 +37,7 @@
     pubGet();
 
     schedulePub(args: ["build", "foo", "web"],
-        output: new RegExp(r'Built 16 files to "build".'));
+        output: new RegExp(r'Built 12 files to "build".'));
 
     d.dir(appPath, [
       d.dir('build', [
diff --git a/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dependency_override_test.dart b/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dependency_override_test.dart
index 59d0ace..893eec3 100644
--- a/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dependency_override_test.dart
+++ b/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dependency_override_test.dart
@@ -36,7 +36,7 @@
     pubGet();
 
     schedulePub(args: ["build", "--all"],
-        output: new RegExp(r'Built 4 files to "build".'));
+        output: new RegExp(r'Built 3 files to "build".'));
 
     d.dir(appPath, [
       d.dir('build', [
diff --git a/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dev_dependency_test.dart b/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dev_dependency_test.dart
index 831de86..a174e3e 100644
--- a/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dev_dependency_test.dart
+++ b/sdk/lib/_internal/pub/test/build/copies_browser_js_with_dev_dependency_test.dart
@@ -36,7 +36,7 @@
     pubGet();
 
     schedulePub(args: ["build", "--all"],
-        output: new RegExp(r'Built 4 files to "build".'));
+        output: new RegExp(r'Built 3 files to "build".'));
 
     d.dir(appPath, [
       d.dir('build', [
diff --git a/sdk/lib/_internal/pub/test/build/outputs_results_to_json_test.dart b/sdk/lib/_internal/pub/test/build/outputs_results_to_json_test.dart
index 0099f0d..3fb7c1c 100644
--- a/sdk/lib/_internal/pub/test/build/outputs_results_to_json_test.dart
+++ b/sdk/lib/_internal/pub/test/build/outputs_results_to_json_test.dart
@@ -26,7 +26,7 @@
         outputJson: {
           'buildResult': 'success',
           'outputDirectory': 'build',
-          'numFiles': 2,
+          'numFiles': 1,
           'log': [
             {
               'level': 'Info',
diff --git a/sdk/lib/_internal/pub/test/dart2js/compiles_entrypoints_in_root_package_test.dart b/sdk/lib/_internal/pub/test/dart2js/compiles_entrypoints_in_root_package_test.dart
index c2ab7b4..f8207e6 100644
--- a/sdk/lib/_internal/pub/test/dart2js/compiles_entrypoints_in_root_package_test.dart
+++ b/sdk/lib/_internal/pub/test/dart2js/compiles_entrypoints_in_root_package_test.dart
@@ -40,7 +40,7 @@
     ]).create();
 
     schedulePub(args: ["build", "benchmark", "foo", "web"],
-        output: new RegExp(r'Built 12 files to "build".'));
+        output: new RegExp(r'Built 6 files to "build".'));
 
     d.dir(appPath, [
       d.dir('build', [
diff --git a/sdk/lib/_internal/pub/test/dart2js/omits_source_map_in_release_test.dart b/sdk/lib/_internal/pub/test/dart2js/omits_source_map_in_release_test.dart
index d4dbeaf..f26611e 100644
--- a/sdk/lib/_internal/pub/test/dart2js/omits_source_map_in_release_test.dart
+++ b/sdk/lib/_internal/pub/test/dart2js/omits_source_map_in_release_test.dart
@@ -16,7 +16,7 @@
     ]).create();
 
     schedulePub(args: ["build"],
-        output: new RegExp(r'Built 2 files to "build".'),
+        output: new RegExp(r'Built 1 file to "build".'),
         exitCode: 0);
 
     d.dir(appPath, [
diff --git a/sdk/lib/_internal/pub/test/dart2js/outputs_deferred_libraries_test.dart b/sdk/lib/_internal/pub/test/dart2js/outputs_deferred_libraries_test.dart
index 6680f12..7a0f4ae 100644
--- a/sdk/lib/_internal/pub/test/dart2js/outputs_deferred_libraries_test.dart
+++ b/sdk/lib/_internal/pub/test/dart2js/outputs_deferred_libraries_test.dart
@@ -50,7 +50,7 @@
     ]).create();
 
     schedulePub(args: ["build"],
-        output: new RegExp(r'Built 4 files to "build".'));
+        output: new RegExp(r'Built 3 files to "build".'));
 
     d.dir(appPath, [
       d.dir('build', [
diff --git a/sdk/lib/_internal/pub/test/dart2js/supports_configuration_with_build_test.dart b/sdk/lib/_internal/pub/test/dart2js/supports_configuration_with_build_test.dart
index e4d56c8..9650192 100644
--- a/sdk/lib/_internal/pub/test/dart2js/supports_configuration_with_build_test.dart
+++ b/sdk/lib/_internal/pub/test/dart2js/supports_configuration_with_build_test.dart
@@ -68,7 +68,7 @@
     pubGet();
 
     schedulePub(args: ["build"],
-        output: new RegExp(r'Built 4 files to "build".'),
+        output: new RegExp(r'Built 3 files to "build".'),
         exitCode: 0);
 
     d.dir(appPath, [
diff --git a/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_next_to_entrypoints_test.dart b/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_next_to_entrypoints_test.dart
index 21a73ab..d05ef15 100644
--- a/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_next_to_entrypoints_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_next_to_entrypoints_test.dart
@@ -40,7 +40,7 @@
 
     schedulePub(
         args: ["build", "foo", "web"],
-        output: new RegExp(r'Built 16 files to "build".'));
+        output: new RegExp(r'Built 12 files to "build".'));
 
     d.dir(
         appPath,
diff --git a/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dependency_override_test.dart b/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dependency_override_test.dart
index 2f27b26..de98aaa 100644
--- a/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dependency_override_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dependency_override_test.dart
@@ -37,7 +37,7 @@
 
     schedulePub(
         args: ["build", "--all"],
-        output: new RegExp(r'Built 4 files to "build".'));
+        output: new RegExp(r'Built 3 files to "build".'));
 
     d.dir(
         appPath,
diff --git a/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dev_dependency_test.dart b/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dev_dependency_test.dart
index abfbfa4..26184aa 100644
--- a/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dev_dependency_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/build/copies_browser_js_with_dev_dependency_test.dart
@@ -37,7 +37,7 @@
 
     schedulePub(
         args: ["build", "--all"],
-        output: new RegExp(r'Built 4 files to "build".'));
+        output: new RegExp(r'Built 3 files to "build".'));
 
     d.dir(
         appPath,
diff --git a/sdk/lib/_internal/pub_generated/test/build/outputs_results_to_json_test.dart b/sdk/lib/_internal/pub_generated/test/build/outputs_results_to_json_test.dart
index 497901e..8eff17d 100644
--- a/sdk/lib/_internal/pub_generated/test/build/outputs_results_to_json_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/build/outputs_results_to_json_test.dart
@@ -26,7 +26,7 @@
     schedulePub(args: ["build", "--format", "json"], outputJson: {
       'buildResult': 'success',
       'outputDirectory': 'build',
-      'numFiles': 2,
+      'numFiles': 1,
       'log': [{
           'level': 'Info',
           'transformer': {
diff --git a/sdk/lib/_internal/pub_generated/test/dart2js/compiles_entrypoints_in_root_package_test.dart b/sdk/lib/_internal/pub_generated/test/dart2js/compiles_entrypoints_in_root_package_test.dart
index 316754a..6fb2e5e 100644
--- a/sdk/lib/_internal/pub_generated/test/dart2js/compiles_entrypoints_in_root_package_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/dart2js/compiles_entrypoints_in_root_package_test.dart
@@ -41,7 +41,7 @@
 
     schedulePub(
         args: ["build", "benchmark", "foo", "web"],
-        output: new RegExp(r'Built 12 files to "build".'));
+        output: new RegExp(r'Built 6 files to "build".'));
 
     d.dir(
         appPath,
diff --git a/sdk/lib/_internal/pub_generated/test/dart2js/omits_source_map_in_release_test.dart b/sdk/lib/_internal/pub_generated/test/dart2js/omits_source_map_in_release_test.dart
index 070892f..248d2a2 100644
--- a/sdk/lib/_internal/pub_generated/test/dart2js/omits_source_map_in_release_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/dart2js/omits_source_map_in_release_test.dart
@@ -18,7 +18,7 @@
 
     schedulePub(
         args: ["build"],
-        output: new RegExp(r'Built 2 files to "build".'),
+        output: new RegExp(r'Built 1 file to "build".'),
         exitCode: 0);
 
     d.dir(
diff --git a/sdk/lib/_internal/pub_generated/test/dart2js/outputs_deferred_libraries_test.dart b/sdk/lib/_internal/pub_generated/test/dart2js/outputs_deferred_libraries_test.dart
index 2efeb0f..fc1ac70 100644
--- a/sdk/lib/_internal/pub_generated/test/dart2js/outputs_deferred_libraries_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/dart2js/outputs_deferred_libraries_test.dart
@@ -53,7 +53,7 @@
 
     schedulePub(
         args: ["build"],
-        output: new RegExp(r'Built 4 files to "build".'));
+        output: new RegExp(r'Built 3 files to "build".'));
 
     d.dir(
         appPath,
diff --git a/sdk/lib/_internal/pub_generated/test/dart2js/supports_configuration_with_build_test.dart b/sdk/lib/_internal/pub_generated/test/dart2js/supports_configuration_with_build_test.dart
index 6e217f0a..1c46412 100644
--- a/sdk/lib/_internal/pub_generated/test/dart2js/supports_configuration_with_build_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/dart2js/supports_configuration_with_build_test.dart
@@ -70,7 +70,7 @@
 
     schedulePub(
         args: ["build"],
-        output: new RegExp(r'Built 4 files to "build".'),
+        output: new RegExp(r'Built 3 files to "build".'),
         exitCode: 0);
 
     d.dir(
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index f4509eb..b8a3157 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -79,52 +79,14 @@
       return object.toString();
     }
     if (object is String) {
-      String string = object;
-      StringBuffer buffer = new StringBuffer('"');
-      const int TAB = 0x09;
-      const int NEWLINE = 0x0a;
-      const int CARRIGE_RETURN = 0x0d;
-      const int BACKSLASH = 0x5c;
-      const int DOUBLE_QUOTE = 0x22;
-      const int DIGIT_ZERO = 0x30;
-      const int LOWERCASE_A = 0x61;
-      const int MAX_CONTROL = 0x1f;
-      for (int i = 0; i < string.length; i++) {
-        int codeUnit = string.codeUnitAt(i);
-        if (codeUnit <= MAX_CONTROL) {
-          if (codeUnit == NEWLINE) {
-            buffer.write(r"\n");
-          } else if (codeUnit == CARRIGE_RETURN) {
-            buffer.write(r"\r");
-          } else if (codeUnit == TAB) {
-            buffer.write(r"\t");
-          } else {
-            buffer.write(r"\x");
-            // Convert code in range 0x00 .. 0x1f to hex a two-digit hex string.
-            if (codeUnit < 0x10) {
-              buffer.write("0");
-            } else {
-              buffer.write("1");
-              codeUnit -= 0x10;
-            }
-            // Single digit to hex.
-            buffer.writeCharCode(codeUnit < 10 ? DIGIT_ZERO + codeUnit
-                                               : LOWERCASE_A - 10 + codeUnit);
-          }
-        } else if (codeUnit == BACKSLASH) {
-          buffer.write(r"\\");
-        } else if (codeUnit == DOUBLE_QUOTE) {
-          buffer.write(r'\"');
-        } else {
-          buffer.writeCharCode(codeUnit);
-        }
-      }
-      buffer.write('"');
-      return buffer.toString();
+      return _stringToSafeString(object);
     }
     return _objectToString(object);
   }
 
+  /** Convert string to a valid string literal with no control characters. */
+  external static String _stringToSafeString(String string);
+
   external static String _objectToString(Object object);
 
   external StackTrace get stackTrace;
@@ -210,10 +172,11 @@
 
   String toString() {
     if (!_hasValue) {
+      var result = "Invalid arguments(s)";
       if (message != null) {
-        return "Invalid argument(s): $message";
+        result = "$result: $message";
       }
-      return "Invalid argument(s)";
+      return result;
     }
     String nameString = "";
     if (name != null) {
@@ -227,8 +190,6 @@
  * Error thrown due to an index being outside a valid range.
  */
 class RangeError extends ArgumentError {
-  /** The value that is outside its valid range. */
-  final num invalidValue;
   /** The minimum value that [value] is allowed to assume. */
   final num start;
   /** The maximum value that [value] is allowed to assume. */
@@ -240,12 +201,19 @@
    * Create a new [RangeError] with the given [message].
    */
   RangeError(var message)
-      : invalidValue = null, start = null, end = null, super(message);
+      : start = null, end = null, super(message);
 
-  /** Create a new [RangeError] with a message for the given [value]. */
-  RangeError.value(num value, [String message = "Value not in range"])
-      : invalidValue = value, start = null, end = null,
-        super(message);
+  /**
+   * Create a new [RangeError] with a message for the given [value].
+   *
+   * An optional [name] can specify the argument name that has the
+   * invalid value, and the [message] can override the default error
+   * description.
+   */
+  RangeError.value(num value, [String name, String message])
+      : start = null, end = null,
+        super.value(value, name,
+                    (message != null) ? message : "Value not in range");
 
   /**
    * Create a new [RangeError] with for an invalid value being outside a range.
@@ -255,41 +223,52 @@
    *
    * For a range from 0 to the length of something, end exclusive, use
    * [RangeError.index].
+   *
+   * An optional [name] can specify the argument name that has the
+   * invalid value, and the [message] can override the default error
+   * description.
    */
-  RangeError.range(this.invalidValue, this.start, this.end,
-                   [String message = "Invalid value"]) : super(message);
+  RangeError.range(num invalidValue, this.start, this.end,
+                   [String name, String message])
+      : super.value(invalidValue, name,
+                    (message != null) ? message : "Invalid value");
 
   /**
    * Creates a new [RangeError] stating that [index] is not a valid index
    * into [indexable].
    *
+   * An optional [name] can specify the argument name that has the
+   * invalid value, and the [message] can override the default error
+   * description.
+   *
    * The [length] is the length of [indexable] at the time of the error.
    * If `length` is omitted, it defaults to `indexable.length`.
-   *
-   * The message is used as part of the string representation of the error.
    */
   factory RangeError.index(int index, indexable,
-                           [String message,
+                           [String name,
+                            String message,
                             int length]) = IndexError;
 
   String toString() {
-    if (invalidValue == null) return "$message";
+    if (!_hasValue) return "RangeError: $message";
     String value = Error.safeToString(invalidValue);
+    String explanation = "";
     if (start == null) {
-      if (end == null) {
-        return "$message ($value)";
+      if (end != null) {
+        explanation = ": Not less than or equal to $end";
       }
-      return "$message ($value): Value must be less than or equal to $end";
+      // If both are null, we don't add a description of the limits.
+    } else if (end == null) {
+      explanation = ": Not greater than or equal to $start";
+    } else if (end > start) {
+      explanation = ": Not in range $start..$end, inclusive.";
+    } else if (end < start) {
+      explanation = ": Valid value range is empty";
+    } else {
+      // end == start.
+      explanation = ": Only valid value is $start";
     }
-    if (end == null) {
-      return "$message ($value): Value must be greater than or equal to $start";
-    }
-    if (end > start) {
-      return "$message ($value): Value must be in range $start..$end, "
-             "inclusive.";
-    }
-    if (end < start) return "$message ($value): Valid range is empty";
-    return "$message ($value): Only valid value is $start";
+    return "RangeError: $message ($value)$explanation";
   }
 }
 
@@ -303,8 +282,6 @@
 class IndexError extends ArgumentError implements RangeError {
   /** The indexable object that [index] was not a valid index into. */
   final indexable;
-  /** The invalid index. */
-  final int invalidValue;
   /** The length of [indexable] at the time of the error. */
   final int length;
 
@@ -317,24 +294,25 @@
    *
    * The message is used as part of the string representation of the error.
    */
-  IndexError(this.invalidValue, indexable,
-             [String message = "Index out of range", int length])
+  IndexError(int invalidValue, indexable,
+             [String name, String message, int length])
       : this.indexable = indexable,
         this.length = (length != null) ? length : indexable.length,
-        super(message);
+        super.value(invalidValue, name,
+                    (message != null) ? message : "Index out of range");
 
   // Getters inherited from RangeError.
   int get start => 0;
   int get end => length - 1;
 
   String toString() {
+    assert(_hasValue);
     String target = Error.safeToString(indexable);
+    var explanation = "index should be less than $length";
     if (invalidValue < 0) {
-      return "RangeError: $message ($target[$invalidValue]): "
-             "index must not be negative.";
+      explanation = "index must not be negative";
     }
-    return "RangeError: $message: ($target[$invalidValue]): "
-           "index should be less than $length.";
+    return "RangeError: $message ($target[$invalidValue]): $explanation";
   }
 }
 
diff --git a/tests/corelib/safe_to_string_test.dart b/tests/corelib/safe_to_string_test.dart
index 233eb5d..c48b5dd 100644
--- a/tests/corelib/safe_to_string_test.dart
+++ b/tests/corelib/safe_to_string_test.dart
@@ -15,13 +15,13 @@
 
   Expect.stringEquals(r'"\\\"\n\r"', Error.safeToString('\\"\n\r'));
 
-  Expect.stringEquals(r'"\x00\x01\x02\x03\x04\x05\x06\x07"',
+  Expect.stringEquals(r'"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"',
                       Error.safeToString('\x00\x01\x02\x03\x04\x05\x06\x07'));
-  Expect.stringEquals(r'"\x08\t\n\x0b\x0c\r\x0e\x0f"',
+  Expect.stringEquals(r'"\b\t\n\u000b\f\r\u000e\u000f"',
                       Error.safeToString('\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'));
-  Expect.stringEquals(r'"\x10\x11\x12\x13\x14\x15\x16\x17"',
+  Expect.stringEquals(r'"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017"',
                       Error.safeToString('\x10\x11\x12\x13\x14\x15\x16\x17'));
-  Expect.stringEquals(r'"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"',
+  Expect.stringEquals(r'"\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"',
                       Error.safeToString('\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'));
   Expect.stringEquals('" "', Error.safeToString(" "));
 
diff --git a/tools/VERSION b/tools/VERSION
index 79f8ce9..ffab7bc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 8
 PATCH 0
 PRERELEASE 4
-PRERELEASE_PATCH 0
+PRERELEASE_PATCH 1