| Index: tool/input_sdk/lib/convert/json.dart
 | 
| diff --git a/tool/input_sdk/lib/convert/json.dart b/tool/input_sdk/lib/convert/json.dart
 | 
| index 083d26e3c35e0f824872a38c0c1dd635d71ad45b..e80a9868fab20b1c881dc54f198c90467ac8c569 100644
 | 
| --- a/tool/input_sdk/lib/convert/json.dart
 | 
| +++ b/tool/input_sdk/lib/convert/json.dart
 | 
| @@ -9,10 +9,10 @@ part of dart.convert;
 | 
|   *
 | 
|   * The [unsupportedObject] field holds that object that failed to be serialized.
 | 
|   *
 | 
| - * If an object isn't directly serializable, the serializer calls the 'toJson'
 | 
| + * If an object isn't directly serializable, the serializer calls the `toJson`
 | 
|   * method on the object. If that call fails, the error will be stored in the
 | 
|   * [cause] field. If the call returns an object that isn't directly
 | 
| - * serializable, the [cause] is be null.
 | 
| + * serializable, the [cause] is null.
 | 
|   */
 | 
|  class JsonUnsupportedObjectError extends Error {
 | 
|    /** The object that could not be serialized. */
 | 
| @@ -65,6 +65,11 @@ typedef _ToEncodable(var o);
 | 
|  /**
 | 
|   * A [JsonCodec] encodes JSON objects to strings and decodes strings to
 | 
|   * JSON objects.
 | 
| + *
 | 
| + * Examples:
 | 
| + *
 | 
| + *     var encoded = JSON.encode([1, 2, { "a": null }]);
 | 
| + *     var decoded = JSON.decode('["foo", { "bar": 499 }]');
 | 
|   */
 | 
|  class JsonCodec extends Codec<Object, String> {
 | 
|    final _Reviver _reviver;
 | 
| @@ -73,24 +78,22 @@ class JsonCodec extends Codec<Object, String> {
 | 
|    /**
 | 
|     * Creates a `JsonCodec` with the given reviver and encoding function.
 | 
|     *
 | 
| -   * The [reviver] function is called during decoding. It is invoked
 | 
| -   * once for each object or list property that has been parsed.
 | 
| -   * The `key` argument is either the
 | 
| -   * integer list index for a list property, the string map key for object
 | 
| -   * properties, or `null` for the final result.
 | 
| +   * The [reviver] function is called during decoding. It is invoked once for
 | 
| +   * each object or list property that has been parsed.
 | 
| +   * The `key` argument is either the integer list index for a list property,
 | 
| +   * the string map key for object properties, or `null` for the final result.
 | 
|     *
 | 
|     * If [reviver] is omitted, it defaults to returning the value argument.
 | 
|     *
 | 
|     * The [toEncodable] function is used during encoding. It is invoked for
 | 
| -   * values that are not directly encodable to a JSON1toE
 | 
| -   * string (a value that is not a number, boolean, string, null, list or a map
 | 
| -   * with string keys). The function must return an object that is directly
 | 
| -   * encodable. The elements of a returned list and values of a returned map
 | 
| -   * do not need be directly encodable, and if they aren't, `toEncodable` will
 | 
| -   * be used on them as well.
 | 
| -   * Please notice that it is possible to cause an infinite recursive
 | 
| -   * regress in this way, by effectively creating an infinite data structure
 | 
| -   * through repeated call to `toEncodable`.
 | 
| +   * values that are not directly encodable to a string (a value that is not a
 | 
| +   * number, boolean, string, null, list or a map with string keys). The
 | 
| +   * function must return an object that is directly encodable. The elements of
 | 
| +   * a returned list and values of a returned map do not need to be directly
 | 
| +   * encodable, and if they aren't, `toEncodable` will be used on them as well.
 | 
| +   * Please notice that it is possible to cause an infinite recursive regress
 | 
| +   * in this way, by effectively creating an infinite data structure through
 | 
| +   * repeated call to `toEncodable`.
 | 
|     *
 | 
|     * If [toEncodable] is omitted, it defaults to a function that returns the
 | 
|     * result of calling `.toJson()` on the unencodable object.
 | 
| @@ -156,7 +159,7 @@ class JsonCodec extends Codec<Object, String> {
 | 
|  /**
 | 
|   * This class converts JSON objects to strings.
 | 
|   */
 | 
| -class JsonEncoder extends Converter<Object, String> {
 | 
| +class JsonEncoder extends ChunkedConverter<Object, String, Object, String> {
 | 
|    /**
 | 
|     * The string used for indention.
 | 
|     *
 | 
| @@ -215,14 +218,14 @@ class JsonEncoder extends Converter<Object, String> {
 | 
|     * Converts [object] to a JSON [String].
 | 
|     *
 | 
|     * Directly serializable values are [num], [String], [bool], and [Null], as
 | 
| -   * well as some [List] and [Map] values.
 | 
| -   * For [List], the elements must all be serializable.
 | 
| -   * For [Map], the keys must be [String] and the values must be serializable.
 | 
| +   * well as some [List] and [Map] values. For [List], the elements must all be
 | 
| +   * serializable. For [Map], the keys must be [String] and the values must be
 | 
| +   * serializable.
 | 
|     *
 | 
| -   * If a value is any other type is attempted serialized, the conversion
 | 
| -   * function provided in the constructor is invoked with the object as argument
 | 
| -   * and the result, which must be a directly serializable value,
 | 
| -   * is serialized instead of the original value.
 | 
| +   * If a value of any other type is attempted to be serialized, the
 | 
| +   * `toEncodable` function provided in the constructor is called with the value
 | 
| +   * as argument. The result, which must be a directly serializable value, is
 | 
| +   * serialized instead of the original value.
 | 
|     *
 | 
|     * If the conversion throws, or returns a value that is not directly
 | 
|     * serializable, a [JsonUnsupportedObjectError] exception is thrown.
 | 
| @@ -262,7 +265,7 @@ class JsonEncoder extends Converter<Object, String> {
 | 
|      return new _JsonEncoderSink(sink, _toEncodable, indent);
 | 
|    }
 | 
|  
 | 
| -  // Override the base-classes bind, to provide a better type.
 | 
| +  // Override the base class's bind, to provide a better type.
 | 
|    Stream<String> bind(Stream<Object> stream) => super.bind(stream);
 | 
|  
 | 
|    Converter<Object, dynamic> fuse(Converter<String, dynamic> other) {
 | 
| @@ -280,7 +283,8 @@ class JsonEncoder extends Converter<Object, String> {
 | 
|   * a JSON string, and then UTF-8 encoding the string, but without
 | 
|   * creating an intermediate string.
 | 
|   */
 | 
| -class JsonUtf8Encoder extends Converter<Object, List<int>> {
 | 
| +class JsonUtf8Encoder extends
 | 
| +    ChunkedConverter<Object, List<int>, Object, List<int>> {
 | 
|    /** Default buffer size used by the JSON-to-UTF-8 encoder. */
 | 
|    static const int DEFAULT_BUFFER_SIZE = 256;
 | 
|    /** Indentation used in pretty-print mode, `null` if not pretty. */
 | 
| @@ -299,20 +303,21 @@ class JsonUtf8Encoder extends Converter<Object, List<int>> {
 | 
|     * If `indent` contains characters that are not valid JSON whitespace
 | 
|     * characters, the result will not be valid JSON. JSON whitespace characters
 | 
|     * are space (U+0020), tab (U+0009), line feed (U+000a) and carriage return
 | 
| -   * (U+000d) (ECMA 404).
 | 
| +   * (U+000d) ([ECMA
 | 
| +   * 404](http://www.ecma-international.org/publications/standards/Ecma-404.htm)).
 | 
|     *
 | 
|     * The [bufferSize] is the size of the internal buffers used to collect
 | 
|     * UTF-8 code units.
 | 
|     * If using [startChunkedConversion], it will be the size of the chunks.
 | 
|     *
 | 
| -   * The JSON encoder handles numbers, strings, booleans, null, lists and
 | 
| -   * maps directly.
 | 
| +   * The JSON encoder handles numbers, strings, booleans, null, lists and maps
 | 
| +   * directly.
 | 
|     *
 | 
| -   * Any other object is attempted converted by [toEncodable] to an
 | 
| -   * object that is of one of the convertible types.
 | 
| +   * Any other object is attempted converted by [toEncodable] to an object that
 | 
| +   * is of one of the convertible types.
 | 
|     *
 | 
| -   * If [toEncodable] is omitted, it defaults to calling `.toJson()` on
 | 
| -   * the object.
 | 
| +   * If [toEncodable] is omitted, it defaults to calling `.toJson()` on the
 | 
| +   * object.
 | 
|     */
 | 
|    JsonUtf8Encoder([String indent,
 | 
|                     toEncodable(Object object),
 | 
| @@ -386,7 +391,7 @@ class JsonUtf8Encoder extends Converter<Object, List<int>> {
 | 
|                                      _indent, _bufferSize);
 | 
|    }
 | 
|  
 | 
| -  // Override the base-classes bind, to provide a better type.
 | 
| +  // Override the base class's bind, to provide a better type.
 | 
|    Stream<List<int>> bind(Stream<Object> stream) {
 | 
|      return super.bind(stream);
 | 
|    }
 | 
| @@ -469,7 +474,7 @@ class _JsonUtf8EncoderSink extends ChunkedConversionSink<Object> {
 | 
|  /**
 | 
|   * This class parses JSON strings and builds the corresponding objects.
 | 
|   */
 | 
| -class JsonDecoder extends Converter<String, Object> {
 | 
| +class JsonDecoder extends ChunkedConverter<String, Object, String, Object> {
 | 
|    final _Reviver _reviver;
 | 
|    /**
 | 
|     * Constructs a new JsonDecoder.
 | 
| @@ -482,8 +487,8 @@ class JsonDecoder extends Converter<String, Object> {
 | 
|     * Converts the given JSON-string [input] to its corresponding object.
 | 
|     *
 | 
|     * Parsed JSON values are of the types [num], [String], [bool], [Null],
 | 
| -   * [List]s of parsed JSON values or [Map]s from [String] to parsed
 | 
| -   * JSON values.
 | 
| +   * [List]s of parsed JSON values or [Map]s from [String] to parsed JSON
 | 
| +   * values.
 | 
|     *
 | 
|     * If `this` was initialized with a reviver, then the parsing operation
 | 
|     * invokes the reviver on every object or list property that has been parsed.
 | 
| @@ -496,14 +501,13 @@ class JsonDecoder extends Converter<String, Object> {
 | 
|    dynamic convert(String input) => _parseJson(input, _reviver);
 | 
|  
 | 
|    /**
 | 
| -   * Starts a conversion from a chunked JSON string to its corresponding
 | 
| -   * object.
 | 
| +   * Starts a conversion from a chunked JSON string to its corresponding object.
 | 
|     *
 | 
|     * The output [sink] receives exactly one decoded element through `add`.
 | 
|     */
 | 
|    external StringConversionSink startChunkedConversion(Sink<Object> sink);
 | 
|  
 | 
| -  // Override the base-classes bind, to provide a better type.
 | 
| +  // Override the base class's bind, to provide a better type.
 | 
|    Stream<Object> bind(Stream<String> stream) => super.bind(stream);
 | 
|  }
 | 
|  
 | 
| @@ -613,9 +617,8 @@ abstract class _JsonStringifier {
 | 
|    /**
 | 
|     * Check if an encountered object is already being traversed.
 | 
|     *
 | 
| -   * Records the object if it isn't already seen.
 | 
| -   * Should have a matching call to [_removeSeen] when the object
 | 
| -   * is no longer being traversed.
 | 
| +   * Records the object if it isn't already seen. Should have a matching call to
 | 
| +   * [_removeSeen] when the object is no longer being traversed.
 | 
|     */
 | 
|    void _checkCycle(object) {
 | 
|      for (int i = 0; i < _seen.length; i++) {
 | 
| @@ -627,7 +630,7 @@ abstract class _JsonStringifier {
 | 
|    }
 | 
|  
 | 
|    /**
 | 
| -   * Removes object from the list of currently traversed objects.
 | 
| +   * Remove [object] from the list of currently traversed objects.
 | 
|     *
 | 
|     * Should be called in the opposite order of the matching [_checkCycle]
 | 
|     * calls.
 | 
| @@ -639,10 +642,10 @@ abstract class _JsonStringifier {
 | 
|    }
 | 
|  
 | 
|    /**
 | 
| -   * Writes an object.
 | 
| +   * Write an object.
 | 
|     *
 | 
| -   * If the object isn't directly encodable, the [_toEncodable] function
 | 
| -   * gets one chance to return a replacement which is encodable.
 | 
| +   * If [object] isn't directly encodable, the [_toEncodable] function gets one
 | 
| +   * chance to return a replacement which is encodable.
 | 
|     */
 | 
|    void writeObject(object) {
 | 
|      // Tries stringifying object directly. If it's not a simple value, List or
 | 
| @@ -662,7 +665,7 @@ abstract class _JsonStringifier {
 | 
|    }
 | 
|  
 | 
|    /**
 | 
| -   * Serializes a [num], [String], [bool], [Null], [List] or [Map] value.
 | 
| +   * Serialize a [num], [String], [bool], [Null], [List] or [Map] value.
 | 
|     *
 | 
|     * Returns true if the value is one of these types, and false if not.
 | 
|     * If a value is both a [List] and a [Map], it's serialized as a [List].
 | 
| @@ -693,15 +696,16 @@ abstract class _JsonStringifier {
 | 
|        return true;
 | 
|      } else if (object is Map) {
 | 
|        _checkCycle(object);
 | 
| -      writeMap(object);
 | 
| +      // writeMap can fail if keys are not all strings.
 | 
| +      var success = writeMap(object);
 | 
|        _removeSeen(object);
 | 
| -      return true;
 | 
| +      return success;
 | 
|      } else {
 | 
|        return false;
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  /** Serializes a [List]. */
 | 
| +  /** Serialize a [List]. */
 | 
|    void writeList(List list) {
 | 
|      writeString('[');
 | 
|      if (list.length > 0) {
 | 
| @@ -714,18 +718,34 @@ abstract class _JsonStringifier {
 | 
|      writeString(']');
 | 
|    }
 | 
|  
 | 
| -  /** Serializes a [Map]. */
 | 
| -  void writeMap(Map<String, Object> map) {
 | 
| +  /** Serialize a [Map]. */
 | 
| +  bool writeMap(Map<String, Object> map) {
 | 
| +    if (map.isEmpty) {
 | 
| +      writeString("{}");
 | 
| +      return true;
 | 
| +    }
 | 
| +    List keyValueList = new List(map.length * 2);
 | 
| +    int i = 0;
 | 
| +    bool allStringKeys = true;
 | 
| +    map.forEach((key, value) {
 | 
| +      if (key is! String) {
 | 
| +        allStringKeys = false;
 | 
| +      }
 | 
| +      keyValueList[i++] = key;
 | 
| +      keyValueList[i++] = value;
 | 
| +    });
 | 
| +    if (!allStringKeys) return false;
 | 
|      writeString('{');
 | 
|      String separator = '"';
 | 
| -    map.forEach((String key, value) {
 | 
| +    for (int i = 0; i < keyValueList.length; i += 2) {
 | 
|        writeString(separator);
 | 
|        separator = ',"';
 | 
| -      writeStringContent(key);
 | 
| +      writeStringContent(keyValueList[i]);
 | 
|        writeString('":');
 | 
| -      writeObject(value);
 | 
| -    });
 | 
| +      writeObject(keyValueList[i + 1]);
 | 
| +    }
 | 
|      writeString('}');
 | 
| +    return true;
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -763,29 +783,39 @@ abstract class _JsonPrettyPrintMixin implements _JsonStringifier {
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  void writeMap(Map map) {
 | 
| +  bool writeMap(Map map) {
 | 
|      if (map.isEmpty) {
 | 
| -      writeString('{}');
 | 
| -    } else {
 | 
| -      writeString('{\n');
 | 
| -      _indentLevel++;
 | 
| -      bool first = true;
 | 
| -      map.forEach((String key, Object value) {
 | 
| -        if (!first) {
 | 
| -          writeString(",\n");
 | 
| -        }
 | 
| -        writeIndentation(_indentLevel);
 | 
| -        writeString('"');
 | 
| -        writeStringContent(key);
 | 
| -        writeString('": ');
 | 
| -        writeObject(value);
 | 
| -        first = false;
 | 
| -      });
 | 
| -      writeString('\n');
 | 
| -      _indentLevel--;
 | 
| +      writeString("{}");
 | 
| +      return true;
 | 
| +    }
 | 
| +    List keyValueList = new List(map.length * 2);
 | 
| +    int i = 0;
 | 
| +    bool allStringKeys = true;
 | 
| +    map.forEach((key, value) {
 | 
| +      if (key is! String) {
 | 
| +        allStringKeys = false;
 | 
| +      }
 | 
| +      keyValueList[i++] = key;
 | 
| +      keyValueList[i++] = value;
 | 
| +    });
 | 
| +    if (!allStringKeys) return false;
 | 
| +    writeString('{\n');
 | 
| +    _indentLevel++;
 | 
| +    String separator = "";
 | 
| +    for (int i = 0; i < keyValueList.length; i += 2) {
 | 
| +      writeString(separator);
 | 
| +      separator = ",\n";
 | 
|        writeIndentation(_indentLevel);
 | 
| -      writeString('}');
 | 
| +      writeString('"');
 | 
| +      writeStringContent(keyValueList[i]);
 | 
| +      writeString('": ');
 | 
| +      writeObject(keyValueList[i + 1]);
 | 
|      }
 | 
| +    writeString('\n');
 | 
| +    _indentLevel--;
 | 
| +    writeIndentation(_indentLevel);
 | 
| +    writeString('}');
 | 
| +    return true;
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -873,19 +903,18 @@ class _JsonUtf8Stringifier extends _JsonStringifier {
 | 
|    _JsonUtf8Stringifier(toEncodable, int bufferSize, this.addChunk)
 | 
|        : this.bufferSize = bufferSize,
 | 
|          buffer = new Uint8List(bufferSize),
 | 
| -        super(toEncodable)
 | 
| -        ;
 | 
| +        super(toEncodable);
 | 
|  
 | 
|    /**
 | 
|     * Convert [object] to UTF-8 encoded JSON.
 | 
|     *
 | 
|     * Calls [addChunk] with slices of UTF-8 code units.
 | 
|     * These will typically have size [bufferSize], but may be shorter.
 | 
| -   * The buffers are not reused, so the [addChunk] call may keep and reuse
 | 
| -   * the chunks.
 | 
| +   * The buffers are not reused, so the [addChunk] call may keep and reuse the
 | 
| +   * chunks.
 | 
|     *
 | 
| -   * If [indent] is non-`null`, the result will be "pretty-printed" with
 | 
| -   * extra newlines and indentation, using [indent] as the indentation.
 | 
| +   * If [indent] is non-`null`, the result will be "pretty-printed" with extra
 | 
| +   * newlines and indentation, using [indent] as the indentation.
 | 
|     */
 | 
|    static void stringify(Object object,
 | 
|                          List<int> indent,
 | 
| 
 |